Merge branch 'development'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be4cb6e..17ee507 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,41 @@
+# 2.1.0-beta.1 (2018-08-27)

+

+Major release after many months of development in "development" branch and features branches. Many new features added, some bugs fixed. API stays backward-compatible.

+

+Major changes:

+

+- Added linear allocation algorithm, accessible for custom pools, that can be used as free-at-once, stack, double stack, or ring buffer. See "Linear allocation algorithm" documentation chapter.

+  - Added `VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT`, `VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT`.

+- Added feature to record sequence of calls to the library to a file and replay it using dedicated application. See documentation chapter "Record and replay".

+  - Recording: added `VmaAllocatorCreateInfo::pRecordSettings`.

+  - Replaying: added VmaReplay project.

+  - Recording file format: added document "docs/Recording file format.md".

+- Improved support for non-coherent memory.

+  - Added functions: `vmaFlushAllocation`, `vmaInvalidateAllocation`.

+  - `nonCoherentAtomSize` is now respected automatically.

+  - Added `VmaVulkanFunctions::vkFlushMappedMemoryRanges`, `vkInvalidateMappedMemoryRanges`.

+- Improved debug features related to detecting incorrect mapped memory usage. See documentation chapter "Debugging incorrect memory usage".

+  - Added debug macro `VMA_DEBUG_DETECT_CORRUPTION`, functions `vmaCheckCorruption`, `vmaCheckPoolCorruption`.

+  - Added debug macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to initialize contents of allocations with a bit pattern.

+  - Changed behavior of `VMA_DEBUG_MARGIN` macro - it now adds margin also before first and after last allocation in a block.

+- Changed format of JSON dump returned by `vmaBuildStatsString` (not backward compatible!).

+  - Custom pools and memory blocks now have IDs that don't change after sorting.

+  - Added properties: "CreationFrameIndex", "LastUseFrameIndex", "Usage".

+  - Changed VmaDumpVis tool to use these new properties for better coloring.

+  - Changed behavior of `vmaGetAllocationInfo` and `vmaTouchAllocation` to update `allocation.lastUseFrameIndex` even if allocation cannot become lost.

+

+Minor changes:

+

+- Changes in custom pools:

+  - Added new structure member `VmaPoolStats::blockCount`.

+  - Changed behavior of `VmaPoolCreateInfo::blockSize` = 0 (default) - it now means that pool may use variable block sizes, just like default pools do.

+- Improved logic of `vmaFindMemoryTypeIndex` for some cases, especially integrated GPUs.

+- VulkanSample application: Removed dependency on external library MathFu. Added own vector and matrix structures.

+- Changes that improve compatibility with various platforms, including: Visual Studio 2012, 32-bit code, C compilers.

+  - Changed usage of "VK_KHR_dedicated_allocation" extension in the code to be optional, driven by macro `VMA_DEDICATED_ALLOCATION`, for compatibility with Android.

+- Many additions and fixes in documentation, including description of new features, as well as "Validation layer warnings".

+- Other bugfixes.

+

 # 2.0.0 (2018-03-19)

 

 A major release with many compatibility-breaking changes.

diff --git a/README.md b/README.md
index cb699b2..7bd6d53 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,9 @@
 - Configuration: Fill optional members of CreateInfo structure to provide custom CPU memory allocator, pointers to Vulkan functions and other parameters.
 - Customization: Predefine appropriate macros to provide your own implementation of all external facilities used by the library, from assert, mutex, and atomic, to vector and linked list. 
 - Support for memory mapping, reference-counted internally. Support for persistently mapped memory: Just allocate with appropriate flag and you get access to mapped pointer.
+- Support for non-coherent memory. Functions that flush/invalidate memory. nonCoherentAtomSize is respected automatically.
 - Custom memory pools: Create a pool with desired parameters (e.g. fixed or limited maximum size) and allocate memory out of it.
+- Linear allocator: Create a pool with linear algorithm and use it for much faster allocations and deallocations in free-at-once, stack, double stack, or ring buffer fashion.
 - Support for VK_KHR_dedicated_allocation extension: Just enable it and it will be used automatically by the library.
 - Defragmentation: Call one function and let the library move data around to free some memory blocks and make your allocations better compacted.
 - Lost allocations: Allocate memory with appropriate flags and let the library remove allocations that are not used for many frames to make room for new ones.
@@ -49,6 +51,8 @@
 - Debug annotations: Associate string with name or opaque pointer to your own data with every allocation.
 - JSON dump: Obtain a string in JSON format with detailed map of internal state, including list of allocations and gaps between them.
 - 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.
 
 # Prequisites
 
diff --git a/bin/Shader.frag.spv b/bin/Shader.frag.spv
index 1fb2f32..7fde5eb 100644
--- a/bin/Shader.frag.spv
+++ b/bin/Shader.frag.spv
Binary files differ
diff --git a/bin/Shader.vert.spv b/bin/Shader.vert.spv
index 699b878..8a0c6f7 100644
--- a/bin/Shader.vert.spv
+++ b/bin/Shader.vert.spv
Binary files differ
diff --git a/bin/VmaReplay_Release_vs2015.exe b/bin/VmaReplay_Release_vs2015.exe
new file mode 100644
index 0000000..31f08ee
--- /dev/null
+++ b/bin/VmaReplay_Release_vs2015.exe
Binary files differ
diff --git a/bin/VulkanSample_Release_vs2015.exe b/bin/VulkanSample_Release_vs2015.exe
index 05ae82b..4d40827 100644
--- a/bin/VulkanSample_Release_vs2015.exe
+++ b/bin/VulkanSample_Release_vs2015.exe
Binary files differ
diff --git a/docs/Recording file format.md b/docs/Recording file format.md
new file mode 100644
index 0000000..b01eaf4
--- /dev/null
+++ b/docs/Recording file format.md
@@ -0,0 +1,287 @@
+This is an official documentation for file format used by Vulkan Memory Allocator library

+to record and replay sequence of calls to its functions.

+This feature can be enabled by using `VmaAllocatorCreateInfo::pRecordSettings` structure members.

+For details, see main documentation of the library.

+Playback can be launched using **VmaReplay** console application.

+

+Recording is a text file.

+Line endings: Unix `'\n'`.

+Character encoding: single-byte (can be ASCII or UTF-8, whaterver you use in custom strings).

+Suggested file extension: **csv**. File can be processed sequentially - no random access is needed.

+Each line forms a separate entry.

+Each line consists of a set of values (also called columns), separated by comma `','` (hence "CSV" format - Comma Separated Values).

+Number of columns is different in different lines.

+

+# Header

+

+First line identifies file format. It must always be:

+

+    Vulkan Memory Allocator,Calls recording

+

+Second line identifies format version, where first column is major version and second column is minor version.

+Formats with only minor version incremented are backward compatible.

+VmaReplay application supports all older versions.

+Current version is:

+

+    1,3

+

+# Configuration

+

+Header is followed by mandatory configuration section (min format version 1.3). It starts with line:

+

+    Config,Begin

+

+And ends with line:

+

+    Config,End

+

+Between them there can be zero or more lines with configuration options. They store values of various variables from the current environment from the time of recording, like properties and limits of Vulkan physical device, available memory heaps and types, enabled Vulkan extensions, as well macros that configure VMA internals. Supported configuration options are:

+

+    PhysicalDevice,apiVersion,<uint32>

+    PhysicalDevice,driverVersion,<uint32>

+    PhysicalDevice,vendorID,<uint32>

+    PhysicalDevice,deviceID,<uint32>

+    PhysicalDevice,deviceType,<uint32>

+    PhysicalDevice,deviceName,<string>

+    

+    PhysicalDeviceLimits,maxMemoryAllocationCount,<uint32>

+    PhysicalDeviceLimits,bufferImageGranularity,<uint64>

+    PhysicalDeviceLimits,nonCoherentAtomSize,<uint64>

+    

+    PhysicalDeviceMemory,HeapCount,<uint32>

+    PhysicalDeviceMemory,Heap,<index:uint32>,size,<uint64>

+    PhysicalDeviceMemory,Heap,<index:uint32>,flags,<uint32>

+    PhysicalDeviceMemory,TypeCount,<uint32>

+    PhysicalDeviceMemory,Type,<index:uint32>,heapIndex,<uint32>

+    PhysicalDeviceMemory,Type,<index:uint32>,propertyFlags,<uint32>

+    

+    Extension,VK_KHR_dedicated_allocation,<bool>

+    

+    Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,<bool>

+    Macro,VMA_DEBUG_ALIGNMENT,<uint64>

+    Macro,VMA_DEBUG_MARGIN,<uint64>

+    Macro,VMA_DEBUG_INITIALIZE_ALLOCATIONS,<bool>

+    Macro,VMA_DEBUG_DETECT_CORRUPTION,<bool>

+    Macro,VMA_DEBUG_GLOBAL_MUTEX,<bool>

+    Macro,VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,<uint64>

+    Macro,VMA_SMALL_HEAP_MAX_SIZE,<uint64>

+    Macro,VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,<uint64>

+

+# Function calls

+

+Remaining lines contain recorded calls to VMA functions. First columns are always:

+

+- Thread ID : uint32

+- Time since first call : float, in seconds

+- VMA frame index : uint32

+- Function name : string

+

+Remaining columns are function parameters and output, depending on function name, which can be:

+

+**vmaCreateAllocator, vmaDestroyAllocator**

+

+No parameters.

+

+**vmaCreatePool**

+

+- memoryTypeIndex : uint32

+- flags : uint32

+- blockSize : uint64

+- minBlockCount : uint64

+- maxBlockCount : uint64

+- frameInUseCount : uint32

+- pool (output) : pointer

+

+**vmaDestroyPool**

+

+- pool : pointer

+

+**vmaSetAllocationUserData**

+

+- allocation : pointer

+- pUserData : string (may contain additional commas)

+

+**vmaCreateBuffer**

+

+- bufferCreateInfo.flags : uint32

+- bufferCreateInfo.size : uint64

+- bufferCreateInfo.usage : uint32

+- bufferCreateInfo.sharingMode : uint32

+- allocationCreateInfo.flags : uint32

+- allocationCreateInfo.usage : uint32

+- allocationCreateInfo.requiredFlags : uint32

+- allocationCreateInfo.preferredFlags : uint32

+- allocationCreateInfo.memoryTypeBits : uint32

+- allocationCreateInfo.pool : pointer

+- allocation (output) : pointer

+- allocationCreateInfo.pUserData : string (may contain additional commas)

+

+**vmaDestroyBuffer**

+

+- allocation : pointer

+

+**vmaCreateImage**

+

+- imageCreateInfo.flags : uint32

+- imageCreateInfo.imageType : uint32

+- imageCreateInfo.format : uint32

+- imageCreateInfo.extent.width : uint32

+- imageCreateInfo.extent.height : uint32

+- imageCreateInfo.extent.depth : uint32

+- imageCreateInfo.mipLevels : uint32

+- imageCreateInfo.arrayLayers : uint32

+- imageCreateInfo.samples : uint32

+- imageCreateInfo.tiling : uint32

+- imageCreateInfo.usage : uint32

+- imageCreateInfo.sharingMode : uint32

+- imageCreateInfo.initialLayout : uint32

+- allocationCreateInfo.flags : uint32

+- allocationCreateInfo.usage : uint32

+- allocationCreateInfo.requiredFlags : uint32

+- allocationCreateInfo.preferredFlags : uint32

+- allocationCreateInfo.memoryTypeBits : uint32

+- allocationCreateInfo.pool : pointer

+- allocation (output) : pointer

+- allocationCreateInfo.pUserData : string (may contain additional commas)

+

+**vmaDestroyImage**

+

+- allocation : pointer

+

+**vmaFreeMemory** (min format version 1.1)

+

+- allocation : pointer

+

+**vmaCreateLostAllocation** (min format version 1.2)

+

+- allocation (output) : pointer

+

+**vmaAllocateMemory** (min format version 1.2)

+

+- vkMemoryRequirements.size : uint64

+- vkMemoryRequirements.alignment : uint64

+- vkMemoryRequirements.memoryTypeBits : uint32

+- allocationCreateInfo.flags : uint32

+- allocationCreateInfo.usage : uint32

+- allocationCreateInfo.requiredFlags : uint32

+- allocationCreateInfo.preferredFlags : uint32

+- allocationCreateInfo.memoryTypeBits : uint32

+- allocationCreateInfo.pool : pointer

+- allocation (output) : pointer

+- allocationCreateInfo.pUserData : string (may contain additional commas)

+

+**vmaAllocateMemoryForBuffer, vmaAllocateMemoryForImage** (min format version 1.2)

+

+- vkMemoryRequirements.size : uint64

+- vkMemoryRequirements.alignment : uint64

+- vkMemoryRequirements.memoryTypeBits : uint32

+- requiresDedicatedAllocation : bool

+- prefersDedicatedAllocation : bool

+- allocationCreateInfo.flags : uint32

+- allocationCreateInfo.usage : uint32

+- allocationCreateInfo.requiredFlags : uint32

+- allocationCreateInfo.preferredFlags : uint32

+- allocationCreateInfo.memoryTypeBits : uint32

+- allocationCreateInfo.pool : pointer

+- allocation (output) : pointer

+- allocationCreateInfo.pUserData : string (may contain additional commas)

+

+**vmaMapMemory, vmaUnmapMemory** (min format version 1.2)

+

+- allocation : pointer

+

+**vmaFlushAllocation, vmaInvalidateAllocation** (min format version 1.2)

+

+- allocation : pointer

+- offset : uint64

+- size : uint64

+

+**vmaTouchAllocation, vmaGetAllocationInfo** (min format version 1.2)

+

+- allocation : pointer

+

+**vmaMakePoolAllocationsLost** (min format version: 1.2)

+

+- pool : pointer

+

+# Data types

+

+**bool**

+

+Encoded as `0` for false or `1` for true.

+

+**uint32, uint64**

+

+Encoded in decimal format.

+

+**pointer**

+

+Encoded in hexadecimal format.

+

+**pUserData**

+

+If `pUserData` was a pointer, it is encoded as hexadecimal string.

+If `VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT` was used with the allocation, the string is written as-is.

+It may contain additional commas.

+It should not contain end-of-line characters - results are then undefined.

+

+# Example file

+

+    Vulkan Memory Allocator,Calls recording

+    1,3

+    Config,Begin

+    PhysicalDevice,apiVersion,4198477

+    PhysicalDevice,driverVersion,8388653

+    PhysicalDevice,vendorID,4098

+    PhysicalDevice,deviceID,26751

+    PhysicalDevice,deviceType,2

+    PhysicalDevice,deviceName,Radeon RX Vega

+    PhysicalDeviceLimits,maxMemoryAllocationCount,4096

+    PhysicalDeviceLimits,bufferImageGranularity,1

+    PhysicalDeviceLimits,nonCoherentAtomSize,128

+    PhysicalDeviceMemory,HeapCount,3

+    PhysicalDeviceMemory,Heap,0,size,8304721920

+    PhysicalDeviceMemory,Heap,0,flags,3

+    PhysicalDeviceMemory,Heap,1,size,8286175232

+    PhysicalDeviceMemory,Heap,1,flags,0

+    PhysicalDeviceMemory,Heap,2,size,268435456

+    PhysicalDeviceMemory,Heap,2,flags,3

+    PhysicalDeviceMemory,TypeCount,4

+    PhysicalDeviceMemory,Type,0,heapIndex,0

+    PhysicalDeviceMemory,Type,0,propertyFlags,1

+    PhysicalDeviceMemory,Type,1,heapIndex,1

+    PhysicalDeviceMemory,Type,1,propertyFlags,6

+    PhysicalDeviceMemory,Type,2,heapIndex,2

+    PhysicalDeviceMemory,Type,2,propertyFlags,7

+    PhysicalDeviceMemory,Type,3,heapIndex,1

+    PhysicalDeviceMemory,Type,3,propertyFlags,14

+    Extension,VK_KHR_dedicated_allocation,1

+    Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,0

+    Macro,VMA_DEBUG_ALIGNMENT,1

+    Macro,VMA_DEBUG_MARGIN,0

+    Macro,VMA_DEBUG_INITIALIZE_ALLOCATIONS,0

+    Macro,VMA_DEBUG_DETECT_CORRUPTION,0

+    Macro,VMA_DEBUG_GLOBAL_MUTEX,0

+    Macro,VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,1

+    Macro,VMA_SMALL_HEAP_MAX_SIZE,1073741824

+    Macro,VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,268435456

+    Config,End 

+    12552,0.000,0,vmaCreateAllocator

+    12552,0.010,0,vmaCreateImage,0,1,37,128,128,1,1,1,1,1,1,0,8,36,2,0,0,0,0000000000000000,000001D85B8B1A80,

+    12552,0.010,0,vmaSetAllocationUserData,000001D85B8B1A80,Ala ma kota

+    12552,0.015,0,vmaCreateImage,0,1,37,128,128,1,1,1,1,0,6,0,0,0,1,0,0,0,0000000000000000,000001D85B8B1620,

+    12552,0.017,0,vmaDestroyImage,000001D85B8B1A80

+    12552,0.017,0,vmaCreateBuffer,0,768,1,0,4,2,0,0,0,0000000000000000,000001D85B8B19E0,

+    12552,0.017,0,vmaCreateBuffer,0,768,130,0,0,1,0,0,0,0000000000000000,000001D85B8B1A80,

+    12552,0.017,0,vmaCreateBuffer,0,60,1,0,4,2,0,0,0,0000000000000000,000001D85B8B1DA0,

+    12552,0.017,0,vmaCreateBuffer,0,60,66,0,0,1,0,0,0,0000000000000000,000001D85B8B16C0,

+    12552,0.017,0,vmaDestroyBuffer,000001D85B8B1DA0

+    12552,0.017,0,vmaDestroyBuffer,000001D85B8B19E0

+    12552,0.022,0,vmaCreateImage,0,1,126,1424,704,1,1,1,1,0,32,0,0,0,1,0,0,0,0000000000000000,000001D85B8B1EE0,

+    12552,0.048,0,vmaDestroyImage,000001D85B8B1EE0

+    12552,0.053,0,vmaCreateImage,0,1,126,1424,704,1,1,1,1,0,32,0,0,0,1,0,0,0,0000000000000000,000001D85B8B1EE0,

+    12552,0.662,0,vmaDestroyImage,000001D85B8B1EE0

+    12552,0.695,0,vmaDestroyImage,000001D85B8B1620

+    12552,0.695,0,vmaDestroyBuffer,000001D85B8B16C0

+    12552,0.695,0,vmaDestroyBuffer,000001D85B8B1A80

+    12552,0.695,0,vmaDestroyAllocator
\ No newline at end of file
diff --git a/docs/gfx/Linear_allocator_1_algo_default.png b/docs/gfx/Linear_allocator_1_algo_default.png
new file mode 100644
index 0000000..e3e8f47
--- /dev/null
+++ b/docs/gfx/Linear_allocator_1_algo_default.png
Binary files differ
diff --git a/docs/gfx/Linear_allocator_2_algo_linear.png b/docs/gfx/Linear_allocator_2_algo_linear.png
new file mode 100644
index 0000000..c2a38b2
--- /dev/null
+++ b/docs/gfx/Linear_allocator_2_algo_linear.png
Binary files differ
diff --git a/docs/gfx/Linear_allocator_3_free_at_once.png b/docs/gfx/Linear_allocator_3_free_at_once.png
new file mode 100644
index 0000000..a000ad5
--- /dev/null
+++ b/docs/gfx/Linear_allocator_3_free_at_once.png
Binary files differ
diff --git a/docs/gfx/Linear_allocator_4_stack.png b/docs/gfx/Linear_allocator_4_stack.png
new file mode 100644
index 0000000..4dba064
--- /dev/null
+++ b/docs/gfx/Linear_allocator_4_stack.png
Binary files differ
diff --git a/docs/gfx/Linear_allocator_5_ring_buffer.png b/docs/gfx/Linear_allocator_5_ring_buffer.png
new file mode 100644
index 0000000..0686702
--- /dev/null
+++ b/docs/gfx/Linear_allocator_5_ring_buffer.png
Binary files differ
diff --git a/docs/gfx/Linear_allocator_6_ring_buffer_lost.png b/docs/gfx/Linear_allocator_6_ring_buffer_lost.png
new file mode 100644
index 0000000..9a2338c
--- /dev/null
+++ b/docs/gfx/Linear_allocator_6_ring_buffer_lost.png
Binary files differ
diff --git a/docs/gfx/Linear_allocator_7_double_stack.png b/docs/gfx/Linear_allocator_7_double_stack.png
new file mode 100644
index 0000000..77d1468
--- /dev/null
+++ b/docs/gfx/Linear_allocator_7_double_stack.png
Binary files differ
diff --git a/docs/gfx/Margins_1.png b/docs/gfx/Margins_1.png
new file mode 100644
index 0000000..8c9e184
--- /dev/null
+++ b/docs/gfx/Margins_1.png
Binary files differ
diff --git a/docs/gfx/Margins_2.png b/docs/gfx/Margins_2.png
new file mode 100644
index 0000000..6f75877
--- /dev/null
+++ b/docs/gfx/Margins_2.png
Binary files differ
diff --git a/docs/html/_v_k__k_h_r_dedicated_allocation.html b/docs/html/_v_k__k_h_r_dedicated_allocation.html
deleted file mode 100644
index fded3c2..0000000
--- a/docs/html/_v_k__k_h_r_dedicated_allocation.html
+++ /dev/null
@@ -1,100 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: VK_KHR_dedicated_allocation</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div id="nav-path" class="navpath">
-  <ul>
-<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
-</div>
-</div><!-- top -->
-<div class="header">
-  <div class="headertitle">
-<div class="title">VK_KHR_dedicated_allocation </div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="textblock"><p>VK_KHR_dedicated_allocation is a Vulkan extension which can be used to improve performance on some GPUs. It augments Vulkan API with possibility to query driver whether it prefers particular buffer or image to have its own, dedicated allocation (separate <code>VkDeviceMemory</code> block) for better efficiency - to be able to do some internal optimizations.</p>
-<p>The extension is supported by this library. It will be used automatically when enabled. To enable it:</p>
-<p>1 . When creating Vulkan device, check if following 2 device extensions are supported (call <code>vkEnumerateDeviceExtensionProperties()</code>). If yes, enable them (fill <code>VkDeviceCreateInfo::ppEnabledExtensionNames</code>).</p>
-<ul>
-<li>VK_KHR_get_memory_requirements2</li>
-<li>VK_KHR_dedicated_allocation</li>
-</ul>
-<p>If you enabled these extensions:</p>
-<p>2 . Query device for pointers to following 2 extension functions, using <code>vkGetDeviceProcAddr()</code>. Pass them in structure <a class="el" href="struct_vma_vulkan_functions.html" title="Pointers to some Vulkan functions - a subset used by the library. ">VmaVulkanFunctions</a> while creating your <code>VmaAllocator</code>.</p>
-<ul>
-<li><code>vkGetBufferMemoryRequirements2KHR</code></li>
-<li><code>vkGetImageMemoryRequirements2KHR</code></li>
-</ul>
-<p>Other members of this structure can be null as long as you leave <code>VMA_STATIC_VULKAN_FUNCTIONS</code> defined to 1, which is the default.</p>
-<div class="fragment"><div class="line"><a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a> vulkanFunctions = {};</div><div class="line">vulkanFunctions.<a class="code" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">vkGetBufferMemoryRequirements2KHR</a> =</div><div class="line">    (PFN_vkGetBufferMemoryRequirements2KHR)vkGetDeviceProcAddr(device, <span class="stringliteral">&quot;vkGetBufferMemoryRequirements2KHR&quot;</span>);</div><div class="line">vulkanFunctions.<a class="code" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">vkGetImageMemoryRequirements2KHR</a> =</div><div class="line">    (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(device, <span class="stringliteral">&quot;vkGetImageMemoryRequirements2KHR&quot;</span>);</div><div class="line">    </div><div class="line"><a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a> allocatorInfo = {};</div><div class="line">allocatorInfo.<a class="code" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a> = &amp;vulkanFunctions;</div><div class="line"><span class="comment">// Fill other members of allocatorInfo...</span></div></div><!-- fragment --><p>3 . Use <code>VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</code> flag when creating your <code>VmaAllocator</code> to inform the library that you enabled required extensions and you want the library to use them.</p>
-<div class="fragment"><div class="line">allocatorInfo.<a class="code" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">flags</a> |= <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a>;</div><div class="line"></div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a>(&amp;allocatorInfo, &amp;allocator);</div></div><!-- fragment --><p>That's all. The extension will be automatically used whenever you create a buffer using <a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a> or image using <a class="el" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a>.</p>
-<p>When using the extension together with Vulkan Validation Layer, you will receive warnings like this: </p><pre class="fragment">vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer.
-</pre><p>It is OK, you should just ignore it. It happens because you use function <code>vkGetBufferMemoryRequirements2KHR()</code> instead of standard <code>vkGetBufferMemoryRequirements()</code>, while the validation layer seems to be unaware of it.</p>
-<p>To learn more about this extension, see:</p>
-<ul>
-<li><a href="https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_dedicated_allocation">VK_KHR_dedicated_allocation in Vulkan specification</a></li>
-<li><a href="http://asawicki.info/articles/VK_KHR_dedicated_allocation.php5">VK_KHR_dedicated_allocation unofficial manual</a> </li>
-</ul>
-</div></div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/annotated.html b/docs/html/annotated.html
index 18ddbd5..37ef74d 100644
--- a/docs/html/annotated.html
+++ b/docs/html/annotated.html
@@ -75,9 +75,10 @@
 <tr id="row_8_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_pool.html" target="_self">VmaPool</a></td><td class="desc">Represents custom memory pool </td></tr>
 <tr id="row_9_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_pool_create_info.html" target="_self">VmaPoolCreateInfo</a></td><td class="desc">Describes parameter of created <a class="el" href="struct_vma_pool.html" title="Represents custom memory pool. ">VmaPool</a> </td></tr>
 <tr id="row_10_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_pool_stats.html" target="_self">VmaPoolStats</a></td><td class="desc">Describes parameter of existing <a class="el" href="struct_vma_pool.html" title="Represents custom memory pool. ">VmaPool</a> </td></tr>
-<tr id="row_11_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_stat_info.html" target="_self">VmaStatInfo</a></td><td class="desc">Calculated statistics of memory usage in entire allocator </td></tr>
-<tr id="row_12_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_stats.html" target="_self">VmaStats</a></td><td class="desc">General statistics from current state of Allocator </td></tr>
-<tr id="row_13_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_vulkan_functions.html" target="_self">VmaVulkanFunctions</a></td><td class="desc">Pointers to some Vulkan functions - a subset used by the library </td></tr>
+<tr id="row_11_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_record_settings.html" target="_self">VmaRecordSettings</a></td><td class="desc">Parameters for recording calls to VMA functions. To be used in <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee" title="Parameters for recording of VMA calls. Can be null. ">VmaAllocatorCreateInfo::pRecordSettings</a> </td></tr>
+<tr id="row_12_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_stat_info.html" target="_self">VmaStatInfo</a></td><td class="desc">Calculated statistics of memory usage in entire allocator </td></tr>
+<tr id="row_13_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_stats.html" target="_self">VmaStats</a></td><td class="desc">General statistics from current state of Allocator </td></tr>
+<tr id="row_14_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="struct_vma_vulkan_functions.html" target="_self">VmaVulkanFunctions</a></td><td class="desc">Pointers to some Vulkan functions - a subset used by the library </td></tr>
 </table>
 </div><!-- directory -->
 </div><!-- contents -->
diff --git a/docs/html/classes.html b/docs/html/classes.html
index b900f2a..099f7e3 100644
--- a/docs/html/classes.html
+++ b/docs/html/classes.html
@@ -65,10 +65,10 @@
 <div class="qindex"><a class="qindex" href="#letter_v">v</a></div>
 <table class="classindex">
 <tr><td rowspan="2" valign="bottom"><a name="letter_v"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;v&#160;&#160;</div></td></tr></table>
-</td><td valign="top"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a>&#160;&#160;&#160;</td><td></td></tr>
-<tr><td valign="top"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_stat_info.html">VmaStatInfo</a>&#160;&#160;&#160;</td><td></td></tr>
-<tr><td valign="top"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_pool.html">VmaPool</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_stats.html">VmaStats</a>&#160;&#160;&#160;</td><td></td></tr>
-<tr><td valign="top"><a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>&#160;&#160;&#160;</td><td></td></tr>
+</td><td valign="top"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>&#160;&#160;&#160;</td></tr>
+<tr><td valign="top"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a>&#160;&#160;&#160;</td><td></td></tr>
+<tr><td valign="top"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_pool.html">VmaPool</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_stat_info.html">VmaStatInfo</a>&#160;&#160;&#160;</td><td></td></tr>
+<tr><td valign="top"><a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="struct_vma_stats.html">VmaStats</a>&#160;&#160;&#160;</td><td></td></tr>
 <tr><td></td><td></td><td></td><td></td><td></td></tr>
 </table>
 <div class="qindex"><a class="qindex" href="#letter_v">v</a></div>
diff --git a/docs/html/custom_memory_pools.html b/docs/html/custom_memory_pools.html
index fed21c8..35197c6 100644
--- a/docs/html/custom_memory_pools.html
+++ b/docs/html/custom_memory_pools.html
@@ -78,7 +78,7 @@
 <ol type="1">
 <li>Fill <a class="el" href="struct_vma_pool_create_info.html" title="Describes parameter of created VmaPool. ">VmaPoolCreateInfo</a> structure.</li>
 <li>Call <a class="el" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50" title="Allocates Vulkan device memory and creates VmaPool object. ">vmaCreatePool()</a> to obtain <a class="el" href="struct_vma_pool.html" title="Represents custom memory pool. ">VmaPool</a> handle.</li>
-<li>When making an allocation, set <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> to this handle. You don't need to specify any other parameters of this structure, like usage.</li>
+<li>When making an allocation, set <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> to this handle. You don't need to specify any other parameters of this structure, like <code>usage</code>.</li>
 </ol>
 <p>Example:</p>
 <div class="fragment"><div class="line"><span class="comment">// Create a pool that can have at most 2 blocks, 128 MiB each.</span></div><div class="line"><a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> poolCreateInfo = {};</div><div class="line">poolCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a> = ...</div><div class="line">poolCreateInfo.blockSize = 128ull * 1024 * 1024;</div><div class="line">poolCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a> = 2;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_pool.html">VmaPool</a> pool;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(allocator, &amp;poolCreateInfo, &amp;pool);</div><div class="line"></div><div class="line"><span class="comment">// Allocate a buffer out of it.</span></div><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = 1024;</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> = pool;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line"><a class="code" href="struct_vma_allocation.html">VmaAllocation</a> alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div></div><!-- fragment --><p>You have to free all allocations made from this pool before destroying it.</p>
@@ -88,8 +88,57 @@
 <div class="fragment"><div class="line">VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">exampleBufCreateInfo.size = 1024; <span class="comment">// Whatever.</span></div><div class="line">exampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; <span class="comment">// Change if needed.</span></div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>; <span class="comment">// Change if needed.</span></div><div class="line"></div><div class="line">uint32_t memTypeIndex;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(allocator, &amp;exampleBufCreateInfo, &amp;allocCreateInfo, &amp;memTypeIndex);</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> poolCreateInfo = {};</div><div class="line">poolCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a> = memTypeIndex;</div><div class="line"><span class="comment">// ...</span></div></div><!-- fragment --><p>When creating buffers/images allocated in that pool, provide following parameters:</p>
 <ul>
 <li><code>VkBufferCreateInfo</code>: Prefer to pass same parameters as above. Otherwise you risk creating resources in a memory type that is not suitable for them, which may result in undefined behavior. Using different <code>VK_BUFFER_USAGE_</code> flags may work, but you shouldn't create images in a pool intended for buffers or the other way around.</li>
-<li><a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>: You don't need to pass same parameters. Fill only <code>pool</code> member. Other members are ignored anyway. </li>
+<li><a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>: You don't need to pass same parameters. Fill only <code>pool</code> member. Other members are ignored anyway.</li>
 </ul>
+<h1><a class="anchor" id="linear_algorithm"></a>
+Linear allocation algorithm</h1>
+<p>Each Vulkan memory block managed by this library has accompanying metadata that keeps track of used and unused regions. By default, the metadata structure and algorithm tries to find best place for new allocations among free regions to optimize memory usage. This way you can allocate and free objects in any order.</p>
+<div class="image">
+<img src="../gfx/Linear_allocator_1_algo_default.png" alt="Default allocation algorithm"/>
+</div>
+<p>Sometimes there is a need to use simpler, linear allocation algorithm. You can create custom pool that uses such algorithm by adding flag <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726" title="Enables alternative, linear allocation algorithm in this pool. ">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a> to <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446" title="Use combination of VmaPoolCreateFlagBits. ">VmaPoolCreateInfo::flags</a> while creating <a class="el" href="struct_vma_pool.html" title="Represents custom memory pool. ">VmaPool</a> object. Then an alternative metadata management is used. It always creates new allocations after last one and doesn't reuse free regions after allocations freed in the middle. It results in better allocation performance and less memory consumed by metadata.</p>
+<div class="image">
+<img src="../gfx/Linear_allocator_2_algo_linear.png" alt="Linear allocation algorithm"/>
+</div>
+<p>With this one flag, you can create a custom pool that can be used in many ways: free-at-once, stack, double stack, and ring buffer. See below for details.</p>
+<h2><a class="anchor" id="linear_algorithm_free_at_once"></a>
+Free-at-once</h2>
+<p>In a pool that uses linear algorithm, you still need to free all the allocations individually, e.g. by using <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a> or <a class="el" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77" title="Destroys Vulkan buffer and frees allocated memory. ">vmaDestroyBuffer()</a>. You can free them in any order. New allocations are always made after last one - free space in the middle is not reused. However, when you release all the allocation and the pool becomes empty, allocation starts from the beginning again. This way you can use linear algorithm to speed up creation of allocations that you are going to release all at once.</p>
+<div class="image">
+<img src="../gfx/Linear_allocator_3_free_at_once.png" alt="Free-at-once"/>
+</div>
+<p>This mode is also available for pools created with <a class="el" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c" title="Maximum number of blocks that can be allocated in this pool. Optional. ">VmaPoolCreateInfo::maxBlockCount</a> value that allows multiple memory blocks.</p>
+<h2><a class="anchor" id="linear_algorithm_stack"></a>
+Stack</h2>
+<p>When you free an allocation that was created last, its space can be reused. Thanks to this, if you always release allocations in the order opposite to their creation (LIFO - Last In First Out), you can achieve behavior of a stack.</p>
+<div class="image">
+<img src="../gfx/Linear_allocator_4_stack.png" alt="Stack"/>
+</div>
+<p>This mode is also available for pools created with <a class="el" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c" title="Maximum number of blocks that can be allocated in this pool. Optional. ">VmaPoolCreateInfo::maxBlockCount</a> value that allows multiple memory blocks.</p>
+<h2><a class="anchor" id="linear_algorithm_double_stack"></a>
+Double stack</h2>
+<p>The space reserved by a custom pool with linear algorithm may be used by two stacks:</p>
+<ul>
+<li>First, default one, growing up from offset 0.</li>
+<li>Second, "upper" one, growing down from the end towards lower offsets.</li>
+</ul>
+<p>To make allocation from upper stack, add flag <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a> to <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>.</p>
+<div class="image">
+<img src="../gfx/Linear_allocator_7_double_stack.png" alt="Double stack"/>
+</div>
+<p>Double stack is available only in pools with one memory block - <a class="el" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c" title="Maximum number of blocks that can be allocated in this pool. Optional. ">VmaPoolCreateInfo::maxBlockCount</a> must be 1. Otherwise behavior is undefined.</p>
+<p>When the two stacks' ends meet so there is not enough space between them for a new allocation, such allocation fails with usual <code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code> error.</p>
+<h2><a class="anchor" id="linear_algorithm_ring_buffer"></a>
+Ring buffer</h2>
+<p>When you free some allocations from the beginning and there is not enough free space for a new one at the end of a pool, allocator's "cursor" wraps around to the beginning and starts allocation there. Thanks to this, if you always release allocations in the same order as you created them (FIFO - First In First Out), you can achieve behavior of a ring buffer / queue.</p>
+<div class="image">
+<img src="../gfx/Linear_allocator_5_ring_buffer.png" alt="Ring buffer"/>
+</div>
+<p>Pools with linear algorithm support <a class="el" href="lost_allocations.html">lost allocations</a> when used as ring buffer. If there is not enough free space for a new allocation, but existing allocations from the front of the queue can become lost, they become lost and the allocation succeeds.</p>
+<div class="image">
+<img src="../gfx/Linear_allocator_6_ring_buffer_lost.png" alt="Ring buffer with lost allocations"/>
+</div>
+<p>Ring buffer is available only in pools with one memory block - <a class="el" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c" title="Maximum number of blocks that can be allocated in this pool. Optional. ">VmaPoolCreateInfo::maxBlockCount</a> must be 1. Otherwise behavior is undefined. </p>
 </div></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/html/debugging_memory_usage.html b/docs/html/debugging_memory_usage.html
new file mode 100644
index 0000000..83e8d35
--- /dev/null
+++ b/docs/html/debugging_memory_usage.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.13"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Vulkan Memory Allocator: Debugging incorrect memory usage</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Vulkan Memory Allocator
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.13 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="headertitle">
+<div class="title">Debugging incorrect memory usage </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>If you suspect a bug with memory usage, like usage of uninitialized memory or memory being overwritten out of bounds of an allocation, you can use debug features of this library to verify this.</p>
+<h1><a class="anchor" id="debugging_memory_usage_initialization"></a>
+Memory initialization</h1>
+<p>If you experience a bug with incorrect and nondeterministic data in your program and you suspect uninitialized memory to be used, you can enable automatic memory initialization to verify this. To do it, define macro <code>VMA_DEBUG_INITIALIZE_ALLOCATIONS</code> to 1.</p>
+<div class="fragment"><div class="line"><span class="preprocessor">#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1</span></div><div class="line"><span class="preprocessor">#include &quot;vk_mem_alloc.h&quot;</span></div></div><!-- fragment --><p>It makes memory of all new allocations initialized to bit pattern <code>0xDCDCDCDC</code>. Before an allocation is destroyed, its memory is filled with bit pattern <code>0xEFEFEFEF</code>. Memory is automatically mapped and unmapped if necessary.</p>
+<p>If you find these values while debugging your program, good chances are that you incorrectly read Vulkan memory that is allocated but not initialized, or already freed, respectively.</p>
+<p>Memory initialization works only with memory types that are <code>HOST_VISIBLE</code>. It works also with dedicated allocations. It doesn't work with allocations created with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> flag, as they cannot be mapped.</p>
+<h1><a class="anchor" id="debugging_memory_usage_margins"></a>
+Margins</h1>
+<p>By default, allocations are laid out in memory blocks next to each other if possible (considering required alignment, <code>bufferImageGranularity</code>, and <code>nonCoherentAtomSize</code>).</p>
+<div class="image">
+<img src="../gfx/Margins_1.png" alt="Allocations without margin"/>
+</div>
+<p>Define macro <code>VMA_DEBUG_MARGIN</code> to some non-zero value (e.g. 16) to enforce specified number of bytes as a margin before and after every allocation.</p>
+<div class="fragment"><div class="line"><span class="preprocessor">#define VMA_DEBUG_MARGIN 16</span></div><div class="line"><span class="preprocessor">#include &quot;vk_mem_alloc.h&quot;</span></div></div><!-- fragment --><div class="image">
+<img src="../gfx/Margins_2.png" alt="Allocations with margin"/>
+</div>
+<p>If your bug goes away after enabling margins, it means it may be caused by memory being overwritten outside of allocation boundaries. It is not 100% certain though. Change in application behavior may also be caused by different order and distribution of allocations across memory blocks after margins are applied.</p>
+<p>The margin is applied also before first and after last allocation in a block. It may occur only once between two adjacent allocations.</p>
+<p>Margins work with all types of memory.</p>
+<p>Margin is applied only to allocations made out of memory blocks and not to dedicated allocations, which have their own memory block of specific size. It is thus not applied to allocations made using <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block. ">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> flag or those automatically decided to put into dedicated allocations, e.g. due to its large size or recommended by VK_KHR_dedicated_allocation extension.</p>
+<p>Margins appear in <a class="el" href="statistics.html#statistics_json_dump">JSON dump</a> as part of free space.</p>
+<p>Note that enabling margins increases memory usage and fragmentation.</p>
+<h1><a class="anchor" id="debugging_memory_usage_corruption_detection"></a>
+Corruption detection</h1>
+<p>You can additionally define macro <code>VMA_DEBUG_DETECT_CORRUPTION</code> to 1 to enable validation of contents of the margins.</p>
+<div class="fragment"><div class="line"><span class="preprocessor">#define VMA_DEBUG_MARGIN 16</span></div><div class="line"><span class="preprocessor">#define VMA_DEBUG_DETECT_CORRUPTION 1</span></div><div class="line"><span class="preprocessor">#include &quot;vk_mem_alloc.h&quot;</span></div></div><!-- fragment --><p>When this feature is enabled, number of bytes specified as <code>VMA_DEBUG_MARGIN</code> (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.</p>
+<p>This number is validated automatically when the allocation is destroyed. If it's not equal to the expected value, <code>VMA_ASSERT()</code> is executed. It clearly means that either CPU or GPU overwritten the memory outside of boundaries of the allocation, which indicates a serious bug.</p>
+<p>You can also explicitly request checking margins of all allocations in all memory blocks that belong to specified memory types by using function <a class="el" href="vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98" title="Checks magic number in margins around all allocations in given memory types (in both default and cust...">vmaCheckCorruption()</a>, or in memory blocks that belong to specified custom pool, by using function <a class="el" href="vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89" title="Checks magic number in margins around all allocations in given memory pool in search for corruptions...">vmaCheckPoolCorruption()</a>.</p>
+<p>Margin validation (corruption detection) works only for memory types that are <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. </p>
+</div></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.13
+</small></address>
+</body>
+</html>
diff --git a/docs/html/functions.html b/docs/html/functions.html
index 1ee5475..efb1f35 100644
--- a/docs/html/functions.html
+++ b/docs/html/functions.html
@@ -82,7 +82,8 @@
 
 <h3><a id="index_b"></a>- b -</h3><ul>
 <li>blockCount
-: <a class="el" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">VmaStatInfo</a>
+: <a class="el" href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7">VmaPoolStats</a>
+, <a class="el" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">VmaStatInfo</a>
 </li>
 <li>blockSize
 : <a class="el" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">VmaPoolCreateInfo</a>
@@ -114,6 +115,7 @@
 : <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">VmaAllocationCreateInfo</a>
 , <a class="el" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">VmaAllocatorCreateInfo</a>
 , <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">VmaPoolCreateInfo</a>
+, <a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a">VmaRecordSettings</a>
 </li>
 <li>frameInUseCount
 : <a class="el" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">VmaAllocatorCreateInfo</a>
@@ -165,6 +167,9 @@
 <li>pDeviceMemoryCallbacks
 : <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">VmaAllocatorCreateInfo</a>
 </li>
+<li>pFilePath
+: <a class="el" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">VmaRecordSettings</a>
+</li>
 <li>pfnAllocate
 : <a class="el" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">VmaDeviceMemoryCallbacks</a>
 </li>
@@ -183,6 +188,9 @@
 <li>pool
 : <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">VmaAllocationCreateInfo</a>
 </li>
+<li>pRecordSettings
+: <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">VmaAllocatorCreateInfo</a>
+</li>
 <li>preferredFlags
 : <a class="el" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">VmaAllocationCreateInfo</a>
 </li>
@@ -273,27 +281,27 @@
 <li>vkDestroyImage
 : <a class="el" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">VmaVulkanFunctions</a>
 </li>
+<li>vkFlushMappedMemoryRanges
+: <a class="el" href="struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9">VmaVulkanFunctions</a>
+</li>
 <li>vkFreeMemory
 : <a class="el" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">VmaVulkanFunctions</a>
 </li>
 <li>vkGetBufferMemoryRequirements
 : <a class="el" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">VmaVulkanFunctions</a>
 </li>
-<li>vkGetBufferMemoryRequirements2KHR
-: <a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">VmaVulkanFunctions</a>
-</li>
 <li>vkGetImageMemoryRequirements
 : <a class="el" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">VmaVulkanFunctions</a>
 </li>
-<li>vkGetImageMemoryRequirements2KHR
-: <a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">VmaVulkanFunctions</a>
-</li>
 <li>vkGetPhysicalDeviceMemoryProperties
 : <a class="el" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">VmaVulkanFunctions</a>
 </li>
 <li>vkGetPhysicalDeviceProperties
 : <a class="el" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">VmaVulkanFunctions</a>
 </li>
+<li>vkInvalidateMappedMemoryRanges
+: <a class="el" href="struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1">VmaVulkanFunctions</a>
+</li>
 <li>vkMapMemory
 : <a class="el" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">VmaVulkanFunctions</a>
 </li>
diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html
index 9a0ee19..bb5c24c 100644
--- a/docs/html/functions_vars.html
+++ b/docs/html/functions_vars.html
@@ -82,7 +82,8 @@
 
 <h3><a id="index_b"></a>- b -</h3><ul>
 <li>blockCount
-: <a class="el" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">VmaStatInfo</a>
+: <a class="el" href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7">VmaPoolStats</a>
+, <a class="el" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">VmaStatInfo</a>
 </li>
 <li>blockSize
 : <a class="el" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">VmaPoolCreateInfo</a>
@@ -114,6 +115,7 @@
 : <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">VmaAllocationCreateInfo</a>
 , <a class="el" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">VmaAllocatorCreateInfo</a>
 , <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">VmaPoolCreateInfo</a>
+, <a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a">VmaRecordSettings</a>
 </li>
 <li>frameInUseCount
 : <a class="el" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">VmaAllocatorCreateInfo</a>
@@ -165,6 +167,9 @@
 <li>pDeviceMemoryCallbacks
 : <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">VmaAllocatorCreateInfo</a>
 </li>
+<li>pFilePath
+: <a class="el" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">VmaRecordSettings</a>
+</li>
 <li>pfnAllocate
 : <a class="el" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">VmaDeviceMemoryCallbacks</a>
 </li>
@@ -183,6 +188,9 @@
 <li>pool
 : <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">VmaAllocationCreateInfo</a>
 </li>
+<li>pRecordSettings
+: <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">VmaAllocatorCreateInfo</a>
+</li>
 <li>preferredFlags
 : <a class="el" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">VmaAllocationCreateInfo</a>
 </li>
@@ -273,27 +281,27 @@
 <li>vkDestroyImage
 : <a class="el" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">VmaVulkanFunctions</a>
 </li>
+<li>vkFlushMappedMemoryRanges
+: <a class="el" href="struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9">VmaVulkanFunctions</a>
+</li>
 <li>vkFreeMemory
 : <a class="el" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">VmaVulkanFunctions</a>
 </li>
 <li>vkGetBufferMemoryRequirements
 : <a class="el" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">VmaVulkanFunctions</a>
 </li>
-<li>vkGetBufferMemoryRequirements2KHR
-: <a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">VmaVulkanFunctions</a>
-</li>
 <li>vkGetImageMemoryRequirements
 : <a class="el" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">VmaVulkanFunctions</a>
 </li>
-<li>vkGetImageMemoryRequirements2KHR
-: <a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">VmaVulkanFunctions</a>
-</li>
 <li>vkGetPhysicalDeviceMemoryProperties
 : <a class="el" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">VmaVulkanFunctions</a>
 </li>
 <li>vkGetPhysicalDeviceProperties
 : <a class="el" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">VmaVulkanFunctions</a>
 </li>
+<li>vkInvalidateMappedMemoryRanges
+: <a class="el" href="struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1">VmaVulkanFunctions</a>
+</li>
 <li>vkMapMemory
 : <a class="el" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">VmaVulkanFunctions</a>
 </li>
diff --git a/docs/html/general_considerations.html b/docs/html/general_considerations.html
index 139d6e6..f631ac8 100644
--- a/docs/html/general_considerations.html
+++ b/docs/html/general_considerations.html
@@ -74,6 +74,23 @@
 <li>When the allocator is created with <a class="el" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d" title="Allocator and all objects created from it will not be synchronized internally, so you must guarantee ...">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a> flag, calls to functions that take such <a class="el" href="struct_vma_allocator.html" title="Represents main object of this library initialized. ">VmaAllocator</a> object must be synchronized externally.</li>
 <li>Access to a <a class="el" href="struct_vma_allocation.html" title="Represents single memory allocation. ">VmaAllocation</a> object must be externally synchronized. For example, you must not call <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation and atomically marks it as used in current fra...">vmaGetAllocationInfo()</a> and <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> from different threads at the same time if you pass the same <a class="el" href="struct_vma_allocation.html" title="Represents single memory allocation. ">VmaAllocation</a> object to these functions.</li>
 </ul>
+<h1><a class="anchor" id="general_considerations_validation_layer_warnings"></a>
+Validation layer warnings</h1>
+<p>When using this library, you can meet following types of warnings issued by Vulkan validation layer. They don't necessarily indicate a bug, so you may need to just ignore them.</p>
+<ul>
+<li><em>vkBindBufferMemory(): Binding memory to buffer 0xeb8e4 but vkGetBufferMemoryRequirements() has not been called on that buffer.</em><ul>
+<li>It happens when VK_KHR_dedicated_allocation extension is enabled. <code>vkGetBufferMemoryRequirements2KHR</code> function is used instead, while validation layer seems to be unaware of it.</li>
+</ul>
+</li>
+<li><em>Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.</em><ul>
+<li>It happens when you map a buffer or image, because the library maps entire <code>VkDeviceMemory</code> block, where different types of images and buffers may end up together, especially on GPUs with unified memory like Intel.</li>
+</ul>
+</li>
+<li><em>Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug.</em><ul>
+<li>It happens when you use lost allocations, and a new image or buffer is created in place of an existing object that bacame lost.</li>
+</ul>
+</li>
+</ul>
 <h1><a class="anchor" id="general_considerations_allocation_algorithm"></a>
 Allocation algorithm</h1>
 <p>The library uses following algorithm for allocation, in order:</p>
@@ -90,7 +107,8 @@
 Features not supported</h1>
 <p>Features deliberately excluded from the scope of this library:</p>
 <ul>
-<li>Data transfer - issuing commands that transfer data between buffers or images, any usage of <code>VkCommandList</code> or <code>VkCommandQueue</code> and related synchronization is responsibility of the user.</li>
+<li>Data transfer - issuing commands that transfer data between buffers or images, any usage of <code>VkCommandList</code> or <code>VkQueue</code> and related synchronization is responsibility of the user.</li>
+<li>Allocations for imported/exported external memory. They tend to require explicit memory type index and dedicated allocation anyway, so they don't interact with main features of this library. Such special purpose allocations should be made manually, using <code>vkCreateBuffer()</code> and <code>vkAllocateMemory()</code>.</li>
 <li>Support for any programming languages other than C/C++. Bindings to other languages are welcomed as external projects. </li>
 </ul>
 </div></div><!-- contents -->
diff --git a/docs/html/globals.html b/docs/html/globals.html
index e94b352..73bdc76 100644
--- a/docs/html/globals.html
+++ b/docs/html/globals.html
@@ -89,6 +89,9 @@
 <li>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT
 : <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">vk_mem_alloc.h</a>
 </li>
+<li>VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT
+: <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">vk_mem_alloc.h</a>
+</li>
 <li>VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT
 : <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">vk_mem_alloc.h</a>
 </li>
@@ -101,6 +104,9 @@
 <li>VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT
 : <a class="el" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">vk_mem_alloc.h</a>
 </li>
+<li>VMA_DEDICATED_ALLOCATION
+: <a class="el" href="vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4">vk_mem_alloc.h</a>
+</li>
 <li>VMA_MEMORY_USAGE_CPU_ONLY
 : <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">vk_mem_alloc.h</a>
 </li>
@@ -125,6 +131,18 @@
 <li>VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT
 : <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">vk_mem_alloc.h</a>
 </li>
+<li>VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT
+: <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726">vk_mem_alloc.h</a>
+</li>
+<li>VMA_RECORD_FLAG_BITS_MAX_ENUM
+: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e">vk_mem_alloc.h</a>
+</li>
+<li>VMA_RECORD_FLUSH_AFTER_CALL_BIT
+: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7">vk_mem_alloc.h</a>
+</li>
+<li>VMA_RECORDING_ENABLED
+: <a class="el" href="vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c">vk_mem_alloc.h</a>
+</li>
 <li>VMA_STATS_STRING_ENABLED
 : <a class="el" href="vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1">vk_mem_alloc.h</a>
 </li>
@@ -170,6 +188,12 @@
 <li>vmaCalculateStats()
 : <a class="el" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3">vk_mem_alloc.h</a>
 </li>
+<li>vmaCheckCorruption()
+: <a class="el" href="vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98">vk_mem_alloc.h</a>
+</li>
+<li>vmaCheckPoolCorruption()
+: <a class="el" href="vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89">vk_mem_alloc.h</a>
+</li>
 <li>vmaCreateAllocator()
 : <a class="el" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vk_mem_alloc.h</a>
 </li>
@@ -218,6 +242,9 @@
 <li>vmaFindMemoryTypeIndexForImageInfo()
 : <a class="el" href="vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472">vk_mem_alloc.h</a>
 </li>
+<li>vmaFlushAllocation()
+: <a class="el" href="vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de">vk_mem_alloc.h</a>
+</li>
 <li>vmaFreeMemory()
 : <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vk_mem_alloc.h</a>
 </li>
@@ -239,6 +266,9 @@
 <li>vmaGetPoolStats()
 : <a class="el" href="vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153">vk_mem_alloc.h</a>
 </li>
+<li>vmaInvalidateAllocation()
+: <a class="el" href="vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006">vk_mem_alloc.h</a>
+</li>
 <li>vmaMakePoolAllocationsLost()
 : <a class="el" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vk_mem_alloc.h</a>
 </li>
@@ -260,6 +290,15 @@
 <li>VmaPoolStats
 : <a class="el" href="vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34">vk_mem_alloc.h</a>
 </li>
+<li>VmaRecordFlagBits
+: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">vk_mem_alloc.h</a>
+</li>
+<li>VmaRecordFlags
+: <a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">vk_mem_alloc.h</a>
+</li>
+<li>VmaRecordSettings
+: <a class="el" href="vk__mem__alloc_8h.html#a0ab61e87ff6365f1d59915eadc37a9f0">vk_mem_alloc.h</a>
+</li>
 <li>vmaSetAllocationUserData()
 : <a class="el" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f">vk_mem_alloc.h</a>
 </li>
diff --git a/docs/html/globals_defs.html b/docs/html/globals_defs.html
index 95a5846..ca5de3f 100644
--- a/docs/html/globals_defs.html
+++ b/docs/html/globals_defs.html
@@ -59,6 +59,12 @@
 
 <div class="contents">
 &#160;<ul>
+<li>VMA_DEDICATED_ALLOCATION
+: <a class="el" href="vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4">vk_mem_alloc.h</a>
+</li>
+<li>VMA_RECORDING_ENABLED
+: <a class="el" href="vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c">vk_mem_alloc.h</a>
+</li>
 <li>VMA_STATS_STRING_ENABLED
 : <a class="el" href="vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1">vk_mem_alloc.h</a>
 </li>
diff --git a/docs/html/globals_enum.html b/docs/html/globals_enum.html
index 1df06f1..d295ccd 100644
--- a/docs/html/globals_enum.html
+++ b/docs/html/globals_enum.html
@@ -71,6 +71,9 @@
 <li>VmaPoolCreateFlagBits
 : <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">vk_mem_alloc.h</a>
 </li>
+<li>VmaRecordFlagBits
+: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">vk_mem_alloc.h</a>
+</li>
 </ul>
 </div><!-- contents -->
 <!-- start footer part -->
diff --git a/docs/html/globals_eval.html b/docs/html/globals_eval.html
index 2035414..38d7955 100644
--- a/docs/html/globals_eval.html
+++ b/docs/html/globals_eval.html
@@ -77,6 +77,9 @@
 <li>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT
 : <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">vk_mem_alloc.h</a>
 </li>
+<li>VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT
+: <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">vk_mem_alloc.h</a>
+</li>
 <li>VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT
 : <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">vk_mem_alloc.h</a>
 </li>
@@ -113,6 +116,15 @@
 <li>VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT
 : <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">vk_mem_alloc.h</a>
 </li>
+<li>VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT
+: <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726">vk_mem_alloc.h</a>
+</li>
+<li>VMA_RECORD_FLAG_BITS_MAX_ENUM
+: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e">vk_mem_alloc.h</a>
+</li>
+<li>VMA_RECORD_FLUSH_AFTER_CALL_BIT
+: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7">vk_mem_alloc.h</a>
+</li>
 </ul>
 </div><!-- contents -->
 <!-- start footer part -->
diff --git a/docs/html/globals_func.html b/docs/html/globals_func.html
index 55ac717..a31da7d 100644
--- a/docs/html/globals_func.html
+++ b/docs/html/globals_func.html
@@ -82,6 +82,12 @@
 <li>vmaCalculateStats()
 : <a class="el" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3">vk_mem_alloc.h</a>
 </li>
+<li>vmaCheckCorruption()
+: <a class="el" href="vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98">vk_mem_alloc.h</a>
+</li>
+<li>vmaCheckPoolCorruption()
+: <a class="el" href="vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89">vk_mem_alloc.h</a>
+</li>
 <li>vmaCreateAllocator()
 : <a class="el" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vk_mem_alloc.h</a>
 </li>
@@ -121,6 +127,9 @@
 <li>vmaFindMemoryTypeIndexForImageInfo()
 : <a class="el" href="vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472">vk_mem_alloc.h</a>
 </li>
+<li>vmaFlushAllocation()
+: <a class="el" href="vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de">vk_mem_alloc.h</a>
+</li>
 <li>vmaFreeMemory()
 : <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vk_mem_alloc.h</a>
 </li>
@@ -142,6 +151,9 @@
 <li>vmaGetPoolStats()
 : <a class="el" href="vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153">vk_mem_alloc.h</a>
 </li>
+<li>vmaInvalidateAllocation()
+: <a class="el" href="vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006">vk_mem_alloc.h</a>
+</li>
 <li>vmaMakePoolAllocationsLost()
 : <a class="el" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vk_mem_alloc.h</a>
 </li>
diff --git a/docs/html/globals_type.html b/docs/html/globals_type.html
index 0b3156b..68106a1 100644
--- a/docs/html/globals_type.html
+++ b/docs/html/globals_type.html
@@ -110,6 +110,15 @@
 <li>VmaPoolStats
 : <a class="el" href="vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34">vk_mem_alloc.h</a>
 </li>
+<li>VmaRecordFlagBits
+: <a class="el" href="vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4">vk_mem_alloc.h</a>
+</li>
+<li>VmaRecordFlags
+: <a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">vk_mem_alloc.h</a>
+</li>
+<li>VmaRecordSettings
+: <a class="el" href="vk__mem__alloc_8h.html#a0ab61e87ff6365f1d59915eadc37a9f0">vk_mem_alloc.h</a>
+</li>
 <li>VmaStatInfo
 : <a class="el" href="vk__mem__alloc_8h.html#a810b009a788ee8aac72a25b42ffbe31c">vk_mem_alloc.h</a>
 </li>
diff --git a/docs/html/group__general.html b/docs/html/group__general.html
deleted file mode 100644
index cbb5a09..0000000
--- a/docs/html/group__general.html
+++ /dev/null
@@ -1,643 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: General</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="summary">
-<a href="#nested-classes">Classes</a> &#124;
-<a href="#define-members">Macros</a> &#124;
-<a href="#typedef-members">Typedefs</a> &#124;
-<a href="#enum-members">Enumerations</a> &#124;
-<a href="#func-members">Functions</a>  </div>
-  <div class="headertitle">
-<div class="title">General</div>  </div>
-</div><!--header-->
-<div class="contents">
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
-Classes</h2></td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Set of callbacks that the library will call for <code>vkAllocateMemory</code> and <code>vkFreeMemory</code>.  <a href="struct_vma_device_memory_callbacks.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pointers to some Vulkan functions - a subset used by the library.  <a href="struct_vma_vulkan_functions.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Description of a Allocator to be created.  <a href="struct_vma_allocator_create_info.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_stat_info.html">VmaStatInfo</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Calculated statistics of memory usage in entire allocator.  <a href="struct_vma_stat_info.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_stats.html">VmaStats</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">General statistics from current state of Allocator.  <a href="struct_vma_stats.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
-Macros</h2></td></tr>
-<tr class="memitem:gae25f0d55fd91cb166f002b63244800e1"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gae25f0d55fd91cb166f002b63244800e1">VMA_STATS_STRING_ENABLED</a>&#160;&#160;&#160;1</td></tr>
-<tr class="separator:gae25f0d55fd91cb166f002b63244800e1"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a>
-Typedefs</h2></td></tr>
-<tr class="memitem:gab6a6477cda1ce775b30bde96d766203b"><td class="memItemLeft" align="right" valign="top">typedef void(VKAPI_PTR *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gab6a6477cda1ce775b30bde96d766203b">PFN_vmaAllocateDeviceMemoryFunction</a>) (VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</td></tr>
-<tr class="memdesc:gab6a6477cda1ce775b30bde96d766203b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Callback function called after successful vkAllocateMemory.  <a href="#gab6a6477cda1ce775b30bde96d766203b">More...</a><br /></td></tr>
-<tr class="separator:gab6a6477cda1ce775b30bde96d766203b"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaef2545dc2e9dd4f29ab9ba6ac6fe2f49"><td class="memItemLeft" align="right" valign="top">typedef void(VKAPI_PTR *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gaef2545dc2e9dd4f29ab9ba6ac6fe2f49">PFN_vmaFreeDeviceMemoryFunction</a>) (VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</td></tr>
-<tr class="memdesc:gaef2545dc2e9dd4f29ab9ba6ac6fe2f49"><td class="mdescLeft">&#160;</td><td class="mdescRight">Callback function called before vkFreeMemory.  <a href="#gaef2545dc2e9dd4f29ab9ba6ac6fe2f49">More...</a><br /></td></tr>
-<tr class="separator:gaef2545dc2e9dd4f29ab9ba6ac6fe2f49"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga5e2eb68d727cfd4df25702b027b7aa31"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga5e2eb68d727cfd4df25702b027b7aa31">VmaDeviceMemoryCallbacks</a></td></tr>
-<tr class="memdesc:ga5e2eb68d727cfd4df25702b027b7aa31"><td class="mdescLeft">&#160;</td><td class="mdescRight">Set of callbacks that the library will call for <code>vkAllocateMemory</code> and <code>vkFreeMemory</code>.  <a href="#ga5e2eb68d727cfd4df25702b027b7aa31">More...</a><br /></td></tr>
-<tr class="separator:ga5e2eb68d727cfd4df25702b027b7aa31"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga4ddf381b6ce795bdfbc6c614640b9915"><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__general.html#ga4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga4ddf381b6ce795bdfbc6c614640b9915">VmaAllocatorCreateFlagBits</a></td></tr>
-<tr class="memdesc:ga4ddf381b6ce795bdfbc6c614640b9915"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags for created VmaAllocator.  <a href="#ga4ddf381b6ce795bdfbc6c614640b9915">More...</a><br /></td></tr>
-<tr class="separator:ga4ddf381b6ce795bdfbc6c614640b9915"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gacfe6863e160722c2c1bbcf7573fddc4d"><td class="memItemLeft" align="right" valign="top">typedef VkFlags&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gacfe6863e160722c2c1bbcf7573fddc4d">VmaAllocatorCreateFlags</a></td></tr>
-<tr class="separator:gacfe6863e160722c2c1bbcf7573fddc4d"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga97064a1a271b0061ebfc3a079862d0c5"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga97064a1a271b0061ebfc3a079862d0c5">VmaVulkanFunctions</a></td></tr>
-<tr class="memdesc:ga97064a1a271b0061ebfc3a079862d0c5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pointers to some Vulkan functions - a subset used by the library.  <a href="#ga97064a1a271b0061ebfc3a079862d0c5">More...</a><br /></td></tr>
-<tr class="separator:ga97064a1a271b0061ebfc3a079862d0c5"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gae0f6d1d733dded220d28134da46b4283"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gae0f6d1d733dded220d28134da46b4283">VmaAllocatorCreateInfo</a></td></tr>
-<tr class="memdesc:gae0f6d1d733dded220d28134da46b4283"><td class="mdescLeft">&#160;</td><td class="mdescRight">Description of a Allocator to be created.  <a href="#gae0f6d1d733dded220d28134da46b4283">More...</a><br /></td></tr>
-<tr class="separator:gae0f6d1d733dded220d28134da46b4283"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga810b009a788ee8aac72a25b42ffbe31c"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_stat_info.html">VmaStatInfo</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga810b009a788ee8aac72a25b42ffbe31c">VmaStatInfo</a></td></tr>
-<tr class="memdesc:ga810b009a788ee8aac72a25b42ffbe31c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Calculated statistics of memory usage in entire allocator.  <a href="#ga810b009a788ee8aac72a25b42ffbe31c">More...</a><br /></td></tr>
-<tr class="separator:ga810b009a788ee8aac72a25b42ffbe31c"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga732be855fb4a7c248e6853d928a729af"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_stats.html">VmaStats</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga732be855fb4a7c248e6853d928a729af">VmaStats</a></td></tr>
-<tr class="memdesc:ga732be855fb4a7c248e6853d928a729af"><td class="mdescLeft">&#160;</td><td class="mdescRight">General statistics from current state of Allocator.  <a href="#ga732be855fb4a7c248e6853d928a729af">More...</a><br /></td></tr>
-<tr class="separator:ga732be855fb4a7c248e6853d928a729af"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="enum-members"></a>
-Enumerations</h2></td></tr>
-<tr class="memitem:ga4f87c9100d154a65a4ad495f7763cf7c"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a> { <a class="el" href="group__general.html#gga4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a> = 0x00000001, 
-<a class="el" href="group__general.html#gga4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a> = 0x00000002, 
-<a class="el" href="group__general.html#gga4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c">VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
- }<tr class="memdesc:ga4f87c9100d154a65a4ad495f7763cf7c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags for created VmaAllocator.  <a href="group__general.html#ga4f87c9100d154a65a4ad495f7763cf7c">More...</a><br /></td></tr>
-</td></tr>
-<tr class="separator:ga4f87c9100d154a65a4ad495f7763cf7c"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
-Functions</h2></td></tr>
-<tr class="memitem:ga200692051ddb34240248234f5f4c17bb"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a> (const <a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a> *pCreateInfo, VmaAllocator *pAllocator)</td></tr>
-<tr class="memdesc:ga200692051ddb34240248234f5f4c17bb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates Allocator object.  <a href="#ga200692051ddb34240248234f5f4c17bb">More...</a><br /></td></tr>
-<tr class="separator:ga200692051ddb34240248234f5f4c17bb"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaa8d164061c88f22fb1fd3c8f3534bc1d"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gaa8d164061c88f22fb1fd3c8f3534bc1d">vmaDestroyAllocator</a> (VmaAllocator allocator)</td></tr>
-<tr class="memdesc:gaa8d164061c88f22fb1fd3c8f3534bc1d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destroys allocator object.  <a href="#gaa8d164061c88f22fb1fd3c8f3534bc1d">More...</a><br /></td></tr>
-<tr class="separator:gaa8d164061c88f22fb1fd3c8f3534bc1d"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaecabf7b6e91ea87d0316fa0a9e014fe0"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gaecabf7b6e91ea87d0316fa0a9e014fe0">vmaGetPhysicalDeviceProperties</a> (VmaAllocator allocator, const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)</td></tr>
-<tr class="separator:gaecabf7b6e91ea87d0316fa0a9e014fe0"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gab88db292a17974f911182543fda52d19"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gab88db292a17974f911182543fda52d19">vmaGetMemoryProperties</a> (VmaAllocator allocator, const VkPhysicalDeviceMemoryProperties **ppPhysicalDeviceMemoryProperties)</td></tr>
-<tr class="separator:gab88db292a17974f911182543fda52d19"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga8701444752eb5de4464adb5a2b514bca"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a> (VmaAllocator allocator, uint32_t memoryTypeIndex, VkMemoryPropertyFlags *pFlags)</td></tr>
-<tr class="memdesc:ga8701444752eb5de4464adb5a2b514bca"><td class="mdescLeft">&#160;</td><td class="mdescRight">Given Memory Type Index, returns Property Flags of this memory type.  <a href="#ga8701444752eb5de4464adb5a2b514bca">More...</a><br /></td></tr>
-<tr class="separator:ga8701444752eb5de4464adb5a2b514bca"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gade56bf8dc9f5a5eaddf5f119ed525236"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gade56bf8dc9f5a5eaddf5f119ed525236">vmaSetCurrentFrameIndex</a> (VmaAllocator allocator, uint32_t frameIndex)</td></tr>
-<tr class="memdesc:gade56bf8dc9f5a5eaddf5f119ed525236"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sets index of the current frame.  <a href="#gade56bf8dc9f5a5eaddf5f119ed525236">More...</a><br /></td></tr>
-<tr class="separator:gade56bf8dc9f5a5eaddf5f119ed525236"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga333b61c1788cb23559177531e6a93ca3"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga333b61c1788cb23559177531e6a93ca3">vmaCalculateStats</a> (VmaAllocator allocator, <a class="el" href="struct_vma_stats.html">VmaStats</a> *pStats)</td></tr>
-<tr class="memdesc:ga333b61c1788cb23559177531e6a93ca3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Retrieves statistics from current state of the Allocator.  <a href="#ga333b61c1788cb23559177531e6a93ca3">More...</a><br /></td></tr>
-<tr class="separator:ga333b61c1788cb23559177531e6a93ca3"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaa4fee7eb5253377599ef4fd38c93c2a0"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#gaa4fee7eb5253377599ef4fd38c93c2a0">vmaBuildStatsString</a> (VmaAllocator allocator, char **ppStatsString, VkBool32 detailedMap)</td></tr>
-<tr class="memdesc:gaa4fee7eb5253377599ef4fd38c93c2a0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Builds and returns statistics as string in JSON format.  <a href="#gaa4fee7eb5253377599ef4fd38c93c2a0">More...</a><br /></td></tr>
-<tr class="separator:gaa4fee7eb5253377599ef4fd38c93c2a0"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga3104eb30d8122c84dd8541063f145288"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga3104eb30d8122c84dd8541063f145288">vmaFreeStatsString</a> (VmaAllocator allocator, char *pStatsString)</td></tr>
-<tr class="separator:ga3104eb30d8122c84dd8541063f145288"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<h2 class="groupheader">Macro Definition Documentation</h2>
-<a id="gae25f0d55fd91cb166f002b63244800e1"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gae25f0d55fd91cb166f002b63244800e1">&#9670;&nbsp;</a></span>VMA_STATS_STRING_ENABLED</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define VMA_STATS_STRING_ENABLED&#160;&#160;&#160;1</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<h2 class="groupheader">Typedef Documentation</h2>
-<a id="gab6a6477cda1ce775b30bde96d766203b"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gab6a6477cda1ce775b30bde96d766203b">&#9670;&nbsp;</a></span>PFN_vmaAllocateDeviceMemoryFunction</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef void(VKAPI_PTR * PFN_vmaAllocateDeviceMemoryFunction) (VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Callback function called after successful vkAllocateMemory. </p>
-
-</div>
-</div>
-<a id="gaef2545dc2e9dd4f29ab9ba6ac6fe2f49"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gaef2545dc2e9dd4f29ab9ba6ac6fe2f49">&#9670;&nbsp;</a></span>PFN_vmaFreeDeviceMemoryFunction</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef void(VKAPI_PTR * PFN_vmaFreeDeviceMemoryFunction) (VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Callback function called before vkFreeMemory. </p>
-
-</div>
-</div>
-<a id="ga4ddf381b6ce795bdfbc6c614640b9915"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga4ddf381b6ce795bdfbc6c614640b9915">&#9670;&nbsp;</a></span>VmaAllocatorCreateFlagBits</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef enum <a class="el" href="group__general.html#ga4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a>  <a class="el" href="group__general.html#ga4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags for created VmaAllocator. </p>
-
-</div>
-</div>
-<a id="gacfe6863e160722c2c1bbcf7573fddc4d"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gacfe6863e160722c2c1bbcf7573fddc4d">&#9670;&nbsp;</a></span>VmaAllocatorCreateFlags</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef VkFlags <a class="el" href="group__general.html#gacfe6863e160722c2c1bbcf7573fddc4d">VmaAllocatorCreateFlags</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<a id="gae0f6d1d733dded220d28134da46b4283"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gae0f6d1d733dded220d28134da46b4283">&#9670;&nbsp;</a></span>VmaAllocatorCreateInfo</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>  <a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Description of a Allocator to be created. </p>
-
-</div>
-</div>
-<a id="ga5e2eb68d727cfd4df25702b027b7aa31"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga5e2eb68d727cfd4df25702b027b7aa31">&#9670;&nbsp;</a></span>VmaDeviceMemoryCallbacks</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a>  <a class="el" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Set of callbacks that the library will call for <code>vkAllocateMemory</code> and <code>vkFreeMemory</code>. </p>
-<p>Provided for informative purpose, e.g. to gather statistics about number of allocations or total amount of memory allocated in Vulkan.</p>
-<p>Used in <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e" title="Informative callbacks for vkAllocateMemory, vkFreeMemory. ">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a>. </p>
-
-</div>
-</div>
-<a id="ga810b009a788ee8aac72a25b42ffbe31c"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga810b009a788ee8aac72a25b42ffbe31c">&#9670;&nbsp;</a></span>VmaStatInfo</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_stat_info.html">VmaStatInfo</a>  <a class="el" href="struct_vma_stat_info.html">VmaStatInfo</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Calculated statistics of memory usage in entire allocator. </p>
-
-</div>
-</div>
-<a id="ga732be855fb4a7c248e6853d928a729af"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga732be855fb4a7c248e6853d928a729af">&#9670;&nbsp;</a></span>VmaStats</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_stats.html">VmaStats</a>  <a class="el" href="struct_vma_stats.html">VmaStats</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>General statistics from current state of Allocator. </p>
-
-</div>
-</div>
-<a id="ga97064a1a271b0061ebfc3a079862d0c5"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga97064a1a271b0061ebfc3a079862d0c5">&#9670;&nbsp;</a></span>VmaVulkanFunctions</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>  <a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Pointers to some Vulkan functions - a subset used by the library. </p>
-<p>Used in <a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd" title="Pointers to Vulkan functions. Can be null if you leave define VMA_STATIC_VULKAN_FUNCTIONS 1...">VmaAllocatorCreateInfo::pVulkanFunctions</a>. </p>
-
-</div>
-</div>
-<h2 class="groupheader">Enumeration Type Documentation</h2>
-<a id="ga4f87c9100d154a65a4ad495f7763cf7c"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga4f87c9100d154a65a4ad495f7763cf7c">&#9670;&nbsp;</a></span>VmaAllocatorCreateFlagBits</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group__general.html#ga4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags for created VmaAllocator. </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="gga4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d"></a>VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT&#160;</td><td class="fielddoc"><p>Allocator and all objects created from it will not be synchronized internally, so you must guarantee they are used from only one thread at a time or synchronized externally by you. </p>
-<p>Using this flag may increase performance because internal mutexes are not used. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="gga4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878"></a>VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT&#160;</td><td class="fielddoc"><p>Enables usage of VK_KHR_dedicated_allocation extension. </p>
-<p>Using this extenion will automatically allocate dedicated blocks of memory for some buffers and images instead of suballocating place for them out of bigger memory blocks (as if you explicitly used VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag) when it is recommended by the driver. It may improve performance on some GPUs.</p>
-<p>You may set this flag only if you found out that following device extensions are supported, you enabled them while creating Vulkan device passed as <a class="el" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500" title="Vulkan device. ">VmaAllocatorCreateInfo::device</a>, and you want them to be used internally by this library:</p>
-<ul>
-<li>VK_KHR_get_memory_requirements2</li>
-<li>VK_KHR_dedicated_allocation</li>
-</ul>
-<p>If this flag is enabled, you must also provide <a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd" title="Pointers to Vulkan functions. Can be null if you leave define VMA_STATIC_VULKAN_FUNCTIONS 1...">VmaAllocatorCreateInfo::pVulkanFunctions</a> and fill at least members: <a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">VmaVulkanFunctions::vkGetBufferMemoryRequirements2KHR</a>, <a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">VmaVulkanFunctions::vkGetImageMemoryRequirements2KHR</a>, because they are never imported statically.</p>
-<p>When this flag is set, you can experience following warnings reported by Vulkan validation layer. You can ignore them.</p>
-<blockquote class="doxtable">
-<p>vkBindBufferMemory(): Binding memory to buffer 0x2d but vkGetBufferMemoryRequirements() has not been called on that buffer.</p>
-</blockquote>
-</td></tr>
-<tr><td class="fieldname"><a id="gga4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c"></a>VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
-</table>
-
-</div>
-</div>
-<h2 class="groupheader">Function Documentation</h2>
-<a id="gaa4fee7eb5253377599ef4fd38c93c2a0"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gaa4fee7eb5253377599ef4fd38c93c2a0">&#9670;&nbsp;</a></span>vmaBuildStatsString()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaBuildStatsString </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">char **&#160;</td>
-          <td class="paramname"><em>ppStatsString</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkBool32&#160;</td>
-          <td class="paramname"><em>detailedMap</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Builds and returns statistics as string in JSON format. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir">[out]</td><td class="paramname">ppStatsString</td><td>Must be freed using <a class="el" href="group__general.html#ga3104eb30d8122c84dd8541063f145288">vmaFreeStatsString()</a> function. </td></tr>
-  </table>
-  </dd>
-</dl>
-
-</div>
-</div>
-<a id="ga333b61c1788cb23559177531e6a93ca3"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga333b61c1788cb23559177531e6a93ca3">&#9670;&nbsp;</a></span>vmaCalculateStats()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaCalculateStats </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_stats.html">VmaStats</a> *&#160;</td>
-          <td class="paramname"><em>pStats</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Retrieves statistics from current state of the Allocator. </p>
-
-</div>
-</div>
-<a id="ga200692051ddb34240248234f5f4c17bb"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga200692051ddb34240248234f5f4c17bb">&#9670;&nbsp;</a></span>vmaCreateAllocator()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaCreateAllocator </td>
-          <td>(</td>
-          <td class="paramtype">const <a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocator *&#160;</td>
-          <td class="paramname"><em>pAllocator</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Creates Allocator object. </p>
-
-</div>
-</div>
-<a id="gaa8d164061c88f22fb1fd3c8f3534bc1d"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gaa8d164061c88f22fb1fd3c8f3534bc1d">&#9670;&nbsp;</a></span>vmaDestroyAllocator()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaDestroyAllocator </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Destroys allocator object. </p>
-
-</div>
-</div>
-<a id="ga3104eb30d8122c84dd8541063f145288"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga3104eb30d8122c84dd8541063f145288">&#9670;&nbsp;</a></span>vmaFreeStatsString()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaFreeStatsString </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">char *&#160;</td>
-          <td class="paramname"><em>pStatsString</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<a id="gab88db292a17974f911182543fda52d19"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gab88db292a17974f911182543fda52d19">&#9670;&nbsp;</a></span>vmaGetMemoryProperties()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaGetMemoryProperties </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const VkPhysicalDeviceMemoryProperties **&#160;</td>
-          <td class="paramname"><em>ppPhysicalDeviceMemoryProperties</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-<p>PhysicalDeviceMemoryProperties are fetched from physicalDevice by the allocator. You can access it here, without fetching it again on your own. </p>
-
-</div>
-</div>
-<a id="ga8701444752eb5de4464adb5a2b514bca"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga8701444752eb5de4464adb5a2b514bca">&#9670;&nbsp;</a></span>vmaGetMemoryTypeProperties()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaGetMemoryTypeProperties </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">uint32_t&#160;</td>
-          <td class="paramname"><em>memoryTypeIndex</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkMemoryPropertyFlags *&#160;</td>
-          <td class="paramname"><em>pFlags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Given Memory Type Index, returns Property Flags of this memory type. </p>
-<p>This is just a convenience function. Same information can be obtained using <a class="el" href="group__general.html#gab88db292a17974f911182543fda52d19">vmaGetMemoryProperties()</a>. </p>
-
-</div>
-</div>
-<a id="gaecabf7b6e91ea87d0316fa0a9e014fe0"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gaecabf7b6e91ea87d0316fa0a9e014fe0">&#9670;&nbsp;</a></span>vmaGetPhysicalDeviceProperties()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaGetPhysicalDeviceProperties </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const VkPhysicalDeviceProperties **&#160;</td>
-          <td class="paramname"><em>ppPhysicalDeviceProperties</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-<p>PhysicalDeviceProperties are fetched from physicalDevice by the allocator. You can access it here, without fetching it again on your own. </p>
-
-</div>
-</div>
-<a id="gade56bf8dc9f5a5eaddf5f119ed525236"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gade56bf8dc9f5a5eaddf5f119ed525236">&#9670;&nbsp;</a></span>vmaSetCurrentFrameIndex()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaSetCurrentFrameIndex </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">uint32_t&#160;</td>
-          <td class="paramname"><em>frameIndex</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Sets index of the current frame. </p>
-<p>This function must be used if you make allocations with <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> and <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flags to inform the allocator when a new frame begins. Allocations queried using <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> cannot become lost in the current frame. </p>
-
-</div>
-</div>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/group__layer1.html b/docs/html/group__layer1.html
deleted file mode 100644
index a77dca8..0000000
--- a/docs/html/group__layer1.html
+++ /dev/null
@@ -1,308 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: Layer 1 Choosing Memory Type</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="summary">
-<a href="#nested-classes">Classes</a> &#124;
-<a href="#typedef-members">Typedefs</a> &#124;
-<a href="#enum-members">Enumerations</a> &#124;
-<a href="#func-members">Functions</a>  </div>
-  <div class="headertitle">
-<div class="title">Layer 1 Choosing Memory Type</div>  </div>
-</div><!--header-->
-<div class="contents">
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
-Classes</h2></td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a>
-Typedefs</h2></td></tr>
-<tr class="memitem:gad63b2113c0bfdbeade1cb498f5a8580d"><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#gad63b2113c0bfdbeade1cb498f5a8580d">VmaMemoryUsage</a></td></tr>
-<tr class="separator:gad63b2113c0bfdbeade1cb498f5a8580d"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gabf6bf6748c7a9fe7ce5b7835c0f56af4"><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#gabf6bf6748c7a9fe7ce5b7835c0f56af4">VmaAllocationCreateFlagBits</a></td></tr>
-<tr class="memdesc:gabf6bf6748c7a9fe7ce5b7835c0f56af4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be passed as <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>.  <a href="#gabf6bf6748c7a9fe7ce5b7835c0f56af4">More...</a><br /></td></tr>
-<tr class="separator:gabf6bf6748c7a9fe7ce5b7835c0f56af4"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga5225e5e11f8376f6a31a1791f3d6e817"><td class="memItemLeft" align="right" valign="top">typedef VkFlags&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#ga5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a></td></tr>
-<tr class="separator:ga5225e5e11f8376f6a31a1791f3d6e817"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga86c44f9950b40d50088ed93a17870a7a"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#ga86c44f9950b40d50088ed93a17870a7a">VmaAllocationCreateInfo</a></td></tr>
-<tr class="separator:ga86c44f9950b40d50088ed93a17870a7a"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="enum-members"></a>
-Enumerations</h2></td></tr>
-<tr class="memitem:gaa5846affa1e9da3800e3e78fae2305cc"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a> { <br />
-&#160;&#160;<a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a> = 0, 
-<a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a> = 1, 
-<a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a> = 2, 
-<a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a> = 3, 
-<br />
-&#160;&#160;<a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a> = 4, 
-<a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e">VMA_MEMORY_USAGE_MAX_ENUM</a> = 0x7FFFFFFF
-<br />
- }</td></tr>
-<tr class="separator:gaa5846affa1e9da3800e3e78fae2305cc"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gad9889c10c798b040d59c92f257cae597"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a> { <br />
-&#160;&#160;<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> = 0x00000001, 
-<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a> = 0x00000002, 
-<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312">VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</a> = 0x00000004, 
-<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> = 0x00000008, 
-<br />
-&#160;&#160;<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> = 0x00000010, 
-<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
-<br />
- }<tr class="memdesc:gad9889c10c798b040d59c92f257cae597"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be passed as <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>.  <a href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">More...</a><br /></td></tr>
-</td></tr>
-<tr class="separator:gad9889c10c798b040d59c92f257cae597"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
-Functions</h2></td></tr>
-<tr class="memitem:gaef15a94b58fbcb0fe706d5720e84a74a"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#gaef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a> (VmaAllocator allocator, uint32_t memoryTypeBits, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)</td></tr>
-<tr class="separator:gaef15a94b58fbcb0fe706d5720e84a74a"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<h2 class="groupheader">Typedef Documentation</h2>
-<a id="gabf6bf6748c7a9fe7ce5b7835c0f56af4"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gabf6bf6748c7a9fe7ce5b7835c0f56af4">&#9670;&nbsp;</a></span>VmaAllocationCreateFlagBits</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef enum <a class="el" href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a>  <a class="el" href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags to be passed as <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. </p>
-
-</div>
-</div>
-<a id="ga5225e5e11f8376f6a31a1791f3d6e817"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga5225e5e11f8376f6a31a1791f3d6e817">&#9670;&nbsp;</a></span>VmaAllocationCreateFlags</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef VkFlags <a class="el" href="group__layer1.html#ga5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<a id="ga86c44f9950b40d50088ed93a17870a7a"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga86c44f9950b40d50088ed93a17870a7a">&#9670;&nbsp;</a></span>VmaAllocationCreateInfo</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>  <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<a id="gad63b2113c0bfdbeade1cb498f5a8580d"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gad63b2113c0bfdbeade1cb498f5a8580d">&#9670;&nbsp;</a></span>VmaMemoryUsage</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef enum <a class="el" href="group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a>  <a class="el" href="group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<h2 class="groupheader">Enumeration Type Documentation</h2>
-<a id="gad9889c10c798b040d59c92f257cae597"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gad9889c10c798b040d59c92f257cae597">&#9670;&nbsp;</a></span>VmaAllocationCreateFlagBits</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags to be passed as <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f"></a>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT&#160;</td><td class="fielddoc"><p>Set this flag if the allocation should have its own memory block. </p>
-<p>Use it for special, big resources, like fullscreen images used as attachments.</p>
-<p>This flag must also be used for host visible resources that you want to map simultaneously because otherwise they might end up as regions of the same <code>VkDeviceMemory</code>, while mapping same <code>VkDeviceMemory</code> multiple times simultaneously is illegal.</p>
-<p>You should not use this flag if <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> is not null. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff"></a>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT&#160;</td><td class="fielddoc"><p>Set this flag to only try to allocate from existing <code>VkDeviceMemory</code> blocks and never create new such block. </p>
-<p>If new allocation cannot be placed in any of the existing blocks, allocation fails with <code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code> error.</p>
-<p>You should not use <code>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</code> and <code>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</code> at the same time. It makes no sense.</p>
-<p>If <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> is not null, this flag is implied and ignored. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312"></a>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT&#160;</td><td class="fielddoc"><p>Set this flag to use a memory that will be persistently mapped and retrieve pointer to it. </p>
-<p>Pointer to mapped memory will be returned through <a class="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>. You cannot map the memory on your own as multiple mappings of a single <code>VkDeviceMemory</code> are illegal.</p>
-<p>If <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> is not null, usage of this flag must match usage of flag <code>VMA_POOL_CREATE_PERSISTENT_MAP_BIT</code> used during pool creation.</p>
-<p>Is it valid to use this flag for allocation made from memory type that is not <code>HOST_VISIBLE</code>. This flag is then ignored and memory is not mapped. This is useful if you need an allocation that is efficient to use on GPU (<code>DEVICE_LOCAL</code>) and still want to map it directly if possible on platforms that support it (e.g. Intel GPU). </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2"></a>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT&#160;</td><td class="fielddoc"><p>Allocation created with this flag can become lost as a result of another allocation with <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag, so you must check it before use.</p>
-<p>To check if allocation is not lost, call <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> and check if <a class="el" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67" title="Handle to Vulkan memory object. ">VmaAllocationInfo::deviceMemory</a> is not <code>VK_NULL_HANDLE</code>.</p>
-<p>For details about supporting lost allocations, see Lost Allocations chapter of User Guide on Main Page. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e"></a>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT&#160;</td><td class="fielddoc"><p>While creating allocation using this flag, other allocations that were created with flag <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> can become lost.</p>
-<p>For details about supporting lost allocations, see Lost Allocations chapter of User Guide on Main Page. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882"></a>VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
-</table>
-
-</div>
-</div>
-<a id="gaa5846affa1e9da3800e3e78fae2305cc"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gaa5846affa1e9da3800e3e78fae2305cc">&#9670;&nbsp;</a></span>VmaMemoryUsage</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd"></a>VMA_MEMORY_USAGE_UNKNOWN&#160;</td><td class="fielddoc"><p>No intended memory usage specified. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7"></a>VMA_MEMORY_USAGE_GPU_ONLY&#160;</td><td class="fielddoc"><p>Memory will be used on device only, so faster access from the device is preferred. No need to be mappable on host. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"></a>VMA_MEMORY_USAGE_CPU_ONLY&#160;</td><td class="fielddoc"><p>Memory will be mapped on host. Could be used for transfer to/from device. </p>
-<p>Guarantees to be <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67"></a>VMA_MEMORY_USAGE_CPU_TO_GPU&#160;</td><td class="fielddoc"><p>Memory will be used for frequent (dynamic) updates from host and reads on device (upload). </p>
-<p>Guarantees to be <code>HOST_VISIBLE</code>. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27"></a>VMA_MEMORY_USAGE_GPU_TO_CPU&#160;</td><td class="fielddoc"><p>Memory will be used for frequent writing on device and readback on host (download). </p>
-<p>Guarantees to be <code>HOST_VISIBLE</code>. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e"></a>VMA_MEMORY_USAGE_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
-</table>
-
-</div>
-</div>
-<h2 class="groupheader">Function Documentation</h2>
-<a id="gaef15a94b58fbcb0fe706d5720e84a74a"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gaef15a94b58fbcb0fe706d5720e84a74a">&#9670;&nbsp;</a></span>vmaFindMemoryTypeIndex()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaFindMemoryTypeIndex </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">uint32_t&#160;</td>
-          <td class="paramname"><em>memoryTypeBits</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">uint32_t *&#160;</td>
-          <td class="paramname"><em>pMemoryTypeIndex</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-<p>This algorithm tries to find a memory type that:</p>
-<ul>
-<li>Is allowed by memoryTypeBits.</li>
-<li>Contains all the flags from pAllocationCreateInfo-&gt;requiredFlags.</li>
-<li>Matches intended usage.</li>
-<li>Has as many flags from pAllocationCreateInfo-&gt;preferredFlags as possible.</li>
-</ul>
-<dl class="section return"><dt>Returns</dt><dd>Returns VK_ERROR_FEATURE_NOT_PRESENT if not found. Receiving such result from this function or any other allocating function probably means that your device doesn't support any memory type with requested features for the specific type of resource you want to use it for. Please check parameters of your resource, like image layout (OPTIMAL versus LINEAR) or mip level count. </dd></dl>
-
-</div>
-</div>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/group__layer2.html b/docs/html/group__layer2.html
deleted file mode 100644
index 1024a4f..0000000
--- a/docs/html/group__layer2.html
+++ /dev/null
@@ -1,988 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: Layer 2 Allocating Memory</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="summary">
-<a href="#nested-classes">Classes</a> &#124;
-<a href="#typedef-members">Typedefs</a> &#124;
-<a href="#enum-members">Enumerations</a> &#124;
-<a href="#func-members">Functions</a>  </div>
-  <div class="headertitle">
-<div class="title">Layer 2 Allocating Memory</div>  </div>
-</div><!--header-->
-<div class="contents">
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
-Classes</h2></td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Describes parameter of created <code>VmaPool</code>.  <a href="struct_vma_pool_create_info.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Describes parameter of existing <code>VmaPool</code>.  <a href="struct_vma_pool_stats.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Parameters of <code>VmaAllocation</code> objects, that can be retrieved using function <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a>.  <a href="struct_vma_allocation_info.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Optional configuration parameters to be passed to function <a class="el" href="group__layer2.html#ga6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>.  <a href="struct_vma_defragmentation_info.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Statistics returned by function <a class="el" href="group__layer2.html#ga6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>.  <a href="struct_vma_defragmentation_stats.html#details">More...</a><br /></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a>
-Typedefs</h2></td></tr>
-<tr class="memitem:ga8f93195158e0e2ac80ca352064e71c1f"><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__layer2.html#ga9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga8f93195158e0e2ac80ca352064e71c1f">VmaPoolCreateFlagBits</a></td></tr>
-<tr class="memdesc:ga8f93195158e0e2ac80ca352064e71c1f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be passed as <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446" title="Use combination of VmaPoolCreateFlagBits. ">VmaPoolCreateInfo::flags</a>.  <a href="#ga8f93195158e0e2ac80ca352064e71c1f">More...</a><br /></td></tr>
-<tr class="separator:ga8f93195158e0e2ac80ca352064e71c1f"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga2770e325ea42e087c1b91fdf46d0292a"><td class="memItemLeft" align="right" valign="top">typedef VkFlags&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga2770e325ea42e087c1b91fdf46d0292a">VmaPoolCreateFlags</a></td></tr>
-<tr class="separator:ga2770e325ea42e087c1b91fdf46d0292a"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga211706e9348dcee25a843ed4ea69bce7"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga211706e9348dcee25a843ed4ea69bce7">VmaPoolCreateInfo</a></td></tr>
-<tr class="memdesc:ga211706e9348dcee25a843ed4ea69bce7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Describes parameter of created <code>VmaPool</code>.  <a href="#ga211706e9348dcee25a843ed4ea69bce7">More...</a><br /></td></tr>
-<tr class="separator:ga211706e9348dcee25a843ed4ea69bce7"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga2e5612d871d64c5624087b837a338c34"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga2e5612d871d64c5624087b837a338c34">VmaPoolStats</a></td></tr>
-<tr class="memdesc:ga2e5612d871d64c5624087b837a338c34"><td class="mdescLeft">&#160;</td><td class="mdescRight">Describes parameter of existing <code>VmaPool</code>.  <a href="#ga2e5612d871d64c5624087b837a338c34">More...</a><br /></td></tr>
-<tr class="separator:ga2e5612d871d64c5624087b837a338c34"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga795e6ff02a21d5486c0565f403dd9255"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga795e6ff02a21d5486c0565f403dd9255">VmaAllocationInfo</a></td></tr>
-<tr class="memdesc:ga795e6ff02a21d5486c0565f403dd9255"><td class="mdescLeft">&#160;</td><td class="mdescRight">Parameters of <code>VmaAllocation</code> objects, that can be retrieved using function <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a>.  <a href="#ga795e6ff02a21d5486c0565f403dd9255">More...</a><br /></td></tr>
-<tr class="separator:ga795e6ff02a21d5486c0565f403dd9255"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gae67f8573a0cf20f16f0a1eecbca566a0"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#gae67f8573a0cf20f16f0a1eecbca566a0">VmaDefragmentationInfo</a></td></tr>
-<tr class="memdesc:gae67f8573a0cf20f16f0a1eecbca566a0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Optional configuration parameters to be passed to function <a class="el" href="group__layer2.html#ga6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>.  <a href="#gae67f8573a0cf20f16f0a1eecbca566a0">More...</a><br /></td></tr>
-<tr class="separator:gae67f8573a0cf20f16f0a1eecbca566a0"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gab0f9b06441c840fee560de4a2967f8c9"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#gab0f9b06441c840fee560de4a2967f8c9">VmaDefragmentationStats</a></td></tr>
-<tr class="memdesc:gab0f9b06441c840fee560de4a2967f8c9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Statistics returned by function <a class="el" href="group__layer2.html#ga6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>.  <a href="#gab0f9b06441c840fee560de4a2967f8c9">More...</a><br /></td></tr>
-<tr class="separator:gab0f9b06441c840fee560de4a2967f8c9"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="enum-members"></a>
-Enumerations</h2></td></tr>
-<tr class="memitem:ga9a7c45f9c863695d98c83fa5ac940fe7"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a> { <a class="el" href="group__layer2.html#gga9a7c45f9c863695d98c83fa5ac940fe7a918441f7b40dca90481b114f5d224fe9">VMA_POOL_CREATE_PERSISTENT_MAP_BIT</a> = 0x00000001, 
-<a class="el" href="group__layer2.html#gga9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a> = 0x00000002, 
-<a class="el" href="group__layer2.html#gga9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec">VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
- }<tr class="memdesc:ga9a7c45f9c863695d98c83fa5ac940fe7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be passed as <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446" title="Use combination of VmaPoolCreateFlagBits. ">VmaPoolCreateInfo::flags</a>.  <a href="group__layer2.html#ga9a7c45f9c863695d98c83fa5ac940fe7">More...</a><br /></td></tr>
-</td></tr>
-<tr class="separator:ga9a7c45f9c863695d98c83fa5ac940fe7"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
-Functions</h2></td></tr>
-<tr class="memitem:ga5c8770ded7c59c8caac6de0c2cb00b50"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a> (VmaAllocator allocator, const <a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> *pCreateInfo, VmaPool *pPool)</td></tr>
-<tr class="memdesc:ga5c8770ded7c59c8caac6de0c2cb00b50"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocates Vulkan device memory and creates <code>VmaPool</code> object.  <a href="#ga5c8770ded7c59c8caac6de0c2cb00b50">More...</a><br /></td></tr>
-<tr class="separator:ga5c8770ded7c59c8caac6de0c2cb00b50"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga5485779c8f1948238fc4e92232fa65e1"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a> (VmaAllocator allocator, VmaPool pool)</td></tr>
-<tr class="memdesc:ga5485779c8f1948238fc4e92232fa65e1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destroys VmaPool object and frees Vulkan device memory.  <a href="#ga5485779c8f1948238fc4e92232fa65e1">More...</a><br /></td></tr>
-<tr class="separator:ga5485779c8f1948238fc4e92232fa65e1"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gae8bf76997b234ef68aad922616df4153"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#gae8bf76997b234ef68aad922616df4153">vmaGetPoolStats</a> (VmaAllocator allocator, VmaPool pool, <a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a> *pPoolStats)</td></tr>
-<tr class="memdesc:gae8bf76997b234ef68aad922616df4153"><td class="mdescLeft">&#160;</td><td class="mdescRight">Retrieves statistics of existing VmaPool object.  <a href="#gae8bf76997b234ef68aad922616df4153">More...</a><br /></td></tr>
-<tr class="separator:gae8bf76997b234ef68aad922616df4153"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga736bd6cbda886f36c891727e73bd4024"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga736bd6cbda886f36c891727e73bd4024">vmaMakePoolAllocationsLost</a> (VmaAllocator allocator, VmaPool pool, size_t *pLostAllocationCount)</td></tr>
-<tr class="memdesc:ga736bd6cbda886f36c891727e73bd4024"><td class="mdescLeft">&#160;</td><td class="mdescRight">Marks all allocations in given pool as lost if they are not used in current frame or <a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> back from now.  <a href="#ga736bd6cbda886f36c891727e73bd4024">More...</a><br /></td></tr>
-<tr class="separator:ga736bd6cbda886f36c891727e73bd4024"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gabf28077dbf82d0908b8acbe8ee8dd9b8"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#gabf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a> (VmaAllocator allocator, const VkMemoryRequirements *pVkMemoryRequirements, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, VmaAllocation *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
-<tr class="memdesc:gabf28077dbf82d0908b8acbe8ee8dd9b8"><td class="mdescLeft">&#160;</td><td class="mdescRight">General purpose memory allocation.  <a href="#gabf28077dbf82d0908b8acbe8ee8dd9b8">More...</a><br /></td></tr>
-<tr class="separator:gabf28077dbf82d0908b8acbe8ee8dd9b8"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga7fdf64415b6c3d83c454f28d2c53df7b"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer</a> (VmaAllocator allocator, VkBuffer buffer, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, VmaAllocation *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
-<tr class="separator:ga7fdf64415b6c3d83c454f28d2c53df7b"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga0faa3f9e5fb233d29d1e00390650febb"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga0faa3f9e5fb233d29d1e00390650febb">vmaAllocateMemoryForImage</a> (VmaAllocator allocator, VkImage image, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, VmaAllocation *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
-<tr class="memdesc:ga0faa3f9e5fb233d29d1e00390650febb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Function similar to <a class="el" href="group__layer2.html#ga7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>.  <a href="#ga0faa3f9e5fb233d29d1e00390650febb">More...</a><br /></td></tr>
-<tr class="separator:ga0faa3f9e5fb233d29d1e00390650febb"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga11f0fbc034fa81a4efedd73d61ce7568"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga11f0fbc034fa81a4efedd73d61ce7568">vmaFreeMemory</a> (VmaAllocator allocator, VmaAllocation allocation)</td></tr>
-<tr class="memdesc:ga11f0fbc034fa81a4efedd73d61ce7568"><td class="mdescLeft">&#160;</td><td class="mdescRight">Frees memory previously allocated using <a class="el" href="group__layer2.html#gabf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>, <a class="el" href="group__layer2.html#ga7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, or <a class="el" href="group__layer2.html#ga0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a>.  <a href="#ga11f0fbc034fa81a4efedd73d61ce7568">More...</a><br /></td></tr>
-<tr class="separator:ga11f0fbc034fa81a4efedd73d61ce7568"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga86dd08aba8633bfa4ad0df2e76481d8b"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a> (VmaAllocator allocator, VmaAllocation allocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
-<tr class="memdesc:ga86dd08aba8633bfa4ad0df2e76481d8b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns current information about specified allocation.  <a href="#ga86dd08aba8633bfa4ad0df2e76481d8b">More...</a><br /></td></tr>
-<tr class="separator:ga86dd08aba8633bfa4ad0df2e76481d8b"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaf9147d31ffc11d62fc187bde283ed14f"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#gaf9147d31ffc11d62fc187bde283ed14f">vmaSetAllocationUserData</a> (VmaAllocator allocator, VmaAllocation allocation, void *pUserData)</td></tr>
-<tr class="memdesc:gaf9147d31ffc11d62fc187bde283ed14f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sets pUserData in given allocation to new value.  <a href="#gaf9147d31ffc11d62fc187bde283ed14f">More...</a><br /></td></tr>
-<tr class="separator:gaf9147d31ffc11d62fc187bde283ed14f"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gae5c9657d9e94756269145b01c05d16f1"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#gae5c9657d9e94756269145b01c05d16f1">vmaCreateLostAllocation</a> (VmaAllocator allocator, VmaAllocation *pAllocation)</td></tr>
-<tr class="memdesc:gae5c9657d9e94756269145b01c05d16f1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new allocation that is in lost state from the beginning.  <a href="#gae5c9657d9e94756269145b01c05d16f1">More...</a><br /></td></tr>
-<tr class="separator:gae5c9657d9e94756269145b01c05d16f1"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gad5bd1243512d099706de88168992f069"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#gad5bd1243512d099706de88168992f069">vmaMapMemory</a> (VmaAllocator allocator, VmaAllocation allocation, void **ppData)</td></tr>
-<tr class="separator:gad5bd1243512d099706de88168992f069"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga9bc268595cb33f6ec4d519cfce81ff45"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a> (VmaAllocator allocator, VmaAllocation allocation)</td></tr>
-<tr class="separator:ga9bc268595cb33f6ec4d519cfce81ff45"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga26b87244491c1fe77f11fe9ab5779c27"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga26b87244491c1fe77f11fe9ab5779c27">vmaUnmapPersistentlyMappedMemory</a> (VmaAllocator allocator)</td></tr>
-<tr class="memdesc:ga26b87244491c1fe77f11fe9ab5779c27"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unmaps persistently mapped memory of types that are <code>HOST_COHERENT</code> and <code>DEVICE_LOCAL</code>.  <a href="#ga26b87244491c1fe77f11fe9ab5779c27">More...</a><br /></td></tr>
-<tr class="separator:ga26b87244491c1fe77f11fe9ab5779c27"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga03366170bb8e186605518d2f5d65b85a"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga03366170bb8e186605518d2f5d65b85a">vmaMapPersistentlyMappedMemory</a> (VmaAllocator allocator)</td></tr>
-<tr class="memdesc:ga03366170bb8e186605518d2f5d65b85a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Maps back persistently mapped memory of types that are <code>HOST_COHERENT</code> and <code>DEVICE_LOCAL</code>.  <a href="#ga03366170bb8e186605518d2f5d65b85a">More...</a><br /></td></tr>
-<tr class="separator:ga03366170bb8e186605518d2f5d65b85a"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga6aced90fcc7b39882b6654a740a0b9bb"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer2.html#ga6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a> (VmaAllocator allocator, VmaAllocation *pAllocations, size_t allocationCount, VkBool32 *pAllocationsChanged, const <a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *pDefragmentationInfo, <a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a> *pDefragmentationStats)</td></tr>
-<tr class="memdesc:ga6aced90fcc7b39882b6654a740a0b9bb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compacts memory by moving allocations.  <a href="#ga6aced90fcc7b39882b6654a740a0b9bb">More...</a><br /></td></tr>
-<tr class="separator:ga6aced90fcc7b39882b6654a740a0b9bb"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<h2 class="groupheader">Typedef Documentation</h2>
-<a id="ga795e6ff02a21d5486c0565f403dd9255"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga795e6ff02a21d5486c0565f403dd9255">&#9670;&nbsp;</a></span>VmaAllocationInfo</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>  <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Parameters of <code>VmaAllocation</code> objects, that can be retrieved using function <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a>. </p>
-
-</div>
-</div>
-<a id="gae67f8573a0cf20f16f0a1eecbca566a0"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gae67f8573a0cf20f16f0a1eecbca566a0">&#9670;&nbsp;</a></span>VmaDefragmentationInfo</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>  <a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Optional configuration parameters to be passed to function <a class="el" href="group__layer2.html#ga6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>. </p>
-
-</div>
-</div>
-<a id="gab0f9b06441c840fee560de4a2967f8c9"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gab0f9b06441c840fee560de4a2967f8c9">&#9670;&nbsp;</a></span>VmaDefragmentationStats</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>  <a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Statistics returned by function <a class="el" href="group__layer2.html#ga6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>. </p>
-
-</div>
-</div>
-<a id="ga8f93195158e0e2ac80ca352064e71c1f"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga8f93195158e0e2ac80ca352064e71c1f">&#9670;&nbsp;</a></span>VmaPoolCreateFlagBits</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef enum <a class="el" href="group__layer2.html#ga9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a>  <a class="el" href="group__layer2.html#ga9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags to be passed as <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446" title="Use combination of VmaPoolCreateFlagBits. ">VmaPoolCreateInfo::flags</a>. </p>
-
-</div>
-</div>
-<a id="ga2770e325ea42e087c1b91fdf46d0292a"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga2770e325ea42e087c1b91fdf46d0292a">&#9670;&nbsp;</a></span>VmaPoolCreateFlags</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef VkFlags <a class="el" href="group__layer2.html#ga2770e325ea42e087c1b91fdf46d0292a">VmaPoolCreateFlags</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<a id="ga211706e9348dcee25a843ed4ea69bce7"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga211706e9348dcee25a843ed4ea69bce7">&#9670;&nbsp;</a></span>VmaPoolCreateInfo</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>  <a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Describes parameter of created <code>VmaPool</code>. </p>
-
-</div>
-</div>
-<a id="ga2e5612d871d64c5624087b837a338c34"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga2e5612d871d64c5624087b837a338c34">&#9670;&nbsp;</a></span>VmaPoolStats</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a>  <a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Describes parameter of existing <code>VmaPool</code>. </p>
-
-</div>
-</div>
-<h2 class="groupheader">Enumeration Type Documentation</h2>
-<a id="ga9a7c45f9c863695d98c83fa5ac940fe7"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga9a7c45f9c863695d98c83fa5ac940fe7">&#9670;&nbsp;</a></span>VmaPoolCreateFlagBits</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group__layer2.html#ga9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags to be passed as <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446" title="Use combination of VmaPoolCreateFlagBits. ">VmaPoolCreateInfo::flags</a>. </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="gga9a7c45f9c863695d98c83fa5ac940fe7a918441f7b40dca90481b114f5d224fe9"></a>VMA_POOL_CREATE_PERSISTENT_MAP_BIT&#160;</td><td class="fielddoc"><p>Set this flag to use a memory that will be persistently mapped.</p>
-<p>Each allocation made from this pool will have <a class="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> available.</p>
-<p>Usage of this flag must match usage of VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT flag for every allocation made from this pool. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="gga9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2"></a>VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT&#160;</td><td class="fielddoc"><p>Use this flag if you always allocate only buffers and linear images or only optimal images out of this pool and so Buffer-Image Granularity can be ignored. </p>
-<p>This is na optional optimization flag.</p>
-<p>If you always allocate using <a class="el" href="group__layer3.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>, <a class="el" href="group__layer3.html#ga02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a>, <a class="el" href="group__layer2.html#ga7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, then you don't need to use it because allocator knows exact type of your allocations so it can handle Buffer-Image Granularity in the optimal way.</p>
-<p>If you also allocate using <a class="el" href="group__layer2.html#ga0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a> or <a class="el" href="group__layer2.html#gabf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>, exact type of such allocations is not known, so allocator must be conservative in handling Buffer-Image Granularity, which can lead to suboptimal allocation (wasted memory). In that case, if you can make sure you always allocate only buffers and linear images or only optimal images out of this pool, use this flag to make allocator disregard Buffer-Image Granularity and so make allocations more optimal. </p>
-</td></tr>
-<tr><td class="fieldname"><a id="gga9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec"></a>VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
-</table>
-
-</div>
-</div>
-<h2 class="groupheader">Function Documentation</h2>
-<a id="gabf28077dbf82d0908b8acbe8ee8dd9b8"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gabf28077dbf82d0908b8acbe8ee8dd9b8">&#9670;&nbsp;</a></span>vmaAllocateMemory()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaAllocateMemory </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const VkMemoryRequirements *&#160;</td>
-          <td class="paramname"><em>pVkMemoryRequirements</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation *&#160;</td>
-          <td class="paramname"><em>pAllocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationInfo</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>General purpose memory allocation. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir">[out]</td><td class="paramname">pAllocation</td><td>Handle to allocated memory. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pAllocationInfo</td><td>Optional. Information about allocated memory. It can be later fetched using function <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a>.</td></tr>
-  </table>
-  </dd>
-</dl>
-<p>You should free the memory using <a class="el" href="group__layer2.html#ga11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a>.</p>
-<p>It is recommended to use <a class="el" href="group__layer2.html#ga7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, <a class="el" href="group__layer2.html#ga0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a>, <a class="el" href="group__layer3.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>, <a class="el" href="group__layer3.html#ga02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a> instead whenever possible. </p>
-
-</div>
-</div>
-<a id="ga7fdf64415b6c3d83c454f28d2c53df7b"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga7fdf64415b6c3d83c454f28d2c53df7b">&#9670;&nbsp;</a></span>vmaAllocateMemoryForBuffer()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaAllocateMemoryForBuffer </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkBuffer&#160;</td>
-          <td class="paramname"><em>buffer</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation *&#160;</td>
-          <td class="paramname"><em>pAllocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationInfo</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir">[out]</td><td class="paramname">pAllocation</td><td>Handle to allocated memory. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pAllocationInfo</td><td>Optional. Information about allocated memory. It can be later fetched using function <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a>.</td></tr>
-  </table>
-  </dd>
-</dl>
-<p>You should free the memory using <a class="el" href="group__layer2.html#ga11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a>. </p>
-
-</div>
-</div>
-<a id="ga0faa3f9e5fb233d29d1e00390650febb"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga0faa3f9e5fb233d29d1e00390650febb">&#9670;&nbsp;</a></span>vmaAllocateMemoryForImage()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaAllocateMemoryForImage </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkImage&#160;</td>
-          <td class="paramname"><em>image</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation *&#160;</td>
-          <td class="paramname"><em>pAllocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationInfo</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Function similar to <a class="el" href="group__layer2.html#ga7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>. </p>
-
-</div>
-</div>
-<a id="gae5c9657d9e94756269145b01c05d16f1"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gae5c9657d9e94756269145b01c05d16f1">&#9670;&nbsp;</a></span>vmaCreateLostAllocation()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaCreateLostAllocation </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation *&#160;</td>
-          <td class="paramname"><em>pAllocation</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Creates new allocation that is in lost state from the beginning. </p>
-<p>It can be useful if you need a dummy, non-null allocation.</p>
-<p>You still need to destroy created object using <a class="el" href="group__layer2.html#ga11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a>.</p>
-<p>Returned allocation is not tied to any specific memory pool or memory type and not bound to any image or buffer. It has size = 0. It cannot be turned into a real, non-empty allocation. </p>
-
-</div>
-</div>
-<a id="ga5c8770ded7c59c8caac6de0c2cb00b50"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga5c8770ded7c59c8caac6de0c2cb00b50">&#9670;&nbsp;</a></span>vmaCreatePool()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaCreatePool </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaPool *&#160;</td>
-          <td class="paramname"><em>pPool</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Allocates Vulkan device memory and creates <code>VmaPool</code> object. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir"></td><td class="paramname">allocator</td><td>Allocator object. </td></tr>
-    <tr><td class="paramdir"></td><td class="paramname">pCreateInfo</td><td>Parameters of pool to create. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pPool</td><td>Handle to created pool. </td></tr>
-  </table>
-  </dd>
-</dl>
-
-</div>
-</div>
-<a id="ga6aced90fcc7b39882b6654a740a0b9bb"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga6aced90fcc7b39882b6654a740a0b9bb">&#9670;&nbsp;</a></span>vmaDefragment()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaDefragment </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation *&#160;</td>
-          <td class="paramname"><em>pAllocations</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">size_t&#160;</td>
-          <td class="paramname"><em>allocationCount</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkBool32 *&#160;</td>
-          <td class="paramname"><em>pAllocationsChanged</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *&#160;</td>
-          <td class="paramname"><em>pDefragmentationInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a> *&#160;</td>
-          <td class="paramname"><em>pDefragmentationStats</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Compacts memory by moving allocations. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir"></td><td class="paramname">pAllocations</td><td>Array of allocations that can be moved during this compation. </td></tr>
-    <tr><td class="paramdir"></td><td class="paramname">allocationCount</td><td>Number of elements in pAllocations and pAllocationsChanged arrays. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pAllocationsChanged</td><td>Array of boolean values that will indicate whether matching allocation in pAllocations array has been moved. This parameter is optional. Pass null if you don't need this information. </td></tr>
-    <tr><td class="paramdir"></td><td class="paramname">pDefragmentationInfo</td><td>Configuration parameters. Optional - pass null to use default values. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pDefragmentationStats</td><td>Statistics returned by the function. Optional - pass null if you don't need this information. </td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>VK_SUCCESS if completed, VK_INCOMPLETE if succeeded but didn't make all possible optimizations because limits specified in pDefragmentationInfo have been reached, negative error code in case of error.</dd></dl>
-<p>This function works by moving allocations to different places (different <code>VkDeviceMemory</code> objects and/or different offsets) in order to optimize memory usage. Only allocations that are in pAllocations array can be moved. All other allocations are considered nonmovable in this call. Basic rules:</p>
-<ul>
-<li>Only allocations made in memory types that have <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code> flag can be compacted. You may pass other allocations but it makes no sense - these will never be moved.</li>
-<li>You may pass allocations made with <code>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</code> but it makes no sense - they will never be moved.</li>
-<li>Both allocations made with or without <code>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</code> flag can be compacted. If not persistently mapped, memory will be mapped temporarily inside this function if needed, so it shouldn't be mapped by you for the time of this call.</li>
-<li>You must not pass same <code>VmaAllocation</code> object multiple times in pAllocations array.</li>
-</ul>
-<p>The function also frees empty <code>VkDeviceMemory</code> blocks.</p>
-<p>After allocation has been moved, its <a class="el" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67" title="Handle to Vulkan memory object. ">VmaAllocationInfo::deviceMemory</a> and/or <a class="el" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268" title="Offset into deviceMemory object to the beginning of this allocation, in bytes. (deviceMemory, offset) pair is unique to this allocation. ">VmaAllocationInfo::offset</a> changes. You must query them again using <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> if you need them.</p>
-<p>If an allocation has been moved, data in memory is copied to new place automatically, but if it was bound to a buffer or an image, you must destroy that object yourself, create new one and bind it to the new memory pointed by the allocation. You must use <code>vkDestroyBuffer()</code>, <code>vkDestroyImage()</code>, <code>vkCreateBuffer()</code>, <code>vkCreateImage()</code> for that purpose and NOT <a class="el" href="group__layer3.html#ga0d9f4e4ba5bf9aab1f1c746387753d77" title="Destroys Vulkan buffer and frees allocated memory. ">vmaDestroyBuffer()</a>, <a class="el" href="group__layer3.html#gae50d2cb3b4a3bfd4dd40987234e50e7e" title="Destroys Vulkan image and frees allocated memory. ">vmaDestroyImage()</a>, <a class="el" href="group__layer3.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>, <a class="el" href="group__layer3.html#ga02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a>! Example:</p>
-<pre class="fragment">VkDevice device = ...;
-VmaAllocator allocator = ...;
-std::vector&lt;VkBuffer&gt; buffers = ...;
-std::vector&lt;VmaAllocation&gt; allocations = ...;
-
-std::vector&lt;VkBool32&gt; allocationsChanged(allocations.size());
-vmaDefragment(allocator, allocations.data(), allocations.size(), allocationsChanged.data(), nullptr, nullptr);
-
-for(size_t i = 0; i &lt; allocations.size(); ++i)
-{
-    if(allocationsChanged[i])
-    {
-        VmaAllocationInfo allocInfo;
-        vmaGetAllocationInfo(allocator, allocations[i], &amp;allocInfo);
-
-        vkDestroyBuffer(device, buffers[i], nullptr);
-
-        VkBufferCreateInfo bufferInfo = ...;
-        vkCreateBuffer(device, &amp;bufferInfo, nullptr, &amp;buffers[i]);
-
-        .// You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning.
-
-        vkBindBufferMemory(device, buffers[i], allocInfo.deviceMemory, allocInfo.offset);
-    }
-}
-</pre><p>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). </p>
-
-</div>
-</div>
-<a id="ga5485779c8f1948238fc4e92232fa65e1"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga5485779c8f1948238fc4e92232fa65e1">&#9670;&nbsp;</a></span>vmaDestroyPool()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaDestroyPool </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaPool&#160;</td>
-          <td class="paramname"><em>pool</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Destroys VmaPool object and frees Vulkan device memory. </p>
-
-</div>
-</div>
-<a id="ga11f0fbc034fa81a4efedd73d61ce7568"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga11f0fbc034fa81a4efedd73d61ce7568">&#9670;&nbsp;</a></span>vmaFreeMemory()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaFreeMemory </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation&#160;</td>
-          <td class="paramname"><em>allocation</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Frees memory previously allocated using <a class="el" href="group__layer2.html#gabf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>, <a class="el" href="group__layer2.html#ga7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, or <a class="el" href="group__layer2.html#ga0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a>. </p>
-
-</div>
-</div>
-<a id="ga86dd08aba8633bfa4ad0df2e76481d8b"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga86dd08aba8633bfa4ad0df2e76481d8b">&#9670;&nbsp;</a></span>vmaGetAllocationInfo()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaGetAllocationInfo </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation&#160;</td>
-          <td class="paramname"><em>allocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationInfo</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Returns current information about specified allocation. </p>
-
-</div>
-</div>
-<a id="gae8bf76997b234ef68aad922616df4153"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gae8bf76997b234ef68aad922616df4153">&#9670;&nbsp;</a></span>vmaGetPoolStats()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaGetPoolStats </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaPool&#160;</td>
-          <td class="paramname"><em>pool</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a> *&#160;</td>
-          <td class="paramname"><em>pPoolStats</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Retrieves statistics of existing VmaPool object. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir"></td><td class="paramname">allocator</td><td>Allocator object. </td></tr>
-    <tr><td class="paramdir"></td><td class="paramname">pool</td><td>Pool object. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pPoolStats</td><td>Statistics of specified pool. </td></tr>
-  </table>
-  </dd>
-</dl>
-
-</div>
-</div>
-<a id="ga736bd6cbda886f36c891727e73bd4024"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga736bd6cbda886f36c891727e73bd4024">&#9670;&nbsp;</a></span>vmaMakePoolAllocationsLost()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaMakePoolAllocationsLost </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaPool&#160;</td>
-          <td class="paramname"><em>pool</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">size_t *&#160;</td>
-          <td class="paramname"><em>pLostAllocationCount</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Marks all allocations in given pool as lost if they are not used in current frame or <a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> back from now. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir"></td><td class="paramname">allocator</td><td>Allocator object. </td></tr>
-    <tr><td class="paramdir"></td><td class="paramname">pool</td><td>Pool. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pLostAllocationCount</td><td>Number of allocations marked as lost. Optional - pass null if you don't need this information. </td></tr>
-  </table>
-  </dd>
-</dl>
-
-</div>
-</div>
-<a id="gad5bd1243512d099706de88168992f069"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gad5bd1243512d099706de88168992f069">&#9670;&nbsp;</a></span>vmaMapMemory()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaMapMemory </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation&#160;</td>
-          <td class="paramname"><em>allocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">void **&#160;</td>
-          <td class="paramname"><em>ppData</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-<p>Feel free to use vkMapMemory on these memory blocks on you own if you want, but just for convenience and to make sure correct offset and size is always specified, usage of <a class="el" href="group__layer2.html#gad5bd1243512d099706de88168992f069">vmaMapMemory()</a> / <a class="el" href="group__layer2.html#ga9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory()</a> is recommended.</p>
-<p>Do not use it on memory allocated with <code>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</code> as multiple maps to same <code>VkDeviceMemory</code> is illegal. </p>
-
-</div>
-</div>
-<a id="ga03366170bb8e186605518d2f5d65b85a"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga03366170bb8e186605518d2f5d65b85a">&#9670;&nbsp;</a></span>vmaMapPersistentlyMappedMemory()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaMapPersistentlyMappedMemory </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Maps back persistently mapped memory of types that are <code>HOST_COHERENT</code> and <code>DEVICE_LOCAL</code>. </p>
-<p>See <a class="el" href="group__layer2.html#ga26b87244491c1fe77f11fe9ab5779c27" title="Unmaps persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaUnmapPersistentlyMappedMemory()</a>.</p>
-<p>After this call <a class="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> of some allocation may have value different than before calling <a class="el" href="group__layer2.html#ga26b87244491c1fe77f11fe9ab5779c27" title="Unmaps persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaUnmapPersistentlyMappedMemory()</a>. </p>
-
-</div>
-</div>
-<a id="gaf9147d31ffc11d62fc187bde283ed14f"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gaf9147d31ffc11d62fc187bde283ed14f">&#9670;&nbsp;</a></span>vmaSetAllocationUserData()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaSetAllocationUserData </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation&#160;</td>
-          <td class="paramname"><em>allocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">void *&#160;</td>
-          <td class="paramname"><em>pUserData</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Sets pUserData in given allocation to new value. </p>
-
-</div>
-</div>
-<a id="ga9bc268595cb33f6ec4d519cfce81ff45"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga9bc268595cb33f6ec4d519cfce81ff45">&#9670;&nbsp;</a></span>vmaUnmapMemory()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaUnmapMemory </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation&#160;</td>
-          <td class="paramname"><em>allocation</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<a id="ga26b87244491c1fe77f11fe9ab5779c27"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga26b87244491c1fe77f11fe9ab5779c27">&#9670;&nbsp;</a></span>vmaUnmapPersistentlyMappedMemory()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaUnmapPersistentlyMappedMemory </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Unmaps persistently mapped memory of types that are <code>HOST_COHERENT</code> and <code>DEVICE_LOCAL</code>. </p>
-<p>This is optional performance optimization. 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 this function. Example:</p>
-<pre class="fragment">vmaUnmapPersistentlyMappedMemory(allocator);
-vkQueueSubmit(...)
-vmaMapPersistentlyMappedMemory(allocator);
-</pre><p>After this call <a class="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> of some allocations may become null.</p>
-<p>This call is reference-counted. Memory is mapped again after you call <a class="el" href="group__layer2.html#ga03366170bb8e186605518d2f5d65b85a" title="Maps back persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaMapPersistentlyMappedMemory()</a> same number of times that you called <a class="el" href="group__layer2.html#ga26b87244491c1fe77f11fe9ab5779c27" title="Unmaps persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaUnmapPersistentlyMappedMemory()</a>. </p>
-
-</div>
-</div>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/group__layer3.html b/docs/html/group__layer3.html
deleted file mode 100644
index 0c38ea5..0000000
--- a/docs/html/group__layer3.html
+++ /dev/null
@@ -1,290 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: Layer 3 Creating Buffers and Images</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="summary">
-<a href="#func-members">Functions</a>  </div>
-  <div class="headertitle">
-<div class="title">Layer 3 Creating Buffers and Images</div>  </div>
-</div><!--header-->
-<div class="contents">
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
-Functions</h2></td></tr>
-<tr class="memitem:gac72ee55598617e8eecca384e746bab51"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer3.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a> (VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
-<tr class="separator:gac72ee55598617e8eecca384e746bab51"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga0d9f4e4ba5bf9aab1f1c746387753d77"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer3.html#ga0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a> (VmaAllocator allocator, VkBuffer buffer, VmaAllocation allocation)</td></tr>
-<tr class="memdesc:ga0d9f4e4ba5bf9aab1f1c746387753d77"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destroys Vulkan buffer and frees allocated memory.  <a href="#ga0d9f4e4ba5bf9aab1f1c746387753d77">More...</a><br /></td></tr>
-<tr class="separator:ga0d9f4e4ba5bf9aab1f1c746387753d77"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga02a94f25679275851a53e82eacbcfc73"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer3.html#ga02a94f25679275851a53e82eacbcfc73">vmaCreateImage</a> (VmaAllocator allocator, const VkImageCreateInfo *pImageCreateInfo, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pAllocationCreateInfo, VkImage *pImage, VmaAllocation *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
-<tr class="memdesc:ga02a94f25679275851a53e82eacbcfc73"><td class="mdescLeft">&#160;</td><td class="mdescRight">Function similar to <a class="el" href="group__layer3.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>.  <a href="#ga02a94f25679275851a53e82eacbcfc73">More...</a><br /></td></tr>
-<tr class="separator:ga02a94f25679275851a53e82eacbcfc73"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gae50d2cb3b4a3bfd4dd40987234e50e7e"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer3.html#gae50d2cb3b4a3bfd4dd40987234e50e7e">vmaDestroyImage</a> (VmaAllocator allocator, VkImage image, VmaAllocation allocation)</td></tr>
-<tr class="memdesc:gae50d2cb3b4a3bfd4dd40987234e50e7e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destroys Vulkan image and frees allocated memory.  <a href="#gae50d2cb3b4a3bfd4dd40987234e50e7e">More...</a><br /></td></tr>
-<tr class="separator:gae50d2cb3b4a3bfd4dd40987234e50e7e"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<h2 class="groupheader">Function Documentation</h2>
-<a id="gac72ee55598617e8eecca384e746bab51"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gac72ee55598617e8eecca384e746bab51">&#9670;&nbsp;</a></span>vmaCreateBuffer()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaCreateBuffer </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const VkBufferCreateInfo *&#160;</td>
-          <td class="paramname"><em>pBufferCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkBuffer *&#160;</td>
-          <td class="paramname"><em>pBuffer</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation *&#160;</td>
-          <td class="paramname"><em>pAllocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationInfo</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramdir">[out]</td><td class="paramname">pBuffer</td><td>Buffer that was created. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pAllocation</td><td>Allocation that was created. </td></tr>
-    <tr><td class="paramdir">[out]</td><td class="paramname">pAllocationInfo</td><td>Optional. Information about allocated memory. It can be later fetched using function <a class="el" href="group__layer2.html#ga86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a>.</td></tr>
-  </table>
-  </dd>
-</dl>
-<p>This function automatically:</p>
-<ol type="1">
-<li>Creates buffer.</li>
-<li>Allocates appropriate memory for it.</li>
-<li>Binds the buffer with the memory.</li>
-</ol>
-<p>If any of these operations fail, buffer and allocation are not created, returned value is negative error code, *pBuffer and *pAllocation are null.</p>
-<p>If the function succeeded, you must destroy both buffer and allocation when you no longer need them using either convenience function <a class="el" href="group__layer3.html#ga0d9f4e4ba5bf9aab1f1c746387753d77" title="Destroys Vulkan buffer and frees allocated memory. ">vmaDestroyBuffer()</a> or separately, using vkDestroyBuffer() and <a class="el" href="group__layer2.html#ga11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a>. </p>
-
-</div>
-</div>
-<a id="ga02a94f25679275851a53e82eacbcfc73"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga02a94f25679275851a53e82eacbcfc73">&#9670;&nbsp;</a></span>vmaCreateImage()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkResult vmaCreateImage </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const VkImageCreateInfo *&#160;</td>
-          <td class="paramname"><em>pImageCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationCreateInfo</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkImage *&#160;</td>
-          <td class="paramname"><em>pImage</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation *&#160;</td>
-          <td class="paramname"><em>pAllocation</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *&#160;</td>
-          <td class="paramname"><em>pAllocationInfo</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Function similar to <a class="el" href="group__layer3.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>. </p>
-
-</div>
-</div>
-<a id="ga0d9f4e4ba5bf9aab1f1c746387753d77"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ga0d9f4e4ba5bf9aab1f1c746387753d77">&#9670;&nbsp;</a></span>vmaDestroyBuffer()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaDestroyBuffer </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkBuffer&#160;</td>
-          <td class="paramname"><em>buffer</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation&#160;</td>
-          <td class="paramname"><em>allocation</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Destroys Vulkan buffer and frees allocated memory. </p>
-<p>This is just a convenience function equivalent to:</p>
-<pre class="fragment">vkDestroyBuffer(device, buffer, allocationCallbacks);
-vmaFreeMemory(allocator, allocation);</pre> 
-</div>
-</div>
-<a id="gae50d2cb3b4a3bfd4dd40987234e50e7e"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#gae50d2cb3b4a3bfd4dd40987234e50e7e">&#9670;&nbsp;</a></span>vmaDestroyImage()</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void vmaDestroyImage </td>
-          <td>(</td>
-          <td class="paramtype">VmaAllocator&#160;</td>
-          <td class="paramname"><em>allocator</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VkImage&#160;</td>
-          <td class="paramname"><em>image</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">VmaAllocation&#160;</td>
-          <td class="paramname"><em>allocation</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Destroys Vulkan image and frees allocated memory. </p>
-<p>This is just a convenience function equivalent to:</p>
-<pre class="fragment">vkDestroyImage(device, image, allocationCallbacks);
-vmaFreeMemory(allocator, allocation);</pre> 
-</div>
-</div>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/index.html b/docs/html/index.html
index 95134bc..298454e 100644
--- a/docs/html/index.html
+++ b/docs/html/index.html
@@ -62,7 +62,7 @@
 <div class="title">Vulkan Memory Allocator </div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="textblock"><p><b>Version 2.0.0</b> (2018-03-19)</p>
+<div class="textblock"><p><b>Version 2.1.0-beta.1</b> (2018-08-27)</p>
 <p>Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved. <br />
 License: MIT</p>
 <p>Documentation of all members: <a class="el" href="vk__mem__alloc_8h.html">vk_mem_alloc.h</a></p>
@@ -92,6 +92,13 @@
 </li>
 <li><a class="el" href="custom_memory_pools.html">Custom memory pools</a><ul>
 <li><a class="el" href="custom_memory_pools.html#custom_memory_pools_MemTypeIndex">Choosing memory type index</a></li>
+<li><a class="el" href="custom_memory_pools.html#linear_algorithm">Linear allocation algorithm</a><ul>
+<li><a class="el" href="custom_memory_pools.html#linear_algorithm_free_at_once">Free-at-once</a></li>
+<li><a class="el" href="custom_memory_pools.html#linear_algorithm_stack">Stack</a></li>
+<li><a class="el" href="custom_memory_pools.html#linear_algorithm_double_stack">Double stack</a></li>
+<li><a class="el" href="custom_memory_pools.html#linear_algorithm_ring_buffer">Ring buffer</a></li>
+</ul>
+</li>
 </ul>
 </li>
 <li><a class="el" href="defragmentation.html">Defragmentation</a></li>
@@ -106,6 +113,13 @@
 <li><a class="el" href="allocation_annotation.html#allocation_names">Allocation names</a></li>
 </ul>
 </li>
+<li><a class="el" href="debugging_memory_usage.html">Debugging incorrect memory usage</a><ul>
+<li><a class="el" href="debugging_memory_usage.html#debugging_memory_usage_initialization">Memory initialization</a></li>
+<li><a class="el" href="debugging_memory_usage.html#debugging_memory_usage_margins">Margins</a></li>
+<li><a class="el" href="debugging_memory_usage.html#debugging_memory_usage_corruption_detection">Corruption detection</a></li>
+</ul>
+</li>
+<li><a class="el" href="record_and_replay.html">Record and replay</a></li>
 </ul>
 </li>
 <li><a class="el" href="usage_patterns.html">Recommended usage patterns</a><ul>
@@ -123,6 +137,7 @@
 </li>
 <li><a class="el" href="general_considerations.html">General considerations</a><ul>
 <li><a class="el" href="general_considerations.html#general_considerations_thread_safety">Thread safety</a></li>
+<li><a class="el" href="general_considerations.html#general_considerations_validation_layer_warnings">Validation layer warnings</a></li>
 <li><a class="el" href="general_considerations.html#general_considerations_allocation_algorithm">Allocation algorithm</a></li>
 <li><a class="el" href="general_considerations.html#general_considerations_features_not_supported">Features not supported</a></li>
 </ul>
diff --git a/docs/html/lost_allocations.html b/docs/html/lost_allocations.html
index a4c3113..b001774 100644
--- a/docs/html/lost_allocations.html
+++ b/docs/html/lost_allocations.html
@@ -77,9 +77,11 @@
 <p><b>Q: How do you inform the library when new frame starts?</b></p>
 <p>You need to call function <a class="el" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236" title="Sets index of the current frame. ">vmaSetCurrentFrameIndex()</a>.</p>
 <p>Example code:</p>
-<div class="fragment"><div class="line"><span class="keyword">struct </span>MyBuffer</div><div class="line">{</div><div class="line">    VkBuffer m_Buf = <span class="keyword">nullptr</span>;</div><div class="line">    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> m_Alloc = <span class="keyword">nullptr</span>;</div><div class="line"></div><div class="line">    <span class="comment">// Called when the buffer is really needed in the current frame.</span></div><div class="line">    <span class="keywordtype">void</span> EnsureBuffer();</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keywordtype">void</span> MyBuffer::EnsureBuffer()</div><div class="line">{</div><div class="line">    <span class="comment">// Buffer has been created.</span></div><div class="line">    <span class="keywordflow">if</span>(m_Buf != VK_NULL_HANDLE)</div><div class="line">    {</div><div class="line">        <span class="comment">// Check if its allocation is not lost + mark it as used in current frame.</span></div><div class="line">        <span class="keywordflow">if</span>(<a class="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(allocator, m_Alloc))</div><div class="line">        {</div><div class="line">            <span class="comment">// It&#39;s all OK - safe to use m_Buf.</span></div><div class="line">            <span class="keywordflow">return</span>;</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// Buffer not yet exists or lost - destroy and recreate it.</span></div><div class="line"></div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(allocator, m_Buf, m_Alloc);</div><div class="line"></div><div class="line">    VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">    bufCreateInfo.size = 1024;</div><div class="line">    bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line">    <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">    allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line">    allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> |</div><div class="line">        <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>;</div><div class="line"></div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;m_Buf, &amp;m_Alloc, <span class="keyword">nullptr</span>);</div><div class="line">}</div></div><!-- fragment --><p>When using lost allocations, you may see some Vulkan validation layer warnings about overlapping regions of memory bound to different kinds of buffers and images. This is still valid as long as you implement proper handling of lost allocations (like in the example above) and don't use them.</p>
+<div class="fragment"><div class="line"><span class="keyword">struct </span>MyBuffer</div><div class="line">{</div><div class="line">    VkBuffer m_Buf = <span class="keyword">nullptr</span>;</div><div class="line">    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> m_Alloc = <span class="keyword">nullptr</span>;</div><div class="line"></div><div class="line">    <span class="comment">// Called when the buffer is really needed in the current frame.</span></div><div class="line">    <span class="keywordtype">void</span> EnsureBuffer();</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keywordtype">void</span> MyBuffer::EnsureBuffer()</div><div class="line">{</div><div class="line">    <span class="comment">// Buffer has been created.</span></div><div class="line">    <span class="keywordflow">if</span>(m_Buf != VK_NULL_HANDLE)</div><div class="line">    {</div><div class="line">        <span class="comment">// Check if its allocation is not lost + mark it as used in current frame.</span></div><div class="line">        <span class="keywordflow">if</span>(<a class="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(allocator, m_Alloc))</div><div class="line">        {</div><div class="line">            <span class="comment">// It&#39;s all OK - safe to use m_Buf.</span></div><div class="line">            <span class="keywordflow">return</span>;</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// Buffer not yet exists or lost - destroy and recreate it.</span></div><div class="line"></div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(allocator, m_Buf, m_Alloc);</div><div class="line"></div><div class="line">    VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">    bufCreateInfo.size = 1024;</div><div class="line">    bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line">    <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">    allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line">    allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT |</div><div class="line">        <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>;</div><div class="line"></div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;m_Buf, &amp;m_Alloc, <span class="keyword">nullptr</span>);</div><div class="line">}</div></div><!-- fragment --><p>When using lost allocations, you may see some Vulkan validation layer warnings about overlapping regions of memory bound to different kinds of buffers and images. This is still valid as long as you implement proper handling of lost allocations (like in the example above) and don't use them.</p>
 <p>You can create an allocation that is already in lost state from the beginning using function <a class="el" href="vk__mem__alloc_8h.html#ae5c9657d9e94756269145b01c05d16f1" title="Creates new allocation that is in lost state from the beginning. ">vmaCreateLostAllocation()</a>. It may be useful if you need a "dummy" allocation that is not null.</p>
-<p>You can call function <a class="el" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024" title="Marks all allocations in given pool as lost if they are not used in current frame or VmaPoolCreateInf...">vmaMakePoolAllocationsLost()</a> to set all eligible allocations in a specified custom pool to lost state. Allocations that have been "touched" in current frame or <a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> frames back cannot become lost. </p>
+<p>You can call function <a class="el" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024" title="Marks all allocations in given pool as lost if they are not used in current frame or VmaPoolCreateInf...">vmaMakePoolAllocationsLost()</a> to set all eligible allocations in a specified custom pool to lost state. Allocations that have been "touched" in current frame or <a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> frames back cannot become lost.</p>
+<p><b>Q: Can I touch allocation that cannot become lost?</b></p>
+<p>Yes, although it has no visible effect. Calls to <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation and atomically marks it as used in current fra...">vmaGetAllocationInfo()</a> and <a class="el" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a" title="Returns VK_TRUE if allocation is not lost and atomically marks it as used in current frame...">vmaTouchAllocation()</a> update last use frame index also for allocations that cannot become lost, but the only way to observe it is to dump internal allocator state using <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>. You can use this feature for debugging purposes to explicitly mark allocations that you use in current frame and then analyze JSON dump to see for how long each allocation stays unused. </p>
 </div></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/html/memory_mapping.html b/docs/html/memory_mapping.html
index 90480cb..7e2c263 100644
--- a/docs/html/memory_mapping.html
+++ b/docs/html/memory_mapping.html
@@ -69,8 +69,11 @@
 <div class="textblock"><p>To "map memory" in Vulkan means to obtain a CPU pointer to <code>VkDeviceMemory</code>, to be able to read from it or write to it in CPU code. Mapping is possible only of memory allocated from a memory type that has <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code> flag. Functions <code>vkMapMemory()</code>, <code>vkUnmapMemory()</code> are designed for this purpose. You can use them directly with memory allocated by this library, but it is not recommended because of following issue: Mapping the same <code>VkDeviceMemory</code> block multiple times is illegal - only one mapping at a time is allowed. This includes mapping disjoint regions. Mapping is not reference-counted internally by Vulkan. Because of this, Vulkan Memory Allocator provides following facilities:</p>
 <h1><a class="anchor" id="memory_mapping_mapping_functions"></a>
 Mapping functions</h1>
-<p>The library provides following functions for mapping of a specific <a class="el" href="struct_vma_allocation.html" title="Represents single memory allocation. ">VmaAllocation</a>: <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a>. They are safer and more convenient to use than standard Vulkan functions. You can map an allocation multiple times simultaneously - mapping is reference-counted internally. You can also map different allocations simultaneously regardless of whether they use the same <code>VkDeviceMemory</code> block. They way it's implemented is that the library always maps entire memory block, not just region of the allocation. For further details, see description of <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> function. Example:</p>
-<div class="fragment"><div class="line"><span class="comment">// Having these objects initialized:</span></div><div class="line"></div><div class="line"><span class="keyword">struct </span>ConstantBuffer</div><div class="line">{</div><div class="line">    ...</div><div class="line">};</div><div class="line">ConstantBuffer constantBufferData;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator;</div><div class="line">VmaBuffer constantBuffer;</div><div class="line"><a class="code" href="struct_vma_allocation.html">VmaAllocation</a> constantBufferAllocation;</div><div class="line"></div><div class="line"><span class="comment">// You can map and fill your buffer using following code:</span></div><div class="line"></div><div class="line"><span class="keywordtype">void</span>* mappedData;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(allocator, constantBufferAllocation, &amp;mappedData);</div><div class="line">memcpy(mappedData, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(allocator, constantBufferAllocation);</div></div><!-- fragment --><h1><a class="anchor" id="memory_mapping_persistently_mapped_memory"></a>
+<p>The library provides following functions for mapping of a specific <a class="el" href="struct_vma_allocation.html" title="Represents single memory allocation. ">VmaAllocation</a>: <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a>. They are safer and more convenient to use than standard Vulkan functions. You can map an allocation multiple times simultaneously - mapping is reference-counted internally. You can also map different allocations simultaneously regardless of whether they use the same <code>VkDeviceMemory</code> block. The way it's implemented is that the library always maps entire memory block, not just region of the allocation. For further details, see description of <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> function. Example:</p>
+<div class="fragment"><div class="line"><span class="comment">// Having these objects initialized:</span></div><div class="line"></div><div class="line"><span class="keyword">struct </span>ConstantBuffer</div><div class="line">{</div><div class="line">    ...</div><div class="line">};</div><div class="line">ConstantBuffer constantBufferData;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator;</div><div class="line">VkBuffer constantBuffer;</div><div class="line"><a class="code" href="struct_vma_allocation.html">VmaAllocation</a> constantBufferAllocation;</div><div class="line"></div><div class="line"><span class="comment">// You can map and fill your buffer using following code:</span></div><div class="line"></div><div class="line"><span class="keywordtype">void</span>* mappedData;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(allocator, constantBufferAllocation, &amp;mappedData);</div><div class="line">memcpy(mappedData, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(allocator, constantBufferAllocation);</div></div><!-- fragment --><p>When mapping, you may see a warning from Vulkan validation layer similar to this one:</p>
+<p><em>Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.</em></p>
+<p>It happens because the library maps entire <code>VkDeviceMemory</code> block, where different types of images and buffers may end up together, especially on GPUs with unified memory like Intel. You can safely ignore it if you are sure you access only memory of the intended object that you wanted to map.</p>
+<h1><a class="anchor" id="memory_mapping_persistently_mapped_memory"></a>
 Persistently mapped memory</h1>
 <p>Kepping your memory persistently mapped is generally OK in Vulkan. You don't need to unmap it before using its data on the GPU. The library provides a special feature designed for that: Allocations made with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag set in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a> stay mapped all the time, so you can just access CPU pointer to it any time without a need to call any "map" or "unmap" function. Example:</p>
 <div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = <span class="keyword">sizeof</span>(ConstantBuffer);</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line"><a class="code" href="struct_vma_allocation.html">VmaAllocation</a> alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line"><span class="comment">// Buffer is already mapped. You can access its memory.</span></div><div class="line">memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div></div><!-- fragment --><p>There are some exceptions though, when you should consider mapping memory only for a short period of time:</p>
@@ -80,14 +83,15 @@
 </ul>
 <h1><a class="anchor" id="memory_mapping_cache_control"></a>
 Cache control</h1>
-<p>Memory in Vulkan doesn't need to be unmapped before using it on GPU, but unless a memory types has <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> flag set, you need to manually invalidate cache before reading of mapped pointer using function <code>vkvkInvalidateMappedMemoryRanges()</code> and flush cache after writing to mapped pointer using function <code>vkFlushMappedMemoryRanges()</code>. Example:</p>
-<div class="fragment"><div class="line">memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line"></div><div class="line">VkMemoryPropertyFlags memFlags;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &amp;memFlags);</div><div class="line"><span class="keywordflow">if</span>((memFlags &amp; VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)</div><div class="line">{</div><div class="line">    VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };</div><div class="line">    memRange.memory = allocInfo.<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><div class="line">    memRange.offset = allocInfo.<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><div class="line">    memRange.size   = allocInfo.<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><div class="line">    vkFlushMappedMemoryRanges(device, 1, &amp;memRange);</div><div class="line">}</div></div><!-- fragment --><p>Please note that memory allocated with <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a> is guaranteed to be host coherent.</p>
-<p>Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA) currently provide <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> flag on all memory types that are <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code>, so on this platform you may not need to bother.</p>
+<p>Memory in Vulkan doesn't need to be unmapped before using it on GPU, but unless a memory types has <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> flag set, you need to manually invalidate cache before reading of mapped pointer and flush cache after writing to mapped pointer. Vulkan provides following functions for this purpose <code>vkFlushMappedMemoryRanges()</code>, <code>vkInvalidateMappedMemoryRanges()</code>, but this library provides more convenient functions that refer to given allocation object: <a class="el" href="vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de" title="Flushes memory of given allocation. ">vmaFlushAllocation()</a>, <a class="el" href="vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006" title="Invalidates memory of given allocation. ">vmaInvalidateAllocation()</a>.</p>
+<p>Regions of memory specified for flush/invalidate must be aligned to <code>VkPhysicalDeviceLimits::nonCoherentAtomSize</code>. This is automatically ensured by the library. In any memory type that is <code>HOST_VISIBLE</code> but not <code>HOST_COHERENT</code>, all allocations within blocks are aligned to this value, so their offsets are always multiply of <code>nonCoherentAtomSize</code> and two different allocations never share same "line" of this size.</p>
+<p>Please note that memory allocated with <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a> is guaranteed to be <code>HOST_COHERENT</code>.</p>
+<p>Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA) currently provide <code>HOST_COHERENT</code> flag on all memory types that are <code>HOST_VISIBLE</code>, so on this platform you may not need to bother.</p>
 <h1><a class="anchor" id="memory_mapping_finding_if_memory_mappable"></a>
 Finding out if memory is mappable</h1>
 <p>It may happen that your allocation ends up in memory that is <code>HOST_VISIBLE</code> (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.</p>
 <p>You can detect this case and map such allocation to access its memory on CPU directly, instead of launching a transfer operation. In order to do that: inspect <code>allocInfo.memoryType</code>, call <a class="el" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca" title="Given Memory Type Index, returns Property Flags of this memory type. ">vmaGetMemoryTypeProperties()</a>, and look for <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code> flag in properties of that memory type.</p>
-<div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = <span class="keyword">sizeof</span>(ConstantBuffer);</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line"><a class="code" href="struct_vma_allocation.html">VmaAllocation</a> alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line">VkMemoryPropertyFlags memFlags;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &amp;memFlags);</div><div class="line"><span class="keywordflow">if</span>((memFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)</div><div class="line">{</div><div class="line">    <span class="comment">// Allocation ended up in mappable memory. You can map it and access it directly.</span></div><div class="line">    <span class="keywordtype">void</span>* mappedData;</div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(allocator, alloc, &amp;mappedData);</div><div class="line">    memcpy(mappedData, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(allocator, alloc);</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line">    <span class="comment">// Allocation ended up in non-mappable memory.</span></div><div class="line">    <span class="comment">// You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.</span></div><div class="line">}</div></div><!-- fragment --><p>You can even use <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag while creating allocations that are not necessarily <code>HOST_VISIBLE</code> (e.g. using <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>). If the allocation ends up in memory type that is <code>HOST_VISIBLE</code>, it will be persistently mapped and you can use it directly. If not, the flag is just ignored. Example:</p>
+<div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = <span class="keyword">sizeof</span>(ConstantBuffer);</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a> = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line"><a class="code" href="struct_vma_allocation.html">VmaAllocation</a> alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line">VkMemoryPropertyFlags memFlags;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &amp;memFlags);</div><div class="line"><span class="keywordflow">if</span>((memFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)</div><div class="line">{</div><div class="line">    <span class="comment">// Allocation ended up in mappable memory. You can map it and access it directly.</span></div><div class="line">    <span class="keywordtype">void</span>* mappedData;</div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(allocator, alloc, &amp;mappedData);</div><div class="line">    memcpy(mappedData, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line">    <a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(allocator, alloc);</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line">    <span class="comment">// Allocation ended up in non-mappable memory.</span></div><div class="line">    <span class="comment">// You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.</span></div><div class="line">}</div></div><!-- fragment --><p>You can even use <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag while creating allocations that are not necessarily <code>HOST_VISIBLE</code> (e.g. using <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>). If the allocation ends up in memory type that is <code>HOST_VISIBLE</code>, it will be persistently mapped and you can use it directly. If not, the flag is just ignored. Example:</p>
 <div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = <span class="keyword">sizeof</span>(ConstantBuffer);</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line"><a class="code" href="struct_vma_allocation.html">VmaAllocation</a> alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line"><span class="keywordflow">if</span>(allocInfo.<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> != <span class="keyword">nullptr</span>)</div><div class="line">{</div><div class="line">    <span class="comment">// Allocation ended up in mappable memory.</span></div><div class="line">    <span class="comment">// It&#39;s persistently mapped. You can access it directly.</span></div><div class="line">    memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line">    <span class="comment">// Allocation ended up in non-mappable memory.</span></div><div class="line">    <span class="comment">// You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.</span></div><div class="line">}</div></div><!-- fragment --> </div></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/html/modules.html b/docs/html/modules.html
deleted file mode 100644
index 94017fd..0000000
--- a/docs/html/modules.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: Modules</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="headertitle">
-<div class="title">Modules</div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="textblock">Here is a list of all modules:</div><div class="directory">
-<table class="directory">
-<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><a class="el" href="group__general.html" target="_self">General</a></td><td class="desc"></td></tr>
-<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><a class="el" href="group__layer1.html" target="_self">Layer 1 Choosing Memory Type</a></td><td class="desc"></td></tr>
-<tr id="row_2_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><a class="el" href="group__layer2.html" target="_self">Layer 2 Allocating Memory</a></td><td class="desc"></td></tr>
-<tr id="row_3_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><a class="el" href="group__layer3.html" target="_self">Layer 3 Creating Buffers and Images</a></td><td class="desc"></td></tr>
-</table>
-</div><!-- directory -->
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/persistently_mapped_memory.html b/docs/html/persistently_mapped_memory.html
deleted file mode 100644
index dc98cc8..0000000
--- a/docs/html/persistently_mapped_memory.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: Persistently mapped memory</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div id="nav-path" class="navpath">
-  <ul>
-<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
-</div>
-</div><!-- top -->
-<div class="header">
-  <div class="headertitle">
-<div class="title">Persistently mapped memory </div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="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 <a class="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. <a class="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>
-<div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = 1024;</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312">VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</a>;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line">VmaAllocation alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line"><span class="comment">// Buffer is immediately mapped. You can access its memory.</span></div><div class="line">memcpy(allocInfo.<a class="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>
-<div class="fragment"><div class="line">VkMemoryPropertyFlags memFlags;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &amp;memFlags);</div><div class="line"><span class="keywordflow">if</span>((memFlags &amp; VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)</div><div class="line">{</div><div class="line">    VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };</div><div class="line">    memRange.memory = allocInfo.<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><div class="line">    memRange.offset = allocInfo.<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><div class="line">    memRange.size   = allocInfo.<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><div class="line">    vkFlushMappedMemoryRanges(device, 1, &amp;memRange);</div><div class="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 <a class="el" href="vk__mem__alloc_8h.html#a26b87244491c1fe77f11fe9ab5779c27" title="Unmaps persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaUnmapPersistentlyMappedMemory()</a>, <a class="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>
-</div></div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/quick_start.html b/docs/html/quick_start.html
index ae0bc59..517eca2 100644
--- a/docs/html/quick_start.html
+++ b/docs/html/quick_start.html
@@ -76,6 +76,7 @@
 <li>In exacly one CPP file define following macro before this include. It enables also internal definitions.</li>
 </ol>
 <div class="fragment"><div class="line"><span class="preprocessor">#define VMA_IMPLEMENTATION</span></div><div class="line"><span class="preprocessor">#include &quot;vk_mem_alloc.h&quot;</span></div></div><!-- fragment --><p>It may be a good idea to create dedicated CPP file just for this purpose.</p>
+<p>Please note that this library includes header <code>&lt;vulkan/vulkan.h&gt;</code>, which in turn includes <code>&lt;windows.h&gt;</code> on Windows. If you need some specific macros defined before including these headers (like <code>NOMINMAX</code>, <code>WIN32_LEAN_AND_MEAN</code>, or <code>WINVER</code> for Windows, <code>VK_USE_PLATFORM_WIN32_KHR</code> for Vulkan), you must define them before every <code>#include</code> of this library.</p>
 <h1><a class="anchor" id="quick_start_initialization"></a>
 Initialization</h1>
 <p>At program startup:</p>
diff --git a/docs/html/record_and_replay.html b/docs/html/record_and_replay.html
new file mode 100644
index 0000000..d4484be
--- /dev/null
+++ b/docs/html/record_and_replay.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.13"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Vulkan Memory Allocator: Record and replay</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Vulkan Memory Allocator
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.13 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="headertitle">
+<div class="title">Record and replay </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><h1><a class="anchor" id="record_and_replay_introduction"></a>
+Introduction</h1>
+<p>While using the library, sequence of calls to its functions together with their parameters can be recorded to a file and later replayed using standalone player application. It can be useful to:</p>
+<ul>
+<li>Test correctness - check if same sequence of calls will not cause crash or failures on a target platform.</li>
+<li>Gather statistics - see number of allocations, peak memory usage, number of calls etc.</li>
+<li>Benchmark performance - see how much time it takes to replay the whole sequence.</li>
+</ul>
+<h1><a class="anchor" id="record_and_replay_usage"></a>
+Usage</h1>
+<p><b>To record sequence of calls to a file:</b> Fill in <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee" title="Parameters for recording of VMA calls. Can be null. ">VmaAllocatorCreateInfo::pRecordSettings</a> member while creating <a class="el" href="struct_vma_allocator.html" title="Represents main object of this library initialized. ">VmaAllocator</a> object. File is opened and written during whole lifetime of the allocator.</p>
+<p><b>To replay file:</b> Use VmaReplay - standalone command-line program. Precompiled binary can be found in "bin" directory. Its source can be found in "src/VmaReplay" directory. Its project is generated by Premake. Command line syntax is printed when the program is launched without parameters. Basic usage: </p><pre class="fragment">VmaReplay.exe MyRecording.csv
+</pre><p><b>Documentation of file format</b> can be found in file: "docs/Recording file format.md". It's a human-readable, text file in CSV format (Comma Separated Values).</p>
+<h1><a class="anchor" id="record_and_replay_additional_considerations"></a>
+Additional considerations</h1>
+<ul>
+<li>Replaying file that was recorded on a different GPU (with different parameters like <code>bufferImageGranularity</code>, <code>nonCoherentAtomSize</code>, and especially different set of memory heaps and types) may give different performance and memory usage results, as well as issue some warnings and errors.</li>
+<li>Current implementation of recording in VMA, as well as VmaReplay application, is coded and tested only on Windows. Inclusion of recording code is driven by <code>VMA_RECORDING_ENABLED</code> macro. Support for other platforms should be easy to add. Contributions are welcomed.</li>
+<li>Currently calls to <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a> function are not recorded. </li>
+</ul>
+</div></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.13
+</small></address>
+</body>
+</html>
diff --git a/docs/html/search/all_1.js b/docs/html/search/all_1.js
index cff2c47..7ae997e 100644
--- a/docs/html/search/all_1.js
+++ b/docs/html/search/all_1.js
@@ -1,6 +1,6 @@
 var searchData=
 [
-  ['blockcount',['blockCount',['../struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4',1,'VmaStatInfo']]],
+  ['blockcount',['blockCount',['../struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4',1,'VmaStatInfo::blockCount()'],['../struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7',1,'VmaPoolStats::blockCount()']]],
   ['blocksize',['blockSize',['../struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676',1,'VmaPoolCreateInfo']]],
   ['bytesfreed',['bytesFreed',['../struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28',1,'VmaDefragmentationStats']]],
   ['bytesmoved',['bytesMoved',['../struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d',1,'VmaDefragmentationStats']]]
diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js
index 8789b19..82a7aa0 100644
--- a/docs/html/search/all_3.js
+++ b/docs/html/search/all_3.js
@@ -1,5 +1,6 @@
 var searchData=
 [
+  ['debugging_20incorrect_20memory_20usage',['Debugging incorrect memory usage',['../debugging_memory_usage.html',1,'index']]],
   ['defragmentation',['Defragmentation',['../defragmentation.html',1,'index']]],
   ['device',['device',['../struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500',1,'VmaAllocatorCreateInfo']]],
   ['devicememory',['deviceMemory',['../struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67',1,'VmaAllocationInfo']]],
diff --git a/docs/html/search/all_4.js b/docs/html/search/all_4.js
index 7bacfcc..347c9f3 100644
--- a/docs/html/search/all_4.js
+++ b/docs/html/search/all_4.js
@@ -1,5 +1,5 @@
 var searchData=
 [
-  ['flags',['flags',['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()']]],
+  ['flags',['flags',['../struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a',1,'VmaRecordSettings::flags()'],['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()']]],
   ['frameinusecount',['frameInUseCount',['../struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7',1,'VmaAllocatorCreateInfo::frameInUseCount()'],['../struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa',1,'VmaPoolCreateInfo::frameInUseCount()']]]
 ];
diff --git a/docs/html/search/all_9.js b/docs/html/search/all_9.js
index 590465a..33e01da 100644
--- a/docs/html/search/all_9.js
+++ b/docs/html/search/all_9.js
@@ -2,6 +2,7 @@
 [
   ['pallocationcallbacks',['pAllocationCallbacks',['../struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d',1,'VmaAllocatorCreateInfo']]],
   ['pdevicememorycallbacks',['pDeviceMemoryCallbacks',['../struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e',1,'VmaAllocatorCreateInfo']]],
+  ['pfilepath',['pFilePath',['../struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d',1,'VmaRecordSettings']]],
   ['pfn_5fvmaallocatedevicememoryfunction',['PFN_vmaAllocateDeviceMemoryFunction',['../vk__mem__alloc_8h.html#ab6a6477cda1ce775b30bde96d766203b',1,'vk_mem_alloc.h']]],
   ['pfn_5fvmafreedevicememoryfunction',['PFN_vmaFreeDeviceMemoryFunction',['../vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49',1,'vk_mem_alloc.h']]],
   ['pfnallocate',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
@@ -10,6 +11,7 @@
   ['physicaldevice',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo']]],
   ['pmappeddata',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
   ['pool',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
+  ['precordsettings',['pRecordSettings',['../struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee',1,'VmaAllocatorCreateInfo']]],
   ['preferredflags',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
   ['preferredlargeheapblocksize',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
   ['puserdata',['pUserData',['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()']]],
diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js
index f3376c8..f0c993f 100644
--- a/docs/html/search/all_b.js
+++ b/docs/html/search/all_b.js
@@ -1,5 +1,6 @@
 var searchData=
 [
+  ['record_20and_20replay',['Record and replay',['../record_and_replay.html',1,'index']]],
   ['requiredflags',['requiredFlags',['../struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90',1,'VmaAllocationCreateInfo']]],
   ['recommended_20usage_20patterns',['Recommended usage patterns',['../usage_patterns.html',1,'index']]]
 ];
diff --git a/docs/html/search/all_f.js b/docs/html/search/all_f.js
index c41492b..cc8c748 100644
--- a/docs/html/search/all_f.js
+++ b/docs/html/search/all_f.js
@@ -10,13 +10,13 @@
   ['vkcreateimage',['vkCreateImage',['../struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325',1,'VmaVulkanFunctions']]],
   ['vkdestroybuffer',['vkDestroyBuffer',['../struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45',1,'VmaVulkanFunctions']]],
   ['vkdestroyimage',['vkDestroyImage',['../struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa',1,'VmaVulkanFunctions']]],
+  ['vkflushmappedmemoryranges',['vkFlushMappedMemoryRanges',['../struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9',1,'VmaVulkanFunctions']]],
   ['vkfreememory',['vkFreeMemory',['../struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4',1,'VmaVulkanFunctions']]],
   ['vkgetbuffermemoryrequirements',['vkGetBufferMemoryRequirements',['../struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143',1,'VmaVulkanFunctions']]],
-  ['vkgetbuffermemoryrequirements2khr',['vkGetBufferMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c',1,'VmaVulkanFunctions']]],
   ['vkgetimagememoryrequirements',['vkGetImageMemoryRequirements',['../struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4',1,'VmaVulkanFunctions']]],
-  ['vkgetimagememoryrequirements2khr',['vkGetImageMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875',1,'VmaVulkanFunctions']]],
   ['vkgetphysicaldevicememoryproperties',['vkGetPhysicalDeviceMemoryProperties',['../struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830',1,'VmaVulkanFunctions']]],
   ['vkgetphysicaldeviceproperties',['vkGetPhysicalDeviceProperties',['../struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96',1,'VmaVulkanFunctions']]],
+  ['vkinvalidatemappedmemoryranges',['vkInvalidateMappedMemoryRanges',['../struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1',1,'VmaVulkanFunctions']]],
   ['vkmapmemory',['vkMapMemory',['../struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49',1,'VmaVulkanFunctions']]],
   ['vkunmapmemory',['vkUnmapMemory',['../struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9',1,'VmaVulkanFunctions']]],
   ['vma_5fallocation_5fcreate_5fcan_5fbecome_5flost_5fbit',['VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2',1,'vk_mem_alloc.h']]],
@@ -25,10 +25,12 @@
   ['vma_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882',1,'vk_mem_alloc.h']]],
   ['vma_5fallocation_5fcreate_5fmapped_5fbit',['VMA_ALLOCATION_CREATE_MAPPED_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f',1,'vk_mem_alloc.h']]],
   ['vma_5fallocation_5fcreate_5fnever_5fallocate_5fbit',['VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff',1,'vk_mem_alloc.h']]],
+  ['vma_5fallocation_5fcreate_5fupper_5faddress_5fbit',['VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df',1,'vk_mem_alloc.h']]],
   ['vma_5fallocation_5fcreate_5fuser_5fdata_5fcopy_5fstring_5fbit',['VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520',1,'vk_mem_alloc.h']]],
   ['vma_5fallocator_5fcreate_5fexternally_5fsynchronized_5fbit',['VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT',['../vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d',1,'vk_mem_alloc.h']]],
   ['vma_5fallocator_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c',1,'vk_mem_alloc.h']]],
   ['vma_5fallocator_5fcreate_5fkhr_5fdedicated_5fallocation_5fbit',['VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT',['../vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878',1,'vk_mem_alloc.h']]],
+  ['vma_5fdedicated_5fallocation',['VMA_DEDICATED_ALLOCATION',['../vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4',1,'vk_mem_alloc.h']]],
   ['vma_5fmemory_5fusage_5fcpu_5fonly',['VMA_MEMORY_USAGE_CPU_ONLY',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]],
   ['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]],
   ['vma_5fmemory_5fusage_5fgpu_5fonly',['VMA_MEMORY_USAGE_GPU_ONLY',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]],
@@ -37,6 +39,10 @@
   ['vma_5fmemory_5fusage_5funknown',['VMA_MEMORY_USAGE_UNKNOWN',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]],
   ['vma_5fpool_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec',1,'vk_mem_alloc.h']]],
   ['vma_5fpool_5fcreate_5fignore_5fbuffer_5fimage_5fgranularity_5fbit',['VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2',1,'vk_mem_alloc.h']]],
+  ['vma_5fpool_5fcreate_5flinear_5falgorithm_5fbit',['VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726',1,'vk_mem_alloc.h']]],
+  ['vma_5frecord_5fflag_5fbits_5fmax_5fenum',['VMA_RECORD_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e',1,'vk_mem_alloc.h']]],
+  ['vma_5frecord_5fflush_5fafter_5fcall_5fbit',['VMA_RECORD_FLUSH_AFTER_CALL_BIT',['../vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7',1,'vk_mem_alloc.h']]],
+  ['vma_5frecording_5fenabled',['VMA_RECORDING_ENABLED',['../vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c',1,'vk_mem_alloc.h']]],
   ['vma_5fstats_5fstring_5fenabled',['VMA_STATS_STRING_ENABLED',['../vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1',1,'vk_mem_alloc.h']]],
   ['vmaallocatememory',['vmaAllocateMemory',['../vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8',1,'vk_mem_alloc.h']]],
   ['vmaallocatememoryforbuffer',['vmaAllocateMemoryForBuffer',['../vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b',1,'vk_mem_alloc.h']]],
@@ -54,6 +60,8 @@
   ['vmabindimagememory',['vmaBindImageMemory',['../vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
   ['vmabuildstatsstring',['vmaBuildStatsString',['../vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
   ['vmacalculatestats',['vmaCalculateStats',['../vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3',1,'vk_mem_alloc.h']]],
+  ['vmacheckcorruption',['vmaCheckCorruption',['../vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98',1,'vk_mem_alloc.h']]],
+  ['vmacheckpoolcorruption',['vmaCheckPoolCorruption',['../vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89',1,'vk_mem_alloc.h']]],
   ['vmacreateallocator',['vmaCreateAllocator',['../vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
   ['vmacreatebuffer',['vmaCreateBuffer',['../vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51',1,'vk_mem_alloc.h']]],
   ['vmacreateimage',['vmaCreateImage',['../vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73',1,'vk_mem_alloc.h']]],
@@ -70,6 +78,7 @@
   ['vmafindmemorytypeindex',['vmaFindMemoryTypeIndex',['../vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a',1,'vk_mem_alloc.h']]],
   ['vmafindmemorytypeindexforbufferinfo',['vmaFindMemoryTypeIndexForBufferInfo',['../vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888',1,'vk_mem_alloc.h']]],
   ['vmafindmemorytypeindexforimageinfo',['vmaFindMemoryTypeIndexForImageInfo',['../vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
+  ['vmaflushallocation',['vmaFlushAllocation',['../vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de',1,'vk_mem_alloc.h']]],
   ['vmafreememory',['vmaFreeMemory',['../vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568',1,'vk_mem_alloc.h']]],
   ['vmafreestatsstring',['vmaFreeStatsString',['../vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
   ['vmagetallocationinfo',['vmaGetAllocationInfo',['../vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
@@ -77,6 +86,7 @@
   ['vmagetmemorytypeproperties',['vmaGetMemoryTypeProperties',['../vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]],
   ['vmagetphysicaldeviceproperties',['vmaGetPhysicalDeviceProperties',['../vk__mem__alloc_8h.html#aecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]],
   ['vmagetpoolstats',['vmaGetPoolStats',['../vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153',1,'vk_mem_alloc.h']]],
+  ['vmainvalidateallocation',['vmaInvalidateAllocation',['../vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006',1,'vk_mem_alloc.h']]],
   ['vmamakepoolallocationslost',['vmaMakePoolAllocationsLost',['../vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024',1,'vk_mem_alloc.h']]],
   ['vmamapmemory',['vmaMapMemory',['../vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069',1,'vk_mem_alloc.h']]],
   ['vmamemoryusage',['VmaMemoryUsage',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc',1,'VmaMemoryUsage():&#160;vk_mem_alloc.h'],['../vk__mem__alloc_8h.html#ad63b2113c0bfdbeade1cb498f5a8580d',1,'VmaMemoryUsage():&#160;vk_mem_alloc.h']]],
@@ -85,6 +95,9 @@
   ['vmapoolcreateflags',['VmaPoolCreateFlags',['../vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a',1,'vk_mem_alloc.h']]],
   ['vmapoolcreateinfo',['VmaPoolCreateInfo',['../struct_vma_pool_create_info.html',1,'VmaPoolCreateInfo'],['../vk__mem__alloc_8h.html#a211706e9348dcee25a843ed4ea69bce7',1,'VmaPoolCreateInfo():&#160;vk_mem_alloc.h']]],
   ['vmapoolstats',['VmaPoolStats',['../struct_vma_pool_stats.html',1,'VmaPoolStats'],['../vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34',1,'VmaPoolStats():&#160;vk_mem_alloc.h']]],
+  ['vmarecordflagbits',['VmaRecordFlagBits',['../vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2',1,'VmaRecordFlagBits():&#160;vk_mem_alloc.h'],['../vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4',1,'VmaRecordFlagBits():&#160;vk_mem_alloc.h']]],
+  ['vmarecordflags',['VmaRecordFlags',['../vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828',1,'vk_mem_alloc.h']]],
+  ['vmarecordsettings',['VmaRecordSettings',['../struct_vma_record_settings.html',1,'VmaRecordSettings'],['../vk__mem__alloc_8h.html#a0ab61e87ff6365f1d59915eadc37a9f0',1,'VmaRecordSettings():&#160;vk_mem_alloc.h']]],
   ['vmasetallocationuserdata',['vmaSetAllocationUserData',['../vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f',1,'vk_mem_alloc.h']]],
   ['vmasetcurrentframeindex',['vmaSetCurrentFrameIndex',['../vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236',1,'vk_mem_alloc.h']]],
   ['vmastatinfo',['VmaStatInfo',['../struct_vma_stat_info.html',1,'VmaStatInfo'],['../vk__mem__alloc_8h.html#a810b009a788ee8aac72a25b42ffbe31c',1,'VmaStatInfo():&#160;vk_mem_alloc.h']]],
diff --git a/docs/html/search/classes_0.js b/docs/html/search/classes_0.js
index 152fb2b..7fe2da1 100644
--- a/docs/html/search/classes_0.js
+++ b/docs/html/search/classes_0.js
@@ -11,6 +11,7 @@
   ['vmapool',['VmaPool',['../struct_vma_pool.html',1,'']]],
   ['vmapoolcreateinfo',['VmaPoolCreateInfo',['../struct_vma_pool_create_info.html',1,'']]],
   ['vmapoolstats',['VmaPoolStats',['../struct_vma_pool_stats.html',1,'']]],
+  ['vmarecordsettings',['VmaRecordSettings',['../struct_vma_record_settings.html',1,'']]],
   ['vmastatinfo',['VmaStatInfo',['../struct_vma_stat_info.html',1,'']]],
   ['vmastats',['VmaStats',['../struct_vma_stats.html',1,'']]],
   ['vmavulkanfunctions',['VmaVulkanFunctions',['../struct_vma_vulkan_functions.html',1,'']]]
diff --git a/docs/html/search/defines_0.js b/docs/html/search/defines_0.js
index eb19ead..bf18592 100644
--- a/docs/html/search/defines_0.js
+++ b/docs/html/search/defines_0.js
@@ -1,4 +1,6 @@
 var searchData=
 [
+  ['vma_5fdedicated_5fallocation',['VMA_DEDICATED_ALLOCATION',['../vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4',1,'vk_mem_alloc.h']]],
+  ['vma_5frecording_5fenabled',['VMA_RECORDING_ENABLED',['../vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c',1,'vk_mem_alloc.h']]],
   ['vma_5fstats_5fstring_5fenabled',['VMA_STATS_STRING_ENABLED',['../vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1',1,'vk_mem_alloc.h']]]
 ];
diff --git a/docs/html/search/enums_0.js b/docs/html/search/enums_0.js
index 9bd6e39..c5ed539 100644
--- a/docs/html/search/enums_0.js
+++ b/docs/html/search/enums_0.js
@@ -3,5 +3,6 @@
   ['vmaallocationcreateflagbits',['VmaAllocationCreateFlagBits',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597',1,'vk_mem_alloc.h']]],
   ['vmaallocatorcreateflagbits',['VmaAllocatorCreateFlagBits',['../vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c',1,'vk_mem_alloc.h']]],
   ['vmamemoryusage',['VmaMemoryUsage',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc',1,'vk_mem_alloc.h']]],
-  ['vmapoolcreateflagbits',['VmaPoolCreateFlagBits',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7',1,'vk_mem_alloc.h']]]
+  ['vmapoolcreateflagbits',['VmaPoolCreateFlagBits',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7',1,'vk_mem_alloc.h']]],
+  ['vmarecordflagbits',['VmaRecordFlagBits',['../vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2',1,'vk_mem_alloc.h']]]
 ];
diff --git a/docs/html/search/enumvalues_0.js b/docs/html/search/enumvalues_0.js
index ea47966..ee262d0 100644
--- a/docs/html/search/enumvalues_0.js
+++ b/docs/html/search/enumvalues_0.js
@@ -6,6 +6,7 @@
   ['vma_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882',1,'vk_mem_alloc.h']]],
   ['vma_5fallocation_5fcreate_5fmapped_5fbit',['VMA_ALLOCATION_CREATE_MAPPED_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f',1,'vk_mem_alloc.h']]],
   ['vma_5fallocation_5fcreate_5fnever_5fallocate_5fbit',['VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff',1,'vk_mem_alloc.h']]],
+  ['vma_5fallocation_5fcreate_5fupper_5faddress_5fbit',['VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df',1,'vk_mem_alloc.h']]],
   ['vma_5fallocation_5fcreate_5fuser_5fdata_5fcopy_5fstring_5fbit',['VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520',1,'vk_mem_alloc.h']]],
   ['vma_5fallocator_5fcreate_5fexternally_5fsynchronized_5fbit',['VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT',['../vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d',1,'vk_mem_alloc.h']]],
   ['vma_5fallocator_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c',1,'vk_mem_alloc.h']]],
@@ -17,5 +18,8 @@
   ['vma_5fmemory_5fusage_5fmax_5fenum',['VMA_MEMORY_USAGE_MAX_ENUM',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e',1,'vk_mem_alloc.h']]],
   ['vma_5fmemory_5fusage_5funknown',['VMA_MEMORY_USAGE_UNKNOWN',['../vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]],
   ['vma_5fpool_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec',1,'vk_mem_alloc.h']]],
-  ['vma_5fpool_5fcreate_5fignore_5fbuffer_5fimage_5fgranularity_5fbit',['VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2',1,'vk_mem_alloc.h']]]
+  ['vma_5fpool_5fcreate_5fignore_5fbuffer_5fimage_5fgranularity_5fbit',['VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2',1,'vk_mem_alloc.h']]],
+  ['vma_5fpool_5fcreate_5flinear_5falgorithm_5fbit',['VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT',['../vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726',1,'vk_mem_alloc.h']]],
+  ['vma_5frecord_5fflag_5fbits_5fmax_5fenum',['VMA_RECORD_FLAG_BITS_MAX_ENUM',['../vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e',1,'vk_mem_alloc.h']]],
+  ['vma_5frecord_5fflush_5fafter_5fcall_5fbit',['VMA_RECORD_FLUSH_AFTER_CALL_BIT',['../vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7',1,'vk_mem_alloc.h']]]
 ];
diff --git a/docs/html/search/functions_0.js b/docs/html/search/functions_0.js
index efddc9f..0ab7deb 100644
--- a/docs/html/search/functions_0.js
+++ b/docs/html/search/functions_0.js
@@ -7,6 +7,8 @@
   ['vmabindimagememory',['vmaBindImageMemory',['../vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
   ['vmabuildstatsstring',['vmaBuildStatsString',['../vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
   ['vmacalculatestats',['vmaCalculateStats',['../vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3',1,'vk_mem_alloc.h']]],
+  ['vmacheckcorruption',['vmaCheckCorruption',['../vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98',1,'vk_mem_alloc.h']]],
+  ['vmacheckpoolcorruption',['vmaCheckPoolCorruption',['../vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89',1,'vk_mem_alloc.h']]],
   ['vmacreateallocator',['vmaCreateAllocator',['../vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
   ['vmacreatebuffer',['vmaCreateBuffer',['../vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51',1,'vk_mem_alloc.h']]],
   ['vmacreateimage',['vmaCreateImage',['../vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73',1,'vk_mem_alloc.h']]],
@@ -20,6 +22,7 @@
   ['vmafindmemorytypeindex',['vmaFindMemoryTypeIndex',['../vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a',1,'vk_mem_alloc.h']]],
   ['vmafindmemorytypeindexforbufferinfo',['vmaFindMemoryTypeIndexForBufferInfo',['../vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888',1,'vk_mem_alloc.h']]],
   ['vmafindmemorytypeindexforimageinfo',['vmaFindMemoryTypeIndexForImageInfo',['../vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
+  ['vmaflushallocation',['vmaFlushAllocation',['../vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de',1,'vk_mem_alloc.h']]],
   ['vmafreememory',['vmaFreeMemory',['../vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568',1,'vk_mem_alloc.h']]],
   ['vmafreestatsstring',['vmaFreeStatsString',['../vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
   ['vmagetallocationinfo',['vmaGetAllocationInfo',['../vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
@@ -27,6 +30,7 @@
   ['vmagetmemorytypeproperties',['vmaGetMemoryTypeProperties',['../vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]],
   ['vmagetphysicaldeviceproperties',['vmaGetPhysicalDeviceProperties',['../vk__mem__alloc_8h.html#aecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]],
   ['vmagetpoolstats',['vmaGetPoolStats',['../vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153',1,'vk_mem_alloc.h']]],
+  ['vmainvalidateallocation',['vmaInvalidateAllocation',['../vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006',1,'vk_mem_alloc.h']]],
   ['vmamakepoolallocationslost',['vmaMakePoolAllocationsLost',['../vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024',1,'vk_mem_alloc.h']]],
   ['vmamapmemory',['vmaMapMemory',['../vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069',1,'vk_mem_alloc.h']]],
   ['vmasetallocationuserdata',['vmaSetAllocationUserData',['../vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f',1,'vk_mem_alloc.h']]],
diff --git a/docs/html/search/groups_0.html b/docs/html/search/groups_0.html
deleted file mode 100644
index 1ede28d..0000000
--- a/docs/html/search/groups_0.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="groups_0.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/docs/html/search/groups_0.js b/docs/html/search/groups_0.js
deleted file mode 100644
index 025ecae..0000000
--- a/docs/html/search/groups_0.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['general',['General',['../group__general.html',1,'']]]
-];
diff --git a/docs/html/search/groups_1.html b/docs/html/search/groups_1.html
deleted file mode 100644
index 3c05216..0000000
--- a/docs/html/search/groups_1.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="groups_1.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/docs/html/search/groups_1.js b/docs/html/search/groups_1.js
deleted file mode 100644
index 058f893..0000000
--- a/docs/html/search/groups_1.js
+++ /dev/null
@@ -1,6 +0,0 @@
-var searchData=
-[
-  ['layer_201_20choosing_20memory_20type',['Layer 1 Choosing Memory Type',['../group__layer1.html',1,'']]],
-  ['layer_202_20allocating_20memory',['Layer 2 Allocating Memory',['../group__layer2.html',1,'']]],
-  ['layer_203_20creating_20buffers_20and_20images',['Layer 3 Creating Buffers and Images',['../group__layer3.html',1,'']]]
-];
diff --git a/docs/html/search/pages_2.js b/docs/html/search/pages_2.js
index 07d814d..12ea7b1 100644
--- a/docs/html/search/pages_2.js
+++ b/docs/html/search/pages_2.js
@@ -1,4 +1,5 @@
 var searchData=
 [
+  ['debugging_20incorrect_20memory_20usage',['Debugging incorrect memory usage',['../debugging_memory_usage.html',1,'index']]],
   ['defragmentation',['Defragmentation',['../defragmentation.html',1,'index']]]
 ];
diff --git a/docs/html/search/pages_7.js b/docs/html/search/pages_7.js
index 1e4f738..7394f7d 100644
--- a/docs/html/search/pages_7.js
+++ b/docs/html/search/pages_7.js
@@ -1,4 +1,5 @@
 var searchData=
 [
+  ['record_20and_20replay',['Record and replay',['../record_and_replay.html',1,'index']]],
   ['recommended_20usage_20patterns',['Recommended usage patterns',['../usage_patterns.html',1,'index']]]
 ];
diff --git a/docs/html/search/typedefs_1.js b/docs/html/search/typedefs_1.js
index 716f5e3..5d53a90 100644
--- a/docs/html/search/typedefs_1.js
+++ b/docs/html/search/typedefs_1.js
@@ -15,6 +15,9 @@
   ['vmapoolcreateflags',['VmaPoolCreateFlags',['../vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a',1,'vk_mem_alloc.h']]],
   ['vmapoolcreateinfo',['VmaPoolCreateInfo',['../vk__mem__alloc_8h.html#a211706e9348dcee25a843ed4ea69bce7',1,'vk_mem_alloc.h']]],
   ['vmapoolstats',['VmaPoolStats',['../vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34',1,'vk_mem_alloc.h']]],
+  ['vmarecordflagbits',['VmaRecordFlagBits',['../vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4',1,'vk_mem_alloc.h']]],
+  ['vmarecordflags',['VmaRecordFlags',['../vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828',1,'vk_mem_alloc.h']]],
+  ['vmarecordsettings',['VmaRecordSettings',['../vk__mem__alloc_8h.html#a0ab61e87ff6365f1d59915eadc37a9f0',1,'vk_mem_alloc.h']]],
   ['vmastatinfo',['VmaStatInfo',['../vk__mem__alloc_8h.html#a810b009a788ee8aac72a25b42ffbe31c',1,'vk_mem_alloc.h']]],
   ['vmastats',['VmaStats',['../vk__mem__alloc_8h.html#a732be855fb4a7c248e6853d928a729af',1,'vk_mem_alloc.h']]],
   ['vmavulkanfunctions',['VmaVulkanFunctions',['../vk__mem__alloc_8h.html#a97064a1a271b0061ebfc3a079862d0c5',1,'vk_mem_alloc.h']]]
diff --git a/docs/html/search/variables_1.js b/docs/html/search/variables_1.js
index cff2c47..7ae997e 100644
--- a/docs/html/search/variables_1.js
+++ b/docs/html/search/variables_1.js
@@ -1,6 +1,6 @@
 var searchData=
 [
-  ['blockcount',['blockCount',['../struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4',1,'VmaStatInfo']]],
+  ['blockcount',['blockCount',['../struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4',1,'VmaStatInfo::blockCount()'],['../struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7',1,'VmaPoolStats::blockCount()']]],
   ['blocksize',['blockSize',['../struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676',1,'VmaPoolCreateInfo']]],
   ['bytesfreed',['bytesFreed',['../struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28',1,'VmaDefragmentationStats']]],
   ['bytesmoved',['bytesMoved',['../struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d',1,'VmaDefragmentationStats']]]
diff --git a/docs/html/search/variables_3.js b/docs/html/search/variables_3.js
index 7bacfcc..347c9f3 100644
--- a/docs/html/search/variables_3.js
+++ b/docs/html/search/variables_3.js
@@ -1,5 +1,5 @@
 var searchData=
 [
-  ['flags',['flags',['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()']]],
+  ['flags',['flags',['../struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a',1,'VmaRecordSettings::flags()'],['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()']]],
   ['frameinusecount',['frameInUseCount',['../struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7',1,'VmaAllocatorCreateInfo::frameInUseCount()'],['../struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa',1,'VmaPoolCreateInfo::frameInUseCount()']]]
 ];
diff --git a/docs/html/search/variables_6.js b/docs/html/search/variables_6.js
index 731ce38..46cab85 100644
--- a/docs/html/search/variables_6.js
+++ b/docs/html/search/variables_6.js
@@ -2,12 +2,14 @@
 [
   ['pallocationcallbacks',['pAllocationCallbacks',['../struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d',1,'VmaAllocatorCreateInfo']]],
   ['pdevicememorycallbacks',['pDeviceMemoryCallbacks',['../struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e',1,'VmaAllocatorCreateInfo']]],
+  ['pfilepath',['pFilePath',['../struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d',1,'VmaRecordSettings']]],
   ['pfnallocate',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
   ['pfnfree',['pfnFree',['../struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c',1,'VmaDeviceMemoryCallbacks']]],
   ['pheapsizelimit',['pHeapSizeLimit',['../struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b',1,'VmaAllocatorCreateInfo']]],
   ['physicaldevice',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo']]],
   ['pmappeddata',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
   ['pool',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
+  ['precordsettings',['pRecordSettings',['../struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee',1,'VmaAllocatorCreateInfo']]],
   ['preferredflags',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
   ['preferredlargeheapblocksize',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
   ['puserdata',['pUserData',['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()']]],
diff --git a/docs/html/search/variables_b.js b/docs/html/search/variables_b.js
index 42b7df9..c1444df 100644
--- a/docs/html/search/variables_b.js
+++ b/docs/html/search/variables_b.js
@@ -7,13 +7,13 @@
   ['vkcreateimage',['vkCreateImage',['../struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325',1,'VmaVulkanFunctions']]],
   ['vkdestroybuffer',['vkDestroyBuffer',['../struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45',1,'VmaVulkanFunctions']]],
   ['vkdestroyimage',['vkDestroyImage',['../struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa',1,'VmaVulkanFunctions']]],
+  ['vkflushmappedmemoryranges',['vkFlushMappedMemoryRanges',['../struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9',1,'VmaVulkanFunctions']]],
   ['vkfreememory',['vkFreeMemory',['../struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4',1,'VmaVulkanFunctions']]],
   ['vkgetbuffermemoryrequirements',['vkGetBufferMemoryRequirements',['../struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143',1,'VmaVulkanFunctions']]],
-  ['vkgetbuffermemoryrequirements2khr',['vkGetBufferMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c',1,'VmaVulkanFunctions']]],
   ['vkgetimagememoryrequirements',['vkGetImageMemoryRequirements',['../struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4',1,'VmaVulkanFunctions']]],
-  ['vkgetimagememoryrequirements2khr',['vkGetImageMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875',1,'VmaVulkanFunctions']]],
   ['vkgetphysicaldevicememoryproperties',['vkGetPhysicalDeviceMemoryProperties',['../struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830',1,'VmaVulkanFunctions']]],
   ['vkgetphysicaldeviceproperties',['vkGetPhysicalDeviceProperties',['../struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96',1,'VmaVulkanFunctions']]],
+  ['vkinvalidatemappedmemoryranges',['vkInvalidateMappedMemoryRanges',['../struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1',1,'VmaVulkanFunctions']]],
   ['vkmapmemory',['vkMapMemory',['../struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49',1,'VmaVulkanFunctions']]],
   ['vkunmapmemory',['vkUnmapMemory',['../struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9',1,'VmaVulkanFunctions']]]
 ];
diff --git a/docs/html/struct_vma_allocator_create_info-members.html b/docs/html/struct_vma_allocator_create_info-members.html
index 9340920..598ecde 100644
--- a/docs/html/struct_vma_allocator_create_info-members.html
+++ b/docs/html/struct_vma_allocator_create_info-members.html
@@ -72,8 +72,9 @@
   <tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
   <tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">pRecordSettings</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
 </table></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/html/struct_vma_allocator_create_info.html b/docs/html/struct_vma_allocator_create_info.html
index 35e8d05..f9735fb 100644
--- a/docs/html/struct_vma_allocator_create_info.html
+++ b/docs/html/struct_vma_allocator_create_info.html
@@ -100,6 +100,9 @@
 <tr class="memitem:a3dc197be3227da7338b1643f70db36bd"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a></td></tr>
 <tr class="memdesc:a3dc197be3227da7338b1643f70db36bd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pointers to Vulkan functions. Can be null if you leave define <code>VMA_STATIC_VULKAN_FUNCTIONS 1</code>.  <a href="#a3dc197be3227da7338b1643f70db36bd">More...</a><br /></td></tr>
 <tr class="separator:a3dc197be3227da7338b1643f70db36bd"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ace2aa4877b16a42b0b7673d4e26000ee"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">pRecordSettings</a></td></tr>
+<tr class="memdesc:ace2aa4877b16a42b0b7673d4e26000ee"><td class="mdescLeft">&#160;</td><td class="mdescRight">Parameters for recording of VMA calls. Can be null.  <a href="#ace2aa4877b16a42b0b7673d4e26000ee">More...</a><br /></td></tr>
+<tr class="separator:ace2aa4877b16a42b0b7673d4e26000ee"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><p>Description of a Allocator to be created. </p>
@@ -231,6 +234,23 @@
 
 </div>
 </div>
+<a id="ace2aa4877b16a42b0b7673d4e26000ee"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ace2aa4877b16a42b0b7673d4e26000ee">&#9670;&nbsp;</a></span>pRecordSettings</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">const <a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a>* VmaAllocatorCreateInfo::pRecordSettings</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Parameters for recording of VMA calls. Can be null. </p>
+<p>If not null, it enables recording of calls to VMA functions to a file. If support for recording is not enabled using <code>VMA_RECORDING_ENABLED</code> macro, creation of the allocator object fails with <code>VK_ERROR_FEATURE_NOT_PRESENT</code>. </p>
+
+</div>
+</div>
 <a id="a8e4714298e3121cdd8b214a1ae7a637a"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a8e4714298e3121cdd8b214a1ae7a637a">&#9670;&nbsp;</a></span>preferredLargeHeapBlockSize</h2>
 
diff --git a/docs/html/struct_vma_memory_requirements-members.html b/docs/html/struct_vma_memory_requirements-members.html
deleted file mode 100644
index aefd96c..0000000
--- a/docs/html/struct_vma_memory_requirements-members.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: Member List</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-</div><!-- top -->
-<div class="header">
-  <div class="headertitle">
-<div class="title">VmaMemoryRequirements Member List</div>  </div>
-</div><!--header-->
-<div class="contents">
-
-<p>This is the complete list of members for <a class="el" href="struct_vma_memory_requirements.html">VmaMemoryRequirements</a>, including all inherited members.</p>
-<table class="directory">
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_memory_requirements.html#a53c9ea8c3cbcc12dddbe9ae23bb85eb6">flags</a></td><td class="entry"><a class="el" href="struct_vma_memory_requirements.html">VmaMemoryRequirements</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_memory_requirements.html#a6e105f836c2288034c711815b18226dc">preferredFlags</a></td><td class="entry"><a class="el" href="struct_vma_memory_requirements.html">VmaMemoryRequirements</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_memory_requirements.html#a8470093e93ed07ed2557490cdc67566a">pUserData</a></td><td class="entry"><a class="el" href="struct_vma_memory_requirements.html">VmaMemoryRequirements</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_memory_requirements.html#a8876c1b0f112e13a277f16967064cfe0">requiredFlags</a></td><td class="entry"><a class="el" href="struct_vma_memory_requirements.html">VmaMemoryRequirements</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_memory_requirements.html#ab588497177a57847ed04e0a1aef54bbe">usage</a></td><td class="entry"><a class="el" href="struct_vma_memory_requirements.html">VmaMemoryRequirements</a></td><td class="entry"></td></tr>
-</table></div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/struct_vma_memory_requirements.html b/docs/html/struct_vma_memory_requirements.html
deleted file mode 100644
index c3572f1..0000000
--- a/docs/html/struct_vma_memory_requirements.html
+++ /dev/null
@@ -1,181 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: VmaMemoryRequirements Struct Reference</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-</div><!-- top -->
-<div class="header">
-  <div class="summary">
-<a href="#pub-attribs">Public Attributes</a> &#124;
-<a href="struct_vma_memory_requirements-members.html">List of all members</a>  </div>
-  <div class="headertitle">
-<div class="title">VmaMemoryRequirements Struct Reference<div class="ingroups"><a class="el" href="group__layer1.html">Layer 1 Choosing Memory Type</a></div></div>  </div>
-</div><!--header-->
-<div class="contents">
-
-<p><code>#include &lt;<a class="el" href="vk__mem__alloc_8h_source.html">vk_mem_alloc.h</a>&gt;</code></p>
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-attribs"></a>
-Public Attributes</h2></td></tr>
-<tr class="memitem:a53c9ea8c3cbcc12dddbe9ae23bb85eb6"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__layer1.html#gab96b90d34cd1bd0f340fc48f8ca2664a">VmaMemoryRequirementFlags</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_memory_requirements.html#a53c9ea8c3cbcc12dddbe9ae23bb85eb6">flags</a></td></tr>
-<tr class="separator:a53c9ea8c3cbcc12dddbe9ae23bb85eb6"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ab588497177a57847ed04e0a1aef54bbe"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_memory_requirements.html#ab588497177a57847ed04e0a1aef54bbe">usage</a></td></tr>
-<tr class="memdesc:ab588497177a57847ed04e0a1aef54bbe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Intended usage of memory.  <a href="#ab588497177a57847ed04e0a1aef54bbe">More...</a><br /></td></tr>
-<tr class="separator:ab588497177a57847ed04e0a1aef54bbe"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a8876c1b0f112e13a277f16967064cfe0"><td class="memItemLeft" align="right" valign="top">VkMemoryPropertyFlags&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_memory_requirements.html#a8876c1b0f112e13a277f16967064cfe0">requiredFlags</a></td></tr>
-<tr class="memdesc:a8876c1b0f112e13a277f16967064cfe0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags that must be set in a Memory Type chosen for an allocation.  <a href="#a8876c1b0f112e13a277f16967064cfe0">More...</a><br /></td></tr>
-<tr class="separator:a8876c1b0f112e13a277f16967064cfe0"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a6e105f836c2288034c711815b18226dc"><td class="memItemLeft" align="right" valign="top">VkMemoryPropertyFlags&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_memory_requirements.html#a6e105f836c2288034c711815b18226dc">preferredFlags</a></td></tr>
-<tr class="memdesc:a6e105f836c2288034c711815b18226dc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags that preferably should be set in a Memory Type chosen for an allocation.  <a href="#a6e105f836c2288034c711815b18226dc">More...</a><br /></td></tr>
-<tr class="separator:a6e105f836c2288034c711815b18226dc"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a8470093e93ed07ed2557490cdc67566a"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_memory_requirements.html#a8470093e93ed07ed2557490cdc67566a">pUserData</a></td></tr>
-<tr class="memdesc:a8470093e93ed07ed2557490cdc67566a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Custom general-purpose pointer that will be stored in VmaAllocation, can be read as <a class="el" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13" title="Custom general-purpose pointer that was passed as VmaMemoryRequirements::pUserData or set using vmaSe...">VmaAllocationInfo::pUserData</a> and changed using <a class="el" href="group__layer2.html#gaf9147d31ffc11d62fc187bde283ed14f" title="Sets pUserData in given allocation to new value. ">vmaSetAllocationUserData()</a>.  <a href="#a8470093e93ed07ed2557490cdc67566a">More...</a><br /></td></tr>
-<tr class="separator:a8470093e93ed07ed2557490cdc67566a"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<h2 class="groupheader">Member Data Documentation</h2>
-<a id="a53c9ea8c3cbcc12dddbe9ae23bb85eb6"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a53c9ea8c3cbcc12dddbe9ae23bb85eb6">&#9670;&nbsp;</a></span>flags</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname"><a class="el" href="group__layer1.html#gab96b90d34cd1bd0f340fc48f8ca2664a">VmaMemoryRequirementFlags</a> VmaMemoryRequirements::flags</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
-<a id="a6e105f836c2288034c711815b18226dc"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a6e105f836c2288034c711815b18226dc">&#9670;&nbsp;</a></span>preferredFlags</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkMemoryPropertyFlags VmaMemoryRequirements::preferredFlags</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags that preferably should be set in a Memory Type chosen for an allocation. </p>
-<p>Set to 0 if no additional flags are prefered and only requiredFlags should be used. If not 0, it must be a superset or equal to requiredFlags. </p>
-
-</div>
-</div>
-<a id="a8470093e93ed07ed2557490cdc67566a"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a8470093e93ed07ed2557490cdc67566a">&#9670;&nbsp;</a></span>pUserData</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void* VmaMemoryRequirements::pUserData</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Custom general-purpose pointer that will be stored in VmaAllocation, can be read as <a class="el" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13" title="Custom general-purpose pointer that was passed as VmaMemoryRequirements::pUserData or set using vmaSe...">VmaAllocationInfo::pUserData</a> and changed using <a class="el" href="group__layer2.html#gaf9147d31ffc11d62fc187bde283ed14f" title="Sets pUserData in given allocation to new value. ">vmaSetAllocationUserData()</a>. </p>
-
-</div>
-</div>
-<a id="a8876c1b0f112e13a277f16967064cfe0"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a8876c1b0f112e13a277f16967064cfe0">&#9670;&nbsp;</a></span>requiredFlags</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">VkMemoryPropertyFlags VmaMemoryRequirements::requiredFlags</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Flags that must be set in a Memory Type chosen for an allocation. </p>
-<p>Leave 0 if you specify requirement via usage. </p>
-
-</div>
-</div>
-<a id="ab588497177a57847ed04e0a1aef54bbe"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ab588497177a57847ed04e0a1aef54bbe">&#9670;&nbsp;</a></span>usage</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname"><a class="el" href="group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a> VmaMemoryRequirements::usage</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Intended usage of memory. </p>
-<p>Leave VMA_MEMORY_USAGE_UNKNOWN if you specify requiredFlags. You can also use both. </p>
-
-</div>
-</div>
-<hr/>The documentation for this struct was generated from the following file:<ul>
-<li><a class="el" href="vk__mem__alloc_8h_source.html">vk_mem_alloc.h</a></li>
-</ul>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/struct_vma_pool_create_info.html b/docs/html/struct_vma_pool_create_info.html
index 153ff87..d0bbc42 100644
--- a/docs/html/struct_vma_pool_create_info.html
+++ b/docs/html/struct_vma_pool_create_info.html
@@ -80,7 +80,7 @@
 <tr class="memdesc:a8405139f63d078340ae74513a59f5446"><td class="mdescLeft">&#160;</td><td class="mdescRight">Use combination of <a class="el" href="vk__mem__alloc_8h.html#a8f93195158e0e2ac80ca352064e71c1f" title="Flags to be passed as VmaPoolCreateInfo::flags. ">VmaPoolCreateFlagBits</a>.  <a href="#a8405139f63d078340ae74513a59f5446">More...</a><br /></td></tr>
 <tr class="separator:a8405139f63d078340ae74513a59f5446"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:aa4265160536cdb9be821b7686c16c676"><td class="memItemLeft" align="right" valign="top">VkDeviceSize&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">blockSize</a></td></tr>
-<tr class="memdesc:aa4265160536cdb9be821b7686c16c676"><td class="mdescLeft">&#160;</td><td class="mdescRight">Size of a single <code>VkDeviceMemory</code> block to be allocated as part of this pool, in bytes.  <a href="#aa4265160536cdb9be821b7686c16c676">More...</a><br /></td></tr>
+<tr class="memdesc:aa4265160536cdb9be821b7686c16c676"><td class="mdescLeft">&#160;</td><td class="mdescRight">Size of a single <code>VkDeviceMemory</code> block to be allocated as part of this pool, in bytes. Optional.  <a href="#aa4265160536cdb9be821b7686c16c676">More...</a><br /></td></tr>
 <tr class="separator:aa4265160536cdb9be821b7686c16c676"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ad8006fb803185c0a699d30f3e9a865ae"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae">minBlockCount</a></td></tr>
 <tr class="memdesc:ad8006fb803185c0a699d30f3e9a865ae"><td class="mdescLeft">&#160;</td><td class="mdescRight">Minimum number of blocks to be always allocated in this pool, even if they stay empty.  <a href="#ad8006fb803185c0a699d30f3e9a865ae">More...</a><br /></td></tr>
@@ -107,8 +107,9 @@
       </table>
 </div><div class="memdoc">
 
-<p>Size of a single <code>VkDeviceMemory</code> block to be allocated as part of this pool, in bytes. </p>
-<p>Optional. Leave 0 to use default. </p>
+<p>Size of a single <code>VkDeviceMemory</code> block to be allocated as part of this pool, in bytes. Optional. </p>
+<p>Specify nonzero to set explicit, constant size of memory blocks used by this pool.</p>
+<p>Leave 0 to use default and let the library manage block sizes automatically. Sizes of particular blocks may vary. </p>
 
 </div>
 </div>
@@ -160,8 +161,8 @@
 </div><div class="memdoc">
 
 <p>Maximum number of blocks that can be allocated in this pool. Optional. </p>
-<p>Optional. Set to 0 to use <code>SIZE_MAX</code>, which means no limit.</p>
-<p>Set to same value as minBlockCount to have fixed amount of memory allocated throuout whole lifetime of this pool. </p>
+<p>Set to 0 to use default, which is <code>SIZE_MAX</code>, which means no limit.</p>
+<p>Set to same value as <a class="el" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae" title="Minimum number of blocks to be always allocated in this pool, even if they stay empty. ">VmaPoolCreateInfo::minBlockCount</a> to have fixed amount of memory allocated throughout whole lifetime of this pool. </p>
 
 </div>
 </div>
@@ -194,7 +195,7 @@
 </div><div class="memdoc">
 
 <p>Minimum number of blocks to be always allocated in this pool, even if they stay empty. </p>
-<p>Set to 0 to have no preallocated blocks and let the pool be completely empty. </p>
+<p>Set to 0 to have no preallocated blocks and allow the pool be completely empty. </p>
 
 </div>
 </div>
diff --git a/docs/html/struct_vma_pool_stats-members.html b/docs/html/struct_vma_pool_stats-members.html
index 66df81b..f73f53c 100644
--- a/docs/html/struct_vma_pool_stats-members.html
+++ b/docs/html/struct_vma_pool_stats-members.html
@@ -66,10 +66,11 @@
 <p>This is the complete list of members for <a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a>, including all inherited members.</p>
 <table class="directory">
   <tr class="even"><td class="entry"><a class="el" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7">blockCount</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a></td><td class="entry"><a class="el" href="struct_vma_pool_stats.html">VmaPoolStats</a></td><td class="entry"></td></tr>
 </table></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/html/struct_vma_pool_stats.html b/docs/html/struct_vma_pool_stats.html
index 3ee189b..93866b3 100644
--- a/docs/html/struct_vma_pool_stats.html
+++ b/docs/html/struct_vma_pool_stats.html
@@ -86,8 +86,11 @@
 <tr class="memdesc:ae4f3546ffa4d1e598b64d8e6134854f4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Number of continuous memory ranges in the pool not used by any <a class="el" href="struct_vma_allocation.html" title="Represents single memory allocation. ">VmaAllocation</a>.  <a href="#ae4f3546ffa4d1e598b64d8e6134854f4">More...</a><br /></td></tr>
 <tr class="separator:ae4f3546ffa4d1e598b64d8e6134854f4"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ab4c8f52dd42ab01998f60f0b6acc722b"><td class="memItemLeft" align="right" valign="top">VkDeviceSize&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a></td></tr>
-<tr class="memdesc:ab4c8f52dd42ab01998f60f0b6acc722b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Size of the largest continuous free memory region.  <a href="#ab4c8f52dd42ab01998f60f0b6acc722b">More...</a><br /></td></tr>
+<tr class="memdesc:ab4c8f52dd42ab01998f60f0b6acc722b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Size of the largest continuous free memory region available for new allocation.  <a href="#ab4c8f52dd42ab01998f60f0b6acc722b">More...</a><br /></td></tr>
 <tr class="separator:ab4c8f52dd42ab01998f60f0b6acc722b"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:aa0b5cb45cef6f18571cefb03b9a230e7"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7">blockCount</a></td></tr>
+<tr class="memdesc:aa0b5cb45cef6f18571cefb03b9a230e7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Number of <code>VkDeviceMemory</code> blocks allocated for this pool.  <a href="#aa0b5cb45cef6f18571cefb03b9a230e7">More...</a><br /></td></tr>
+<tr class="separator:aa0b5cb45cef6f18571cefb03b9a230e7"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><p>Describes parameter of existing <a class="el" href="struct_vma_pool.html" title="Represents custom memory pool. ">VmaPool</a>. </p>
@@ -108,6 +111,22 @@
 
 </div>
 </div>
+<a id="aa0b5cb45cef6f18571cefb03b9a230e7"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#aa0b5cb45cef6f18571cefb03b9a230e7">&#9670;&nbsp;</a></span>blockCount</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">size_t VmaPoolStats::blockCount</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Number of <code>VkDeviceMemory</code> blocks allocated for this pool. </p>
+
+</div>
+</div>
 <a id="a326807b2de2b0931cee4ed9a5f2e420c"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a326807b2de2b0931cee4ed9a5f2e420c">&#9670;&nbsp;</a></span>size</h2>
 
@@ -152,7 +171,7 @@
       </table>
 </div><div class="memdoc">
 
-<p>Size of the largest continuous free memory region. </p>
+<p>Size of the largest continuous free memory region available for new allocation. </p>
 <p>Making a new allocation of that size is not guaranteed to succeed because of possible additional margin required to respect alignment and buffer/image granularity. </p>
 
 </div>
diff --git a/docs/html/about_the_library.html b/docs/html/struct_vma_record_settings-members.html
similarity index 74%
rename from docs/html/about_the_library.html
rename to docs/html/struct_vma_record_settings-members.html
index de48ac6..8079ef8 100644
--- a/docs/html/about_the_library.html
+++ b/docs/html/struct_vma_record_settings-members.html
@@ -5,7 +5,7 @@
 <meta http-equiv="X-UA-Compatible" content="IE=9"/>
 <meta name="generator" content="Doxygen 1.8.13"/>
 <meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: About the library</title>
+<title>Vulkan Memory Allocator: Member List</title>
 <link href="tabs.css" rel="stylesheet" type="text/css"/>
 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript" src="dynsections.js"></script>
@@ -56,24 +56,18 @@
 </iframe>
 </div>
 
-<div id="nav-path" class="navpath">
-  <ul>
-<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
-</div>
 </div><!-- top -->
 <div class="header">
   <div class="headertitle">
-<div class="title">About the library </div>  </div>
+<div class="title">VmaRecordSettings Member List</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="textblock"><h1><a class="anchor" id="about_the_library_features_not_supported"></a>
-Features not supported</h1>
-<p>Features deliberately excluded from the scope of this library:</p>
-<ul>
-<li>Data transfer - issuing commands that transfer data between buffers or images, any usage of <code>VkCommandList</code> or <code>VkCommandQueue</code> and related synchronization is responsibility of the user.</li>
-<li>Support for any programming languages other than C/C++. Bindings to other languages are welcomed as external projects. </li>
-</ul>
-</div></div><!-- contents -->
+
+<p>This is the complete list of members for <a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a">flags</a></td><td class="entry"><a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">pFilePath</a></td><td class="entry"><a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
 Generated by &#160;<a href="http://www.doxygen.org/index.html">
diff --git a/docs/html/struct_vma_record_settings.html b/docs/html/struct_vma_record_settings.html
new file mode 100644
index 0000000..fe9f186
--- /dev/null
+++ b/docs/html/struct_vma_record_settings.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.13"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Vulkan Memory Allocator: VmaRecordSettings Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Vulkan Memory Allocator
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.13 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+</div><!-- top -->
+<div class="header">
+  <div class="summary">
+<a href="#pub-attribs">Public Attributes</a> &#124;
+<a href="struct_vma_record_settings-members.html">List of all members</a>  </div>
+  <div class="headertitle">
+<div class="title">VmaRecordSettings Struct Reference</div>  </div>
+</div><!--header-->
+<div class="contents">
+
+<p>Parameters for recording calls to VMA functions. To be used in <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee" title="Parameters for recording of VMA calls. Can be null. ">VmaAllocatorCreateInfo::pRecordSettings</a>.  
+ <a href="struct_vma_record_settings.html#details">More...</a></p>
+
+<p><code>#include &lt;<a class="el" href="vk__mem__alloc_8h_source.html">vk_mem_alloc.h</a>&gt;</code></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-attribs"></a>
+Public Attributes</h2></td></tr>
+<tr class="memitem:ad8fdcc92119ae7a8c08c1a564c01d63a"><td class="memItemLeft" align="right" valign="top"><a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">VmaRecordFlags</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a">flags</a></td></tr>
+<tr class="memdesc:ad8fdcc92119ae7a8c08c1a564c01d63a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags for recording. Use <a class="el" href="vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4" title="Flags to be used in VmaRecordSettings::flags. ">VmaRecordFlagBits</a> enum.  <a href="#ad8fdcc92119ae7a8c08c1a564c01d63a">More...</a><br /></td></tr>
+<tr class="separator:ad8fdcc92119ae7a8c08c1a564c01d63a"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a6cb1fdbf6bcb610b68f2010dd629e89d"><td class="memItemLeft" align="right" valign="top">const char *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">pFilePath</a></td></tr>
+<tr class="memdesc:a6cb1fdbf6bcb610b68f2010dd629e89d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Path to the file that should be written by the recording.  <a href="#a6cb1fdbf6bcb610b68f2010dd629e89d">More...</a><br /></td></tr>
+<tr class="separator:a6cb1fdbf6bcb610b68f2010dd629e89d"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p>Parameters for recording calls to VMA functions. To be used in <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee" title="Parameters for recording of VMA calls. Can be null. ">VmaAllocatorCreateInfo::pRecordSettings</a>. </p>
+</div><h2 class="groupheader">Member Data Documentation</h2>
+<a id="ad8fdcc92119ae7a8c08c1a564c01d63a"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ad8fdcc92119ae7a8c08c1a564c01d63a">&#9670;&nbsp;</a></span>flags</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">VmaRecordFlags</a> VmaRecordSettings::flags</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Flags for recording. Use <a class="el" href="vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4" title="Flags to be used in VmaRecordSettings::flags. ">VmaRecordFlagBits</a> enum. </p>
+
+</div>
+</div>
+<a id="a6cb1fdbf6bcb610b68f2010dd629e89d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a6cb1fdbf6bcb610b68f2010dd629e89d">&#9670;&nbsp;</a></span>pFilePath</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">const char* VmaRecordSettings::pFilePath</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Path to the file that should be written by the recording. </p>
+<p>Suggested extension: "csv". If the file already exists, it will be overwritten. It will be opened for the whole time <a class="el" href="struct_vma_allocator.html" title="Represents main object of this library initialized. ">VmaAllocator</a> object is alive. If opening this file fails, creation of the whole allocator object fails. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="vk__mem__alloc_8h_source.html">vk_mem_alloc.h</a></li>
+</ul>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.13
+</small></address>
+</body>
+</html>
diff --git a/docs/html/struct_vma_vulkan_functions-members.html b/docs/html/struct_vma_vulkan_functions-members.html
index b000949..22699b3 100644
--- a/docs/html/struct_vma_vulkan_functions-members.html
+++ b/docs/html/struct_vma_vulkan_functions-members.html
@@ -72,13 +72,13 @@
   <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325">vkCreateImage</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
   <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45">vkDestroyBuffer</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">vkDestroyImage</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">vkFreeMemory</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">vkGetBufferMemoryRequirements</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">vkGetBufferMemoryRequirements2KHR</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9">vkFlushMappedMemoryRanges</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">vkFreeMemory</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">vkGetBufferMemoryRequirements</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">vkGetImageMemoryRequirements</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">vkGetImageMemoryRequirements2KHR</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">vkGetPhysicalDeviceMemoryProperties</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">vkGetPhysicalDeviceProperties</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">vkGetPhysicalDeviceMemoryProperties</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">vkGetPhysicalDeviceProperties</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1">vkInvalidateMappedMemoryRanges</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">vkMapMemory</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
   <tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9">vkUnmapMemory</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
 </table></div><!-- contents -->
diff --git a/docs/html/struct_vma_vulkan_functions.html b/docs/html/struct_vma_vulkan_functions.html
index 0031942..5e49e4d 100644
--- a/docs/html/struct_vma_vulkan_functions.html
+++ b/docs/html/struct_vma_vulkan_functions.html
@@ -85,6 +85,10 @@
 <tr class="separator:ab5c1f38dea3a2cf00dc9eb4f57218c49"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:acc798589736f0becb317fc2196c1d8b9"><td class="memItemLeft" align="right" valign="top">PFN_vkUnmapMemory&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9">vkUnmapMemory</a></td></tr>
 <tr class="separator:acc798589736f0becb317fc2196c1d8b9"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a33c322f4c4ad2810f8a9c97a277572f9"><td class="memItemLeft" align="right" valign="top">PFN_vkFlushMappedMemoryRanges&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9">vkFlushMappedMemoryRanges</a></td></tr>
+<tr class="separator:a33c322f4c4ad2810f8a9c97a277572f9"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a5c1093bc32386a8060c37c9f282078a1"><td class="memItemLeft" align="right" valign="top">PFN_vkInvalidateMappedMemoryRanges&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1">vkInvalidateMappedMemoryRanges</a></td></tr>
+<tr class="separator:a5c1093bc32386a8060c37c9f282078a1"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a94fc4f3a605d9880bb3c0ba2c2fc80b2"><td class="memItemLeft" align="right" valign="top">PFN_vkBindBufferMemory&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2">vkBindBufferMemory</a></td></tr>
 <tr class="separator:a94fc4f3a605d9880bb3c0ba2c2fc80b2"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a1338d96a128a5ade648b8d934907c637"><td class="memItemLeft" align="right" valign="top">PFN_vkBindImageMemory&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637">vkBindImageMemory</a></td></tr>
@@ -101,10 +105,6 @@
 <tr class="separator:a23ebe70be515b9b5010a1d691200e325"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a90b898227039b1dcb3520f6e91f09ffa"><td class="memItemLeft" align="right" valign="top">PFN_vkDestroyImage&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">vkDestroyImage</a></td></tr>
 <tr class="separator:a90b898227039b1dcb3520f6e91f09ffa"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a9d8d1b05d2b1e7e1d9b27f6f585acf9c"><td class="memItemLeft" align="right" valign="top">PFN_vkGetBufferMemoryRequirements2KHR&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">vkGetBufferMemoryRequirements2KHR</a></td></tr>
-<tr class="separator:a9d8d1b05d2b1e7e1d9b27f6f585acf9c"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a9cdcdc1e2b2ea7c571f7d27e30ba6875"><td class="memItemLeft" align="right" valign="top">PFN_vkGetImageMemoryRequirements2KHR&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">vkGetImageMemoryRequirements2KHR</a></td></tr>
-<tr class="separator:a9cdcdc1e2b2ea7c571f7d27e30ba6875"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><p>Pointers to some Vulkan functions - a subset used by the library. </p>
@@ -208,6 +208,20 @@
 
 </div>
 </div>
+<a id="a33c322f4c4ad2810f8a9c97a277572f9"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a33c322f4c4ad2810f8a9c97a277572f9">&#9670;&nbsp;</a></span>vkFlushMappedMemoryRanges</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">PFN_vkFlushMappedMemoryRanges VmaVulkanFunctions::vkFlushMappedMemoryRanges</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+</div>
+</div>
 <a id="a4c658701778564d62034255b5dda91b4"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a4c658701778564d62034255b5dda91b4">&#9670;&nbsp;</a></span>vkFreeMemory</h2>
 
@@ -236,20 +250,6 @@
 
 </div>
 </div>
-<a id="a9d8d1b05d2b1e7e1d9b27f6f585acf9c"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">&#9670;&nbsp;</a></span>vkGetBufferMemoryRequirements2KHR</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">PFN_vkGetBufferMemoryRequirements2KHR VmaVulkanFunctions::vkGetBufferMemoryRequirements2KHR</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
 <a id="a475f6f49f8debe4d10800592606d53f4"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a475f6f49f8debe4d10800592606d53f4">&#9670;&nbsp;</a></span>vkGetImageMemoryRequirements</h2>
 
@@ -264,20 +264,6 @@
 
 </div>
 </div>
-<a id="a9cdcdc1e2b2ea7c571f7d27e30ba6875"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a9cdcdc1e2b2ea7c571f7d27e30ba6875">&#9670;&nbsp;</a></span>vkGetImageMemoryRequirements2KHR</h2>
-
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">PFN_vkGetImageMemoryRequirements2KHR VmaVulkanFunctions::vkGetImageMemoryRequirements2KHR</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-</div>
-</div>
 <a id="a60d25c33bba06bb8592e6875cbaa9830"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a60d25c33bba06bb8592e6875cbaa9830">&#9670;&nbsp;</a></span>vkGetPhysicalDeviceMemoryProperties</h2>
 
@@ -306,6 +292,20 @@
 
 </div>
 </div>
+<a id="a5c1093bc32386a8060c37c9f282078a1"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a5c1093bc32386a8060c37c9f282078a1">&#9670;&nbsp;</a></span>vkInvalidateMappedMemoryRanges</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">PFN_vkInvalidateMappedMemoryRanges VmaVulkanFunctions::vkInvalidateMappedMemoryRanges</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+</div>
+</div>
 <a id="ab5c1f38dea3a2cf00dc9eb4f57218c49"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#ab5c1f38dea3a2cf00dc9eb4f57218c49">&#9670;&nbsp;</a></span>vkMapMemory</h2>
 
diff --git a/docs/html/thread_safety.html b/docs/html/thread_safety.html
deleted file mode 100644
index 339e09d..0000000
--- a/docs/html/thread_safety.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: Thread safety</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div id="nav-path" class="navpath">
-  <ul>
-<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
-</div>
-</div><!-- top -->
-<div class="header">
-  <div class="headertitle">
-<div class="title">Thread safety </div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="textblock"><ul>
-<li>The library has no global state, so separate <code>VmaAllocator</code> objects can be used independently. There should be no need to create multiple such objects though - one per <code>VkDevice</code> is enough.</li>
-<li>By default, all calls to functions that take <code>VmaAllocator</code> as first parameter are safe to call from multiple threads simultaneously because they are synchronized internally when needed.</li>
-<li>When the allocator is created with <a class="el" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d" title="Allocator and all objects created from it will not be synchronized internally, so you must guarantee ...">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a> flag, calls to functions that take such <code>VmaAllocator</code> object must be synchronized externally.</li>
-<li>Access to a <code>VmaAllocation</code> object must be externally synchronized. For example, you must not call <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation and atomically marks it as used in current fra...">vmaGetAllocationInfo()</a> and <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> from different threads at the same time if you pass the same <code>VmaAllocation</code> object to these functions. </li>
-</ul>
-</div></div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/usage_patterns.html b/docs/html/usage_patterns.html
index 9b9f459..897dca1 100644
--- a/docs/html/usage_patterns.html
+++ b/docs/html/usage_patterns.html
@@ -66,7 +66,8 @@
 <div class="title">Recommended usage patterns </div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="textblock"><h1><a class="anchor" id="usage_patterns_simple"></a>
+<div class="textblock"><p>See also slides from talk: <a href="https://www.gdcvault.com/play/1025458/Advanced-Graphics-Techniques-Tutorial-New">Sawicki, Adam. Advanced Graphics Techniques Tutorial: Memory management in Vulkan and DX12. Game Developers Conference, 2018</a></p>
+<h1><a class="anchor" id="usage_patterns_simple"></a>
 Simple patterns</h1>
 <h2><a class="anchor" id="usage_patterns_simple_render_targets"></a>
 Render targets</h2>
@@ -83,7 +84,7 @@
 Dynamic resources</h2>
 <p><b>When:</b> Any resources that change frequently (aka "dynamic"), e.g. every frame or every draw call, written on CPU, read on GPU.</p>
 <p><b>What to do:</b> Create them using <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a>. You can map it and write to it directly on CPU, as well as read from it on GPU.</p>
-<p>This is a more complex situation. Different solutions are possible, and the best one depends on specific GPU type, but you can use this simple approach for the start. Prefer to write to such resource sequentially (e.g. using <code>memcpy</code>). Don't perform random access or any reads from it, as it may be very slow.</p>
+<p>This is a more complex situation. Different solutions are possible, and the best one depends on specific GPU type, but you can use this simple approach for the start. Prefer to write to such resource sequentially (e.g. using <code>memcpy</code>). Don't perform random access or any reads from it on CPU, as it may be very slow.</p>
 <h2><a class="anchor" id="usage_patterns_readback"></a>
 Readback</h2>
 <p><b>When:</b> Resources that contain data written by GPU that you want to read back on CPU, e.g. results of some computations.</p>
@@ -92,7 +93,7 @@
 Advanced patterns</h1>
 <h2><a class="anchor" id="usage_patterns_integrated_graphics"></a>
 Detecting integrated graphics</h2>
-<p>You can support integrated graphics (like Intel HD Graphics, AMD APU) better by detecting it in Vulkan. To do it, call <code>vkGetPhysicalDeviceProperties()</code>, inspect <code>VkPhysicalDeviceProperties::deviceType</code> and look for <code>VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU</code>. When you find it, you can assume that memory is unified and all memory types are equally fast to access from GPU, regardless of <code>VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT</code>.</p>
+<p>You can support integrated graphics (like Intel HD Graphics, AMD APU) better by detecting it in Vulkan. To do it, call <code>vkGetPhysicalDeviceProperties()</code>, inspect <code>VkPhysicalDeviceProperties::deviceType</code> and look for <code>VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU</code>. When you find it, you can assume that memory is unified and all memory types are comparably fast to access from GPU, regardless of <code>VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT</code>.</p>
 <p>You can then sum up sizes of all available memory heaps and treat them as useful for your GPU resources, instead of only <code>DEVICE_LOCAL</code> ones. You can also prefer to create your resources in memory types that are <code>HOST_VISIBLE</code> to map them directly instead of submitting explicit transfer (see below).</p>
 <h2><a class="anchor" id="usage_patterns_direct_vs_transfer"></a>
 Direct access versus transfer</h2>
@@ -104,7 +105,7 @@
 </ol>
 <p>Which solution is the most efficient depends on your resource and especially on the GPU. It is best to measure it and then make the decision. Some general recommendations:</p>
 <ul>
-<li>On integrated graphics use (2) or (3) to avoid unnecesary time and memory overhead related to using a second copy.</li>
+<li>On integrated graphics use (2) or (3) to avoid unnecesary time and memory overhead related to using a second copy and making transfer.</li>
 <li>For small resources (e.g. constant buffers) use (2). Discrete AMD cards have special 256 MiB pool of video memory that is directly mappable. Even if the resource ends up in system memory, its data may be cached on GPU after first fetch over PCIe bus.</li>
 <li>For larger resources (e.g. textures), decide between (1) and (2). You may want to differentiate NVIDIA and AMD, e.g. by looking for memory type that is both <code>DEVICE_LOCAL</code> and <code>HOST_VISIBLE</code>. When you find it, use (2), otherwise use (1).</li>
 </ul>
@@ -114,7 +115,7 @@
 <li>Create just single copy using <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a>, write to it directly on GPU, map it and read it on CPU.</li>
 </ol>
 <p>You should take some measurements to decide which option is faster in case of your specific resource.</p>
-<p>If you don't want to specialize your code for specific types of GPUs, yon can still make an simple optimization for cases when your resource ends up in mappable memory to use it directly in this case instead of creating CPU-side staging copy. For details see <a class="el" href="memory_mapping.html#memory_mapping_finding_if_memory_mappable">Finding out if memory is mappable</a>. </p>
+<p>If you don't want to specialize your code for specific types of GPUs, you can still make an simple optimization for cases when your resource ends up in mappable memory to use it directly in this case instead of creating CPU-side staging copy. For details see <a class="el" href="memory_mapping.html#memory_mapping_finding_if_memory_mappable">Finding out if memory is mappable</a>. </p>
 </div></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/html/user_guide.html b/docs/html/user_guide.html
deleted file mode 100644
index 1fbfab0..0000000
--- a/docs/html/user_guide.html
+++ /dev/null
@@ -1,254 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.13"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<title>Vulkan Memory Allocator: User guide</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">Vulkan Memory Allocator
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.13 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-<script type="text/javascript" src="menudata.js"></script>
-<script type="text/javascript" src="menu.js"></script>
-<script type="text/javascript">
-$(function() {
-  initMenu('',true,false,'search.php','Search');
-  $(document).ready(function() { init_search(); });
-});
-</script>
-<div id="main-nav"></div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-</div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div id="nav-path" class="navpath">
-  <ul>
-<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
-</div>
-</div><!-- top -->
-<div class="header">
-  <div class="headertitle">
-<div class="title">User guide </div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="textblock"><h1><a class="anchor" id="quick_start"></a>
-Quick start</h1>
-<p>In your project code:</p>
-<ol type="1">
-<li>Include "vk_mem_alloc.h" file wherever you want to use the library.</li>
-<li>In exacly one C++ file define following macro before include to build library implementation.</li>
-</ol>
-<pre class="fragment">#define VMA_IMPLEMENTATION
-#include "vk_mem_alloc.h"
-</pre><p>At program startup:</p>
-<ol type="1">
-<li>Initialize Vulkan to have <code>VkPhysicalDevice</code> and <code>VkDevice</code> object.</li>
-<li>Fill <a class="el" href="struct_vma_allocator_create_info.html" title="Description of a Allocator to be created. ">VmaAllocatorCreateInfo</a> structure and create <code>VmaAllocator</code> object by calling <a class="el" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb" title="Creates Allocator object. ">vmaCreateAllocator()</a>.</li>
-</ol>
-<pre class="fragment">VmaAllocatorCreateInfo allocatorInfo = {};
-allocatorInfo.physicalDevice = physicalDevice;
-allocatorInfo.device = device;
-
-VmaAllocator allocator;
-vmaCreateAllocator(&amp;allocatorInfo, &amp;allocator);
-</pre><p>When you want to create a buffer or image:</p>
-<ol type="1">
-<li>Fill <code>VkBufferCreateInfo</code> / <code>VkImageCreateInfo</code> structure.</li>
-<li>Fill <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> structure.</li>
-<li>Call <a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a> / <a class="el" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a> to get <code>VkBuffer</code>/<code>VkImage</code> with memory already allocated and bound to it.</li>
-</ol>
-<pre class="fragment">VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
-bufferInfo.size = 65536;
-bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-
-VmaAllocationCreateInfo allocInfo = {};
-allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
-
-VkBuffer buffer;
-VmaAllocation allocation;
-vmaCreateBuffer(allocator, &amp;bufferInfo, &amp;allocInfo, &amp;buffer, &amp;allocation, nullptr);
-</pre><p>Don't forget to destroy your objects when no longer needed:</p>
-<pre class="fragment">vmaDestroyBuffer(allocator, buffer, allocation);
-vmaDestroyAllocator(allocator);
-</pre><h1><a class="anchor" id="persistently_mapped_memory"></a>
-Persistently mapped memory</h1>
-<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 <a class="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. <a class="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>
-<pre class="fragment">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
-bufCreateInfo.size = 1024;
-bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
-
-VmaAllocationCreateInfo allocCreateInfo = {};
-allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
-allocCreateInfo.flags = VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT;
-
-VkBuffer buf;
-VmaAllocation alloc;
-VmaAllocationInfo allocInfo;
-vmaCreateBuffer(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);
-
-.// Buffer is immediately mapped. You can access its memory.
-memcpy(allocInfo.pMappedData, myData, 1024);
-</pre><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>
-<pre class="fragment">VkMemoryPropertyFlags memFlags;
-vmaGetMemoryTypeProperties(allocator, allocInfo.memoryType, &amp;memFlags);
-if((memFlags &amp; VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
-{
-    VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
-    memRange.memory = allocInfo.deviceMemory;
-    memRange.offset = allocInfo.offset;
-    memRange.size   = allocInfo.size;
-    vkFlushMappedMemoryRanges(device, 1, &amp;memRange);
-}
-</pre><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 <a class="el" href="vk__mem__alloc_8h.html#a26b87244491c1fe77f11fe9ab5779c27" title="Unmaps persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaUnmapPersistentlyMappedMemory()</a>, <a class="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>
-<h1><a class="anchor" id="custom_memory_pools"></a>
-Custom memory pools</h1>
-<p>The library automatically creates and manages default memory pool for each memory type available on the device. A pool contains a number of <code>VkDeviceMemory</code> blocks. You can create custom pool and allocate memory out of it. It can be useful if you want to:</p>
-<ul>
-<li>Keep certain kind of allocations separate from others.</li>
-<li>Enforce particular size of Vulkan memory blocks.</li>
-<li>Limit maximum amount of Vulkan memory allocated for that pool.</li>
-</ul>
-<p>To use custom memory pools:</p>
-<ol type="1">
-<li>Fill <a class="el" href="struct_vma_pool_create_info.html" title="Describes parameter of created VmaPool. ">VmaPoolCreateInfo</a> structure.</li>
-<li>Call <a class="el" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50" title="Allocates Vulkan device memory and creates VmaPool object. ">vmaCreatePool()</a> to obtain <code>VmaPool</code> handle.</li>
-<li>When making an allocation, set <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> to this handle. You don't need to specify any other parameters of this structure, like usage.</li>
-</ol>
-<p>Example:</p>
-<pre class="fragment">.// Create a pool that could have at most 2 blocks, 128 MB each.
-VmaPoolCreateInfo poolCreateInfo = {};
-poolCreateInfo.memoryTypeIndex = ...
-poolCreateInfo.blockSize = 128ull * 1024 * 1024;
-poolCreateInfo.maxBlockCount = 2;
-
-VmaPool pool;
-vmaCreatePool(allocator, &amp;poolCreateInfo, &amp;pool);
-
-.// Allocate a buffer out of it.
-VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
-bufCreateInfo.size = 1024;
-bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-
-VmaAllocationCreateInfo allocCreateInfo = {};
-allocCreateInfo.pool = pool;
-
-VkBuffer buf;
-VmaAllocation alloc;
-VmaAllocationInfo allocInfo;
-vmaCreateBuffer(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);
-</pre><p>You have to free all allocations made from this pool before destroying it.</p>
-<pre class="fragment">vmaDestroyBuffer(allocator, buf, alloc);
-vmaDestroyPool(allocator, pool);
-</pre><h1><a class="anchor" id="defragmentation"></a>
-Defragmentation</h1>
-<p>Interleaved allocations and deallocations of many objects of varying size can cause fragmentation, which can lead to a situation where the library is unable to find a continuous range of free memory for a new allocation despite there is enough free space, just scattered across many small free ranges between existing allocations.</p>
-<p>To mitigate this problem, you can use <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>. Given set of allocations, this function can move them to compact used memory, ensure more continuous free space and possibly also free some <code>VkDeviceMemory</code>. It can work only on allocations made from memory type that is <code>HOST_VISIBLE</code>. Allocations are modified to point to the new <code>VkDeviceMemory</code> and offset. Data in this memory is also <code>memmove</code>-ed to the new place. However, if you have images or buffers bound to these allocations (and you certainly do), you need to destroy, recreate, and bind them to the new place in memory.</p>
-<p>For further details and example code, see documentation of function <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>.</p>
-<h1><a class="anchor" id="lost_allocations"></a>
-Lost allocations</h1>
-<p>If your game oversubscribes video memory, if may work OK in previous-generation graphics APIs (DirectX 9, 10, 11, OpenGL) because resources are automatically paged to system RAM. In Vulkan you can't do it because when you run out of memory, an allocation just fails. If you have more data (e.g. textures) that can fit into VRAM and you don't need it all at once, you may want to upload them to GPU on demand and "push out" ones that are not used for a long time to make room for the new ones, effectively using VRAM (or a cartain memory pool) as a form of cache. Vulkan Memory Allocator can help you with that by supporting a concept of "lost allocations".</p>
-<p>To create an allocation that can become lost, include <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> flag in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. Before using a buffer or image bound to such allocation in every new frame, you need to query it if it's not lost. To check it: call <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> and see if <a class="el" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67" title="Handle to Vulkan memory object. ">VmaAllocationInfo::deviceMemory</a> is not <code>VK_NULL_HANDLE</code>. If the allocation is lost, you should not use it or buffer/image bound to it. You mustn't forget to destroy this allocation and this buffer/image.</p>
-<p>To create an allocation that can make some other allocations lost to make room for it, use <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag. You will usually use both flags <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> and <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> at the same time.</p>
-<p>Warning! Current implementation uses quite naive, brute force algorithm, which can make allocation calls that use <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag quite slow. A new, more optimal algorithm and data structure to speed this up is planned for the future.</p>
-<p><b>When interleaving creation of new allocations with usage of existing ones, how do you make sure that an allocation won't become lost while it's used in the current frame?</b></p>
-<p>It is ensured because <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> not only returns allocation parameters and checks whether it's not lost, but when it's not, it also atomically marks it as used in the current frame, which makes it impossible to become lost in that frame. It uses lockless algorithm, so it works fast and doesn't involve locking any internal mutex.</p>
-<p><b>What if my allocation may still be in use by the GPU when it's rendering a previous frame while I already submit new frame on the CPU?</b></p>
-<p>You can make sure that allocations "touched" by <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> will not become lost for a number of additional frames back from the current one by specifying this number as <a class="el" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaAllocatorCreateInfo::frameInUseCount</a> (for default memory pool) and <a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> (for custom pool).</p>
-<p><b>How do you inform the library when new frame starts?</b></p>
-<p>You need to call function <a class="el" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236" title="Sets index of the current frame. ">vmaSetCurrentFrameIndex()</a>.</p>
-<p>Example code:</p>
-<pre class="fragment">struct MyBuffer
-{
-    VkBuffer m_Buf = nullptr;
-    VmaAllocation m_Alloc = nullptr;
-
-    .// Called when the buffer is really needed in the current frame.
-    void EnsureBuffer();
-};
-
-void MyBuffer::EnsureBuffer()
-{
-    .// Buffer has been created.
-    if(m_Buf != VK_NULL_HANDLE)
-    {
-        .// Check if its allocation is not lost + mark it as used in current frame.
-        VmaAllocationInfo allocInfo;
-        vmaGetAllocationInfo(allocator, m_Alloc, &amp;allocInfo);
-        if(allocInfo.deviceMemory != VK_NULL_HANDLE)
-        {
-            .// It's all OK - safe to use m_Buf.
-            return;
-        }
-    }
-
-    .// Buffer not yet exists or lost - destroy and recreate it.
-
-    vmaDestroyBuffer(allocator, m_Buf, m_Alloc);
-
-    VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
-    bufCreateInfo.size = 1024;
-    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_CAN_BECOME_LOST_BIT |
-        VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT;
-
-    vmaCreateBuffer(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;m_Buf, &amp;m_Alloc, nullptr);
-}
-</pre><p>When using lost allocations, you may see some Vulkan validation layer warnings about overlapping regions of memory bound to different kinds of buffers and images. This is still valid as long as you implement proper handling of lost allocations (like in the example above) and don't use them.</p>
-<p>The library uses following algorithm for allocation, in order:</p>
-<ol type="1">
-<li>Try to find free range of memory in existing blocks.</li>
-<li>If failed, try to create a new block of <code>VkDeviceMemory</code>, with preferred block size.</li>
-<li>If failed, try to create such block with size/2 and size/4.</li>
-<li>If failed and <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag was specified, try to find space in existing blocks, possilby making some other allocations lost.</li>
-<li>If failed, try to allocate separate <code>VkDeviceMemory</code> for this allocation, just like when you use <code>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</code>.</li>
-<li>If failed, choose other memory type that meets the requirements specified in <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> and go to point 1.</li>
-<li>If failed, return <code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code>. </li>
-</ol>
-</div></div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.13
-</small></address>
-</body>
-</html>
diff --git a/docs/html/vk__mem__alloc_8h.html b/docs/html/vk__mem__alloc_8h.html
index 6fa4720..49c5731 100644
--- a/docs/html/vk__mem__alloc_8h.html
+++ b/docs/html/vk__mem__alloc_8h.html
@@ -80,6 +80,9 @@
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td></tr>
 <tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pointers to some Vulkan functions - a subset used by the library.  <a href="struct_vma_vulkan_functions.html#details">More...</a><br /></td></tr>
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Parameters for recording calls to VMA functions. To be used in <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee" title="Parameters for recording of VMA calls. Can be null. ">VmaAllocatorCreateInfo::pRecordSettings</a>.  <a href="struct_vma_record_settings.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td></tr>
 <tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Description of a Allocator to be created.  <a href="struct_vma_allocator_create_info.html#details">More...</a><br /></td></tr>
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
@@ -109,6 +112,10 @@
 </table><table class="memberdecls">
 <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
 Macros</h2></td></tr>
+<tr class="memitem:af7b860e63b96d11e44ae8587ba06bbf4"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4">VMA_DEDICATED_ALLOCATION</a>&#160;&#160;&#160;0</td></tr>
+<tr class="separator:af7b860e63b96d11e44ae8587ba06bbf4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a1f0c126759fc96ccb6e2d23c101d770c"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c">VMA_RECORDING_ENABLED</a>&#160;&#160;&#160;0</td></tr>
+<tr class="separator:a1f0c126759fc96ccb6e2d23c101d770c"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ae25f0d55fd91cb166f002b63244800e1"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1">VMA_STATS_STRING_ENABLED</a>&#160;&#160;&#160;1</td></tr>
 <tr class="separator:ae25f0d55fd91cb166f002b63244800e1"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table><table class="memberdecls">
@@ -131,6 +138,14 @@
 <tr class="memitem:a97064a1a271b0061ebfc3a079862d0c5"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a97064a1a271b0061ebfc3a079862d0c5">VmaVulkanFunctions</a></td></tr>
 <tr class="memdesc:a97064a1a271b0061ebfc3a079862d0c5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pointers to some Vulkan functions - a subset used by the library.  <a href="#a97064a1a271b0061ebfc3a079862d0c5">More...</a><br /></td></tr>
 <tr class="separator:a97064a1a271b0061ebfc3a079862d0c5"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ade20b626a6635ce1bf30ea53dea774e4"><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4">VmaRecordFlagBits</a></td></tr>
+<tr class="memdesc:ade20b626a6635ce1bf30ea53dea774e4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be used in <a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a" title="Flags for recording. Use VmaRecordFlagBits enum. ">VmaRecordSettings::flags</a>.  <a href="#ade20b626a6635ce1bf30ea53dea774e4">More...</a><br /></td></tr>
+<tr class="separator:ade20b626a6635ce1bf30ea53dea774e4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:af3929a1a4547c592fc0b0e55ef452828"><td class="memItemLeft" align="right" valign="top">typedef VkFlags&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">VmaRecordFlags</a></td></tr>
+<tr class="separator:af3929a1a4547c592fc0b0e55ef452828"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a0ab61e87ff6365f1d59915eadc37a9f0"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a0ab61e87ff6365f1d59915eadc37a9f0">VmaRecordSettings</a></td></tr>
+<tr class="memdesc:a0ab61e87ff6365f1d59915eadc37a9f0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Parameters for recording calls to VMA functions. To be used in <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee" title="Parameters for recording of VMA calls. Can be null. ">VmaAllocatorCreateInfo::pRecordSettings</a>.  <a href="#a0ab61e87ff6365f1d59915eadc37a9f0">More...</a><br /></td></tr>
+<tr class="separator:a0ab61e87ff6365f1d59915eadc37a9f0"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ae0f6d1d733dded220d28134da46b4283"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#ae0f6d1d733dded220d28134da46b4283">VmaAllocatorCreateInfo</a></td></tr>
 <tr class="memdesc:ae0f6d1d733dded220d28134da46b4283"><td class="mdescLeft">&#160;</td><td class="mdescRight">Description of a Allocator to be created.  <a href="#ae0f6d1d733dded220d28134da46b4283">More...</a><br /></td></tr>
 <tr class="separator:ae0f6d1d733dded220d28134da46b4283"><td class="memSeparator" colspan="2">&#160;</td></tr>
@@ -178,6 +193,11 @@
  }<tr class="memdesc:a4f87c9100d154a65a4ad495f7763cf7c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags for created <a class="el" href="struct_vma_allocator.html" title="Represents main object of this library initialized. ">VmaAllocator</a>.  <a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c">More...</a><br /></td></tr>
 </td></tr>
 <tr class="separator:a4f87c9100d154a65a4ad495f7763cf7c"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a4dd2c44642312a147a4e93373a6e64d2"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a> { <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7">VMA_RECORD_FLUSH_AFTER_CALL_BIT</a> = 0x00000001, 
+<a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e">VMA_RECORD_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
+ }<tr class="memdesc:a4dd2c44642312a147a4e93373a6e64d2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be used in <a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a" title="Flags for recording. Use VmaRecordFlagBits enum. ">VmaRecordSettings::flags</a>.  <a href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">More...</a><br /></td></tr>
+</td></tr>
+<tr class="separator:a4dd2c44642312a147a4e93373a6e64d2"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:aa5846affa1e9da3800e3e78fae2305cc"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a> { <br />
 &#160;&#160;<a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a> = 0, 
 <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a> = 1, 
@@ -197,12 +217,14 @@
 <br />
 &#160;&#160;<a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> = 0x00000010, 
 <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a> = 0x00000020, 
+<a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a> = 0x00000040, 
 <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
 <br />
  }<tr class="memdesc:ad9889c10c798b040d59c92f257cae597"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be passed as <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>.  <a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">More...</a><br /></td></tr>
 </td></tr>
 <tr class="separator:ad9889c10c798b040d59c92f257cae597"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a9a7c45f9c863695d98c83fa5ac940fe7"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a> { <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a> = 0x00000002, 
+<a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a> = 0x00000004, 
 <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec">VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
  }<tr class="memdesc:a9a7c45f9c863695d98c83fa5ac940fe7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags to be passed as <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446" title="Use combination of VmaPoolCreateFlagBits. ">VmaPoolCreateInfo::flags</a>.  <a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">More...</a><br /></td></tr>
 </td></tr>
@@ -255,6 +277,9 @@
 <tr class="memitem:a736bd6cbda886f36c891727e73bd4024"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vmaMakePoolAllocationsLost</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_pool.html">VmaPool</a> pool, size_t *pLostAllocationCount)</td></tr>
 <tr class="memdesc:a736bd6cbda886f36c891727e73bd4024"><td class="mdescLeft">&#160;</td><td class="mdescRight">Marks all allocations in given pool as lost if they are not used in current frame or <a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> back from now.  <a href="#a736bd6cbda886f36c891727e73bd4024">More...</a><br /></td></tr>
 <tr class="separator:a736bd6cbda886f36c891727e73bd4024"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ad535935619c7a549bf837e1bb0068f89"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89">vmaCheckPoolCorruption</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_pool.html">VmaPool</a> pool)</td></tr>
+<tr class="memdesc:ad535935619c7a549bf837e1bb0068f89"><td class="mdescLeft">&#160;</td><td class="mdescRight">Checks magic number in margins around all allocations in given memory pool in search for corruptions.  <a href="#ad535935619c7a549bf837e1bb0068f89">More...</a><br /></td></tr>
+<tr class="separator:ad535935619c7a549bf837e1bb0068f89"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:abf28077dbf82d0908b8acbe8ee8dd9b8"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, const VkMemoryRequirements *pVkMemoryRequirements, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
 <tr class="memdesc:abf28077dbf82d0908b8acbe8ee8dd9b8"><td class="mdescLeft">&#160;</td><td class="mdescRight">General purpose memory allocation.  <a href="#abf28077dbf82d0908b8acbe8ee8dd9b8">More...</a><br /></td></tr>
 <tr class="separator:abf28077dbf82d0908b8acbe8ee8dd9b8"><td class="memSeparator" colspan="2">&#160;</td></tr>
@@ -284,6 +309,15 @@
 <tr class="memitem:a9bc268595cb33f6ec4d519cfce81ff45"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</td></tr>
 <tr class="memdesc:a9bc268595cb33f6ec4d519cfce81ff45"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unmaps memory represented by given allocation, mapped previously using <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>.  <a href="#a9bc268595cb33f6ec4d519cfce81ff45">More...</a><br /></td></tr>
 <tr class="separator:a9bc268595cb33f6ec4d519cfce81ff45"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:abc34ee6f021f459aff885f3758c435de"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de">vmaFlushAllocation</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size)</td></tr>
+<tr class="memdesc:abc34ee6f021f459aff885f3758c435de"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flushes memory of given allocation.  <a href="#abc34ee6f021f459aff885f3758c435de">More...</a><br /></td></tr>
+<tr class="separator:abc34ee6f021f459aff885f3758c435de"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a0d0eb0c1102268fa9a476d12ecbe4006"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006">vmaInvalidateAllocation</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size)</td></tr>
+<tr class="memdesc:a0d0eb0c1102268fa9a476d12ecbe4006"><td class="mdescLeft">&#160;</td><td class="mdescRight">Invalidates memory of given allocation.  <a href="#a0d0eb0c1102268fa9a476d12ecbe4006">More...</a><br /></td></tr>
+<tr class="separator:a0d0eb0c1102268fa9a476d12ecbe4006"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a49329a7f030dafcf82f7b73334c22e98"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98">vmaCheckCorruption</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, uint32_t memoryTypeBits)</td></tr>
+<tr class="memdesc:a49329a7f030dafcf82f7b73334c22e98"><td class="mdescLeft">&#160;</td><td class="mdescRight">Checks magic number in margins around all allocations in given memory types (in both default and custom pools) in search for corruptions.  <a href="#a49329a7f030dafcf82f7b73334c22e98">More...</a><br /></td></tr>
+<tr class="separator:a49329a7f030dafcf82f7b73334c22e98"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a6aced90fcc7b39882b6654a740a0b9bb"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocations, size_t allocationCount, VkBool32 *pAllocationsChanged, const <a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *pDefragmentationInfo, <a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a> *pDefragmentationStats)</td></tr>
 <tr class="memdesc:a6aced90fcc7b39882b6654a740a0b9bb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compacts memory by moving allocations.  <a href="#a6aced90fcc7b39882b6654a740a0b9bb">More...</a><br /></td></tr>
 <tr class="separator:a6aced90fcc7b39882b6654a740a0b9bb"><td class="memSeparator" colspan="2">&#160;</td></tr>
@@ -306,6 +340,34 @@
 <tr class="separator:ae50d2cb3b4a3bfd4dd40987234e50e7e"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <h2 class="groupheader">Macro Definition Documentation</h2>
+<a id="af7b860e63b96d11e44ae8587ba06bbf4"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#af7b860e63b96d11e44ae8587ba06bbf4">&#9670;&nbsp;</a></span>VMA_DEDICATED_ALLOCATION</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">#define VMA_DEDICATED_ALLOCATION&#160;&#160;&#160;0</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="a1f0c126759fc96ccb6e2d23c101d770c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a1f0c126759fc96ccb6e2d23c101d770c">&#9670;&nbsp;</a></span>VMA_RECORDING_ENABLED</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">#define VMA_RECORDING_ENABLED&#160;&#160;&#160;0</td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+</div>
+</div>
 <a id="ae25f0d55fd91cb166f002b63244800e1"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#ae25f0d55fd91cb166f002b63244800e1">&#9670;&nbsp;</a></span>VMA_STATS_STRING_ENABLED</h2>
 
@@ -585,6 +647,52 @@
 
 </div>
 </div>
+<a id="ade20b626a6635ce1bf30ea53dea774e4"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ade20b626a6635ce1bf30ea53dea774e4">&#9670;&nbsp;</a></span>VmaRecordFlagBits</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">typedef enum <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a>  <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Flags to be used in <a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a" title="Flags for recording. Use VmaRecordFlagBits enum. ">VmaRecordSettings::flags</a>. </p>
+
+</div>
+</div>
+<a id="af3929a1a4547c592fc0b0e55ef452828"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#af3929a1a4547c592fc0b0e55ef452828">&#9670;&nbsp;</a></span>VmaRecordFlags</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">typedef VkFlags <a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">VmaRecordFlags</a></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="a0ab61e87ff6365f1d59915eadc37a9f0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a0ab61e87ff6365f1d59915eadc37a9f0">&#9670;&nbsp;</a></span>VmaRecordSettings</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">typedef struct <a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a>  <a class="el" href="struct_vma_record_settings.html">VmaRecordSettings</a></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Parameters for recording calls to VMA functions. To be used in <a class="el" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee" title="Parameters for recording of VMA calls. Can be null. ">VmaAllocatorCreateInfo::pRecordSettings</a>. </p>
+
+</div>
+</div>
 <a id="a810b009a788ee8aac72a25b42ffbe31c"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a810b009a788ee8aac72a25b42ffbe31c">&#9670;&nbsp;</a></span>VmaStatInfo</h2>
 
@@ -674,6 +782,9 @@
 </td></tr>
 <tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520"></a>VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT&#160;</td><td class="fielddoc"><p>Set this flag to treat <a class="el" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19" title="Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...">VmaAllocationCreateInfo::pUserData</a> as pointer to a null-terminated string. Instead of copying pointer value, a local copy of the string is made and stored in allocation's <code>pUserData</code>. The string is automatically freed together with the allocation. It is also used in <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>. </p>
 </td></tr>
+<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df"></a>VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT&#160;</td><td class="fielddoc"><p>Allocation will be created from upper stack in a double stack pool.</p>
+<p>This flag is only allowed for custom pools created with <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726" title="Enables alternative, linear allocation algorithm in this pool. ">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a> flag. </p>
+</td></tr>
 <tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882"></a>VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
 </table>
 
@@ -731,14 +842,14 @@
 <p>Usage:</p>
 <ul>
 <li>Resources written and read by device, e.g. images used as attachments.</li>
-<li>Resources transferred from host once (immutable) or infrequently and read by device multiple times, e.g. textures to be sampled, vertex buffers, uniform (constant) buffers, and majority of other types of resources used by device.</li>
+<li>Resources transferred from host once (immutable) or infrequently and read by device multiple times, e.g. textures to be sampled, vertex buffers, uniform (constant) buffers, and majority of other types of resources used on GPU.</li>
 </ul>
 <p>Allocation may still end up in <code>HOST_VISIBLE</code> memory on some implementations. In such case, you are free to map it. You can use <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> with this usage type. </p>
 </td></tr>
-<tr><td class="fieldname"><a id="aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"></a>VMA_MEMORY_USAGE_CPU_ONLY&#160;</td><td class="fielddoc"><p>Memory will be mappable on host. It usually means CPU (system) memory. Resources created in this pool may still be accessible to the device, but access to them can be slower. Guarantees to be <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. CPU read may be uncached. It is roughly equivalent of <code>D3D12_HEAP_TYPE_UPLOAD</code>.</p>
+<tr><td class="fieldname"><a id="aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"></a>VMA_MEMORY_USAGE_CPU_ONLY&#160;</td><td class="fielddoc"><p>Memory will be mappable on host. It usually means CPU (system) memory. Guarantees to be <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. CPU access is typically uncached. Writes may be write-combined. Resources created in this pool may still be accessible to the device, but access to them can be slow. It is roughly equivalent of <code>D3D12_HEAP_TYPE_UPLOAD</code>.</p>
 <p>Usage: Staging copy of resources used as transfer source. </p>
 </td></tr>
-<tr><td class="fieldname"><a id="aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67"></a>VMA_MEMORY_USAGE_CPU_TO_GPU&#160;</td><td class="fielddoc"><p>Memory that is both mappable on host (guarantees to be <code>HOST_VISIBLE</code>) and preferably fast to access by GPU. CPU reads may be uncached and very slow.</p>
+<tr><td class="fieldname"><a id="aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67"></a>VMA_MEMORY_USAGE_CPU_TO_GPU&#160;</td><td class="fielddoc"><p>Memory that is both mappable on host (guarantees to be <code>HOST_VISIBLE</code>) and preferably fast to access by GPU. CPU access is typically uncached. Writes may be write-combined.</p>
 <p>Usage: Resources written frequently by host (dynamic), read by device. E.g. textures, vertex buffers, uniform buffers updated every frame or every draw call. </p>
 </td></tr>
 <tr><td class="fieldname"><a id="aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27"></a>VMA_MEMORY_USAGE_GPU_TO_CPU&#160;</td><td class="fielddoc"><p>Memory mappable on host (guarantees to be <code>HOST_VISIBLE</code>) and cached. It is roughly equivalent of <code>D3D12_HEAP_TYPE_READBACK</code>.</p>
@@ -768,15 +879,42 @@
 <p>Flags to be passed as <a class="el" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446" title="Use combination of VmaPoolCreateFlagBits. ">VmaPoolCreateInfo::flags</a>. </p>
 <table class="fieldtable">
 <tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2"></a>VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT&#160;</td><td class="fielddoc"><p>Use this flag if you always allocate only buffers and linear images or only optimal images out of this pool and so Buffer-Image Granularity can be ignored. </p>
-<p>This is na optional optimization flag.</p>
+<p>This is an optional optimization flag.</p>
 <p>If you always allocate using <a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>, <a class="el" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a>, <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, then you don't need to use it because allocator knows exact type of your allocations so it can handle Buffer-Image Granularity in the optimal way.</p>
 <p>If you also allocate using <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a> or <a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>, exact type of such allocations is not known, so allocator must be conservative in handling Buffer-Image Granularity, which can lead to suboptimal allocation (wasted memory). In that case, if you can make sure you always allocate only buffers and linear images or only optimal images out of this pool, use this flag to make allocator disregard Buffer-Image Granularity and so make allocations more optimal. </p>
 </td></tr>
+<tr><td class="fieldname"><a id="a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726"></a>VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT&#160;</td><td class="fielddoc"><p>Enables alternative, linear allocation algorithm in this pool. </p>
+<p>Specify this flag to enable linear allocation algorithm, which always creates new allocations after last one and doesn't reuse space from allocations freed in between. It trades memory consumption for simplified algorithm and data structure, which has better performance and uses less memory for metadata.</p>
+<p>By using this flag, you can achieve behavior of free-at-once, stack, ring buffer, and double stack. For details, see documentation chapter <a class="el" href="custom_memory_pools.html#linear_algorithm">Linear allocation algorithm</a>.</p>
+<p>When using this flag, you must specify <a class="el" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c" title="Maximum number of blocks that can be allocated in this pool. Optional. ">VmaPoolCreateInfo::maxBlockCount</a> == 1 (or 0 for default). </p>
+</td></tr>
 <tr><td class="fieldname"><a id="a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec"></a>VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
 </table>
 
 </div>
 </div>
+<a id="a4dd2c44642312a147a4e93373a6e64d2"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a4dd2c44642312a147a4e93373a6e64d2">&#9670;&nbsp;</a></span>VmaRecordFlagBits</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">enum <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Flags to be used in <a class="el" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a" title="Flags for recording. Use VmaRecordFlagBits enum. ">VmaRecordSettings::flags</a>. </p>
+<table class="fieldtable">
+<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7"></a>VMA_RECORD_FLUSH_AFTER_CALL_BIT&#160;</td><td class="fielddoc"><p>Enables flush after recording every function call. </p>
+<p>Enable it if you expect your application to crash, which may leave recording file truncated. It may degrade performance though. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e"></a>VMA_RECORD_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
+</table>
+
+</div>
+</div>
 <h2 class="groupheader">Function Documentation</h2>
 <a id="abf28077dbf82d0908b8acbe8ee8dd9b8"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#abf28077dbf82d0908b8acbe8ee8dd9b8">&#9670;&nbsp;</a></span>vmaAllocateMemory()</h2>
@@ -1085,6 +1223,88 @@
 
 </div>
 </div>
+<a id="a49329a7f030dafcf82f7b73334c22e98"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a49329a7f030dafcf82f7b73334c22e98">&#9670;&nbsp;</a></span>vmaCheckCorruption()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">VkResult vmaCheckCorruption </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;</td>
+          <td class="paramname"><em>allocator</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">uint32_t&#160;</td>
+          <td class="paramname"><em>memoryTypeBits</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Checks magic number in margins around all allocations in given memory types (in both default and custom pools) in search for corruptions. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">memoryTypeBits</td><td>Bit mask, where each bit set means that a memory type with that index should be checked.</td></tr>
+  </table>
+  </dd>
+</dl>
+<p>Corruption detection is enabled only when <code>VMA_DEBUG_DETECT_CORRUPTION</code> macro is defined to nonzero, <code>VMA_DEBUG_MARGIN</code> is defined to nonzero and only for memory types that are <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. For more information, see <a class="el" href="debugging_memory_usage.html#debugging_memory_usage_corruption_detection">Corruption detection</a>.</p>
+<p>Possible return values:</p>
+<ul>
+<li><code>VK_ERROR_FEATURE_NOT_PRESENT</code> - corruption detection is not enabled for any of specified memory types.</li>
+<li><code>VK_SUCCESS</code> - corruption detection has been performed and succeeded.</li>
+<li><code>VK_ERROR_VALIDATION_FAILED_EXT</code> - corruption detection has been performed and found memory corruptions around one of the allocations. <code>VMA_ASSERT</code> is also fired in that case.</li>
+<li>Other value: Error returned by Vulkan, e.g. memory mapping failure. </li>
+</ul>
+
+</div>
+</div>
+<a id="ad535935619c7a549bf837e1bb0068f89"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ad535935619c7a549bf837e1bb0068f89">&#9670;&nbsp;</a></span>vmaCheckPoolCorruption()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">VkResult vmaCheckPoolCorruption </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;</td>
+          <td class="paramname"><em>allocator</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="struct_vma_pool.html">VmaPool</a>&#160;</td>
+          <td class="paramname"><em>pool</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Checks magic number in margins around all allocations in given memory pool in search for corruptions. </p>
+<p>Corruption detection is enabled only when <code>VMA_DEBUG_DETECT_CORRUPTION</code> macro is defined to nonzero, <code>VMA_DEBUG_MARGIN</code> is defined to nonzero and the pool is created in memory type that is <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. For more information, see <a class="el" href="debugging_memory_usage.html#debugging_memory_usage_corruption_detection">Corruption detection</a>.</p>
+<p>Possible return values:</p>
+<ul>
+<li><code>VK_ERROR_FEATURE_NOT_PRESENT</code> - corruption detection is not enabled for specified pool.</li>
+<li><code>VK_SUCCESS</code> - corruption detection has been performed and succeeded.</li>
+<li><code>VK_ERROR_VALIDATION_FAILED_EXT</code> - corruption detection has been performed and found memory corruptions around one of the allocations. <code>VMA_ASSERT</code> is also fired in that case.</li>
+<li>Other value: Error returned by Vulkan, e.g. memory mapping failure. </li>
+</ul>
+
+</div>
+</div>
 <a id="a200692051ddb34240248234f5f4c17bb"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a200692051ddb34240248234f5f4c17bb">&#9670;&nbsp;</a></span>vmaCreateAllocator()</h2>
 
@@ -1379,8 +1599,9 @@
 <dl class="section return"><dt>Returns</dt><dd>VK_SUCCESS if completed, VK_INCOMPLETE if succeeded but didn't make all possible optimizations because limits specified in pDefragmentationInfo have been reached, negative error code in case of error.</dd></dl>
 <p>This function works by moving allocations to different places (different <code>VkDeviceMemory</code> objects and/or different offsets) in order to optimize memory usage. Only allocations that are in pAllocations array can be moved. All other allocations are considered nonmovable in this call. Basic rules:</p>
 <ul>
-<li>Only allocations made in memory types that have <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code> flag can be compacted. You may pass other allocations but it makes no sense - these will never be moved.</li>
-<li>You may pass allocations made with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block. ">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> but it makes no sense - they will never be moved.</li>
+<li>Only allocations made in memory types that have <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code> and <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> flags can be compacted. You may pass other allocations but it makes no sense - these will never be moved.</li>
+<li>Custom pools created with <a class="el" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726" title="Enables alternative, linear allocation algorithm in this pool. ">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a> flag are not defragmented. Allocations passed to this function that come from such pools are ignored.</li>
+<li>Allocations created with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block. ">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> or created as dedicated allocations for any other reason are also ignored.</li>
 <li>Both allocations made with or without <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag can be compacted. If not persistently mapped, memory will be mapped temporarily inside this function if needed.</li>
 <li>You must not pass same <a class="el" href="struct_vma_allocation.html" title="Represents single memory allocation. ">VmaAllocation</a> object multiple times in pAllocations array.</li>
 </ul>
@@ -1667,6 +1888,56 @@
 
 </div>
 </div>
+<a id="abc34ee6f021f459aff885f3758c435de"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#abc34ee6f021f459aff885f3758c435de">&#9670;&nbsp;</a></span>vmaFlushAllocation()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void vmaFlushAllocation </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;</td>
+          <td class="paramname"><em>allocator</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a>&#160;</td>
+          <td class="paramname"><em>allocation</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">VkDeviceSize&#160;</td>
+          <td class="paramname"><em>offset</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">VkDeviceSize&#160;</td>
+          <td class="paramname"><em>size</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Flushes memory of given allocation. </p>
+<p>Calls <code>vkFlushMappedMemoryRanges()</code> for memory associated with given range of given allocation.</p>
+<ul>
+<li><code>offset</code> must be relative to the beginning of allocation.</li>
+<li><code>size</code> can be <code>VK_WHOLE_SIZE</code>. It means all memory from <code>offset</code> the the end of given allocation.</li>
+<li><code>offset</code> and <code>size</code> don't have to be aligned. They are internally rounded down/up to multiply of <code>nonCoherentAtomSize</code>.</li>
+<li>If <code>size</code> is 0, this call is ignored.</li>
+<li>If memory type that the <code>allocation</code> belongs to is not <code>HOST_VISIBLE</code> or it is <code>HOST_COHERENT</code>, this call is ignored. </li>
+</ul>
+
+</div>
+</div>
 <a id="a11f0fbc034fa81a4efedd73d61ce7568"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a11f0fbc034fa81a4efedd73d61ce7568">&#9670;&nbsp;</a></span>vmaFreeMemory()</h2>
 
@@ -1907,6 +2178,56 @@
 
 </div>
 </div>
+<a id="a0d0eb0c1102268fa9a476d12ecbe4006"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a0d0eb0c1102268fa9a476d12ecbe4006">&#9670;&nbsp;</a></span>vmaInvalidateAllocation()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void vmaInvalidateAllocation </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;</td>
+          <td class="paramname"><em>allocator</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a>&#160;</td>
+          <td class="paramname"><em>allocation</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">VkDeviceSize&#160;</td>
+          <td class="paramname"><em>offset</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">VkDeviceSize&#160;</td>
+          <td class="paramname"><em>size</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Invalidates memory of given allocation. </p>
+<p>Calls <code>vkInvalidateMappedMemoryRanges()</code> for memory associated with given range of given allocation.</p>
+<ul>
+<li><code>offset</code> must be relative to the beginning of allocation.</li>
+<li><code>size</code> can be <code>VK_WHOLE_SIZE</code>. It means all memory from <code>offset</code> the the end of given allocation.</li>
+<li><code>offset</code> and <code>size</code> don't have to be aligned. They are internally rounded down/up to multiply of <code>nonCoherentAtomSize</code>.</li>
+<li>If <code>size</code> is 0, this call is ignored.</li>
+<li>If memory type that the <code>allocation</code> belongs to is not <code>HOST_VISIBLE</code> or it is <code>HOST_COHERENT</code>, this call is ignored. </li>
+</ul>
+
+</div>
+</div>
 <a id="a736bd6cbda886f36c891727e73bd4024"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a736bd6cbda886f36c891727e73bd4024">&#9670;&nbsp;</a></span>vmaMakePoolAllocationsLost()</h2>
 
diff --git a/docs/html/vk__mem__alloc_8h_source.html b/docs/html/vk__mem__alloc_8h_source.html
index 60bb91c..95cdbf9 100644
--- a/docs/html/vk__mem__alloc_8h_source.html
+++ b/docs/html/vk__mem__alloc_8h_source.html
@@ -62,162 +62,179 @@
 <div class="title">vk_mem_alloc.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<a href="vk__mem__alloc_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment">// Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved.</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment">// Permission is hereby granted, free of charge, to any person obtaining a copy</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment">// of this software and associated documentation files (the &quot;Software&quot;), to deal</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment">// in the Software without restriction, including without limitation the rights</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment">// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment">// copies of the Software, and to permit persons to whom the Software is</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment">// furnished to do so, subject to the following conditions:</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment">// The above copyright notice and this permission notice shall be included in</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment">// all copies or substantial portions of the Software.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment">// THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment">// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;<span class="comment">// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE</span></div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="comment">// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="comment">// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;<span class="comment">// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN</span></div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="comment">// THE SOFTWARE.</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="preprocessor">#ifndef AMD_VULKAN_MEMORY_ALLOCATOR_H</span></div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="preprocessor">#define AMD_VULKAN_MEMORY_ALLOCATOR_H</span></div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;<span class="preprocessor">#ifdef __cplusplus</span></div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="keyword">extern</span> <span class="stringliteral">&quot;C&quot;</span> {</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;</div><div class="line"><a name="l01074"></a><span class="lineno"> 1074</span>&#160;<span class="preprocessor">#include &lt;vulkan/vulkan.h&gt;</span></div><div class="line"><a name="l01075"></a><span class="lineno"> 1075</span>&#160;</div><div class="line"><a name="l01085"></a><span class="lineno"> 1085</span>&#160;VK_DEFINE_HANDLE(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a>)</div><div class="line"><a name="l01086"></a><span class="lineno"> 1086</span>&#160;</div><div class="line"><a name="l01087"></a><span class="lineno"> 1087</span>&#160;<span class="keyword">typedef</span> void (VKAPI_PTR *<a class="code" href="vk__mem__alloc_8h.html#ab6a6477cda1ce775b30bde96d766203b">PFN_vmaAllocateDeviceMemoryFunction</a>)(</div><div class="line"><a name="l01089"></a><span class="lineno"> 1089</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>      allocator,</div><div class="line"><a name="l01090"></a><span class="lineno"> 1090</span>&#160;    uint32_t          memoryType,</div><div class="line"><a name="l01091"></a><span class="lineno"> 1091</span>&#160;    VkDeviceMemory    memory,</div><div class="line"><a name="l01092"></a><span class="lineno"> 1092</span>&#160;    VkDeviceSize      size);</div><div class="line"><a name="l01094"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49"> 1094</a></span>&#160;<span class="keyword">typedef</span> void (VKAPI_PTR *<a class="code" href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49">PFN_vmaFreeDeviceMemoryFunction</a>)(</div><div class="line"><a name="l01095"></a><span class="lineno"> 1095</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>      allocator,</div><div class="line"><a name="l01096"></a><span class="lineno"> 1096</span>&#160;    uint32_t          memoryType,</div><div class="line"><a name="l01097"></a><span class="lineno"> 1097</span>&#160;    VkDeviceMemory    memory,</div><div class="line"><a name="l01098"></a><span class="lineno"> 1098</span>&#160;    VkDeviceSize      size);</div><div class="line"><a name="l01099"></a><span class="lineno"> 1099</span>&#160;</div><div class="line"><a name="l01107"></a><span class="lineno"><a class="line" href="struct_vma_device_memory_callbacks.html"> 1107</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a> {</div><div class="line"><a name="l01109"></a><span class="lineno"><a class="line" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb"> 1109</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ab6a6477cda1ce775b30bde96d766203b">PFN_vmaAllocateDeviceMemoryFunction</a> <a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a>;</div><div class="line"><a name="l01111"></a><span class="lineno"><a class="line" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c"> 1111</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49">PFN_vmaFreeDeviceMemoryFunction</a> <a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a>;</div><div class="line"><a name="l01112"></a><span class="lineno"> 1112</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a5e2eb68d727cfd4df25702b027b7aa31">VmaDeviceMemoryCallbacks</a>;</div><div class="line"><a name="l01113"></a><span class="lineno"> 1113</span>&#160;</div><div class="line"><a name="l01115"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c"> 1115</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">enum</span> <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a> {</div><div class="line"><a name="l01120"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d"> 1120</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a> = 0x00000001,</div><div class="line"><a name="l01142"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878"> 1142</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a> = 0x00000002,</div><div class="line"><a name="l01143"></a><span class="lineno"> 1143</span>&#160;</div><div class="line"><a name="l01144"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c"> 1144</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c">VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01145"></a><span class="lineno"> 1145</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a>;</div><div class="line"><a name="l01146"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#acfe6863e160722c2c1bbcf7573fddc4d"> 1146</a></span>&#160;<span class="keyword">typedef</span> VkFlags <a class="code" href="vk__mem__alloc_8h.html#acfe6863e160722c2c1bbcf7573fddc4d">VmaAllocatorCreateFlags</a>;</div><div class="line"><a name="l01147"></a><span class="lineno"> 1147</span>&#160;</div><div class="line"><a name="l01152"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html"> 1152</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a> {</div><div class="line"><a name="l01153"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96"> 1153</a></span>&#160;    PFN_vkGetPhysicalDeviceProperties <a class="code" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">vkGetPhysicalDeviceProperties</a>;</div><div class="line"><a name="l01154"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830"> 1154</a></span>&#160;    PFN_vkGetPhysicalDeviceMemoryProperties <a class="code" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">vkGetPhysicalDeviceMemoryProperties</a>;</div><div class="line"><a name="l01155"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a2943bf99dfd784a0e8f599d987e22e6c"> 1155</a></span>&#160;    PFN_vkAllocateMemory <a class="code" href="struct_vma_vulkan_functions.html#a2943bf99dfd784a0e8f599d987e22e6c">vkAllocateMemory</a>;</div><div class="line"><a name="l01156"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4"> 1156</a></span>&#160;    PFN_vkFreeMemory <a class="code" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">vkFreeMemory</a>;</div><div class="line"><a name="l01157"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49"> 1157</a></span>&#160;    PFN_vkMapMemory <a class="code" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">vkMapMemory</a>;</div><div class="line"><a name="l01158"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9"> 1158</a></span>&#160;    PFN_vkUnmapMemory <a class="code" href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9">vkUnmapMemory</a>;</div><div class="line"><a name="l01159"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2"> 1159</a></span>&#160;    PFN_vkBindBufferMemory <a class="code" href="struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2">vkBindBufferMemory</a>;</div><div class="line"><a name="l01160"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637"> 1160</a></span>&#160;    PFN_vkBindImageMemory <a class="code" href="struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637">vkBindImageMemory</a>;</div><div class="line"><a name="l01161"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143"> 1161</a></span>&#160;    PFN_vkGetBufferMemoryRequirements <a class="code" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">vkGetBufferMemoryRequirements</a>;</div><div class="line"><a name="l01162"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4"> 1162</a></span>&#160;    PFN_vkGetImageMemoryRequirements <a class="code" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">vkGetImageMemoryRequirements</a>;</div><div class="line"><a name="l01163"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#ae8084315a25006271a2edfc3a447519f"> 1163</a></span>&#160;    PFN_vkCreateBuffer <a class="code" href="struct_vma_vulkan_functions.html#ae8084315a25006271a2edfc3a447519f">vkCreateBuffer</a>;</div><div class="line"><a name="l01164"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45"> 1164</a></span>&#160;    PFN_vkDestroyBuffer <a class="code" href="struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45">vkDestroyBuffer</a>;</div><div class="line"><a name="l01165"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325"> 1165</a></span>&#160;    PFN_vkCreateImage <a class="code" href="struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325">vkCreateImage</a>;</div><div class="line"><a name="l01166"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa"> 1166</a></span>&#160;    PFN_vkDestroyImage <a class="code" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">vkDestroyImage</a>;</div><div class="line"><a name="l01167"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c"> 1167</a></span>&#160;    PFN_vkGetBufferMemoryRequirements2KHR <a class="code" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">vkGetBufferMemoryRequirements2KHR</a>;</div><div class="line"><a name="l01168"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875"> 1168</a></span>&#160;    PFN_vkGetImageMemoryRequirements2KHR <a class="code" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">vkGetImageMemoryRequirements2KHR</a>;</div><div class="line"><a name="l01169"></a><span class="lineno"> 1169</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a97064a1a271b0061ebfc3a079862d0c5">VmaVulkanFunctions</a>;</div><div class="line"><a name="l01170"></a><span class="lineno"> 1170</span>&#160;</div><div class="line"><a name="l01172"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html"> 1172</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></div><div class="line"><a name="l01173"></a><span class="lineno"> 1173</span>&#160;{</div><div class="line"><a name="l01175"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346"> 1175</a></span>&#160;    VmaAllocatorCreateFlags <a class="code" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">flags</a>;</div><div class="line"><a name="l01177"></a><span class="lineno"> 1177</span>&#160;</div><div class="line"><a name="l01178"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156"> 1178</a></span>&#160;    VkPhysicalDevice <a class="code" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a>;</div><div class="line"><a name="l01180"></a><span class="lineno"> 1180</span>&#160;</div><div class="line"><a name="l01181"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500"> 1181</a></span>&#160;    VkDevice <a class="code" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500">device</a>;</div><div class="line"><a name="l01183"></a><span class="lineno"> 1183</span>&#160;</div><div class="line"><a name="l01184"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a"> 1184</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a>;</div><div class="line"><a name="l01186"></a><span class="lineno"> 1186</span>&#160;</div><div class="line"><a name="l01187"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d"> 1187</a></span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* <a class="code" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">pAllocationCallbacks</a>;</div><div class="line"><a name="l01189"></a><span class="lineno"> 1189</span>&#160;</div><div class="line"><a name="l01190"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e"> 1190</a></span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a>* <a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a>;</div><div class="line"><a name="l01204"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7"> 1204</a></span>&#160;    uint32_t <a class="code" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">frameInUseCount</a>;</div><div class="line"><a name="l01228"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b"> 1228</a></span>&#160;    <span class="keyword">const</span> VkDeviceSize* <a class="code" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a>;</div><div class="line"><a name="l01240"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd"> 1240</a></span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>* <a class="code" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a>;</div><div class="line"><a name="l01241"></a><span class="lineno"> 1241</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ae0f6d1d733dded220d28134da46b4283">VmaAllocatorCreateInfo</a>;</div><div class="line"><a name="l01242"></a><span class="lineno"> 1242</span>&#160;</div><div class="line"><a name="l01244"></a><span class="lineno"> 1244</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a>(</div><div class="line"><a name="l01245"></a><span class="lineno"> 1245</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l01246"></a><span class="lineno"> 1246</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>* pAllocator);</div><div class="line"><a name="l01247"></a><span class="lineno"> 1247</span>&#160;</div><div class="line"><a name="l01249"></a><span class="lineno"> 1249</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa8d164061c88f22fb1fd3c8f3534bc1d">vmaDestroyAllocator</a>(</div><div class="line"><a name="l01250"></a><span class="lineno"> 1250</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator);</div><div class="line"><a name="l01251"></a><span class="lineno"> 1251</span>&#160;</div><div class="line"><a name="l01256"></a><span class="lineno"> 1256</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aecabf7b6e91ea87d0316fa0a9e014fe0">vmaGetPhysicalDeviceProperties</a>(</div><div class="line"><a name="l01257"></a><span class="lineno"> 1257</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01258"></a><span class="lineno"> 1258</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceProperties** ppPhysicalDeviceProperties);</div><div class="line"><a name="l01259"></a><span class="lineno"> 1259</span>&#160;</div><div class="line"><a name="l01264"></a><span class="lineno"> 1264</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ab88db292a17974f911182543fda52d19">vmaGetMemoryProperties</a>(</div><div class="line"><a name="l01265"></a><span class="lineno"> 1265</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01266"></a><span class="lineno"> 1266</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties);</div><div class="line"><a name="l01267"></a><span class="lineno"> 1267</span>&#160;</div><div class="line"><a name="l01274"></a><span class="lineno"> 1274</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(</div><div class="line"><a name="l01275"></a><span class="lineno"> 1275</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01276"></a><span class="lineno"> 1276</span>&#160;    uint32_t memoryTypeIndex,</div><div class="line"><a name="l01277"></a><span class="lineno"> 1277</span>&#160;    VkMemoryPropertyFlags* pFlags);</div><div class="line"><a name="l01278"></a><span class="lineno"> 1278</span>&#160;</div><div class="line"><a name="l01287"></a><span class="lineno"> 1287</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236">vmaSetCurrentFrameIndex</a>(</div><div class="line"><a name="l01288"></a><span class="lineno"> 1288</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01289"></a><span class="lineno"> 1289</span>&#160;    uint32_t frameIndex);</div><div class="line"><a name="l01290"></a><span class="lineno"> 1290</span>&#160;</div><div class="line"><a name="l01293"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html"> 1293</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a></div><div class="line"><a name="l01294"></a><span class="lineno"> 1294</span>&#160;{</div><div class="line"><a name="l01296"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4"> 1296</a></span>&#160;    uint32_t <a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a>;</div><div class="line"><a name="l01298"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff"> 1298</a></span>&#160;    uint32_t <a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>;</div><div class="line"><a name="l01300"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9"> 1300</a></span>&#160;    uint32_t <a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l01302"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a"> 1302</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>;</div><div class="line"><a name="l01304"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669"> 1304</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>;</div><div class="line"><a name="l01305"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea"> 1305</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, allocationSizeAvg, allocationSizeMax;</div><div class="line"><a name="l01306"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4"> 1306</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSizeAvg, unusedRangeSizeMax;</div><div class="line"><a name="l01307"></a><span class="lineno"> 1307</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a810b009a788ee8aac72a25b42ffbe31c">VmaStatInfo</a>;</div><div class="line"><a name="l01308"></a><span class="lineno"> 1308</span>&#160;</div><div class="line"><a name="l01310"></a><span class="lineno"><a class="line" href="struct_vma_stats.html"> 1310</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_stats.html">VmaStats</a></div><div class="line"><a name="l01311"></a><span class="lineno"> 1311</span>&#160;{</div><div class="line"><a name="l01312"></a><span class="lineno"><a class="line" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331"> 1312</a></span>&#160;    <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> memoryType[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l01313"></a><span class="lineno"><a class="line" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0"> 1313</a></span>&#160;    <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> memoryHeap[VK_MAX_MEMORY_HEAPS];</div><div class="line"><a name="l01314"></a><span class="lineno"><a class="line" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9"> 1314</a></span>&#160;    <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> <a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>;</div><div class="line"><a name="l01315"></a><span class="lineno"> 1315</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a732be855fb4a7c248e6853d928a729af">VmaStats</a>;</div><div class="line"><a name="l01316"></a><span class="lineno"> 1316</span>&#160;</div><div class="line"><a name="l01318"></a><span class="lineno"> 1318</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3">vmaCalculateStats</a>(</div><div class="line"><a name="l01319"></a><span class="lineno"> 1319</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01320"></a><span class="lineno"> 1320</span>&#160;    <a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats);</div><div class="line"><a name="l01321"></a><span class="lineno"> 1321</span>&#160;</div><div class="line"><a name="l01322"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1"> 1322</a></span>&#160;<span class="preprocessor">#define VMA_STATS_STRING_ENABLED 1</span></div><div class="line"><a name="l01323"></a><span class="lineno"> 1323</span>&#160;</div><div class="line"><a name="l01324"></a><span class="lineno"> 1324</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l01325"></a><span class="lineno"> 1325</span>&#160;</div><div class="line"><a name="l01327"></a><span class="lineno"> 1327</span>&#160;</div><div class="line"><a name="l01329"></a><span class="lineno"> 1329</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0">vmaBuildStatsString</a>(</div><div class="line"><a name="l01330"></a><span class="lineno"> 1330</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01331"></a><span class="lineno"> 1331</span>&#160;    <span class="keywordtype">char</span>** ppStatsString,</div><div class="line"><a name="l01332"></a><span class="lineno"> 1332</span>&#160;    VkBool32 detailedMap);</div><div class="line"><a name="l01333"></a><span class="lineno"> 1333</span>&#160;</div><div class="line"><a name="l01334"></a><span class="lineno"> 1334</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vmaFreeStatsString</a>(</div><div class="line"><a name="l01335"></a><span class="lineno"> 1335</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01336"></a><span class="lineno"> 1336</span>&#160;    <span class="keywordtype">char</span>* pStatsString);</div><div class="line"><a name="l01337"></a><span class="lineno"> 1337</span>&#160;</div><div class="line"><a name="l01338"></a><span class="lineno"> 1338</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l01339"></a><span class="lineno"> 1339</span>&#160;</div><div class="line"><a name="l01348"></a><span class="lineno"> 1348</span>&#160;VK_DEFINE_HANDLE(<a class="code" href="struct_vma_pool.html">VmaPool</a>)</div><div class="line"><a name="l01349"></a><span class="lineno"> 1349</span>&#160;</div><div class="line"><a name="l01350"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc"> 1350</a></span>&#160;typedef enum <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a></div><div class="line"><a name="l01351"></a><span class="lineno"> 1351</span>&#160;{</div><div class="line"><a name="l01355"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd"> 1355</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a> = 0,</div><div class="line"><a name="l01372"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7"> 1372</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a> = 1,</div><div class="line"><a name="l01382"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"> 1382</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a> = 2,</div><div class="line"><a name="l01389"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67"> 1389</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a> = 3,</div><div class="line"><a name="l01398"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27"> 1398</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a> = 4,</div><div class="line"><a name="l01399"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e"> 1399</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e">VMA_MEMORY_USAGE_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01400"></a><span class="lineno"> 1400</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a>;</div><div class="line"><a name="l01401"></a><span class="lineno"> 1401</span>&#160;</div><div class="line"><a name="l01403"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597"> 1403</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">enum</span> <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a> {</div><div class="line"><a name="l01415"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f"> 1415</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> = 0x00000001,</div><div class="line"><a name="l01416"></a><span class="lineno"> 1416</span>&#160;</div><div class="line"><a name="l01426"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff"> 1426</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a> = 0x00000002,</div><div class="line"><a name="l01439"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f"> 1439</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> = 0x00000004,</div><div class="line"><a name="l01452"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2"> 1452</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> = 0x00000008,</div><div class="line"><a name="l01459"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e"> 1459</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> = 0x00000010,</div><div class="line"><a name="l01465"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520"> 1465</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a> = 0x00000020,</div><div class="line"><a name="l01466"></a><span class="lineno"> 1466</span>&#160;</div><div class="line"><a name="l01467"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882"> 1467</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01468"></a><span class="lineno"> 1468</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a>;</div><div class="line"><a name="l01469"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817"> 1469</a></span>&#160;<span class="keyword">typedef</span> VkFlags <a class="code" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a>;</div><div class="line"><a name="l01470"></a><span class="lineno"> 1470</span>&#160;</div><div class="line"><a name="l01471"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html"> 1471</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></div><div class="line"><a name="l01472"></a><span class="lineno"> 1472</span>&#160;{</div><div class="line"><a name="l01474"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b"> 1474</a></span>&#160;    VmaAllocationCreateFlags <a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>;</div><div class="line"><a name="l01480"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910"> 1480</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a> <a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>;</div><div class="line"><a name="l01485"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90"> 1485</a></span>&#160;    VkMemoryPropertyFlags <a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>;</div><div class="line"><a name="l01490"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d"> 1490</a></span>&#160;    VkMemoryPropertyFlags <a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>;</div><div class="line"><a name="l01498"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055"> 1498</a></span>&#160;    uint32_t <a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>;</div><div class="line"><a name="l01504"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150"> 1504</a></span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> <a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>;</div><div class="line"><a name="l01511"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19"> 1511</a></span>&#160;    <span class="keywordtype">void</span>* <a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>;</div><div class="line"><a name="l01512"></a><span class="lineno"> 1512</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a86c44f9950b40d50088ed93a17870a7a">VmaAllocationCreateInfo</a>;</div><div class="line"><a name="l01513"></a><span class="lineno"> 1513</span>&#160;</div><div class="line"><a name="l01530"></a><span class="lineno"> 1530</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l01531"></a><span class="lineno"> 1531</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01532"></a><span class="lineno"> 1532</span>&#160;    uint32_t memoryTypeBits,</div><div class="line"><a name="l01533"></a><span class="lineno"> 1533</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l01534"></a><span class="lineno"> 1534</span>&#160;    uint32_t* pMemoryTypeIndex);</div><div class="line"><a name="l01535"></a><span class="lineno"> 1535</span>&#160;</div><div class="line"><a name="l01548"></a><span class="lineno"> 1548</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(</div><div class="line"><a name="l01549"></a><span class="lineno"> 1549</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01550"></a><span class="lineno"> 1550</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l01551"></a><span class="lineno"> 1551</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l01552"></a><span class="lineno"> 1552</span>&#160;    uint32_t* pMemoryTypeIndex);</div><div class="line"><a name="l01553"></a><span class="lineno"> 1553</span>&#160;</div><div class="line"><a name="l01566"></a><span class="lineno"> 1566</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472">vmaFindMemoryTypeIndexForImageInfo</a>(</div><div class="line"><a name="l01567"></a><span class="lineno"> 1567</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01568"></a><span class="lineno"> 1568</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l01569"></a><span class="lineno"> 1569</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l01570"></a><span class="lineno"> 1570</span>&#160;    uint32_t* pMemoryTypeIndex);</div><div class="line"><a name="l01571"></a><span class="lineno"> 1571</span>&#160;</div><div class="line"><a name="l01573"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7"> 1573</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">enum</span> <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a> {</div><div class="line"><a name="l01591"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2"> 1591</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a> = 0x00000002,</div><div class="line"><a name="l01592"></a><span class="lineno"> 1592</span>&#160;</div><div class="line"><a name="l01593"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec"> 1593</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec">VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01594"></a><span class="lineno"> 1594</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a>;</div><div class="line"><a name="l01595"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a"> 1595</a></span>&#160;<span class="keyword">typedef</span> VkFlags <a class="code" href="vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a">VmaPoolCreateFlags</a>;</div><div class="line"><a name="l01596"></a><span class="lineno"> 1596</span>&#160;</div><div class="line"><a name="l01599"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html"> 1599</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> {</div><div class="line"><a name="l01602"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319"> 1602</a></span>&#160;    uint32_t <a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a>;</div><div class="line"><a name="l01605"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446"> 1605</a></span>&#160;    VmaPoolCreateFlags <a class="code" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">flags</a>;</div><div class="line"><a name="l01610"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676"> 1610</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">blockSize</a>;</div><div class="line"><a name="l01615"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae"> 1615</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae">minBlockCount</a>;</div><div class="line"><a name="l01623"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c"> 1623</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a>;</div><div class="line"><a name="l01637"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa"> 1637</a></span>&#160;    uint32_t <a class="code" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa">frameInUseCount</a>;</div><div class="line"><a name="l01638"></a><span class="lineno"> 1638</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a211706e9348dcee25a843ed4ea69bce7">VmaPoolCreateInfo</a>;</div><div class="line"><a name="l01639"></a><span class="lineno"> 1639</span>&#160;</div><div class="line"><a name="l01642"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html"> 1642</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a> {</div><div class="line"><a name="l01645"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c"> 1645</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a>;</div><div class="line"><a name="l01648"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8"> 1648</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a>;</div><div class="line"><a name="l01651"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb"> 1651</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a>;</div><div class="line"><a name="l01654"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4"> 1654</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l01661"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b"> 1661</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>;</div><div class="line"><a name="l01662"></a><span class="lineno"> 1662</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34">VmaPoolStats</a>;</div><div class="line"><a name="l01663"></a><span class="lineno"> 1663</span>&#160;</div><div class="line"><a name="l01670"></a><span class="lineno"> 1670</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(</div><div class="line"><a name="l01671"></a><span class="lineno"> 1671</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01672"></a><span class="lineno"> 1672</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l01673"></a><span class="lineno"> 1673</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool);</div><div class="line"><a name="l01674"></a><span class="lineno"> 1674</span>&#160;</div><div class="line"><a name="l01677"></a><span class="lineno"> 1677</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a>(</div><div class="line"><a name="l01678"></a><span class="lineno"> 1678</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01679"></a><span class="lineno"> 1679</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l01680"></a><span class="lineno"> 1680</span>&#160;</div><div class="line"><a name="l01687"></a><span class="lineno"> 1687</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153">vmaGetPoolStats</a>(</div><div class="line"><a name="l01688"></a><span class="lineno"> 1688</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01689"></a><span class="lineno"> 1689</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l01690"></a><span class="lineno"> 1690</span>&#160;    <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats);</div><div class="line"><a name="l01691"></a><span class="lineno"> 1691</span>&#160;</div><div class="line"><a name="l01698"></a><span class="lineno"> 1698</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vmaMakePoolAllocationsLost</a>(</div><div class="line"><a name="l01699"></a><span class="lineno"> 1699</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01700"></a><span class="lineno"> 1700</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l01701"></a><span class="lineno"> 1701</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount);</div><div class="line"><a name="l01702"></a><span class="lineno"> 1702</span>&#160;</div><div class="line"><a name="l01727"></a><span class="lineno"> 1727</span>&#160;VK_DEFINE_HANDLE(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a>)</div><div class="line"><a name="l01728"></a><span class="lineno"> 1728</span>&#160;</div><div class="line"><a name="l01729"></a><span class="lineno"> 1729</span>&#160;</div><div class="line"><a name="l01731"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html"> 1731</a></span>&#160;typedef struct <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> {</div><div class="line"><a name="l01736"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5"> 1736</a></span>&#160;    uint32_t <a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>;</div><div class="line"><a name="l01745"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67"> 1745</a></span>&#160;    VkDeviceMemory <a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><div class="line"><a name="l01750"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268"> 1750</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><div class="line"><a name="l01755"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f"> 1755</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><div class="line"><a name="l01764"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2"> 1764</a></span>&#160;    <span class="keywordtype">void</span>* <a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>;</div><div class="line"><a name="l01769"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13"> 1769</a></span>&#160;    <span class="keywordtype">void</span>* <a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a>;</div><div class="line"><a name="l01770"></a><span class="lineno"> 1770</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a795e6ff02a21d5486c0565f403dd9255">VmaAllocationInfo</a>;</div><div class="line"><a name="l01771"></a><span class="lineno"> 1771</span>&#160;</div><div class="line"><a name="l01782"></a><span class="lineno"> 1782</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a>(</div><div class="line"><a name="l01783"></a><span class="lineno"> 1783</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01784"></a><span class="lineno"> 1784</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements* pVkMemoryRequirements,</div><div class="line"><a name="l01785"></a><span class="lineno"> 1785</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l01786"></a><span class="lineno"> 1786</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l01787"></a><span class="lineno"> 1787</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l01788"></a><span class="lineno"> 1788</span>&#160;</div><div class="line"><a name="l01795"></a><span class="lineno"> 1795</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer</a>(</div><div class="line"><a name="l01796"></a><span class="lineno"> 1796</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01797"></a><span class="lineno"> 1797</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l01798"></a><span class="lineno"> 1798</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l01799"></a><span class="lineno"> 1799</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l01800"></a><span class="lineno"> 1800</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l01801"></a><span class="lineno"> 1801</span>&#160;</div><div class="line"><a name="l01803"></a><span class="lineno"> 1803</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vmaAllocateMemoryForImage</a>(</div><div class="line"><a name="l01804"></a><span class="lineno"> 1804</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01805"></a><span class="lineno"> 1805</span>&#160;    VkImage image,</div><div class="line"><a name="l01806"></a><span class="lineno"> 1806</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l01807"></a><span class="lineno"> 1807</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l01808"></a><span class="lineno"> 1808</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l01809"></a><span class="lineno"> 1809</span>&#160;</div><div class="line"><a name="l01811"></a><span class="lineno"> 1811</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vmaFreeMemory</a>(</div><div class="line"><a name="l01812"></a><span class="lineno"> 1812</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01813"></a><span class="lineno"> 1813</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l01814"></a><span class="lineno"> 1814</span>&#160;</div><div class="line"><a name="l01831"></a><span class="lineno"> 1831</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(</div><div class="line"><a name="l01832"></a><span class="lineno"> 1832</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01833"></a><span class="lineno"> 1833</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l01834"></a><span class="lineno"> 1834</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l01835"></a><span class="lineno"> 1835</span>&#160;</div><div class="line"><a name="l01850"></a><span class="lineno"> 1850</span>&#160;VkBool32 <a class="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(</div><div class="line"><a name="l01851"></a><span class="lineno"> 1851</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01852"></a><span class="lineno"> 1852</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l01853"></a><span class="lineno"> 1853</span>&#160;</div><div class="line"><a name="l01867"></a><span class="lineno"> 1867</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f">vmaSetAllocationUserData</a>(</div><div class="line"><a name="l01868"></a><span class="lineno"> 1868</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01869"></a><span class="lineno"> 1869</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l01870"></a><span class="lineno"> 1870</span>&#160;    <span class="keywordtype">void</span>* pUserData);</div><div class="line"><a name="l01871"></a><span class="lineno"> 1871</span>&#160;</div><div class="line"><a name="l01882"></a><span class="lineno"> 1882</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae5c9657d9e94756269145b01c05d16f1">vmaCreateLostAllocation</a>(</div><div class="line"><a name="l01883"></a><span class="lineno"> 1883</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01884"></a><span class="lineno"> 1884</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l01885"></a><span class="lineno"> 1885</span>&#160;</div><div class="line"><a name="l01920"></a><span class="lineno"> 1920</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(</div><div class="line"><a name="l01921"></a><span class="lineno"> 1921</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01922"></a><span class="lineno"> 1922</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l01923"></a><span class="lineno"> 1923</span>&#160;    <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l01924"></a><span class="lineno"> 1924</span>&#160;</div><div class="line"><a name="l01929"></a><span class="lineno"> 1929</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(</div><div class="line"><a name="l01930"></a><span class="lineno"> 1930</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01931"></a><span class="lineno"> 1931</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l01932"></a><span class="lineno"> 1932</span>&#160;</div><div class="line"><a name="l01934"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_info.html"> 1934</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> {</div><div class="line"><a name="l01939"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d"> 1939</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d">maxBytesToMove</a>;</div><div class="line"><a name="l01944"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc"> 1944</a></span>&#160;    uint32_t <a class="code" href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc">maxAllocationsToMove</a>;</div><div class="line"><a name="l01945"></a><span class="lineno"> 1945</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ae67f8573a0cf20f16f0a1eecbca566a0">VmaDefragmentationInfo</a>;</div><div class="line"><a name="l01946"></a><span class="lineno"> 1946</span>&#160;</div><div class="line"><a name="l01948"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html"> 1948</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a> {</div><div class="line"><a name="l01950"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d"> 1950</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a>;</div><div class="line"><a name="l01952"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28"> 1952</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28">bytesFreed</a>;</div><div class="line"><a name="l01954"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9"> 1954</a></span>&#160;    uint32_t <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a>;</div><div class="line"><a name="l01956"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b"> 1956</a></span>&#160;    uint32_t <a class="code" href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b">deviceMemoryBlocksFreed</a>;</div><div class="line"><a name="l01957"></a><span class="lineno"> 1957</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ab0f9b06441c840fee560de4a2967f8c9">VmaDefragmentationStats</a>;</div><div class="line"><a name="l01958"></a><span class="lineno"> 1958</span>&#160;</div><div class="line"><a name="l02041"></a><span class="lineno"> 2041</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a>(</div><div class="line"><a name="l02042"></a><span class="lineno"> 2042</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02043"></a><span class="lineno"> 2043</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l02044"></a><span class="lineno"> 2044</span>&#160;    <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l02045"></a><span class="lineno"> 2045</span>&#160;    VkBool32* pAllocationsChanged,</div><div class="line"><a name="l02046"></a><span class="lineno"> 2046</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *pDefragmentationInfo,</div><div class="line"><a name="l02047"></a><span class="lineno"> 2047</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats);</div><div class="line"><a name="l02048"></a><span class="lineno"> 2048</span>&#160;</div><div class="line"><a name="l02061"></a><span class="lineno"> 2061</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vmaBindBufferMemory</a>(</div><div class="line"><a name="l02062"></a><span class="lineno"> 2062</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02063"></a><span class="lineno"> 2063</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l02064"></a><span class="lineno"> 2064</span>&#160;    VkBuffer buffer);</div><div class="line"><a name="l02065"></a><span class="lineno"> 2065</span>&#160;</div><div class="line"><a name="l02078"></a><span class="lineno"> 2078</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vmaBindImageMemory</a>(</div><div class="line"><a name="l02079"></a><span class="lineno"> 2079</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02080"></a><span class="lineno"> 2080</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l02081"></a><span class="lineno"> 2081</span>&#160;    VkImage image);</div><div class="line"><a name="l02082"></a><span class="lineno"> 2082</span>&#160;</div><div class="line"><a name="l02109"></a><span class="lineno"> 2109</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(</div><div class="line"><a name="l02110"></a><span class="lineno"> 2110</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02111"></a><span class="lineno"> 2111</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l02112"></a><span class="lineno"> 2112</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l02113"></a><span class="lineno"> 2113</span>&#160;    VkBuffer* pBuffer,</div><div class="line"><a name="l02114"></a><span class="lineno"> 2114</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l02115"></a><span class="lineno"> 2115</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02116"></a><span class="lineno"> 2116</span>&#160;</div><div class="line"><a name="l02128"></a><span class="lineno"> 2128</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(</div><div class="line"><a name="l02129"></a><span class="lineno"> 2129</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02130"></a><span class="lineno"> 2130</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l02131"></a><span class="lineno"> 2131</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l02132"></a><span class="lineno"> 2132</span>&#160;</div><div class="line"><a name="l02134"></a><span class="lineno"> 2134</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73">vmaCreateImage</a>(</div><div class="line"><a name="l02135"></a><span class="lineno"> 2135</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02136"></a><span class="lineno"> 2136</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l02137"></a><span class="lineno"> 2137</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l02138"></a><span class="lineno"> 2138</span>&#160;    VkImage* pImage,</div><div class="line"><a name="l02139"></a><span class="lineno"> 2139</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l02140"></a><span class="lineno"> 2140</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02141"></a><span class="lineno"> 2141</span>&#160;</div><div class="line"><a name="l02153"></a><span class="lineno"> 2153</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae50d2cb3b4a3bfd4dd40987234e50e7e">vmaDestroyImage</a>(</div><div class="line"><a name="l02154"></a><span class="lineno"> 2154</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02155"></a><span class="lineno"> 2155</span>&#160;    VkImage image,</div><div class="line"><a name="l02156"></a><span class="lineno"> 2156</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l02157"></a><span class="lineno"> 2157</span>&#160;</div><div class="line"><a name="l02158"></a><span class="lineno"> 2158</span>&#160;<span class="preprocessor">#ifdef __cplusplus</span></div><div class="line"><a name="l02159"></a><span class="lineno"> 2159</span>&#160;}</div><div class="line"><a name="l02160"></a><span class="lineno"> 2160</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02161"></a><span class="lineno"> 2161</span>&#160;</div><div class="line"><a name="l02162"></a><span class="lineno"> 2162</span>&#160;<span class="preprocessor">#endif // AMD_VULKAN_MEMORY_ALLOCATOR_H</span></div><div class="line"><a name="l02163"></a><span class="lineno"> 2163</span>&#160;</div><div class="line"><a name="l02164"></a><span class="lineno"> 2164</span>&#160;<span class="comment">// For Visual Studio IntelliSense.</span></div><div class="line"><a name="l02165"></a><span class="lineno"> 2165</span>&#160;<span class="preprocessor">#ifdef __INTELLISENSE__</span></div><div class="line"><a name="l02166"></a><span class="lineno"> 2166</span>&#160;<span class="preprocessor">#define VMA_IMPLEMENTATION</span></div><div class="line"><a name="l02167"></a><span class="lineno"> 2167</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02168"></a><span class="lineno"> 2168</span>&#160;</div><div class="line"><a name="l02169"></a><span class="lineno"> 2169</span>&#160;<span class="preprocessor">#ifdef VMA_IMPLEMENTATION</span></div><div class="line"><a name="l02170"></a><span class="lineno"> 2170</span>&#160;<span class="preprocessor">#undef VMA_IMPLEMENTATION</span></div><div class="line"><a name="l02171"></a><span class="lineno"> 2171</span>&#160;</div><div class="line"><a name="l02172"></a><span class="lineno"> 2172</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l02173"></a><span class="lineno"> 2173</span>&#160;<span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><a name="l02174"></a><span class="lineno"> 2174</span>&#160;<span class="preprocessor">#include &lt;cstring&gt;</span></div><div class="line"><a name="l02175"></a><span class="lineno"> 2175</span>&#160;</div><div class="line"><a name="l02176"></a><span class="lineno"> 2176</span>&#160;<span class="comment">/*******************************************************************************</span></div><div class="line"><a name="l02177"></a><span class="lineno"> 2177</span>&#160;<span class="comment">CONFIGURATION SECTION</span></div><div class="line"><a name="l02178"></a><span class="lineno"> 2178</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02179"></a><span class="lineno"> 2179</span>&#160;<span class="comment">Define some of these macros before each #include of this header or change them</span></div><div class="line"><a name="l02180"></a><span class="lineno"> 2180</span>&#160;<span class="comment">here if you need other then default behavior depending on your environment.</span></div><div class="line"><a name="l02181"></a><span class="lineno"> 2181</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02182"></a><span class="lineno"> 2182</span>&#160;</div><div class="line"><a name="l02183"></a><span class="lineno"> 2183</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02184"></a><span class="lineno"> 2184</span>&#160;<span class="comment">Define this macro to 1 to make the library fetch pointers to Vulkan functions</span></div><div class="line"><a name="l02185"></a><span class="lineno"> 2185</span>&#160;<span class="comment">internally, like:</span></div><div class="line"><a name="l02186"></a><span class="lineno"> 2186</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02187"></a><span class="lineno"> 2187</span>&#160;<span class="comment">    vulkanFunctions.vkAllocateMemory = &amp;vkAllocateMemory;</span></div><div class="line"><a name="l02188"></a><span class="lineno"> 2188</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02189"></a><span class="lineno"> 2189</span>&#160;<span class="comment">Define to 0 if you are going to provide you own pointers to Vulkan functions via</span></div><div class="line"><a name="l02190"></a><span class="lineno"> 2190</span>&#160;<span class="comment">VmaAllocatorCreateInfo::pVulkanFunctions.</span></div><div class="line"><a name="l02191"></a><span class="lineno"> 2191</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02192"></a><span class="lineno"> 2192</span>&#160;<span class="preprocessor">#if !defined(VMA_STATIC_VULKAN_FUNCTIONS) &amp;&amp; !defined(VK_NO_PROTOTYPES)</span></div><div class="line"><a name="l02193"></a><span class="lineno"> 2193</span>&#160;<span class="preprocessor">#define VMA_STATIC_VULKAN_FUNCTIONS 1</span></div><div class="line"><a name="l02194"></a><span class="lineno"> 2194</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02195"></a><span class="lineno"> 2195</span>&#160;</div><div class="line"><a name="l02196"></a><span class="lineno"> 2196</span>&#160;<span class="comment">// Define this macro to 1 to make the library use STL containers instead of its own implementation.</span></div><div class="line"><a name="l02197"></a><span class="lineno"> 2197</span>&#160;<span class="comment">//#define VMA_USE_STL_CONTAINERS 1</span></div><div class="line"><a name="l02198"></a><span class="lineno"> 2198</span>&#160;</div><div class="line"><a name="l02199"></a><span class="lineno"> 2199</span>&#160;<span class="comment">/* Set this macro to 1 to make the library including and using STL containers:</span></div><div class="line"><a name="l02200"></a><span class="lineno"> 2200</span>&#160;<span class="comment">std::pair, std::vector, std::list, std::unordered_map.</span></div><div class="line"><a name="l02201"></a><span class="lineno"> 2201</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02202"></a><span class="lineno"> 2202</span>&#160;<span class="comment">Set it to 0 or undefined to make the library using its own implementation of</span></div><div class="line"><a name="l02203"></a><span class="lineno"> 2203</span>&#160;<span class="comment">the containers.</span></div><div class="line"><a name="l02204"></a><span class="lineno"> 2204</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02205"></a><span class="lineno"> 2205</span>&#160;<span class="preprocessor">#if VMA_USE_STL_CONTAINERS</span></div><div class="line"><a name="l02206"></a><span class="lineno"> 2206</span>&#160;<span class="preprocessor">   #define VMA_USE_STL_VECTOR 1</span></div><div class="line"><a name="l02207"></a><span class="lineno"> 2207</span>&#160;<span class="preprocessor">   #define VMA_USE_STL_UNORDERED_MAP 1</span></div><div class="line"><a name="l02208"></a><span class="lineno"> 2208</span>&#160;<span class="preprocessor">   #define VMA_USE_STL_LIST 1</span></div><div class="line"><a name="l02209"></a><span class="lineno"> 2209</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02210"></a><span class="lineno"> 2210</span>&#160;</div><div class="line"><a name="l02211"></a><span class="lineno"> 2211</span>&#160;<span class="preprocessor">#if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l02212"></a><span class="lineno"> 2212</span>&#160;<span class="preprocessor">   #include &lt;vector&gt;</span></div><div class="line"><a name="l02213"></a><span class="lineno"> 2213</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02214"></a><span class="lineno"> 2214</span>&#160;</div><div class="line"><a name="l02215"></a><span class="lineno"> 2215</span>&#160;<span class="preprocessor">#if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l02216"></a><span class="lineno"> 2216</span>&#160;<span class="preprocessor">   #include &lt;unordered_map&gt;</span></div><div class="line"><a name="l02217"></a><span class="lineno"> 2217</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02218"></a><span class="lineno"> 2218</span>&#160;</div><div class="line"><a name="l02219"></a><span class="lineno"> 2219</span>&#160;<span class="preprocessor">#if VMA_USE_STL_LIST</span></div><div class="line"><a name="l02220"></a><span class="lineno"> 2220</span>&#160;<span class="preprocessor">   #include &lt;list&gt;</span></div><div class="line"><a name="l02221"></a><span class="lineno"> 2221</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02222"></a><span class="lineno"> 2222</span>&#160;</div><div class="line"><a name="l02223"></a><span class="lineno"> 2223</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02224"></a><span class="lineno"> 2224</span>&#160;<span class="comment">Following headers are used in this CONFIGURATION section only, so feel free to</span></div><div class="line"><a name="l02225"></a><span class="lineno"> 2225</span>&#160;<span class="comment">remove them if not needed.</span></div><div class="line"><a name="l02226"></a><span class="lineno"> 2226</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02227"></a><span class="lineno"> 2227</span>&#160;<span class="preprocessor">#include &lt;cassert&gt;</span> <span class="comment">// for assert</span></div><div class="line"><a name="l02228"></a><span class="lineno"> 2228</span>&#160;<span class="preprocessor">#include &lt;algorithm&gt;</span> <span class="comment">// for min, max</span></div><div class="line"><a name="l02229"></a><span class="lineno"> 2229</span>&#160;<span class="preprocessor">#include &lt;mutex&gt;</span> <span class="comment">// for std::mutex</span></div><div class="line"><a name="l02230"></a><span class="lineno"> 2230</span>&#160;<span class="preprocessor">#include &lt;atomic&gt;</span> <span class="comment">// for std::atomic</span></div><div class="line"><a name="l02231"></a><span class="lineno"> 2231</span>&#160;</div><div class="line"><a name="l02232"></a><span class="lineno"> 2232</span>&#160;<span class="preprocessor">#if !defined(_WIN32) &amp;&amp; !defined(__APPLE__)</span></div><div class="line"><a name="l02233"></a><span class="lineno"> 2233</span>&#160;<span class="preprocessor">    #include &lt;malloc.h&gt;</span> <span class="comment">// for aligned_alloc()</span></div><div class="line"><a name="l02234"></a><span class="lineno"> 2234</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02235"></a><span class="lineno"> 2235</span>&#160;</div><div class="line"><a name="l02236"></a><span class="lineno"> 2236</span>&#160;<span class="preprocessor">#ifndef VMA_NULL</span></div><div class="line"><a name="l02237"></a><span class="lineno"> 2237</span>&#160;   <span class="comment">// Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.</span></div><div class="line"><a name="l02238"></a><span class="lineno"> 2238</span>&#160;<span class="preprocessor">   #define VMA_NULL   nullptr</span></div><div class="line"><a name="l02239"></a><span class="lineno"> 2239</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02240"></a><span class="lineno"> 2240</span>&#160;</div><div class="line"><a name="l02241"></a><span class="lineno"> 2241</span>&#160;<span class="preprocessor">#if defined(__APPLE__) || defined(__ANDROID__)</span></div><div class="line"><a name="l02242"></a><span class="lineno"> 2242</span>&#160;<span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><a name="l02243"></a><span class="lineno"> 2243</span>&#160;<span class="keywordtype">void</span> *aligned_alloc(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size)</div><div class="line"><a name="l02244"></a><span class="lineno"> 2244</span>&#160;{</div><div class="line"><a name="l02245"></a><span class="lineno"> 2245</span>&#160;    <span class="comment">// alignment must be &gt;= sizeof(void*)</span></div><div class="line"><a name="l02246"></a><span class="lineno"> 2246</span>&#160;    <span class="keywordflow">if</span>(alignment &lt; <span class="keyword">sizeof</span>(<span class="keywordtype">void</span>*))</div><div class="line"><a name="l02247"></a><span class="lineno"> 2247</span>&#160;    {</div><div class="line"><a name="l02248"></a><span class="lineno"> 2248</span>&#160;        alignment = <span class="keyword">sizeof</span>(<span class="keywordtype">void</span>*);</div><div class="line"><a name="l02249"></a><span class="lineno"> 2249</span>&#160;    }</div><div class="line"><a name="l02250"></a><span class="lineno"> 2250</span>&#160;</div><div class="line"><a name="l02251"></a><span class="lineno"> 2251</span>&#160;    <span class="keywordtype">void</span> *pointer;</div><div class="line"><a name="l02252"></a><span class="lineno"> 2252</span>&#160;    <span class="keywordflow">if</span>(posix_memalign(&amp;pointer, alignment, size) == 0)</div><div class="line"><a name="l02253"></a><span class="lineno"> 2253</span>&#160;        <span class="keywordflow">return</span> pointer;</div><div class="line"><a name="l02254"></a><span class="lineno"> 2254</span>&#160;    <span class="keywordflow">return</span> VMA_NULL;</div><div class="line"><a name="l02255"></a><span class="lineno"> 2255</span>&#160;}</div><div class="line"><a name="l02256"></a><span class="lineno"> 2256</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02257"></a><span class="lineno"> 2257</span>&#160;</div><div class="line"><a name="l02258"></a><span class="lineno"> 2258</span>&#160;<span class="comment">// Normal assert to check for programmer&#39;s errors, especially in Debug configuration.</span></div><div class="line"><a name="l02259"></a><span class="lineno"> 2259</span>&#160;<span class="preprocessor">#ifndef VMA_ASSERT</span></div><div class="line"><a name="l02260"></a><span class="lineno"> 2260</span>&#160;<span class="preprocessor">   #ifdef _DEBUG</span></div><div class="line"><a name="l02261"></a><span class="lineno"> 2261</span>&#160;<span class="preprocessor">       #define VMA_ASSERT(expr)         assert(expr)</span></div><div class="line"><a name="l02262"></a><span class="lineno"> 2262</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02263"></a><span class="lineno"> 2263</span>&#160;<span class="preprocessor">       #define VMA_ASSERT(expr)</span></div><div class="line"><a name="l02264"></a><span class="lineno"> 2264</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02265"></a><span class="lineno"> 2265</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02266"></a><span class="lineno"> 2266</span>&#160;</div><div class="line"><a name="l02267"></a><span class="lineno"> 2267</span>&#160;<span class="comment">// Assert that will be called very often, like inside data structures e.g. operator[].</span></div><div class="line"><a name="l02268"></a><span class="lineno"> 2268</span>&#160;<span class="comment">// Making it non-empty can make program slow.</span></div><div class="line"><a name="l02269"></a><span class="lineno"> 2269</span>&#160;<span class="preprocessor">#ifndef VMA_HEAVY_ASSERT</span></div><div class="line"><a name="l02270"></a><span class="lineno"> 2270</span>&#160;<span class="preprocessor">   #ifdef _DEBUG</span></div><div class="line"><a name="l02271"></a><span class="lineno"> 2271</span>&#160;<span class="preprocessor">       #define VMA_HEAVY_ASSERT(expr)   //VMA_ASSERT(expr)</span></div><div class="line"><a name="l02272"></a><span class="lineno"> 2272</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02273"></a><span class="lineno"> 2273</span>&#160;<span class="preprocessor">       #define VMA_HEAVY_ASSERT(expr)</span></div><div class="line"><a name="l02274"></a><span class="lineno"> 2274</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02275"></a><span class="lineno"> 2275</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02276"></a><span class="lineno"> 2276</span>&#160;</div><div class="line"><a name="l02277"></a><span class="lineno"> 2277</span>&#160;<span class="preprocessor">#ifndef VMA_ALIGN_OF</span></div><div class="line"><a name="l02278"></a><span class="lineno"> 2278</span>&#160;<span class="preprocessor">   #define VMA_ALIGN_OF(type)       (__alignof(type))</span></div><div class="line"><a name="l02279"></a><span class="lineno"> 2279</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02280"></a><span class="lineno"> 2280</span>&#160;</div><div class="line"><a name="l02281"></a><span class="lineno"> 2281</span>&#160;<span class="preprocessor">#ifndef VMA_SYSTEM_ALIGNED_MALLOC</span></div><div class="line"><a name="l02282"></a><span class="lineno"> 2282</span>&#160;<span class="preprocessor">   #if defined(_WIN32)</span></div><div class="line"><a name="l02283"></a><span class="lineno"> 2283</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment)   (_aligned_malloc((size), (alignment)))</span></div><div class="line"><a name="l02284"></a><span class="lineno"> 2284</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02285"></a><span class="lineno"> 2285</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment)   (aligned_alloc((alignment), (size) ))</span></div><div class="line"><a name="l02286"></a><span class="lineno"> 2286</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02287"></a><span class="lineno"> 2287</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02288"></a><span class="lineno"> 2288</span>&#160;</div><div class="line"><a name="l02289"></a><span class="lineno"> 2289</span>&#160;<span class="preprocessor">#ifndef VMA_SYSTEM_FREE</span></div><div class="line"><a name="l02290"></a><span class="lineno"> 2290</span>&#160;<span class="preprocessor">   #if defined(_WIN32)</span></div><div class="line"><a name="l02291"></a><span class="lineno"> 2291</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_FREE(ptr)   _aligned_free(ptr)</span></div><div class="line"><a name="l02292"></a><span class="lineno"> 2292</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02293"></a><span class="lineno"> 2293</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_FREE(ptr)   free(ptr)</span></div><div class="line"><a name="l02294"></a><span class="lineno"> 2294</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02295"></a><span class="lineno"> 2295</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02296"></a><span class="lineno"> 2296</span>&#160;</div><div class="line"><a name="l02297"></a><span class="lineno"> 2297</span>&#160;<span class="preprocessor">#ifndef VMA_MIN</span></div><div class="line"><a name="l02298"></a><span class="lineno"> 2298</span>&#160;<span class="preprocessor">   #define VMA_MIN(v1, v2)    (std::min((v1), (v2)))</span></div><div class="line"><a name="l02299"></a><span class="lineno"> 2299</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02300"></a><span class="lineno"> 2300</span>&#160;</div><div class="line"><a name="l02301"></a><span class="lineno"> 2301</span>&#160;<span class="preprocessor">#ifndef VMA_MAX</span></div><div class="line"><a name="l02302"></a><span class="lineno"> 2302</span>&#160;<span class="preprocessor">   #define VMA_MAX(v1, v2)    (std::max((v1), (v2)))</span></div><div class="line"><a name="l02303"></a><span class="lineno"> 2303</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02304"></a><span class="lineno"> 2304</span>&#160;</div><div class="line"><a name="l02305"></a><span class="lineno"> 2305</span>&#160;<span class="preprocessor">#ifndef VMA_SWAP</span></div><div class="line"><a name="l02306"></a><span class="lineno"> 2306</span>&#160;<span class="preprocessor">   #define VMA_SWAP(v1, v2)   std::swap((v1), (v2))</span></div><div class="line"><a name="l02307"></a><span class="lineno"> 2307</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02308"></a><span class="lineno"> 2308</span>&#160;</div><div class="line"><a name="l02309"></a><span class="lineno"> 2309</span>&#160;<span class="preprocessor">#ifndef VMA_SORT</span></div><div class="line"><a name="l02310"></a><span class="lineno"> 2310</span>&#160;<span class="preprocessor">   #define VMA_SORT(beg, end, cmp)  std::sort(beg, end, cmp)</span></div><div class="line"><a name="l02311"></a><span class="lineno"> 2311</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02312"></a><span class="lineno"> 2312</span>&#160;</div><div class="line"><a name="l02313"></a><span class="lineno"> 2313</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_LOG</span></div><div class="line"><a name="l02314"></a><span class="lineno"> 2314</span>&#160;<span class="preprocessor">   #define VMA_DEBUG_LOG(format, ...)</span></div><div class="line"><a name="l02315"></a><span class="lineno"> 2315</span>&#160;   <span class="comment">/*</span></div><div class="line"><a name="l02316"></a><span class="lineno"> 2316</span>&#160;<span class="comment">   #define VMA_DEBUG_LOG(format, ...) do { \</span></div><div class="line"><a name="l02317"></a><span class="lineno"> 2317</span>&#160;<span class="comment">       printf(format, __VA_ARGS__); \</span></div><div class="line"><a name="l02318"></a><span class="lineno"> 2318</span>&#160;<span class="comment">       printf(&quot;\n&quot;); \</span></div><div class="line"><a name="l02319"></a><span class="lineno"> 2319</span>&#160;<span class="comment">   } while(false)</span></div><div class="line"><a name="l02320"></a><span class="lineno"> 2320</span>&#160;<span class="comment">   */</span></div><div class="line"><a name="l02321"></a><span class="lineno"> 2321</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02322"></a><span class="lineno"> 2322</span>&#160;</div><div class="line"><a name="l02323"></a><span class="lineno"> 2323</span>&#160;<span class="comment">// Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString.</span></div><div class="line"><a name="l02324"></a><span class="lineno"> 2324</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l02325"></a><span class="lineno"> 2325</span>&#160;   <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> VmaUint32ToStr(<span class="keywordtype">char</span>* outStr, <span class="keywordtype">size_t</span> strLen, uint32_t num)</div><div class="line"><a name="l02326"></a><span class="lineno"> 2326</span>&#160;   {</div><div class="line"><a name="l02327"></a><span class="lineno"> 2327</span>&#160;       snprintf(outStr, strLen, <span class="stringliteral">&quot;%u&quot;</span>, static_cast&lt;unsigned int&gt;(num));</div><div class="line"><a name="l02328"></a><span class="lineno"> 2328</span>&#160;   }</div><div class="line"><a name="l02329"></a><span class="lineno"> 2329</span>&#160;   <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> VmaUint64ToStr(<span class="keywordtype">char</span>* outStr, <span class="keywordtype">size_t</span> strLen, uint64_t num)</div><div class="line"><a name="l02330"></a><span class="lineno"> 2330</span>&#160;   {</div><div class="line"><a name="l02331"></a><span class="lineno"> 2331</span>&#160;       snprintf(outStr, strLen, <span class="stringliteral">&quot;%llu&quot;</span>, static_cast&lt;unsigned long long&gt;(num));</div><div class="line"><a name="l02332"></a><span class="lineno"> 2332</span>&#160;   }</div><div class="line"><a name="l02333"></a><span class="lineno"> 2333</span>&#160;   <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> VmaPtrToStr(<span class="keywordtype">char</span>* outStr, <span class="keywordtype">size_t</span> strLen, <span class="keyword">const</span> <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l02334"></a><span class="lineno"> 2334</span>&#160;   {</div><div class="line"><a name="l02335"></a><span class="lineno"> 2335</span>&#160;       snprintf(outStr, strLen, <span class="stringliteral">&quot;%p&quot;</span>, ptr);</div><div class="line"><a name="l02336"></a><span class="lineno"> 2336</span>&#160;   }</div><div class="line"><a name="l02337"></a><span class="lineno"> 2337</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02338"></a><span class="lineno"> 2338</span>&#160;</div><div class="line"><a name="l02339"></a><span class="lineno"> 2339</span>&#160;<span class="preprocessor">#ifndef VMA_MUTEX</span></div><div class="line"><a name="l02340"></a><span class="lineno"> 2340</span>&#160;   <span class="keyword">class </span>VmaMutex</div><div class="line"><a name="l02341"></a><span class="lineno"> 2341</span>&#160;   {</div><div class="line"><a name="l02342"></a><span class="lineno"> 2342</span>&#160;   <span class="keyword">public</span>:</div><div class="line"><a name="l02343"></a><span class="lineno"> 2343</span>&#160;       VmaMutex() { }</div><div class="line"><a name="l02344"></a><span class="lineno"> 2344</span>&#160;       ~VmaMutex() { }</div><div class="line"><a name="l02345"></a><span class="lineno"> 2345</span>&#160;       <span class="keywordtype">void</span> Lock() { m_Mutex.lock(); }</div><div class="line"><a name="l02346"></a><span class="lineno"> 2346</span>&#160;       <span class="keywordtype">void</span> Unlock() { m_Mutex.unlock(); }</div><div class="line"><a name="l02347"></a><span class="lineno"> 2347</span>&#160;   <span class="keyword">private</span>:</div><div class="line"><a name="l02348"></a><span class="lineno"> 2348</span>&#160;       std::mutex m_Mutex;</div><div class="line"><a name="l02349"></a><span class="lineno"> 2349</span>&#160;   };</div><div class="line"><a name="l02350"></a><span class="lineno"> 2350</span>&#160;<span class="preprocessor">   #define VMA_MUTEX VmaMutex</span></div><div class="line"><a name="l02351"></a><span class="lineno"> 2351</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02352"></a><span class="lineno"> 2352</span>&#160;</div><div class="line"><a name="l02353"></a><span class="lineno"> 2353</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02354"></a><span class="lineno"> 2354</span>&#160;<span class="comment">If providing your own implementation, you need to implement a subset of std::atomic:</span></div><div class="line"><a name="l02355"></a><span class="lineno"> 2355</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02356"></a><span class="lineno"> 2356</span>&#160;<span class="comment">- Constructor(uint32_t desired)</span></div><div class="line"><a name="l02357"></a><span class="lineno"> 2357</span>&#160;<span class="comment">- uint32_t load() const</span></div><div class="line"><a name="l02358"></a><span class="lineno"> 2358</span>&#160;<span class="comment">- void store(uint32_t desired)</span></div><div class="line"><a name="l02359"></a><span class="lineno"> 2359</span>&#160;<span class="comment">- bool compare_exchange_weak(uint32_t&amp; expected, uint32_t desired)</span></div><div class="line"><a name="l02360"></a><span class="lineno"> 2360</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02361"></a><span class="lineno"> 2361</span>&#160;<span class="preprocessor">#ifndef VMA_ATOMIC_UINT32</span></div><div class="line"><a name="l02362"></a><span class="lineno"> 2362</span>&#160;<span class="preprocessor">   #define VMA_ATOMIC_UINT32 std::atomic&lt;uint32_t&gt;</span></div><div class="line"><a name="l02363"></a><span class="lineno"> 2363</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02364"></a><span class="lineno"> 2364</span>&#160;</div><div class="line"><a name="l02365"></a><span class="lineno"> 2365</span>&#160;<span class="preprocessor">#ifndef VMA_BEST_FIT</span></div><div class="line"><a name="l02366"></a><span class="lineno"> 2366</span>&#160;</div><div class="line"><a name="l02378"></a><span class="lineno"> 2378</span>&#160;<span class="preprocessor">   #define VMA_BEST_FIT (1)</span></div><div class="line"><a name="l02379"></a><span class="lineno"> 2379</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02380"></a><span class="lineno"> 2380</span>&#160;</div><div class="line"><a name="l02381"></a><span class="lineno"> 2381</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_ALWAYS_DEDICATED_MEMORY</span></div><div class="line"><a name="l02382"></a><span class="lineno"> 2382</span>&#160;</div><div class="line"><a name="l02386"></a><span class="lineno"> 2386</span>&#160;<span class="preprocessor">   #define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0)</span></div><div class="line"><a name="l02387"></a><span class="lineno"> 2387</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02388"></a><span class="lineno"> 2388</span>&#160;</div><div class="line"><a name="l02389"></a><span class="lineno"> 2389</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_ALIGNMENT</span></div><div class="line"><a name="l02390"></a><span class="lineno"> 2390</span>&#160;</div><div class="line"><a name="l02394"></a><span class="lineno"> 2394</span>&#160;<span class="preprocessor">   #define VMA_DEBUG_ALIGNMENT (1)</span></div><div class="line"><a name="l02395"></a><span class="lineno"> 2395</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02396"></a><span class="lineno"> 2396</span>&#160;</div><div class="line"><a name="l02397"></a><span class="lineno"> 2397</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_MARGIN</span></div><div class="line"><a name="l02398"></a><span class="lineno"> 2398</span>&#160;</div><div class="line"><a name="l02402"></a><span class="lineno"> 2402</span>&#160;<span class="preprocessor">   #define VMA_DEBUG_MARGIN (0)</span></div><div class="line"><a name="l02403"></a><span class="lineno"> 2403</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02404"></a><span class="lineno"> 2404</span>&#160;</div><div class="line"><a name="l02405"></a><span class="lineno"> 2405</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_GLOBAL_MUTEX</span></div><div class="line"><a name="l02406"></a><span class="lineno"> 2406</span>&#160;</div><div class="line"><a name="l02410"></a><span class="lineno"> 2410</span>&#160;<span class="preprocessor">   #define VMA_DEBUG_GLOBAL_MUTEX (0)</span></div><div class="line"><a name="l02411"></a><span class="lineno"> 2411</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02412"></a><span class="lineno"> 2412</span>&#160;</div><div class="line"><a name="l02413"></a><span class="lineno"> 2413</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY</span></div><div class="line"><a name="l02414"></a><span class="lineno"> 2414</span>&#160;</div><div class="line"><a name="l02418"></a><span class="lineno"> 2418</span>&#160;<span class="preprocessor">   #define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1)</span></div><div class="line"><a name="l02419"></a><span class="lineno"> 2419</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02420"></a><span class="lineno"> 2420</span>&#160;</div><div class="line"><a name="l02421"></a><span class="lineno"> 2421</span>&#160;<span class="preprocessor">#ifndef VMA_SMALL_HEAP_MAX_SIZE</span></div><div class="line"><a name="l02422"></a><span class="lineno"> 2422</span>&#160;<span class="preprocessor">   #define VMA_SMALL_HEAP_MAX_SIZE (1024ull * 1024 * 1024)</span></div><div class="line"><a name="l02424"></a><span class="lineno"> 2424</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02425"></a><span class="lineno"> 2425</span>&#160;</div><div class="line"><a name="l02426"></a><span class="lineno"> 2426</span>&#160;<span class="preprocessor">#ifndef VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE</span></div><div class="line"><a name="l02427"></a><span class="lineno"> 2427</span>&#160;<span class="preprocessor">   #define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256ull * 1024 * 1024)</span></div><div class="line"><a name="l02429"></a><span class="lineno"> 2429</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02430"></a><span class="lineno"> 2430</span>&#160;</div><div class="line"><a name="l02431"></a><span class="lineno"> 2431</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint32_t VMA_FRAME_INDEX_LOST = UINT32_MAX;</div><div class="line"><a name="l02432"></a><span class="lineno"> 2432</span>&#160;</div><div class="line"><a name="l02433"></a><span class="lineno"> 2433</span>&#160;<span class="comment">/*******************************************************************************</span></div><div class="line"><a name="l02434"></a><span class="lineno"> 2434</span>&#160;<span class="comment">END OF CONFIGURATION</span></div><div class="line"><a name="l02435"></a><span class="lineno"> 2435</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02436"></a><span class="lineno"> 2436</span>&#160;</div><div class="line"><a name="l02437"></a><span class="lineno"> 2437</span>&#160;<span class="keyword">static</span> VkAllocationCallbacks VmaEmptyAllocationCallbacks = {</div><div class="line"><a name="l02438"></a><span class="lineno"> 2438</span>&#160;    VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL };</div><div class="line"><a name="l02439"></a><span class="lineno"> 2439</span>&#160;</div><div class="line"><a name="l02440"></a><span class="lineno"> 2440</span>&#160;<span class="comment">// Returns number of bits set to 1 in (v).</span></div><div class="line"><a name="l02441"></a><span class="lineno"> 2441</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> uint32_t VmaCountBitsSet(uint32_t v)</div><div class="line"><a name="l02442"></a><span class="lineno"> 2442</span>&#160;{</div><div class="line"><a name="l02443"></a><span class="lineno"> 2443</span>&#160;    uint32_t c = v - ((v &gt;&gt; 1) &amp; 0x55555555);</div><div class="line"><a name="l02444"></a><span class="lineno"> 2444</span>&#160;    c = ((c &gt;&gt;  2) &amp; 0x33333333) + (c &amp; 0x33333333);</div><div class="line"><a name="l02445"></a><span class="lineno"> 2445</span>&#160;    c = ((c &gt;&gt;  4) + c) &amp; 0x0F0F0F0F;</div><div class="line"><a name="l02446"></a><span class="lineno"> 2446</span>&#160;    c = ((c &gt;&gt;  8) + c) &amp; 0x00FF00FF;</div><div class="line"><a name="l02447"></a><span class="lineno"> 2447</span>&#160;    c = ((c &gt;&gt; 16) + c) &amp; 0x0000FFFF;</div><div class="line"><a name="l02448"></a><span class="lineno"> 2448</span>&#160;    <span class="keywordflow">return</span> c;</div><div class="line"><a name="l02449"></a><span class="lineno"> 2449</span>&#160;}</div><div class="line"><a name="l02450"></a><span class="lineno"> 2450</span>&#160;</div><div class="line"><a name="l02451"></a><span class="lineno"> 2451</span>&#160;<span class="comment">// Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16.</span></div><div class="line"><a name="l02452"></a><span class="lineno"> 2452</span>&#160;<span class="comment">// Use types like uint32_t, uint64_t as T.</span></div><div class="line"><a name="l02453"></a><span class="lineno"> 2453</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02454"></a><span class="lineno"> 2454</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> T VmaAlignUp(T val, T align)</div><div class="line"><a name="l02455"></a><span class="lineno"> 2455</span>&#160;{</div><div class="line"><a name="l02456"></a><span class="lineno"> 2456</span>&#160;    <span class="keywordflow">return</span> (val + align - 1) / align * align;</div><div class="line"><a name="l02457"></a><span class="lineno"> 2457</span>&#160;}</div><div class="line"><a name="l02458"></a><span class="lineno"> 2458</span>&#160;</div><div class="line"><a name="l02459"></a><span class="lineno"> 2459</span>&#160;<span class="comment">// Division with mathematical rounding to nearest number.</span></div><div class="line"><a name="l02460"></a><span class="lineno"> 2460</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02461"></a><span class="lineno"> 2461</span>&#160;<span class="keyword">inline</span> T VmaRoundDiv(T x, T y)</div><div class="line"><a name="l02462"></a><span class="lineno"> 2462</span>&#160;{</div><div class="line"><a name="l02463"></a><span class="lineno"> 2463</span>&#160;    <span class="keywordflow">return</span> (x + (y / (T)2)) / y;</div><div class="line"><a name="l02464"></a><span class="lineno"> 2464</span>&#160;}</div><div class="line"><a name="l02465"></a><span class="lineno"> 2465</span>&#160;</div><div class="line"><a name="l02466"></a><span class="lineno"> 2466</span>&#160;<span class="preprocessor">#ifndef VMA_SORT</span></div><div class="line"><a name="l02467"></a><span class="lineno"> 2467</span>&#160;</div><div class="line"><a name="l02468"></a><span class="lineno"> 2468</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> Iterator, <span class="keyword">typename</span> Compare&gt;</div><div class="line"><a name="l02469"></a><span class="lineno"> 2469</span>&#160;Iterator VmaQuickSortPartition(Iterator beg, Iterator end, Compare cmp)</div><div class="line"><a name="l02470"></a><span class="lineno"> 2470</span>&#160;{</div><div class="line"><a name="l02471"></a><span class="lineno"> 2471</span>&#160;    Iterator centerValue = end; --centerValue;</div><div class="line"><a name="l02472"></a><span class="lineno"> 2472</span>&#160;    Iterator insertIndex = beg;</div><div class="line"><a name="l02473"></a><span class="lineno"> 2473</span>&#160;    <span class="keywordflow">for</span>(Iterator memTypeIndex = beg; memTypeIndex &lt; centerValue; ++memTypeIndex)</div><div class="line"><a name="l02474"></a><span class="lineno"> 2474</span>&#160;    {</div><div class="line"><a name="l02475"></a><span class="lineno"> 2475</span>&#160;        <span class="keywordflow">if</span>(cmp(*memTypeIndex, *centerValue))</div><div class="line"><a name="l02476"></a><span class="lineno"> 2476</span>&#160;        {</div><div class="line"><a name="l02477"></a><span class="lineno"> 2477</span>&#160;            <span class="keywordflow">if</span>(insertIndex != memTypeIndex)</div><div class="line"><a name="l02478"></a><span class="lineno"> 2478</span>&#160;            {</div><div class="line"><a name="l02479"></a><span class="lineno"> 2479</span>&#160;                VMA_SWAP(*memTypeIndex, *insertIndex);</div><div class="line"><a name="l02480"></a><span class="lineno"> 2480</span>&#160;            }</div><div class="line"><a name="l02481"></a><span class="lineno"> 2481</span>&#160;            ++insertIndex;</div><div class="line"><a name="l02482"></a><span class="lineno"> 2482</span>&#160;        }</div><div class="line"><a name="l02483"></a><span class="lineno"> 2483</span>&#160;    }</div><div class="line"><a name="l02484"></a><span class="lineno"> 2484</span>&#160;    <span class="keywordflow">if</span>(insertIndex != centerValue)</div><div class="line"><a name="l02485"></a><span class="lineno"> 2485</span>&#160;    {</div><div class="line"><a name="l02486"></a><span class="lineno"> 2486</span>&#160;        VMA_SWAP(*insertIndex, *centerValue);</div><div class="line"><a name="l02487"></a><span class="lineno"> 2487</span>&#160;    }</div><div class="line"><a name="l02488"></a><span class="lineno"> 2488</span>&#160;    <span class="keywordflow">return</span> insertIndex;</div><div class="line"><a name="l02489"></a><span class="lineno"> 2489</span>&#160;}</div><div class="line"><a name="l02490"></a><span class="lineno"> 2490</span>&#160;</div><div class="line"><a name="l02491"></a><span class="lineno"> 2491</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> Iterator, <span class="keyword">typename</span> Compare&gt;</div><div class="line"><a name="l02492"></a><span class="lineno"> 2492</span>&#160;<span class="keywordtype">void</span> VmaQuickSort(Iterator beg, Iterator end, Compare cmp)</div><div class="line"><a name="l02493"></a><span class="lineno"> 2493</span>&#160;{</div><div class="line"><a name="l02494"></a><span class="lineno"> 2494</span>&#160;    <span class="keywordflow">if</span>(beg &lt; end)</div><div class="line"><a name="l02495"></a><span class="lineno"> 2495</span>&#160;    {</div><div class="line"><a name="l02496"></a><span class="lineno"> 2496</span>&#160;        Iterator it = VmaQuickSortPartition&lt;Iterator, Compare&gt;(beg, end, cmp);</div><div class="line"><a name="l02497"></a><span class="lineno"> 2497</span>&#160;        VmaQuickSort&lt;Iterator, Compare&gt;(beg, it, cmp);</div><div class="line"><a name="l02498"></a><span class="lineno"> 2498</span>&#160;        VmaQuickSort&lt;Iterator, Compare&gt;(it + 1, end, cmp);</div><div class="line"><a name="l02499"></a><span class="lineno"> 2499</span>&#160;    }</div><div class="line"><a name="l02500"></a><span class="lineno"> 2500</span>&#160;}</div><div class="line"><a name="l02501"></a><span class="lineno"> 2501</span>&#160;</div><div class="line"><a name="l02502"></a><span class="lineno"> 2502</span>&#160;<span class="preprocessor">#define VMA_SORT(beg, end, cmp) VmaQuickSort(beg, end, cmp)</span></div><div class="line"><a name="l02503"></a><span class="lineno"> 2503</span>&#160;</div><div class="line"><a name="l02504"></a><span class="lineno"> 2504</span>&#160;<span class="preprocessor">#endif // #ifndef VMA_SORT</span></div><div class="line"><a name="l02505"></a><span class="lineno"> 2505</span>&#160;</div><div class="line"><a name="l02506"></a><span class="lineno"> 2506</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02507"></a><span class="lineno"> 2507</span>&#160;<span class="comment">Returns true if two memory blocks occupy overlapping pages.</span></div><div class="line"><a name="l02508"></a><span class="lineno"> 2508</span>&#160;<span class="comment">ResourceA must be in less memory offset than ResourceB.</span></div><div class="line"><a name="l02509"></a><span class="lineno"> 2509</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02510"></a><span class="lineno"> 2510</span>&#160;<span class="comment">Algorithm is based on &quot;Vulkan 1.0.39 - A Specification (with all registered Vulkan extensions)&quot;</span></div><div class="line"><a name="l02511"></a><span class="lineno"> 2511</span>&#160;<span class="comment">chapter 11.6 &quot;Resource Memory Association&quot;, paragraph &quot;Buffer-Image Granularity&quot;.</span></div><div class="line"><a name="l02512"></a><span class="lineno"> 2512</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02513"></a><span class="lineno"> 2513</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> VmaBlocksOnSamePage(</div><div class="line"><a name="l02514"></a><span class="lineno"> 2514</span>&#160;    VkDeviceSize resourceAOffset,</div><div class="line"><a name="l02515"></a><span class="lineno"> 2515</span>&#160;    VkDeviceSize resourceASize,</div><div class="line"><a name="l02516"></a><span class="lineno"> 2516</span>&#160;    VkDeviceSize resourceBOffset,</div><div class="line"><a name="l02517"></a><span class="lineno"> 2517</span>&#160;    VkDeviceSize pageSize)</div><div class="line"><a name="l02518"></a><span class="lineno"> 2518</span>&#160;{</div><div class="line"><a name="l02519"></a><span class="lineno"> 2519</span>&#160;    VMA_ASSERT(resourceAOffset + resourceASize &lt;= resourceBOffset &amp;&amp; resourceASize &gt; 0 &amp;&amp; pageSize &gt; 0);</div><div class="line"><a name="l02520"></a><span class="lineno"> 2520</span>&#160;    VkDeviceSize resourceAEnd = resourceAOffset + resourceASize - 1;</div><div class="line"><a name="l02521"></a><span class="lineno"> 2521</span>&#160;    VkDeviceSize resourceAEndPage = resourceAEnd &amp; ~(pageSize - 1);</div><div class="line"><a name="l02522"></a><span class="lineno"> 2522</span>&#160;    VkDeviceSize resourceBStart = resourceBOffset;</div><div class="line"><a name="l02523"></a><span class="lineno"> 2523</span>&#160;    VkDeviceSize resourceBStartPage = resourceBStart &amp; ~(pageSize - 1);</div><div class="line"><a name="l02524"></a><span class="lineno"> 2524</span>&#160;    <span class="keywordflow">return</span> resourceAEndPage == resourceBStartPage;</div><div class="line"><a name="l02525"></a><span class="lineno"> 2525</span>&#160;}</div><div class="line"><a name="l02526"></a><span class="lineno"> 2526</span>&#160;</div><div class="line"><a name="l02527"></a><span class="lineno"> 2527</span>&#160;<span class="keyword">enum</span> VmaSuballocationType</div><div class="line"><a name="l02528"></a><span class="lineno"> 2528</span>&#160;{</div><div class="line"><a name="l02529"></a><span class="lineno"> 2529</span>&#160;    VMA_SUBALLOCATION_TYPE_FREE = 0,</div><div class="line"><a name="l02530"></a><span class="lineno"> 2530</span>&#160;    VMA_SUBALLOCATION_TYPE_UNKNOWN = 1,</div><div class="line"><a name="l02531"></a><span class="lineno"> 2531</span>&#160;    VMA_SUBALLOCATION_TYPE_BUFFER = 2,</div><div class="line"><a name="l02532"></a><span class="lineno"> 2532</span>&#160;    VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN = 3,</div><div class="line"><a name="l02533"></a><span class="lineno"> 2533</span>&#160;    VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR = 4,</div><div class="line"><a name="l02534"></a><span class="lineno"> 2534</span>&#160;    VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL = 5,</div><div class="line"><a name="l02535"></a><span class="lineno"> 2535</span>&#160;    VMA_SUBALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF</div><div class="line"><a name="l02536"></a><span class="lineno"> 2536</span>&#160;};</div><div class="line"><a name="l02537"></a><span class="lineno"> 2537</span>&#160;</div><div class="line"><a name="l02538"></a><span class="lineno"> 2538</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02539"></a><span class="lineno"> 2539</span>&#160;<span class="comment">Returns true if given suballocation types could conflict and must respect</span></div><div class="line"><a name="l02540"></a><span class="lineno"> 2540</span>&#160;<span class="comment">VkPhysicalDeviceLimits::bufferImageGranularity. They conflict if one is buffer</span></div><div class="line"><a name="l02541"></a><span class="lineno"> 2541</span>&#160;<span class="comment">or linear image and another one is optimal image. If type is unknown, behave</span></div><div class="line"><a name="l02542"></a><span class="lineno"> 2542</span>&#160;<span class="comment">conservatively.</span></div><div class="line"><a name="l02543"></a><span class="lineno"> 2543</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02544"></a><span class="lineno"> 2544</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> VmaIsBufferImageGranularityConflict(</div><div class="line"><a name="l02545"></a><span class="lineno"> 2545</span>&#160;    VmaSuballocationType suballocType1,</div><div class="line"><a name="l02546"></a><span class="lineno"> 2546</span>&#160;    VmaSuballocationType suballocType2)</div><div class="line"><a name="l02547"></a><span class="lineno"> 2547</span>&#160;{</div><div class="line"><a name="l02548"></a><span class="lineno"> 2548</span>&#160;    <span class="keywordflow">if</span>(suballocType1 &gt; suballocType2)</div><div class="line"><a name="l02549"></a><span class="lineno"> 2549</span>&#160;    {</div><div class="line"><a name="l02550"></a><span class="lineno"> 2550</span>&#160;        VMA_SWAP(suballocType1, suballocType2);</div><div class="line"><a name="l02551"></a><span class="lineno"> 2551</span>&#160;    }</div><div class="line"><a name="l02552"></a><span class="lineno"> 2552</span>&#160;    </div><div class="line"><a name="l02553"></a><span class="lineno"> 2553</span>&#160;    <span class="keywordflow">switch</span>(suballocType1)</div><div class="line"><a name="l02554"></a><span class="lineno"> 2554</span>&#160;    {</div><div class="line"><a name="l02555"></a><span class="lineno"> 2555</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_FREE:</div><div class="line"><a name="l02556"></a><span class="lineno"> 2556</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l02557"></a><span class="lineno"> 2557</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_UNKNOWN:</div><div class="line"><a name="l02558"></a><span class="lineno"> 2558</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l02559"></a><span class="lineno"> 2559</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_BUFFER:</div><div class="line"><a name="l02560"></a><span class="lineno"> 2560</span>&#160;        <span class="keywordflow">return</span></div><div class="line"><a name="l02561"></a><span class="lineno"> 2561</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||</div><div class="line"><a name="l02562"></a><span class="lineno"> 2562</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;</div><div class="line"><a name="l02563"></a><span class="lineno"> 2563</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN:</div><div class="line"><a name="l02564"></a><span class="lineno"> 2564</span>&#160;        <span class="keywordflow">return</span></div><div class="line"><a name="l02565"></a><span class="lineno"> 2565</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||</div><div class="line"><a name="l02566"></a><span class="lineno"> 2566</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR ||</div><div class="line"><a name="l02567"></a><span class="lineno"> 2567</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;</div><div class="line"><a name="l02568"></a><span class="lineno"> 2568</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR:</div><div class="line"><a name="l02569"></a><span class="lineno"> 2569</span>&#160;        <span class="keywordflow">return</span></div><div class="line"><a name="l02570"></a><span class="lineno"> 2570</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;</div><div class="line"><a name="l02571"></a><span class="lineno"> 2571</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL:</div><div class="line"><a name="l02572"></a><span class="lineno"> 2572</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l02573"></a><span class="lineno"> 2573</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l02574"></a><span class="lineno"> 2574</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l02575"></a><span class="lineno"> 2575</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l02576"></a><span class="lineno"> 2576</span>&#160;    }</div><div class="line"><a name="l02577"></a><span class="lineno"> 2577</span>&#160;}</div><div class="line"><a name="l02578"></a><span class="lineno"> 2578</span>&#160;</div><div class="line"><a name="l02579"></a><span class="lineno"> 2579</span>&#160;<span class="comment">// Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope).</span></div><div class="line"><a name="l02580"></a><span class="lineno"> 2580</span>&#160;<span class="keyword">struct </span>VmaMutexLock</div><div class="line"><a name="l02581"></a><span class="lineno"> 2581</span>&#160;{</div><div class="line"><a name="l02582"></a><span class="lineno"> 2582</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l02583"></a><span class="lineno"> 2583</span>&#160;    VmaMutexLock(VMA_MUTEX&amp; mutex, <span class="keywordtype">bool</span> useMutex) :</div><div class="line"><a name="l02584"></a><span class="lineno"> 2584</span>&#160;        m_pMutex(useMutex ? &amp;mutex : VMA_NULL)</div><div class="line"><a name="l02585"></a><span class="lineno"> 2585</span>&#160;    {</div><div class="line"><a name="l02586"></a><span class="lineno"> 2586</span>&#160;        <span class="keywordflow">if</span>(m_pMutex)</div><div class="line"><a name="l02587"></a><span class="lineno"> 2587</span>&#160;        {</div><div class="line"><a name="l02588"></a><span class="lineno"> 2588</span>&#160;            m_pMutex-&gt;Lock();</div><div class="line"><a name="l02589"></a><span class="lineno"> 2589</span>&#160;        }</div><div class="line"><a name="l02590"></a><span class="lineno"> 2590</span>&#160;    }</div><div class="line"><a name="l02591"></a><span class="lineno"> 2591</span>&#160;    </div><div class="line"><a name="l02592"></a><span class="lineno"> 2592</span>&#160;    ~VmaMutexLock()</div><div class="line"><a name="l02593"></a><span class="lineno"> 2593</span>&#160;    {</div><div class="line"><a name="l02594"></a><span class="lineno"> 2594</span>&#160;        <span class="keywordflow">if</span>(m_pMutex)</div><div class="line"><a name="l02595"></a><span class="lineno"> 2595</span>&#160;        {</div><div class="line"><a name="l02596"></a><span class="lineno"> 2596</span>&#160;            m_pMutex-&gt;Unlock();</div><div class="line"><a name="l02597"></a><span class="lineno"> 2597</span>&#160;        }</div><div class="line"><a name="l02598"></a><span class="lineno"> 2598</span>&#160;    }</div><div class="line"><a name="l02599"></a><span class="lineno"> 2599</span>&#160;</div><div class="line"><a name="l02600"></a><span class="lineno"> 2600</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l02601"></a><span class="lineno"> 2601</span>&#160;    VMA_MUTEX* m_pMutex;</div><div class="line"><a name="l02602"></a><span class="lineno"> 2602</span>&#160;};</div><div class="line"><a name="l02603"></a><span class="lineno"> 2603</span>&#160;</div><div class="line"><a name="l02604"></a><span class="lineno"> 2604</span>&#160;<span class="preprocessor">#if VMA_DEBUG_GLOBAL_MUTEX</span></div><div class="line"><a name="l02605"></a><span class="lineno"> 2605</span>&#160;    <span class="keyword">static</span> VMA_MUTEX gDebugGlobalMutex;</div><div class="line"><a name="l02606"></a><span class="lineno"> 2606</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex, true);</span></div><div class="line"><a name="l02607"></a><span class="lineno"> 2607</span>&#160;<span class="preprocessor">#else</span></div><div class="line"><a name="l02608"></a><span class="lineno"> 2608</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_GLOBAL_MUTEX_LOCK</span></div><div class="line"><a name="l02609"></a><span class="lineno"> 2609</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02610"></a><span class="lineno"> 2610</span>&#160;</div><div class="line"><a name="l02611"></a><span class="lineno"> 2611</span>&#160;<span class="comment">// Minimum size of a free suballocation to register it in the free suballocation collection.</span></div><div class="line"><a name="l02612"></a><span class="lineno"> 2612</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> VkDeviceSize VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER = 16;</div><div class="line"><a name="l02613"></a><span class="lineno"> 2613</span>&#160;</div><div class="line"><a name="l02614"></a><span class="lineno"> 2614</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02615"></a><span class="lineno"> 2615</span>&#160;<span class="comment">Performs binary search and returns iterator to first element that is greater or</span></div><div class="line"><a name="l02616"></a><span class="lineno"> 2616</span>&#160;<span class="comment">equal to (key), according to comparison (cmp).</span></div><div class="line"><a name="l02617"></a><span class="lineno"> 2617</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02618"></a><span class="lineno"> 2618</span>&#160;<span class="comment">Cmp should return true if first argument is less than second argument.</span></div><div class="line"><a name="l02619"></a><span class="lineno"> 2619</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02620"></a><span class="lineno"> 2620</span>&#160;<span class="comment">Returned value is the found element, if present in the collection or place where</span></div><div class="line"><a name="l02621"></a><span class="lineno"> 2621</span>&#160;<span class="comment">new element with value (key) should be inserted.</span></div><div class="line"><a name="l02622"></a><span class="lineno"> 2622</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02623"></a><span class="lineno"> 2623</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> IterT, <span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> CmpT&gt;</div><div class="line"><a name="l02624"></a><span class="lineno"> 2624</span>&#160;<span class="keyword">static</span> IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, <span class="keyword">const</span> KeyT &amp;key, CmpT cmp)</div><div class="line"><a name="l02625"></a><span class="lineno"> 2625</span>&#160;{</div><div class="line"><a name="l02626"></a><span class="lineno"> 2626</span>&#160;   <span class="keywordtype">size_t</span> down = 0, up = (end - beg);</div><div class="line"><a name="l02627"></a><span class="lineno"> 2627</span>&#160;   <span class="keywordflow">while</span>(down &lt; up)</div><div class="line"><a name="l02628"></a><span class="lineno"> 2628</span>&#160;   {</div><div class="line"><a name="l02629"></a><span class="lineno"> 2629</span>&#160;      <span class="keyword">const</span> <span class="keywordtype">size_t</span> mid = (down + up) / 2;</div><div class="line"><a name="l02630"></a><span class="lineno"> 2630</span>&#160;      <span class="keywordflow">if</span>(cmp(*(beg+mid), key))</div><div class="line"><a name="l02631"></a><span class="lineno"> 2631</span>&#160;      {</div><div class="line"><a name="l02632"></a><span class="lineno"> 2632</span>&#160;         down = mid + 1;</div><div class="line"><a name="l02633"></a><span class="lineno"> 2633</span>&#160;      }</div><div class="line"><a name="l02634"></a><span class="lineno"> 2634</span>&#160;      <span class="keywordflow">else</span></div><div class="line"><a name="l02635"></a><span class="lineno"> 2635</span>&#160;      {</div><div class="line"><a name="l02636"></a><span class="lineno"> 2636</span>&#160;         up = mid;</div><div class="line"><a name="l02637"></a><span class="lineno"> 2637</span>&#160;      }</div><div class="line"><a name="l02638"></a><span class="lineno"> 2638</span>&#160;   }</div><div class="line"><a name="l02639"></a><span class="lineno"> 2639</span>&#160;   <span class="keywordflow">return</span> beg + down;</div><div class="line"><a name="l02640"></a><span class="lineno"> 2640</span>&#160;}</div><div class="line"><a name="l02641"></a><span class="lineno"> 2641</span>&#160;</div><div class="line"><a name="l02643"></a><span class="lineno"> 2643</span>&#160;<span class="comment">// Memory allocation</span></div><div class="line"><a name="l02644"></a><span class="lineno"> 2644</span>&#160;</div><div class="line"><a name="l02645"></a><span class="lineno"> 2645</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span>* VmaMalloc(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment)</div><div class="line"><a name="l02646"></a><span class="lineno"> 2646</span>&#160;{</div><div class="line"><a name="l02647"></a><span class="lineno"> 2647</span>&#160;    <span class="keywordflow">if</span>((pAllocationCallbacks != VMA_NULL) &amp;&amp;</div><div class="line"><a name="l02648"></a><span class="lineno"> 2648</span>&#160;        (pAllocationCallbacks-&gt;pfnAllocation != VMA_NULL))</div><div class="line"><a name="l02649"></a><span class="lineno"> 2649</span>&#160;    {</div><div class="line"><a name="l02650"></a><span class="lineno"> 2650</span>&#160;        <span class="keywordflow">return</span> (*pAllocationCallbacks-&gt;pfnAllocation)(</div><div class="line"><a name="l02651"></a><span class="lineno"> 2651</span>&#160;            pAllocationCallbacks-&gt;pUserData,</div><div class="line"><a name="l02652"></a><span class="lineno"> 2652</span>&#160;            size,</div><div class="line"><a name="l02653"></a><span class="lineno"> 2653</span>&#160;            alignment,</div><div class="line"><a name="l02654"></a><span class="lineno"> 2654</span>&#160;            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);</div><div class="line"><a name="l02655"></a><span class="lineno"> 2655</span>&#160;    }</div><div class="line"><a name="l02656"></a><span class="lineno"> 2656</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l02657"></a><span class="lineno"> 2657</span>&#160;    {</div><div class="line"><a name="l02658"></a><span class="lineno"> 2658</span>&#160;        <span class="keywordflow">return</span> VMA_SYSTEM_ALIGNED_MALLOC(size, alignment);</div><div class="line"><a name="l02659"></a><span class="lineno"> 2659</span>&#160;    }</div><div class="line"><a name="l02660"></a><span class="lineno"> 2660</span>&#160;}</div><div class="line"><a name="l02661"></a><span class="lineno"> 2661</span>&#160;</div><div class="line"><a name="l02662"></a><span class="lineno"> 2662</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaFree(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l02663"></a><span class="lineno"> 2663</span>&#160;{</div><div class="line"><a name="l02664"></a><span class="lineno"> 2664</span>&#160;    <span class="keywordflow">if</span>((pAllocationCallbacks != VMA_NULL) &amp;&amp;</div><div class="line"><a name="l02665"></a><span class="lineno"> 2665</span>&#160;        (pAllocationCallbacks-&gt;pfnFree != VMA_NULL))</div><div class="line"><a name="l02666"></a><span class="lineno"> 2666</span>&#160;    {</div><div class="line"><a name="l02667"></a><span class="lineno"> 2667</span>&#160;        (*pAllocationCallbacks-&gt;pfnFree)(pAllocationCallbacks-&gt;pUserData, ptr);</div><div class="line"><a name="l02668"></a><span class="lineno"> 2668</span>&#160;    }</div><div class="line"><a name="l02669"></a><span class="lineno"> 2669</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l02670"></a><span class="lineno"> 2670</span>&#160;    {</div><div class="line"><a name="l02671"></a><span class="lineno"> 2671</span>&#160;        VMA_SYSTEM_FREE(ptr);</div><div class="line"><a name="l02672"></a><span class="lineno"> 2672</span>&#160;    }</div><div class="line"><a name="l02673"></a><span class="lineno"> 2673</span>&#160;}</div><div class="line"><a name="l02674"></a><span class="lineno"> 2674</span>&#160;</div><div class="line"><a name="l02675"></a><span class="lineno"> 2675</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02676"></a><span class="lineno"> 2676</span>&#160;<span class="keyword">static</span> T* VmaAllocate(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks)</div><div class="line"><a name="l02677"></a><span class="lineno"> 2677</span>&#160;{</div><div class="line"><a name="l02678"></a><span class="lineno"> 2678</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(pAllocationCallbacks, <span class="keyword">sizeof</span>(T), VMA_ALIGN_OF(T));</div><div class="line"><a name="l02679"></a><span class="lineno"> 2679</span>&#160;}</div><div class="line"><a name="l02680"></a><span class="lineno"> 2680</span>&#160;</div><div class="line"><a name="l02681"></a><span class="lineno"> 2681</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02682"></a><span class="lineno"> 2682</span>&#160;<span class="keyword">static</span> T* VmaAllocateArray(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l02683"></a><span class="lineno"> 2683</span>&#160;{</div><div class="line"><a name="l02684"></a><span class="lineno"> 2684</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(pAllocationCallbacks, <span class="keyword">sizeof</span>(T) * count, VMA_ALIGN_OF(T));</div><div class="line"><a name="l02685"></a><span class="lineno"> 2685</span>&#160;}</div><div class="line"><a name="l02686"></a><span class="lineno"> 2686</span>&#160;</div><div class="line"><a name="l02687"></a><span class="lineno"> 2687</span>&#160;<span class="preprocessor">#define vma_new(allocator, type)   new(VmaAllocate&lt;type&gt;(allocator))(type)</span></div><div class="line"><a name="l02688"></a><span class="lineno"> 2688</span>&#160;</div><div class="line"><a name="l02689"></a><span class="lineno"> 2689</span>&#160;<span class="preprocessor">#define vma_new_array(allocator, type, count)   new(VmaAllocateArray&lt;type&gt;((allocator), (count)))(type)</span></div><div class="line"><a name="l02690"></a><span class="lineno"> 2690</span>&#160;</div><div class="line"><a name="l02691"></a><span class="lineno"> 2691</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02692"></a><span class="lineno"> 2692</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, T* ptr)</div><div class="line"><a name="l02693"></a><span class="lineno"> 2693</span>&#160;{</div><div class="line"><a name="l02694"></a><span class="lineno"> 2694</span>&#160;    ptr-&gt;~T();</div><div class="line"><a name="l02695"></a><span class="lineno"> 2695</span>&#160;    VmaFree(pAllocationCallbacks, ptr);</div><div class="line"><a name="l02696"></a><span class="lineno"> 2696</span>&#160;}</div><div class="line"><a name="l02697"></a><span class="lineno"> 2697</span>&#160;</div><div class="line"><a name="l02698"></a><span class="lineno"> 2698</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02699"></a><span class="lineno"> 2699</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete_array(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, T* ptr, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l02700"></a><span class="lineno"> 2700</span>&#160;{</div><div class="line"><a name="l02701"></a><span class="lineno"> 2701</span>&#160;    <span class="keywordflow">if</span>(ptr != VMA_NULL)</div><div class="line"><a name="l02702"></a><span class="lineno"> 2702</span>&#160;    {</div><div class="line"><a name="l02703"></a><span class="lineno"> 2703</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = count; i--; )</div><div class="line"><a name="l02704"></a><span class="lineno"> 2704</span>&#160;        {</div><div class="line"><a name="l02705"></a><span class="lineno"> 2705</span>&#160;            ptr[i].~T();</div><div class="line"><a name="l02706"></a><span class="lineno"> 2706</span>&#160;        }</div><div class="line"><a name="l02707"></a><span class="lineno"> 2707</span>&#160;        VmaFree(pAllocationCallbacks, ptr);</div><div class="line"><a name="l02708"></a><span class="lineno"> 2708</span>&#160;    }</div><div class="line"><a name="l02709"></a><span class="lineno"> 2709</span>&#160;}</div><div class="line"><a name="l02710"></a><span class="lineno"> 2710</span>&#160;</div><div class="line"><a name="l02711"></a><span class="lineno"> 2711</span>&#160;<span class="comment">// STL-compatible allocator.</span></div><div class="line"><a name="l02712"></a><span class="lineno"> 2712</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02713"></a><span class="lineno"> 2713</span>&#160;<span class="keyword">class </span>VmaStlAllocator</div><div class="line"><a name="l02714"></a><span class="lineno"> 2714</span>&#160;{</div><div class="line"><a name="l02715"></a><span class="lineno"> 2715</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l02716"></a><span class="lineno"> 2716</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* <span class="keyword">const</span> m_pCallbacks;</div><div class="line"><a name="l02717"></a><span class="lineno"> 2717</span>&#160;    <span class="keyword">typedef</span> T value_type;</div><div class="line"><a name="l02718"></a><span class="lineno"> 2718</span>&#160;    </div><div class="line"><a name="l02719"></a><span class="lineno"> 2719</span>&#160;    VmaStlAllocator(<span class="keyword">const</span> VkAllocationCallbacks* pCallbacks) : m_pCallbacks(pCallbacks) { }</div><div class="line"><a name="l02720"></a><span class="lineno"> 2720</span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> U&gt; VmaStlAllocator(<span class="keyword">const</span> VmaStlAllocator&lt;U&gt;&amp; src) : m_pCallbacks(src.m_pCallbacks) { }</div><div class="line"><a name="l02721"></a><span class="lineno"> 2721</span>&#160;</div><div class="line"><a name="l02722"></a><span class="lineno"> 2722</span>&#160;    T* allocate(<span class="keywordtype">size_t</span> n) { <span class="keywordflow">return</span> VmaAllocateArray&lt;T&gt;(m_pCallbacks, n); }</div><div class="line"><a name="l02723"></a><span class="lineno"> 2723</span>&#160;    <span class="keywordtype">void</span> deallocate(T* p, <span class="keywordtype">size_t</span> n) { VmaFree(m_pCallbacks, p); }</div><div class="line"><a name="l02724"></a><span class="lineno"> 2724</span>&#160;</div><div class="line"><a name="l02725"></a><span class="lineno"> 2725</span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> U&gt;</div><div class="line"><a name="l02726"></a><span class="lineno"> 2726</span>&#160;    <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> VmaStlAllocator&lt;U&gt;&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l02727"></a><span class="lineno"> 2727</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l02728"></a><span class="lineno"> 2728</span>&#160;        <span class="keywordflow">return</span> m_pCallbacks == rhs.m_pCallbacks;</div><div class="line"><a name="l02729"></a><span class="lineno"> 2729</span>&#160;    }</div><div class="line"><a name="l02730"></a><span class="lineno"> 2730</span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> U&gt;</div><div class="line"><a name="l02731"></a><span class="lineno"> 2731</span>&#160;    <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> VmaStlAllocator&lt;U&gt;&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l02732"></a><span class="lineno"> 2732</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l02733"></a><span class="lineno"> 2733</span>&#160;        <span class="keywordflow">return</span> m_pCallbacks != rhs.m_pCallbacks;</div><div class="line"><a name="l02734"></a><span class="lineno"> 2734</span>&#160;    }</div><div class="line"><a name="l02735"></a><span class="lineno"> 2735</span>&#160;</div><div class="line"><a name="l02736"></a><span class="lineno"> 2736</span>&#160;    VmaStlAllocator&amp; operator=(<span class="keyword">const</span> VmaStlAllocator&amp; x) = <span class="keyword">delete</span>;</div><div class="line"><a name="l02737"></a><span class="lineno"> 2737</span>&#160;};</div><div class="line"><a name="l02738"></a><span class="lineno"> 2738</span>&#160;</div><div class="line"><a name="l02739"></a><span class="lineno"> 2739</span>&#160;<span class="preprocessor">#if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l02740"></a><span class="lineno"> 2740</span>&#160;</div><div class="line"><a name="l02741"></a><span class="lineno"> 2741</span>&#160;<span class="preprocessor">#define VmaVector std::vector</span></div><div class="line"><a name="l02742"></a><span class="lineno"> 2742</span>&#160;</div><div class="line"><a name="l02743"></a><span class="lineno"> 2743</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l02744"></a><span class="lineno"> 2744</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorInsert(std::vector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index, <span class="keyword">const</span> T&amp; item)</div><div class="line"><a name="l02745"></a><span class="lineno"> 2745</span>&#160;{</div><div class="line"><a name="l02746"></a><span class="lineno"> 2746</span>&#160;    vec.insert(vec.begin() + index, item);</div><div class="line"><a name="l02747"></a><span class="lineno"> 2747</span>&#160;}</div><div class="line"><a name="l02748"></a><span class="lineno"> 2748</span>&#160;</div><div class="line"><a name="l02749"></a><span class="lineno"> 2749</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l02750"></a><span class="lineno"> 2750</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorRemove(std::vector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l02751"></a><span class="lineno"> 2751</span>&#160;{</div><div class="line"><a name="l02752"></a><span class="lineno"> 2752</span>&#160;    vec.erase(vec.begin() + index);</div><div class="line"><a name="l02753"></a><span class="lineno"> 2753</span>&#160;}</div><div class="line"><a name="l02754"></a><span class="lineno"> 2754</span>&#160;</div><div class="line"><a name="l02755"></a><span class="lineno"> 2755</span>&#160;<span class="preprocessor">#else // #if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l02756"></a><span class="lineno"> 2756</span>&#160;</div><div class="line"><a name="l02757"></a><span class="lineno"> 2757</span>&#160;<span class="comment">/* Class with interface compatible with subset of std::vector.</span></div><div class="line"><a name="l02758"></a><span class="lineno"> 2758</span>&#160;<span class="comment">T must be POD because constructors and destructors are not called and memcpy is</span></div><div class="line"><a name="l02759"></a><span class="lineno"> 2759</span>&#160;<span class="comment">used for these objects. */</span></div><div class="line"><a name="l02760"></a><span class="lineno"> 2760</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> AllocatorT&gt;</div><div class="line"><a name="l02761"></a><span class="lineno"> 2761</span>&#160;<span class="keyword">class </span>VmaVector</div><div class="line"><a name="l02762"></a><span class="lineno"> 2762</span>&#160;{</div><div class="line"><a name="l02763"></a><span class="lineno"> 2763</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l02764"></a><span class="lineno"> 2764</span>&#160;    <span class="keyword">typedef</span> T value_type;</div><div class="line"><a name="l02765"></a><span class="lineno"> 2765</span>&#160;</div><div class="line"><a name="l02766"></a><span class="lineno"> 2766</span>&#160;    VmaVector(<span class="keyword">const</span> AllocatorT&amp; allocator) :</div><div class="line"><a name="l02767"></a><span class="lineno"> 2767</span>&#160;        m_Allocator(allocator),</div><div class="line"><a name="l02768"></a><span class="lineno"> 2768</span>&#160;        m_pArray(VMA_NULL),</div><div class="line"><a name="l02769"></a><span class="lineno"> 2769</span>&#160;        m_Count(0),</div><div class="line"><a name="l02770"></a><span class="lineno"> 2770</span>&#160;        m_Capacity(0)</div><div class="line"><a name="l02771"></a><span class="lineno"> 2771</span>&#160;    {</div><div class="line"><a name="l02772"></a><span class="lineno"> 2772</span>&#160;    }</div><div class="line"><a name="l02773"></a><span class="lineno"> 2773</span>&#160;</div><div class="line"><a name="l02774"></a><span class="lineno"> 2774</span>&#160;    VmaVector(<span class="keywordtype">size_t</span> count, <span class="keyword">const</span> AllocatorT&amp; allocator) :</div><div class="line"><a name="l02775"></a><span class="lineno"> 2775</span>&#160;        m_Allocator(allocator),</div><div class="line"><a name="l02776"></a><span class="lineno"> 2776</span>&#160;        m_pArray(count ? (T*)VmaAllocateArray&lt;T&gt;(allocator.m_pCallbacks, count) : VMA_NULL),</div><div class="line"><a name="l02777"></a><span class="lineno"> 2777</span>&#160;        m_Count(count),</div><div class="line"><a name="l02778"></a><span class="lineno"> 2778</span>&#160;        m_Capacity(count)</div><div class="line"><a name="l02779"></a><span class="lineno"> 2779</span>&#160;    {</div><div class="line"><a name="l02780"></a><span class="lineno"> 2780</span>&#160;    }</div><div class="line"><a name="l02781"></a><span class="lineno"> 2781</span>&#160;    </div><div class="line"><a name="l02782"></a><span class="lineno"> 2782</span>&#160;    VmaVector(<span class="keyword">const</span> VmaVector&lt;T, AllocatorT&gt;&amp; src) :</div><div class="line"><a name="l02783"></a><span class="lineno"> 2783</span>&#160;        m_Allocator(src.m_Allocator),</div><div class="line"><a name="l02784"></a><span class="lineno"> 2784</span>&#160;        m_pArray(src.m_Count ? (T*)VmaAllocateArray&lt;T&gt;(src.m_Allocator.m_pCallbacks, src.m_Count) : VMA_NULL),</div><div class="line"><a name="l02785"></a><span class="lineno"> 2785</span>&#160;        m_Count(src.m_Count),</div><div class="line"><a name="l02786"></a><span class="lineno"> 2786</span>&#160;        m_Capacity(src.m_Count)</div><div class="line"><a name="l02787"></a><span class="lineno"> 2787</span>&#160;    {</div><div class="line"><a name="l02788"></a><span class="lineno"> 2788</span>&#160;        <span class="keywordflow">if</span>(m_Count != 0)</div><div class="line"><a name="l02789"></a><span class="lineno"> 2789</span>&#160;        {</div><div class="line"><a name="l02790"></a><span class="lineno"> 2790</span>&#160;            memcpy(m_pArray, src.m_pArray, m_Count * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l02791"></a><span class="lineno"> 2791</span>&#160;        }</div><div class="line"><a name="l02792"></a><span class="lineno"> 2792</span>&#160;    }</div><div class="line"><a name="l02793"></a><span class="lineno"> 2793</span>&#160;    </div><div class="line"><a name="l02794"></a><span class="lineno"> 2794</span>&#160;    ~VmaVector()</div><div class="line"><a name="l02795"></a><span class="lineno"> 2795</span>&#160;    {</div><div class="line"><a name="l02796"></a><span class="lineno"> 2796</span>&#160;        VmaFree(m_Allocator.m_pCallbacks, m_pArray);</div><div class="line"><a name="l02797"></a><span class="lineno"> 2797</span>&#160;    }</div><div class="line"><a name="l02798"></a><span class="lineno"> 2798</span>&#160;</div><div class="line"><a name="l02799"></a><span class="lineno"> 2799</span>&#160;    VmaVector&amp; operator=(<span class="keyword">const</span> VmaVector&lt;T, AllocatorT&gt;&amp; rhs)</div><div class="line"><a name="l02800"></a><span class="lineno"> 2800</span>&#160;    {</div><div class="line"><a name="l02801"></a><span class="lineno"> 2801</span>&#160;        <span class="keywordflow">if</span>(&amp;rhs != <span class="keyword">this</span>)</div><div class="line"><a name="l02802"></a><span class="lineno"> 2802</span>&#160;        {</div><div class="line"><a name="l02803"></a><span class="lineno"> 2803</span>&#160;            resize(rhs.m_Count);</div><div class="line"><a name="l02804"></a><span class="lineno"> 2804</span>&#160;            <span class="keywordflow">if</span>(m_Count != 0)</div><div class="line"><a name="l02805"></a><span class="lineno"> 2805</span>&#160;            {</div><div class="line"><a name="l02806"></a><span class="lineno"> 2806</span>&#160;                memcpy(m_pArray, rhs.m_pArray, m_Count * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l02807"></a><span class="lineno"> 2807</span>&#160;            }</div><div class="line"><a name="l02808"></a><span class="lineno"> 2808</span>&#160;        }</div><div class="line"><a name="l02809"></a><span class="lineno"> 2809</span>&#160;        <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l02810"></a><span class="lineno"> 2810</span>&#160;    }</div><div class="line"><a name="l02811"></a><span class="lineno"> 2811</span>&#160;    </div><div class="line"><a name="l02812"></a><span class="lineno"> 2812</span>&#160;    <span class="keywordtype">bool</span> empty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count == 0; }</div><div class="line"><a name="l02813"></a><span class="lineno"> 2813</span>&#160;    <span class="keywordtype">size_t</span> size()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count; }</div><div class="line"><a name="l02814"></a><span class="lineno"> 2814</span>&#160;    T* data() { <span class="keywordflow">return</span> m_pArray; }</div><div class="line"><a name="l02815"></a><span class="lineno"> 2815</span>&#160;    <span class="keyword">const</span> T* data()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pArray; }</div><div class="line"><a name="l02816"></a><span class="lineno"> 2816</span>&#160;    </div><div class="line"><a name="l02817"></a><span class="lineno"> 2817</span>&#160;    T&amp; operator[](<span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l02818"></a><span class="lineno"> 2818</span>&#160;    {</div><div class="line"><a name="l02819"></a><span class="lineno"> 2819</span>&#160;        VMA_HEAVY_ASSERT(index &lt; m_Count);</div><div class="line"><a name="l02820"></a><span class="lineno"> 2820</span>&#160;        <span class="keywordflow">return</span> m_pArray[index];</div><div class="line"><a name="l02821"></a><span class="lineno"> 2821</span>&#160;    }</div><div class="line"><a name="l02822"></a><span class="lineno"> 2822</span>&#160;    <span class="keyword">const</span> T&amp; operator[](<span class="keywordtype">size_t</span> index)<span class="keyword"> const</span></div><div class="line"><a name="l02823"></a><span class="lineno"> 2823</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l02824"></a><span class="lineno"> 2824</span>&#160;        VMA_HEAVY_ASSERT(index &lt; m_Count);</div><div class="line"><a name="l02825"></a><span class="lineno"> 2825</span>&#160;        <span class="keywordflow">return</span> m_pArray[index];</div><div class="line"><a name="l02826"></a><span class="lineno"> 2826</span>&#160;    }</div><div class="line"><a name="l02827"></a><span class="lineno"> 2827</span>&#160;</div><div class="line"><a name="l02828"></a><span class="lineno"> 2828</span>&#160;    T&amp; front()</div><div class="line"><a name="l02829"></a><span class="lineno"> 2829</span>&#160;    {</div><div class="line"><a name="l02830"></a><span class="lineno"> 2830</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l02831"></a><span class="lineno"> 2831</span>&#160;        <span class="keywordflow">return</span> m_pArray[0];</div><div class="line"><a name="l02832"></a><span class="lineno"> 2832</span>&#160;    }</div><div class="line"><a name="l02833"></a><span class="lineno"> 2833</span>&#160;    <span class="keyword">const</span> T&amp; front()<span class="keyword"> const</span></div><div class="line"><a name="l02834"></a><span class="lineno"> 2834</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l02835"></a><span class="lineno"> 2835</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l02836"></a><span class="lineno"> 2836</span>&#160;        <span class="keywordflow">return</span> m_pArray[0];</div><div class="line"><a name="l02837"></a><span class="lineno"> 2837</span>&#160;    }</div><div class="line"><a name="l02838"></a><span class="lineno"> 2838</span>&#160;    T&amp; back()</div><div class="line"><a name="l02839"></a><span class="lineno"> 2839</span>&#160;    {</div><div class="line"><a name="l02840"></a><span class="lineno"> 2840</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l02841"></a><span class="lineno"> 2841</span>&#160;        <span class="keywordflow">return</span> m_pArray[m_Count - 1];</div><div class="line"><a name="l02842"></a><span class="lineno"> 2842</span>&#160;    }</div><div class="line"><a name="l02843"></a><span class="lineno"> 2843</span>&#160;    <span class="keyword">const</span> T&amp; back()<span class="keyword"> const</span></div><div class="line"><a name="l02844"></a><span class="lineno"> 2844</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l02845"></a><span class="lineno"> 2845</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l02846"></a><span class="lineno"> 2846</span>&#160;        <span class="keywordflow">return</span> m_pArray[m_Count - 1];</div><div class="line"><a name="l02847"></a><span class="lineno"> 2847</span>&#160;    }</div><div class="line"><a name="l02848"></a><span class="lineno"> 2848</span>&#160;</div><div class="line"><a name="l02849"></a><span class="lineno"> 2849</span>&#160;    <span class="keywordtype">void</span> reserve(<span class="keywordtype">size_t</span> newCapacity, <span class="keywordtype">bool</span> freeMemory = <span class="keyword">false</span>)</div><div class="line"><a name="l02850"></a><span class="lineno"> 2850</span>&#160;    {</div><div class="line"><a name="l02851"></a><span class="lineno"> 2851</span>&#160;        newCapacity = VMA_MAX(newCapacity, m_Count);</div><div class="line"><a name="l02852"></a><span class="lineno"> 2852</span>&#160;        </div><div class="line"><a name="l02853"></a><span class="lineno"> 2853</span>&#160;        <span class="keywordflow">if</span>((newCapacity &lt; m_Capacity) &amp;&amp; !freeMemory)</div><div class="line"><a name="l02854"></a><span class="lineno"> 2854</span>&#160;        {</div><div class="line"><a name="l02855"></a><span class="lineno"> 2855</span>&#160;            newCapacity = m_Capacity;</div><div class="line"><a name="l02856"></a><span class="lineno"> 2856</span>&#160;        }</div><div class="line"><a name="l02857"></a><span class="lineno"> 2857</span>&#160;        </div><div class="line"><a name="l02858"></a><span class="lineno"> 2858</span>&#160;        <span class="keywordflow">if</span>(newCapacity != m_Capacity)</div><div class="line"><a name="l02859"></a><span class="lineno"> 2859</span>&#160;        {</div><div class="line"><a name="l02860"></a><span class="lineno"> 2860</span>&#160;            T* <span class="keyword">const</span> newArray = newCapacity ? VmaAllocateArray&lt;T&gt;(m_Allocator, newCapacity) : VMA_NULL;</div><div class="line"><a name="l02861"></a><span class="lineno"> 2861</span>&#160;            <span class="keywordflow">if</span>(m_Count != 0)</div><div class="line"><a name="l02862"></a><span class="lineno"> 2862</span>&#160;            {</div><div class="line"><a name="l02863"></a><span class="lineno"> 2863</span>&#160;                memcpy(newArray, m_pArray, m_Count * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l02864"></a><span class="lineno"> 2864</span>&#160;            }</div><div class="line"><a name="l02865"></a><span class="lineno"> 2865</span>&#160;            VmaFree(m_Allocator.m_pCallbacks, m_pArray);</div><div class="line"><a name="l02866"></a><span class="lineno"> 2866</span>&#160;            m_Capacity = newCapacity;</div><div class="line"><a name="l02867"></a><span class="lineno"> 2867</span>&#160;            m_pArray = newArray;</div><div class="line"><a name="l02868"></a><span class="lineno"> 2868</span>&#160;        }</div><div class="line"><a name="l02869"></a><span class="lineno"> 2869</span>&#160;    }</div><div class="line"><a name="l02870"></a><span class="lineno"> 2870</span>&#160;</div><div class="line"><a name="l02871"></a><span class="lineno"> 2871</span>&#160;    <span class="keywordtype">void</span> resize(<span class="keywordtype">size_t</span> newCount, <span class="keywordtype">bool</span> freeMemory = <span class="keyword">false</span>)</div><div class="line"><a name="l02872"></a><span class="lineno"> 2872</span>&#160;    {</div><div class="line"><a name="l02873"></a><span class="lineno"> 2873</span>&#160;        <span class="keywordtype">size_t</span> newCapacity = m_Capacity;</div><div class="line"><a name="l02874"></a><span class="lineno"> 2874</span>&#160;        <span class="keywordflow">if</span>(newCount &gt; m_Capacity)</div><div class="line"><a name="l02875"></a><span class="lineno"> 2875</span>&#160;        {</div><div class="line"><a name="l02876"></a><span class="lineno"> 2876</span>&#160;            newCapacity = VMA_MAX(newCount, VMA_MAX(m_Capacity * 3 / 2, (<span class="keywordtype">size_t</span>)8));</div><div class="line"><a name="l02877"></a><span class="lineno"> 2877</span>&#160;        }</div><div class="line"><a name="l02878"></a><span class="lineno"> 2878</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(freeMemory)</div><div class="line"><a name="l02879"></a><span class="lineno"> 2879</span>&#160;        {</div><div class="line"><a name="l02880"></a><span class="lineno"> 2880</span>&#160;            newCapacity = newCount;</div><div class="line"><a name="l02881"></a><span class="lineno"> 2881</span>&#160;        }</div><div class="line"><a name="l02882"></a><span class="lineno"> 2882</span>&#160;</div><div class="line"><a name="l02883"></a><span class="lineno"> 2883</span>&#160;        <span class="keywordflow">if</span>(newCapacity != m_Capacity)</div><div class="line"><a name="l02884"></a><span class="lineno"> 2884</span>&#160;        {</div><div class="line"><a name="l02885"></a><span class="lineno"> 2885</span>&#160;            T* <span class="keyword">const</span> newArray = newCapacity ? VmaAllocateArray&lt;T&gt;(m_Allocator.m_pCallbacks, newCapacity) : VMA_NULL;</div><div class="line"><a name="l02886"></a><span class="lineno"> 2886</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> elementsToCopy = VMA_MIN(m_Count, newCount);</div><div class="line"><a name="l02887"></a><span class="lineno"> 2887</span>&#160;            <span class="keywordflow">if</span>(elementsToCopy != 0)</div><div class="line"><a name="l02888"></a><span class="lineno"> 2888</span>&#160;            {</div><div class="line"><a name="l02889"></a><span class="lineno"> 2889</span>&#160;                memcpy(newArray, m_pArray, elementsToCopy * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l02890"></a><span class="lineno"> 2890</span>&#160;            }</div><div class="line"><a name="l02891"></a><span class="lineno"> 2891</span>&#160;            VmaFree(m_Allocator.m_pCallbacks, m_pArray);</div><div class="line"><a name="l02892"></a><span class="lineno"> 2892</span>&#160;            m_Capacity = newCapacity;</div><div class="line"><a name="l02893"></a><span class="lineno"> 2893</span>&#160;            m_pArray = newArray;</div><div class="line"><a name="l02894"></a><span class="lineno"> 2894</span>&#160;        }</div><div class="line"><a name="l02895"></a><span class="lineno"> 2895</span>&#160;</div><div class="line"><a name="l02896"></a><span class="lineno"> 2896</span>&#160;        m_Count = newCount;</div><div class="line"><a name="l02897"></a><span class="lineno"> 2897</span>&#160;    }</div><div class="line"><a name="l02898"></a><span class="lineno"> 2898</span>&#160;</div><div class="line"><a name="l02899"></a><span class="lineno"> 2899</span>&#160;    <span class="keywordtype">void</span> clear(<span class="keywordtype">bool</span> freeMemory = <span class="keyword">false</span>)</div><div class="line"><a name="l02900"></a><span class="lineno"> 2900</span>&#160;    {</div><div class="line"><a name="l02901"></a><span class="lineno"> 2901</span>&#160;        resize(0, freeMemory);</div><div class="line"><a name="l02902"></a><span class="lineno"> 2902</span>&#160;    }</div><div class="line"><a name="l02903"></a><span class="lineno"> 2903</span>&#160;</div><div class="line"><a name="l02904"></a><span class="lineno"> 2904</span>&#160;    <span class="keywordtype">void</span> insert(<span class="keywordtype">size_t</span> index, <span class="keyword">const</span> T&amp; src)</div><div class="line"><a name="l02905"></a><span class="lineno"> 2905</span>&#160;    {</div><div class="line"><a name="l02906"></a><span class="lineno"> 2906</span>&#160;        VMA_HEAVY_ASSERT(index &lt;= m_Count);</div><div class="line"><a name="l02907"></a><span class="lineno"> 2907</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldCount = size();</div><div class="line"><a name="l02908"></a><span class="lineno"> 2908</span>&#160;        resize(oldCount + 1);</div><div class="line"><a name="l02909"></a><span class="lineno"> 2909</span>&#160;        <span class="keywordflow">if</span>(index &lt; oldCount)</div><div class="line"><a name="l02910"></a><span class="lineno"> 2910</span>&#160;        {</div><div class="line"><a name="l02911"></a><span class="lineno"> 2911</span>&#160;            memmove(m_pArray + (index + 1), m_pArray + index, (oldCount - index) * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l02912"></a><span class="lineno"> 2912</span>&#160;        }</div><div class="line"><a name="l02913"></a><span class="lineno"> 2913</span>&#160;        m_pArray[index] = src;</div><div class="line"><a name="l02914"></a><span class="lineno"> 2914</span>&#160;    }</div><div class="line"><a name="l02915"></a><span class="lineno"> 2915</span>&#160;</div><div class="line"><a name="l02916"></a><span class="lineno"> 2916</span>&#160;    <span class="keywordtype">void</span> <span class="keyword">remove</span>(<span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l02917"></a><span class="lineno"> 2917</span>&#160;    {</div><div class="line"><a name="l02918"></a><span class="lineno"> 2918</span>&#160;        VMA_HEAVY_ASSERT(index &lt; m_Count);</div><div class="line"><a name="l02919"></a><span class="lineno"> 2919</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldCount = size();</div><div class="line"><a name="l02920"></a><span class="lineno"> 2920</span>&#160;        <span class="keywordflow">if</span>(index &lt; oldCount - 1)</div><div class="line"><a name="l02921"></a><span class="lineno"> 2921</span>&#160;        {</div><div class="line"><a name="l02922"></a><span class="lineno"> 2922</span>&#160;            memmove(m_pArray + index, m_pArray + (index + 1), (oldCount - index - 1) * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l02923"></a><span class="lineno"> 2923</span>&#160;        }</div><div class="line"><a name="l02924"></a><span class="lineno"> 2924</span>&#160;        resize(oldCount - 1);</div><div class="line"><a name="l02925"></a><span class="lineno"> 2925</span>&#160;    }</div><div class="line"><a name="l02926"></a><span class="lineno"> 2926</span>&#160;</div><div class="line"><a name="l02927"></a><span class="lineno"> 2927</span>&#160;    <span class="keywordtype">void</span> push_back(<span class="keyword">const</span> T&amp; src)</div><div class="line"><a name="l02928"></a><span class="lineno"> 2928</span>&#160;    {</div><div class="line"><a name="l02929"></a><span class="lineno"> 2929</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> newIndex = size();</div><div class="line"><a name="l02930"></a><span class="lineno"> 2930</span>&#160;        resize(newIndex + 1);</div><div class="line"><a name="l02931"></a><span class="lineno"> 2931</span>&#160;        m_pArray[newIndex] = src;</div><div class="line"><a name="l02932"></a><span class="lineno"> 2932</span>&#160;    }</div><div class="line"><a name="l02933"></a><span class="lineno"> 2933</span>&#160;</div><div class="line"><a name="l02934"></a><span class="lineno"> 2934</span>&#160;    <span class="keywordtype">void</span> pop_back()</div><div class="line"><a name="l02935"></a><span class="lineno"> 2935</span>&#160;    {</div><div class="line"><a name="l02936"></a><span class="lineno"> 2936</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l02937"></a><span class="lineno"> 2937</span>&#160;        resize(size() - 1);</div><div class="line"><a name="l02938"></a><span class="lineno"> 2938</span>&#160;    }</div><div class="line"><a name="l02939"></a><span class="lineno"> 2939</span>&#160;</div><div class="line"><a name="l02940"></a><span class="lineno"> 2940</span>&#160;    <span class="keywordtype">void</span> push_front(<span class="keyword">const</span> T&amp; src)</div><div class="line"><a name="l02941"></a><span class="lineno"> 2941</span>&#160;    {</div><div class="line"><a name="l02942"></a><span class="lineno"> 2942</span>&#160;        insert(0, src);</div><div class="line"><a name="l02943"></a><span class="lineno"> 2943</span>&#160;    }</div><div class="line"><a name="l02944"></a><span class="lineno"> 2944</span>&#160;</div><div class="line"><a name="l02945"></a><span class="lineno"> 2945</span>&#160;    <span class="keywordtype">void</span> pop_front()</div><div class="line"><a name="l02946"></a><span class="lineno"> 2946</span>&#160;    {</div><div class="line"><a name="l02947"></a><span class="lineno"> 2947</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l02948"></a><span class="lineno"> 2948</span>&#160;        <span class="keyword">remove</span>(0);</div><div class="line"><a name="l02949"></a><span class="lineno"> 2949</span>&#160;    }</div><div class="line"><a name="l02950"></a><span class="lineno"> 2950</span>&#160;</div><div class="line"><a name="l02951"></a><span class="lineno"> 2951</span>&#160;    <span class="keyword">typedef</span> T* iterator;</div><div class="line"><a name="l02952"></a><span class="lineno"> 2952</span>&#160;</div><div class="line"><a name="l02953"></a><span class="lineno"> 2953</span>&#160;    iterator begin() { <span class="keywordflow">return</span> m_pArray; }</div><div class="line"><a name="l02954"></a><span class="lineno"> 2954</span>&#160;    iterator end() { <span class="keywordflow">return</span> m_pArray + m_Count; }</div><div class="line"><a name="l02955"></a><span class="lineno"> 2955</span>&#160;</div><div class="line"><a name="l02956"></a><span class="lineno"> 2956</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l02957"></a><span class="lineno"> 2957</span>&#160;    AllocatorT m_Allocator;</div><div class="line"><a name="l02958"></a><span class="lineno"> 2958</span>&#160;    T* m_pArray;</div><div class="line"><a name="l02959"></a><span class="lineno"> 2959</span>&#160;    <span class="keywordtype">size_t</span> m_Count;</div><div class="line"><a name="l02960"></a><span class="lineno"> 2960</span>&#160;    <span class="keywordtype">size_t</span> m_Capacity;</div><div class="line"><a name="l02961"></a><span class="lineno"> 2961</span>&#160;};</div><div class="line"><a name="l02962"></a><span class="lineno"> 2962</span>&#160;</div><div class="line"><a name="l02963"></a><span class="lineno"> 2963</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l02964"></a><span class="lineno"> 2964</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorInsert(VmaVector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index, <span class="keyword">const</span> T&amp; item)</div><div class="line"><a name="l02965"></a><span class="lineno"> 2965</span>&#160;{</div><div class="line"><a name="l02966"></a><span class="lineno"> 2966</span>&#160;    vec.insert(index, item);</div><div class="line"><a name="l02967"></a><span class="lineno"> 2967</span>&#160;}</div><div class="line"><a name="l02968"></a><span class="lineno"> 2968</span>&#160;</div><div class="line"><a name="l02969"></a><span class="lineno"> 2969</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l02970"></a><span class="lineno"> 2970</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorRemove(VmaVector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l02971"></a><span class="lineno"> 2971</span>&#160;{</div><div class="line"><a name="l02972"></a><span class="lineno"> 2972</span>&#160;    vec.remove(index);</div><div class="line"><a name="l02973"></a><span class="lineno"> 2973</span>&#160;}</div><div class="line"><a name="l02974"></a><span class="lineno"> 2974</span>&#160;</div><div class="line"><a name="l02975"></a><span class="lineno"> 2975</span>&#160;<span class="preprocessor">#endif // #if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l02976"></a><span class="lineno"> 2976</span>&#160;</div><div class="line"><a name="l02977"></a><span class="lineno"> 2977</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> CmpLess, <span class="keyword">typename</span> VectorT&gt;</div><div class="line"><a name="l02978"></a><span class="lineno"> 2978</span>&#160;<span class="keywordtype">size_t</span> VmaVectorInsertSorted(VectorT&amp; vector, <span class="keyword">const</span> <span class="keyword">typename</span> VectorT::value_type&amp; value)</div><div class="line"><a name="l02979"></a><span class="lineno"> 2979</span>&#160;{</div><div class="line"><a name="l02980"></a><span class="lineno"> 2980</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> indexToInsert = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l02981"></a><span class="lineno"> 2981</span>&#160;        vector.data(),</div><div class="line"><a name="l02982"></a><span class="lineno"> 2982</span>&#160;        vector.data() + vector.size(),</div><div class="line"><a name="l02983"></a><span class="lineno"> 2983</span>&#160;        value,</div><div class="line"><a name="l02984"></a><span class="lineno"> 2984</span>&#160;        CmpLess()) - vector.data();</div><div class="line"><a name="l02985"></a><span class="lineno"> 2985</span>&#160;    VmaVectorInsert(vector, indexToInsert, value);</div><div class="line"><a name="l02986"></a><span class="lineno"> 2986</span>&#160;    <span class="keywordflow">return</span> indexToInsert;</div><div class="line"><a name="l02987"></a><span class="lineno"> 2987</span>&#160;}</div><div class="line"><a name="l02988"></a><span class="lineno"> 2988</span>&#160;</div><div class="line"><a name="l02989"></a><span class="lineno"> 2989</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> CmpLess, <span class="keyword">typename</span> VectorT&gt;</div><div class="line"><a name="l02990"></a><span class="lineno"> 2990</span>&#160;<span class="keywordtype">bool</span> VmaVectorRemoveSorted(VectorT&amp; vector, <span class="keyword">const</span> <span class="keyword">typename</span> VectorT::value_type&amp; value)</div><div class="line"><a name="l02991"></a><span class="lineno"> 2991</span>&#160;{</div><div class="line"><a name="l02992"></a><span class="lineno"> 2992</span>&#160;    CmpLess comparator;</div><div class="line"><a name="l02993"></a><span class="lineno"> 2993</span>&#160;    <span class="keyword">typename</span> VectorT::iterator it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l02994"></a><span class="lineno"> 2994</span>&#160;        vector.begin(),</div><div class="line"><a name="l02995"></a><span class="lineno"> 2995</span>&#160;        vector.end(),</div><div class="line"><a name="l02996"></a><span class="lineno"> 2996</span>&#160;        value,</div><div class="line"><a name="l02997"></a><span class="lineno"> 2997</span>&#160;        comparator);</div><div class="line"><a name="l02998"></a><span class="lineno"> 2998</span>&#160;    <span class="keywordflow">if</span>((it != vector.end()) &amp;&amp; !comparator(*it, value) &amp;&amp; !comparator(value, *it))</div><div class="line"><a name="l02999"></a><span class="lineno"> 2999</span>&#160;    {</div><div class="line"><a name="l03000"></a><span class="lineno"> 3000</span>&#160;        <span class="keywordtype">size_t</span> indexToRemove = it - vector.begin();</div><div class="line"><a name="l03001"></a><span class="lineno"> 3001</span>&#160;        VmaVectorRemove(vector, indexToRemove);</div><div class="line"><a name="l03002"></a><span class="lineno"> 3002</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l03003"></a><span class="lineno"> 3003</span>&#160;    }</div><div class="line"><a name="l03004"></a><span class="lineno"> 3004</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l03005"></a><span class="lineno"> 3005</span>&#160;}</div><div class="line"><a name="l03006"></a><span class="lineno"> 3006</span>&#160;</div><div class="line"><a name="l03007"></a><span class="lineno"> 3007</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> CmpLess, <span class="keyword">typename</span> VectorT&gt;</div><div class="line"><a name="l03008"></a><span class="lineno"> 3008</span>&#160;<span class="keywordtype">size_t</span> VmaVectorFindSorted(<span class="keyword">const</span> VectorT&amp; vector, <span class="keyword">const</span> <span class="keyword">typename</span> VectorT::value_type&amp; value)</div><div class="line"><a name="l03009"></a><span class="lineno"> 3009</span>&#160;{</div><div class="line"><a name="l03010"></a><span class="lineno"> 3010</span>&#160;    CmpLess comparator;</div><div class="line"><a name="l03011"></a><span class="lineno"> 3011</span>&#160;    <span class="keyword">typename</span> VectorT::iterator it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l03012"></a><span class="lineno"> 3012</span>&#160;        vector.data(),</div><div class="line"><a name="l03013"></a><span class="lineno"> 3013</span>&#160;        vector.data() + vector.size(),</div><div class="line"><a name="l03014"></a><span class="lineno"> 3014</span>&#160;        value,</div><div class="line"><a name="l03015"></a><span class="lineno"> 3015</span>&#160;        comparator);</div><div class="line"><a name="l03016"></a><span class="lineno"> 3016</span>&#160;    <span class="keywordflow">if</span>(it != vector.size() &amp;&amp; !comparator(*it, value) &amp;&amp; !comparator(value, *it))</div><div class="line"><a name="l03017"></a><span class="lineno"> 3017</span>&#160;    {</div><div class="line"><a name="l03018"></a><span class="lineno"> 3018</span>&#160;        <span class="keywordflow">return</span> it - vector.begin();</div><div class="line"><a name="l03019"></a><span class="lineno"> 3019</span>&#160;    }</div><div class="line"><a name="l03020"></a><span class="lineno"> 3020</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03021"></a><span class="lineno"> 3021</span>&#160;    {</div><div class="line"><a name="l03022"></a><span class="lineno"> 3022</span>&#160;        <span class="keywordflow">return</span> vector.size();</div><div class="line"><a name="l03023"></a><span class="lineno"> 3023</span>&#160;    }</div><div class="line"><a name="l03024"></a><span class="lineno"> 3024</span>&#160;}</div><div class="line"><a name="l03025"></a><span class="lineno"> 3025</span>&#160;</div><div class="line"><a name="l03027"></a><span class="lineno"> 3027</span>&#160;<span class="comment">// class VmaPoolAllocator</span></div><div class="line"><a name="l03028"></a><span class="lineno"> 3028</span>&#160;</div><div class="line"><a name="l03029"></a><span class="lineno"> 3029</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l03030"></a><span class="lineno"> 3030</span>&#160;<span class="comment">Allocator for objects of type T using a list of arrays (pools) to speed up</span></div><div class="line"><a name="l03031"></a><span class="lineno"> 3031</span>&#160;<span class="comment">allocation. Number of elements that can be allocated is not bounded because</span></div><div class="line"><a name="l03032"></a><span class="lineno"> 3032</span>&#160;<span class="comment">allocator can create multiple blocks.</span></div><div class="line"><a name="l03033"></a><span class="lineno"> 3033</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03034"></a><span class="lineno"> 3034</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03035"></a><span class="lineno"> 3035</span>&#160;<span class="keyword">class </span>VmaPoolAllocator</div><div class="line"><a name="l03036"></a><span class="lineno"> 3036</span>&#160;{</div><div class="line"><a name="l03037"></a><span class="lineno"> 3037</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03038"></a><span class="lineno"> 3038</span>&#160;    VmaPoolAllocator(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> itemsPerBlock);</div><div class="line"><a name="l03039"></a><span class="lineno"> 3039</span>&#160;    ~VmaPoolAllocator();</div><div class="line"><a name="l03040"></a><span class="lineno"> 3040</span>&#160;    <span class="keywordtype">void</span> Clear();</div><div class="line"><a name="l03041"></a><span class="lineno"> 3041</span>&#160;    T* Alloc();</div><div class="line"><a name="l03042"></a><span class="lineno"> 3042</span>&#160;    <span class="keywordtype">void</span> Free(T* ptr);</div><div class="line"><a name="l03043"></a><span class="lineno"> 3043</span>&#160;</div><div class="line"><a name="l03044"></a><span class="lineno"> 3044</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03045"></a><span class="lineno"> 3045</span>&#160;    <span class="keyword">union </span>Item</div><div class="line"><a name="l03046"></a><span class="lineno"> 3046</span>&#160;    {</div><div class="line"><a name="l03047"></a><span class="lineno"> 3047</span>&#160;        uint32_t NextFreeIndex;</div><div class="line"><a name="l03048"></a><span class="lineno"> 3048</span>&#160;        T Value;</div><div class="line"><a name="l03049"></a><span class="lineno"> 3049</span>&#160;    };</div><div class="line"><a name="l03050"></a><span class="lineno"> 3050</span>&#160;</div><div class="line"><a name="l03051"></a><span class="lineno"> 3051</span>&#160;    <span class="keyword">struct </span>ItemBlock</div><div class="line"><a name="l03052"></a><span class="lineno"> 3052</span>&#160;    {</div><div class="line"><a name="l03053"></a><span class="lineno"> 3053</span>&#160;        Item* pItems;</div><div class="line"><a name="l03054"></a><span class="lineno"> 3054</span>&#160;        uint32_t FirstFreeIndex;</div><div class="line"><a name="l03055"></a><span class="lineno"> 3055</span>&#160;    };</div><div class="line"><a name="l03056"></a><span class="lineno"> 3056</span>&#160;    </div><div class="line"><a name="l03057"></a><span class="lineno"> 3057</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* m_pAllocationCallbacks;</div><div class="line"><a name="l03058"></a><span class="lineno"> 3058</span>&#160;    <span class="keywordtype">size_t</span> m_ItemsPerBlock;</div><div class="line"><a name="l03059"></a><span class="lineno"> 3059</span>&#160;    VmaVector&lt; ItemBlock, VmaStlAllocator&lt;ItemBlock&gt; &gt; m_ItemBlocks;</div><div class="line"><a name="l03060"></a><span class="lineno"> 3060</span>&#160;</div><div class="line"><a name="l03061"></a><span class="lineno"> 3061</span>&#160;    ItemBlock&amp; CreateNewBlock();</div><div class="line"><a name="l03062"></a><span class="lineno"> 3062</span>&#160;};</div><div class="line"><a name="l03063"></a><span class="lineno"> 3063</span>&#160;</div><div class="line"><a name="l03064"></a><span class="lineno"> 3064</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03065"></a><span class="lineno"> 3065</span>&#160;VmaPoolAllocator&lt;T&gt;::VmaPoolAllocator(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> itemsPerBlock) :</div><div class="line"><a name="l03066"></a><span class="lineno"> 3066</span>&#160;    m_pAllocationCallbacks(pAllocationCallbacks),</div><div class="line"><a name="l03067"></a><span class="lineno"> 3067</span>&#160;    m_ItemsPerBlock(itemsPerBlock),</div><div class="line"><a name="l03068"></a><span class="lineno"> 3068</span>&#160;    m_ItemBlocks(VmaStlAllocator&lt;ItemBlock&gt;(pAllocationCallbacks))</div><div class="line"><a name="l03069"></a><span class="lineno"> 3069</span>&#160;{</div><div class="line"><a name="l03070"></a><span class="lineno"> 3070</span>&#160;    VMA_ASSERT(itemsPerBlock &gt; 0);</div><div class="line"><a name="l03071"></a><span class="lineno"> 3071</span>&#160;}</div><div class="line"><a name="l03072"></a><span class="lineno"> 3072</span>&#160;</div><div class="line"><a name="l03073"></a><span class="lineno"> 3073</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03074"></a><span class="lineno"> 3074</span>&#160;VmaPoolAllocator&lt;T&gt;::~VmaPoolAllocator()</div><div class="line"><a name="l03075"></a><span class="lineno"> 3075</span>&#160;{</div><div class="line"><a name="l03076"></a><span class="lineno"> 3076</span>&#160;    Clear();</div><div class="line"><a name="l03077"></a><span class="lineno"> 3077</span>&#160;}</div><div class="line"><a name="l03078"></a><span class="lineno"> 3078</span>&#160;</div><div class="line"><a name="l03079"></a><span class="lineno"> 3079</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03080"></a><span class="lineno"> 3080</span>&#160;<span class="keywordtype">void</span> VmaPoolAllocator&lt;T&gt;::Clear()</div><div class="line"><a name="l03081"></a><span class="lineno"> 3081</span>&#160;{</div><div class="line"><a name="l03082"></a><span class="lineno"> 3082</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_ItemBlocks.size(); i--; )</div><div class="line"><a name="l03083"></a><span class="lineno"> 3083</span>&#160;        vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemsPerBlock);</div><div class="line"><a name="l03084"></a><span class="lineno"> 3084</span>&#160;    m_ItemBlocks.clear();</div><div class="line"><a name="l03085"></a><span class="lineno"> 3085</span>&#160;}</div><div class="line"><a name="l03086"></a><span class="lineno"> 3086</span>&#160;</div><div class="line"><a name="l03087"></a><span class="lineno"> 3087</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03088"></a><span class="lineno"> 3088</span>&#160;T* VmaPoolAllocator&lt;T&gt;::Alloc()</div><div class="line"><a name="l03089"></a><span class="lineno"> 3089</span>&#160;{</div><div class="line"><a name="l03090"></a><span class="lineno"> 3090</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_ItemBlocks.size(); i--; )</div><div class="line"><a name="l03091"></a><span class="lineno"> 3091</span>&#160;    {</div><div class="line"><a name="l03092"></a><span class="lineno"> 3092</span>&#160;        ItemBlock&amp; block = m_ItemBlocks[i];</div><div class="line"><a name="l03093"></a><span class="lineno"> 3093</span>&#160;        <span class="comment">// This block has some free items: Use first one.</span></div><div class="line"><a name="l03094"></a><span class="lineno"> 3094</span>&#160;        <span class="keywordflow">if</span>(block.FirstFreeIndex != UINT32_MAX)</div><div class="line"><a name="l03095"></a><span class="lineno"> 3095</span>&#160;        {</div><div class="line"><a name="l03096"></a><span class="lineno"> 3096</span>&#160;            Item* <span class="keyword">const</span> pItem = &amp;block.pItems[block.FirstFreeIndex];</div><div class="line"><a name="l03097"></a><span class="lineno"> 3097</span>&#160;            block.FirstFreeIndex = pItem-&gt;NextFreeIndex;</div><div class="line"><a name="l03098"></a><span class="lineno"> 3098</span>&#160;            <span class="keywordflow">return</span> &amp;pItem-&gt;Value;</div><div class="line"><a name="l03099"></a><span class="lineno"> 3099</span>&#160;        }</div><div class="line"><a name="l03100"></a><span class="lineno"> 3100</span>&#160;    }</div><div class="line"><a name="l03101"></a><span class="lineno"> 3101</span>&#160;</div><div class="line"><a name="l03102"></a><span class="lineno"> 3102</span>&#160;    <span class="comment">// No block has free item: Create new one and use it.</span></div><div class="line"><a name="l03103"></a><span class="lineno"> 3103</span>&#160;    ItemBlock&amp; newBlock = CreateNewBlock();</div><div class="line"><a name="l03104"></a><span class="lineno"> 3104</span>&#160;    Item* <span class="keyword">const</span> pItem = &amp;newBlock.pItems[0];</div><div class="line"><a name="l03105"></a><span class="lineno"> 3105</span>&#160;    newBlock.FirstFreeIndex = pItem-&gt;NextFreeIndex;</div><div class="line"><a name="l03106"></a><span class="lineno"> 3106</span>&#160;    <span class="keywordflow">return</span> &amp;pItem-&gt;Value;</div><div class="line"><a name="l03107"></a><span class="lineno"> 3107</span>&#160;}</div><div class="line"><a name="l03108"></a><span class="lineno"> 3108</span>&#160;</div><div class="line"><a name="l03109"></a><span class="lineno"> 3109</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03110"></a><span class="lineno"> 3110</span>&#160;<span class="keywordtype">void</span> VmaPoolAllocator&lt;T&gt;::Free(T* ptr)</div><div class="line"><a name="l03111"></a><span class="lineno"> 3111</span>&#160;{</div><div class="line"><a name="l03112"></a><span class="lineno"> 3112</span>&#160;    <span class="comment">// Search all memory blocks to find ptr.</span></div><div class="line"><a name="l03113"></a><span class="lineno"> 3113</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_ItemBlocks.size(); ++i)</div><div class="line"><a name="l03114"></a><span class="lineno"> 3114</span>&#160;    {</div><div class="line"><a name="l03115"></a><span class="lineno"> 3115</span>&#160;        ItemBlock&amp; block = m_ItemBlocks[i];</div><div class="line"><a name="l03116"></a><span class="lineno"> 3116</span>&#160;        </div><div class="line"><a name="l03117"></a><span class="lineno"> 3117</span>&#160;        <span class="comment">// Casting to union.</span></div><div class="line"><a name="l03118"></a><span class="lineno"> 3118</span>&#160;        Item* pItemPtr;</div><div class="line"><a name="l03119"></a><span class="lineno"> 3119</span>&#160;        memcpy(&amp;pItemPtr, &amp;ptr, <span class="keyword">sizeof</span>(pItemPtr));</div><div class="line"><a name="l03120"></a><span class="lineno"> 3120</span>&#160;        </div><div class="line"><a name="l03121"></a><span class="lineno"> 3121</span>&#160;        <span class="comment">// Check if pItemPtr is in address range of this block.</span></div><div class="line"><a name="l03122"></a><span class="lineno"> 3122</span>&#160;        <span class="keywordflow">if</span>((pItemPtr &gt;= block.pItems) &amp;&amp; (pItemPtr &lt; block.pItems + m_ItemsPerBlock))</div><div class="line"><a name="l03123"></a><span class="lineno"> 3123</span>&#160;        {</div><div class="line"><a name="l03124"></a><span class="lineno"> 3124</span>&#160;            <span class="keyword">const</span> uint32_t index = <span class="keyword">static_cast&lt;</span>uint32_t<span class="keyword">&gt;</span>(pItemPtr - block.pItems);</div><div class="line"><a name="l03125"></a><span class="lineno"> 3125</span>&#160;            pItemPtr-&gt;NextFreeIndex = block.FirstFreeIndex;</div><div class="line"><a name="l03126"></a><span class="lineno"> 3126</span>&#160;            block.FirstFreeIndex = index;</div><div class="line"><a name="l03127"></a><span class="lineno"> 3127</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l03128"></a><span class="lineno"> 3128</span>&#160;        }</div><div class="line"><a name="l03129"></a><span class="lineno"> 3129</span>&#160;    }</div><div class="line"><a name="l03130"></a><span class="lineno"> 3130</span>&#160;    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Pointer doesn&#39;t belong to this memory pool.&quot;</span>);</div><div class="line"><a name="l03131"></a><span class="lineno"> 3131</span>&#160;}</div><div class="line"><a name="l03132"></a><span class="lineno"> 3132</span>&#160;</div><div class="line"><a name="l03133"></a><span class="lineno"> 3133</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03134"></a><span class="lineno"> 3134</span>&#160;<span class="keyword">typename</span> VmaPoolAllocator&lt;T&gt;::ItemBlock&amp; VmaPoolAllocator&lt;T&gt;::CreateNewBlock()</div><div class="line"><a name="l03135"></a><span class="lineno"> 3135</span>&#160;{</div><div class="line"><a name="l03136"></a><span class="lineno"> 3136</span>&#160;    ItemBlock newBlock = {</div><div class="line"><a name="l03137"></a><span class="lineno"> 3137</span>&#160;        vma_new_array(m_pAllocationCallbacks, Item, m_ItemsPerBlock), 0 };</div><div class="line"><a name="l03138"></a><span class="lineno"> 3138</span>&#160;</div><div class="line"><a name="l03139"></a><span class="lineno"> 3139</span>&#160;    m_ItemBlocks.push_back(newBlock);</div><div class="line"><a name="l03140"></a><span class="lineno"> 3140</span>&#160;</div><div class="line"><a name="l03141"></a><span class="lineno"> 3141</span>&#160;    <span class="comment">// Setup singly-linked list of all free items in this block.</span></div><div class="line"><a name="l03142"></a><span class="lineno"> 3142</span>&#160;    <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; m_ItemsPerBlock - 1; ++i)</div><div class="line"><a name="l03143"></a><span class="lineno"> 3143</span>&#160;        newBlock.pItems[i].NextFreeIndex = i + 1;</div><div class="line"><a name="l03144"></a><span class="lineno"> 3144</span>&#160;    newBlock.pItems[m_ItemsPerBlock - 1].NextFreeIndex = UINT32_MAX;</div><div class="line"><a name="l03145"></a><span class="lineno"> 3145</span>&#160;    <span class="keywordflow">return</span> m_ItemBlocks.back();</div><div class="line"><a name="l03146"></a><span class="lineno"> 3146</span>&#160;}</div><div class="line"><a name="l03147"></a><span class="lineno"> 3147</span>&#160;</div><div class="line"><a name="l03149"></a><span class="lineno"> 3149</span>&#160;<span class="comment">// class VmaRawList, VmaList</span></div><div class="line"><a name="l03150"></a><span class="lineno"> 3150</span>&#160;</div><div class="line"><a name="l03151"></a><span class="lineno"> 3151</span>&#160;<span class="preprocessor">#if VMA_USE_STL_LIST</span></div><div class="line"><a name="l03152"></a><span class="lineno"> 3152</span>&#160;</div><div class="line"><a name="l03153"></a><span class="lineno"> 3153</span>&#160;<span class="preprocessor">#define VmaList std::list</span></div><div class="line"><a name="l03154"></a><span class="lineno"> 3154</span>&#160;</div><div class="line"><a name="l03155"></a><span class="lineno"> 3155</span>&#160;<span class="preprocessor">#else // #if VMA_USE_STL_LIST</span></div><div class="line"><a name="l03156"></a><span class="lineno"> 3156</span>&#160;</div><div class="line"><a name="l03157"></a><span class="lineno"> 3157</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03158"></a><span class="lineno"> 3158</span>&#160;<span class="keyword">struct </span>VmaListItem</div><div class="line"><a name="l03159"></a><span class="lineno"> 3159</span>&#160;{</div><div class="line"><a name="l03160"></a><span class="lineno"> 3160</span>&#160;    VmaListItem* pPrev;</div><div class="line"><a name="l03161"></a><span class="lineno"> 3161</span>&#160;    VmaListItem* pNext;</div><div class="line"><a name="l03162"></a><span class="lineno"> 3162</span>&#160;    T Value;</div><div class="line"><a name="l03163"></a><span class="lineno"> 3163</span>&#160;};</div><div class="line"><a name="l03164"></a><span class="lineno"> 3164</span>&#160;</div><div class="line"><a name="l03165"></a><span class="lineno"> 3165</span>&#160;<span class="comment">// Doubly linked list.</span></div><div class="line"><a name="l03166"></a><span class="lineno"> 3166</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03167"></a><span class="lineno"> 3167</span>&#160;<span class="keyword">class </span>VmaRawList</div><div class="line"><a name="l03168"></a><span class="lineno"> 3168</span>&#160;{</div><div class="line"><a name="l03169"></a><span class="lineno"> 3169</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03170"></a><span class="lineno"> 3170</span>&#160;    <span class="keyword">typedef</span> VmaListItem&lt;T&gt; ItemType;</div><div class="line"><a name="l03171"></a><span class="lineno"> 3171</span>&#160;</div><div class="line"><a name="l03172"></a><span class="lineno"> 3172</span>&#160;    VmaRawList(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks);</div><div class="line"><a name="l03173"></a><span class="lineno"> 3173</span>&#160;    ~VmaRawList();</div><div class="line"><a name="l03174"></a><span class="lineno"> 3174</span>&#160;    <span class="keywordtype">void</span> Clear();</div><div class="line"><a name="l03175"></a><span class="lineno"> 3175</span>&#160;</div><div class="line"><a name="l03176"></a><span class="lineno"> 3176</span>&#160;    <span class="keywordtype">size_t</span> GetCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count; }</div><div class="line"><a name="l03177"></a><span class="lineno"> 3177</span>&#160;    <span class="keywordtype">bool</span> IsEmpty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count == 0; }</div><div class="line"><a name="l03178"></a><span class="lineno"> 3178</span>&#160;</div><div class="line"><a name="l03179"></a><span class="lineno"> 3179</span>&#160;    ItemType* Front() { <span class="keywordflow">return</span> m_pFront; }</div><div class="line"><a name="l03180"></a><span class="lineno"> 3180</span>&#160;    <span class="keyword">const</span> ItemType* Front()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pFront; }</div><div class="line"><a name="l03181"></a><span class="lineno"> 3181</span>&#160;    ItemType* Back() { <span class="keywordflow">return</span> m_pBack; }</div><div class="line"><a name="l03182"></a><span class="lineno"> 3182</span>&#160;    <span class="keyword">const</span> ItemType* Back()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pBack; }</div><div class="line"><a name="l03183"></a><span class="lineno"> 3183</span>&#160;</div><div class="line"><a name="l03184"></a><span class="lineno"> 3184</span>&#160;    ItemType* PushBack();</div><div class="line"><a name="l03185"></a><span class="lineno"> 3185</span>&#160;    ItemType* PushFront();</div><div class="line"><a name="l03186"></a><span class="lineno"> 3186</span>&#160;    ItemType* PushBack(<span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03187"></a><span class="lineno"> 3187</span>&#160;    ItemType* PushFront(<span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03188"></a><span class="lineno"> 3188</span>&#160;    <span class="keywordtype">void</span> PopBack();</div><div class="line"><a name="l03189"></a><span class="lineno"> 3189</span>&#160;    <span class="keywordtype">void</span> PopFront();</div><div class="line"><a name="l03190"></a><span class="lineno"> 3190</span>&#160;    </div><div class="line"><a name="l03191"></a><span class="lineno"> 3191</span>&#160;    <span class="comment">// Item can be null - it means PushBack.</span></div><div class="line"><a name="l03192"></a><span class="lineno"> 3192</span>&#160;    ItemType* InsertBefore(ItemType* pItem);</div><div class="line"><a name="l03193"></a><span class="lineno"> 3193</span>&#160;    <span class="comment">// Item can be null - it means PushFront.</span></div><div class="line"><a name="l03194"></a><span class="lineno"> 3194</span>&#160;    ItemType* InsertAfter(ItemType* pItem);</div><div class="line"><a name="l03195"></a><span class="lineno"> 3195</span>&#160;</div><div class="line"><a name="l03196"></a><span class="lineno"> 3196</span>&#160;    ItemType* InsertBefore(ItemType* pItem, <span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03197"></a><span class="lineno"> 3197</span>&#160;    ItemType* InsertAfter(ItemType* pItem, <span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03198"></a><span class="lineno"> 3198</span>&#160;</div><div class="line"><a name="l03199"></a><span class="lineno"> 3199</span>&#160;    <span class="keywordtype">void</span> Remove(ItemType* pItem);</div><div class="line"><a name="l03200"></a><span class="lineno"> 3200</span>&#160;</div><div class="line"><a name="l03201"></a><span class="lineno"> 3201</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03202"></a><span class="lineno"> 3202</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* <span class="keyword">const</span> m_pAllocationCallbacks;</div><div class="line"><a name="l03203"></a><span class="lineno"> 3203</span>&#160;    VmaPoolAllocator&lt;ItemType&gt; m_ItemAllocator;</div><div class="line"><a name="l03204"></a><span class="lineno"> 3204</span>&#160;    ItemType* m_pFront;</div><div class="line"><a name="l03205"></a><span class="lineno"> 3205</span>&#160;    ItemType* m_pBack;</div><div class="line"><a name="l03206"></a><span class="lineno"> 3206</span>&#160;    <span class="keywordtype">size_t</span> m_Count;</div><div class="line"><a name="l03207"></a><span class="lineno"> 3207</span>&#160;</div><div class="line"><a name="l03208"></a><span class="lineno"> 3208</span>&#160;    <span class="comment">// Declared not defined, to block copy constructor and assignment operator.</span></div><div class="line"><a name="l03209"></a><span class="lineno"> 3209</span>&#160;    VmaRawList(<span class="keyword">const</span> VmaRawList&lt;T&gt;&amp; src);</div><div class="line"><a name="l03210"></a><span class="lineno"> 3210</span>&#160;    VmaRawList&lt;T&gt;&amp; operator=(<span class="keyword">const</span> VmaRawList&lt;T&gt;&amp; rhs);</div><div class="line"><a name="l03211"></a><span class="lineno"> 3211</span>&#160;};</div><div class="line"><a name="l03212"></a><span class="lineno"> 3212</span>&#160;</div><div class="line"><a name="l03213"></a><span class="lineno"> 3213</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03214"></a><span class="lineno"> 3214</span>&#160;VmaRawList&lt;T&gt;::VmaRawList(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks) :</div><div class="line"><a name="l03215"></a><span class="lineno"> 3215</span>&#160;    m_pAllocationCallbacks(pAllocationCallbacks),</div><div class="line"><a name="l03216"></a><span class="lineno"> 3216</span>&#160;    m_ItemAllocator(pAllocationCallbacks, 128),</div><div class="line"><a name="l03217"></a><span class="lineno"> 3217</span>&#160;    m_pFront(VMA_NULL),</div><div class="line"><a name="l03218"></a><span class="lineno"> 3218</span>&#160;    m_pBack(VMA_NULL),</div><div class="line"><a name="l03219"></a><span class="lineno"> 3219</span>&#160;    m_Count(0)</div><div class="line"><a name="l03220"></a><span class="lineno"> 3220</span>&#160;{</div><div class="line"><a name="l03221"></a><span class="lineno"> 3221</span>&#160;}</div><div class="line"><a name="l03222"></a><span class="lineno"> 3222</span>&#160;</div><div class="line"><a name="l03223"></a><span class="lineno"> 3223</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03224"></a><span class="lineno"> 3224</span>&#160;VmaRawList&lt;T&gt;::~VmaRawList()</div><div class="line"><a name="l03225"></a><span class="lineno"> 3225</span>&#160;{</div><div class="line"><a name="l03226"></a><span class="lineno"> 3226</span>&#160;    <span class="comment">// Intentionally not calling Clear, because that would be unnecessary</span></div><div class="line"><a name="l03227"></a><span class="lineno"> 3227</span>&#160;    <span class="comment">// computations to return all items to m_ItemAllocator as free.</span></div><div class="line"><a name="l03228"></a><span class="lineno"> 3228</span>&#160;}</div><div class="line"><a name="l03229"></a><span class="lineno"> 3229</span>&#160;</div><div class="line"><a name="l03230"></a><span class="lineno"> 3230</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03231"></a><span class="lineno"> 3231</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::Clear()</div><div class="line"><a name="l03232"></a><span class="lineno"> 3232</span>&#160;{</div><div class="line"><a name="l03233"></a><span class="lineno"> 3233</span>&#160;    <span class="keywordflow">if</span>(IsEmpty() == <span class="keyword">false</span>)</div><div class="line"><a name="l03234"></a><span class="lineno"> 3234</span>&#160;    {</div><div class="line"><a name="l03235"></a><span class="lineno"> 3235</span>&#160;        ItemType* pItem = m_pBack;</div><div class="line"><a name="l03236"></a><span class="lineno"> 3236</span>&#160;        <span class="keywordflow">while</span>(pItem != VMA_NULL)</div><div class="line"><a name="l03237"></a><span class="lineno"> 3237</span>&#160;        {</div><div class="line"><a name="l03238"></a><span class="lineno"> 3238</span>&#160;            ItemType* <span class="keyword">const</span> pPrevItem = pItem-&gt;pPrev;</div><div class="line"><a name="l03239"></a><span class="lineno"> 3239</span>&#160;            m_ItemAllocator.Free(pItem);</div><div class="line"><a name="l03240"></a><span class="lineno"> 3240</span>&#160;            pItem = pPrevItem;</div><div class="line"><a name="l03241"></a><span class="lineno"> 3241</span>&#160;        }</div><div class="line"><a name="l03242"></a><span class="lineno"> 3242</span>&#160;        m_pFront = VMA_NULL;</div><div class="line"><a name="l03243"></a><span class="lineno"> 3243</span>&#160;        m_pBack = VMA_NULL;</div><div class="line"><a name="l03244"></a><span class="lineno"> 3244</span>&#160;        m_Count = 0;</div><div class="line"><a name="l03245"></a><span class="lineno"> 3245</span>&#160;    }</div><div class="line"><a name="l03246"></a><span class="lineno"> 3246</span>&#160;}</div><div class="line"><a name="l03247"></a><span class="lineno"> 3247</span>&#160;</div><div class="line"><a name="l03248"></a><span class="lineno"> 3248</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03249"></a><span class="lineno"> 3249</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushBack()</div><div class="line"><a name="l03250"></a><span class="lineno"> 3250</span>&#160;{</div><div class="line"><a name="l03251"></a><span class="lineno"> 3251</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03252"></a><span class="lineno"> 3252</span>&#160;    pNewItem-&gt;pNext = VMA_NULL;</div><div class="line"><a name="l03253"></a><span class="lineno"> 3253</span>&#160;    <span class="keywordflow">if</span>(IsEmpty())</div><div class="line"><a name="l03254"></a><span class="lineno"> 3254</span>&#160;    {</div><div class="line"><a name="l03255"></a><span class="lineno"> 3255</span>&#160;        pNewItem-&gt;pPrev = VMA_NULL;</div><div class="line"><a name="l03256"></a><span class="lineno"> 3256</span>&#160;        m_pFront = pNewItem;</div><div class="line"><a name="l03257"></a><span class="lineno"> 3257</span>&#160;        m_pBack = pNewItem;</div><div class="line"><a name="l03258"></a><span class="lineno"> 3258</span>&#160;        m_Count = 1;</div><div class="line"><a name="l03259"></a><span class="lineno"> 3259</span>&#160;    }</div><div class="line"><a name="l03260"></a><span class="lineno"> 3260</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03261"></a><span class="lineno"> 3261</span>&#160;    {</div><div class="line"><a name="l03262"></a><span class="lineno"> 3262</span>&#160;        pNewItem-&gt;pPrev = m_pBack;</div><div class="line"><a name="l03263"></a><span class="lineno"> 3263</span>&#160;        m_pBack-&gt;pNext = pNewItem;</div><div class="line"><a name="l03264"></a><span class="lineno"> 3264</span>&#160;        m_pBack = pNewItem;</div><div class="line"><a name="l03265"></a><span class="lineno"> 3265</span>&#160;        ++m_Count;</div><div class="line"><a name="l03266"></a><span class="lineno"> 3266</span>&#160;    }</div><div class="line"><a name="l03267"></a><span class="lineno"> 3267</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03268"></a><span class="lineno"> 3268</span>&#160;}</div><div class="line"><a name="l03269"></a><span class="lineno"> 3269</span>&#160;</div><div class="line"><a name="l03270"></a><span class="lineno"> 3270</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03271"></a><span class="lineno"> 3271</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushFront()</div><div class="line"><a name="l03272"></a><span class="lineno"> 3272</span>&#160;{</div><div class="line"><a name="l03273"></a><span class="lineno"> 3273</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03274"></a><span class="lineno"> 3274</span>&#160;    pNewItem-&gt;pPrev = VMA_NULL;</div><div class="line"><a name="l03275"></a><span class="lineno"> 3275</span>&#160;    <span class="keywordflow">if</span>(IsEmpty())</div><div class="line"><a name="l03276"></a><span class="lineno"> 3276</span>&#160;    {</div><div class="line"><a name="l03277"></a><span class="lineno"> 3277</span>&#160;        pNewItem-&gt;pNext = VMA_NULL;</div><div class="line"><a name="l03278"></a><span class="lineno"> 3278</span>&#160;        m_pFront = pNewItem;</div><div class="line"><a name="l03279"></a><span class="lineno"> 3279</span>&#160;        m_pBack = pNewItem;</div><div class="line"><a name="l03280"></a><span class="lineno"> 3280</span>&#160;        m_Count = 1;</div><div class="line"><a name="l03281"></a><span class="lineno"> 3281</span>&#160;    }</div><div class="line"><a name="l03282"></a><span class="lineno"> 3282</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03283"></a><span class="lineno"> 3283</span>&#160;    {</div><div class="line"><a name="l03284"></a><span class="lineno"> 3284</span>&#160;        pNewItem-&gt;pNext = m_pFront;</div><div class="line"><a name="l03285"></a><span class="lineno"> 3285</span>&#160;        m_pFront-&gt;pPrev = pNewItem;</div><div class="line"><a name="l03286"></a><span class="lineno"> 3286</span>&#160;        m_pFront = pNewItem;</div><div class="line"><a name="l03287"></a><span class="lineno"> 3287</span>&#160;        ++m_Count;</div><div class="line"><a name="l03288"></a><span class="lineno"> 3288</span>&#160;    }</div><div class="line"><a name="l03289"></a><span class="lineno"> 3289</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03290"></a><span class="lineno"> 3290</span>&#160;}</div><div class="line"><a name="l03291"></a><span class="lineno"> 3291</span>&#160;</div><div class="line"><a name="l03292"></a><span class="lineno"> 3292</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03293"></a><span class="lineno"> 3293</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushBack(<span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03294"></a><span class="lineno"> 3294</span>&#160;{</div><div class="line"><a name="l03295"></a><span class="lineno"> 3295</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = PushBack();</div><div class="line"><a name="l03296"></a><span class="lineno"> 3296</span>&#160;    pNewItem-&gt;Value = value;</div><div class="line"><a name="l03297"></a><span class="lineno"> 3297</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03298"></a><span class="lineno"> 3298</span>&#160;}</div><div class="line"><a name="l03299"></a><span class="lineno"> 3299</span>&#160;</div><div class="line"><a name="l03300"></a><span class="lineno"> 3300</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03301"></a><span class="lineno"> 3301</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushFront(<span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03302"></a><span class="lineno"> 3302</span>&#160;{</div><div class="line"><a name="l03303"></a><span class="lineno"> 3303</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = PushFront();</div><div class="line"><a name="l03304"></a><span class="lineno"> 3304</span>&#160;    pNewItem-&gt;Value = value;</div><div class="line"><a name="l03305"></a><span class="lineno"> 3305</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03306"></a><span class="lineno"> 3306</span>&#160;}</div><div class="line"><a name="l03307"></a><span class="lineno"> 3307</span>&#160;</div><div class="line"><a name="l03308"></a><span class="lineno"> 3308</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03309"></a><span class="lineno"> 3309</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::PopBack()</div><div class="line"><a name="l03310"></a><span class="lineno"> 3310</span>&#160;{</div><div class="line"><a name="l03311"></a><span class="lineno"> 3311</span>&#160;    VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03312"></a><span class="lineno"> 3312</span>&#160;    ItemType* <span class="keyword">const</span> pBackItem = m_pBack;</div><div class="line"><a name="l03313"></a><span class="lineno"> 3313</span>&#160;    ItemType* <span class="keyword">const</span> pPrevItem = pBackItem-&gt;pPrev;</div><div class="line"><a name="l03314"></a><span class="lineno"> 3314</span>&#160;    <span class="keywordflow">if</span>(pPrevItem != VMA_NULL)</div><div class="line"><a name="l03315"></a><span class="lineno"> 3315</span>&#160;    {</div><div class="line"><a name="l03316"></a><span class="lineno"> 3316</span>&#160;        pPrevItem-&gt;pNext = VMA_NULL;</div><div class="line"><a name="l03317"></a><span class="lineno"> 3317</span>&#160;    }</div><div class="line"><a name="l03318"></a><span class="lineno"> 3318</span>&#160;    m_pBack = pPrevItem;</div><div class="line"><a name="l03319"></a><span class="lineno"> 3319</span>&#160;    m_ItemAllocator.Free(pBackItem);</div><div class="line"><a name="l03320"></a><span class="lineno"> 3320</span>&#160;    --m_Count;</div><div class="line"><a name="l03321"></a><span class="lineno"> 3321</span>&#160;}</div><div class="line"><a name="l03322"></a><span class="lineno"> 3322</span>&#160;</div><div class="line"><a name="l03323"></a><span class="lineno"> 3323</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03324"></a><span class="lineno"> 3324</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::PopFront()</div><div class="line"><a name="l03325"></a><span class="lineno"> 3325</span>&#160;{</div><div class="line"><a name="l03326"></a><span class="lineno"> 3326</span>&#160;    VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03327"></a><span class="lineno"> 3327</span>&#160;    ItemType* <span class="keyword">const</span> pFrontItem = m_pFront;</div><div class="line"><a name="l03328"></a><span class="lineno"> 3328</span>&#160;    ItemType* <span class="keyword">const</span> pNextItem = pFrontItem-&gt;pNext;</div><div class="line"><a name="l03329"></a><span class="lineno"> 3329</span>&#160;    <span class="keywordflow">if</span>(pNextItem != VMA_NULL)</div><div class="line"><a name="l03330"></a><span class="lineno"> 3330</span>&#160;    {</div><div class="line"><a name="l03331"></a><span class="lineno"> 3331</span>&#160;        pNextItem-&gt;pPrev = VMA_NULL;</div><div class="line"><a name="l03332"></a><span class="lineno"> 3332</span>&#160;    }</div><div class="line"><a name="l03333"></a><span class="lineno"> 3333</span>&#160;    m_pFront = pNextItem;</div><div class="line"><a name="l03334"></a><span class="lineno"> 3334</span>&#160;    m_ItemAllocator.Free(pFrontItem);</div><div class="line"><a name="l03335"></a><span class="lineno"> 3335</span>&#160;    --m_Count;</div><div class="line"><a name="l03336"></a><span class="lineno"> 3336</span>&#160;}</div><div class="line"><a name="l03337"></a><span class="lineno"> 3337</span>&#160;</div><div class="line"><a name="l03338"></a><span class="lineno"> 3338</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03339"></a><span class="lineno"> 3339</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::Remove(ItemType* pItem)</div><div class="line"><a name="l03340"></a><span class="lineno"> 3340</span>&#160;{</div><div class="line"><a name="l03341"></a><span class="lineno"> 3341</span>&#160;    VMA_HEAVY_ASSERT(pItem != VMA_NULL);</div><div class="line"><a name="l03342"></a><span class="lineno"> 3342</span>&#160;    VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03343"></a><span class="lineno"> 3343</span>&#160;</div><div class="line"><a name="l03344"></a><span class="lineno"> 3344</span>&#160;    <span class="keywordflow">if</span>(pItem-&gt;pPrev != VMA_NULL)</div><div class="line"><a name="l03345"></a><span class="lineno"> 3345</span>&#160;    {</div><div class="line"><a name="l03346"></a><span class="lineno"> 3346</span>&#160;        pItem-&gt;pPrev-&gt;pNext = pItem-&gt;pNext;</div><div class="line"><a name="l03347"></a><span class="lineno"> 3347</span>&#160;    }</div><div class="line"><a name="l03348"></a><span class="lineno"> 3348</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03349"></a><span class="lineno"> 3349</span>&#160;    {</div><div class="line"><a name="l03350"></a><span class="lineno"> 3350</span>&#160;        VMA_HEAVY_ASSERT(m_pFront == pItem);</div><div class="line"><a name="l03351"></a><span class="lineno"> 3351</span>&#160;        m_pFront = pItem-&gt;pNext;</div><div class="line"><a name="l03352"></a><span class="lineno"> 3352</span>&#160;    }</div><div class="line"><a name="l03353"></a><span class="lineno"> 3353</span>&#160;</div><div class="line"><a name="l03354"></a><span class="lineno"> 3354</span>&#160;    <span class="keywordflow">if</span>(pItem-&gt;pNext != VMA_NULL)</div><div class="line"><a name="l03355"></a><span class="lineno"> 3355</span>&#160;    {</div><div class="line"><a name="l03356"></a><span class="lineno"> 3356</span>&#160;        pItem-&gt;pNext-&gt;pPrev = pItem-&gt;pPrev;</div><div class="line"><a name="l03357"></a><span class="lineno"> 3357</span>&#160;    }</div><div class="line"><a name="l03358"></a><span class="lineno"> 3358</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03359"></a><span class="lineno"> 3359</span>&#160;    {</div><div class="line"><a name="l03360"></a><span class="lineno"> 3360</span>&#160;        VMA_HEAVY_ASSERT(m_pBack == pItem);</div><div class="line"><a name="l03361"></a><span class="lineno"> 3361</span>&#160;        m_pBack = pItem-&gt;pPrev;</div><div class="line"><a name="l03362"></a><span class="lineno"> 3362</span>&#160;    }</div><div class="line"><a name="l03363"></a><span class="lineno"> 3363</span>&#160;</div><div class="line"><a name="l03364"></a><span class="lineno"> 3364</span>&#160;    m_ItemAllocator.Free(pItem);</div><div class="line"><a name="l03365"></a><span class="lineno"> 3365</span>&#160;    --m_Count;</div><div class="line"><a name="l03366"></a><span class="lineno"> 3366</span>&#160;}</div><div class="line"><a name="l03367"></a><span class="lineno"> 3367</span>&#160;</div><div class="line"><a name="l03368"></a><span class="lineno"> 3368</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03369"></a><span class="lineno"> 3369</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertBefore(ItemType* pItem)</div><div class="line"><a name="l03370"></a><span class="lineno"> 3370</span>&#160;{</div><div class="line"><a name="l03371"></a><span class="lineno"> 3371</span>&#160;    <span class="keywordflow">if</span>(pItem != VMA_NULL)</div><div class="line"><a name="l03372"></a><span class="lineno"> 3372</span>&#160;    {</div><div class="line"><a name="l03373"></a><span class="lineno"> 3373</span>&#160;        ItemType* <span class="keyword">const</span> prevItem = pItem-&gt;pPrev;</div><div class="line"><a name="l03374"></a><span class="lineno"> 3374</span>&#160;        ItemType* <span class="keyword">const</span> newItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03375"></a><span class="lineno"> 3375</span>&#160;        newItem-&gt;pPrev = prevItem;</div><div class="line"><a name="l03376"></a><span class="lineno"> 3376</span>&#160;        newItem-&gt;pNext = pItem;</div><div class="line"><a name="l03377"></a><span class="lineno"> 3377</span>&#160;        pItem-&gt;pPrev = newItem;</div><div class="line"><a name="l03378"></a><span class="lineno"> 3378</span>&#160;        <span class="keywordflow">if</span>(prevItem != VMA_NULL)</div><div class="line"><a name="l03379"></a><span class="lineno"> 3379</span>&#160;        {</div><div class="line"><a name="l03380"></a><span class="lineno"> 3380</span>&#160;            prevItem-&gt;pNext = newItem;</div><div class="line"><a name="l03381"></a><span class="lineno"> 3381</span>&#160;        }</div><div class="line"><a name="l03382"></a><span class="lineno"> 3382</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l03383"></a><span class="lineno"> 3383</span>&#160;        {</div><div class="line"><a name="l03384"></a><span class="lineno"> 3384</span>&#160;            VMA_HEAVY_ASSERT(m_pFront == pItem);</div><div class="line"><a name="l03385"></a><span class="lineno"> 3385</span>&#160;            m_pFront = newItem;</div><div class="line"><a name="l03386"></a><span class="lineno"> 3386</span>&#160;        }</div><div class="line"><a name="l03387"></a><span class="lineno"> 3387</span>&#160;        ++m_Count;</div><div class="line"><a name="l03388"></a><span class="lineno"> 3388</span>&#160;        <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03389"></a><span class="lineno"> 3389</span>&#160;    }</div><div class="line"><a name="l03390"></a><span class="lineno"> 3390</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03391"></a><span class="lineno"> 3391</span>&#160;        <span class="keywordflow">return</span> PushBack();</div><div class="line"><a name="l03392"></a><span class="lineno"> 3392</span>&#160;}</div><div class="line"><a name="l03393"></a><span class="lineno"> 3393</span>&#160;</div><div class="line"><a name="l03394"></a><span class="lineno"> 3394</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03395"></a><span class="lineno"> 3395</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertAfter(ItemType* pItem)</div><div class="line"><a name="l03396"></a><span class="lineno"> 3396</span>&#160;{</div><div class="line"><a name="l03397"></a><span class="lineno"> 3397</span>&#160;    <span class="keywordflow">if</span>(pItem != VMA_NULL)</div><div class="line"><a name="l03398"></a><span class="lineno"> 3398</span>&#160;    {</div><div class="line"><a name="l03399"></a><span class="lineno"> 3399</span>&#160;        ItemType* <span class="keyword">const</span> nextItem = pItem-&gt;pNext;</div><div class="line"><a name="l03400"></a><span class="lineno"> 3400</span>&#160;        ItemType* <span class="keyword">const</span> newItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03401"></a><span class="lineno"> 3401</span>&#160;        newItem-&gt;pNext = nextItem;</div><div class="line"><a name="l03402"></a><span class="lineno"> 3402</span>&#160;        newItem-&gt;pPrev = pItem;</div><div class="line"><a name="l03403"></a><span class="lineno"> 3403</span>&#160;        pItem-&gt;pNext = newItem;</div><div class="line"><a name="l03404"></a><span class="lineno"> 3404</span>&#160;        <span class="keywordflow">if</span>(nextItem != VMA_NULL)</div><div class="line"><a name="l03405"></a><span class="lineno"> 3405</span>&#160;        {</div><div class="line"><a name="l03406"></a><span class="lineno"> 3406</span>&#160;            nextItem-&gt;pPrev = newItem;</div><div class="line"><a name="l03407"></a><span class="lineno"> 3407</span>&#160;        }</div><div class="line"><a name="l03408"></a><span class="lineno"> 3408</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l03409"></a><span class="lineno"> 3409</span>&#160;        {</div><div class="line"><a name="l03410"></a><span class="lineno"> 3410</span>&#160;            VMA_HEAVY_ASSERT(m_pBack == pItem);</div><div class="line"><a name="l03411"></a><span class="lineno"> 3411</span>&#160;            m_pBack = newItem;</div><div class="line"><a name="l03412"></a><span class="lineno"> 3412</span>&#160;        }</div><div class="line"><a name="l03413"></a><span class="lineno"> 3413</span>&#160;        ++m_Count;</div><div class="line"><a name="l03414"></a><span class="lineno"> 3414</span>&#160;        <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03415"></a><span class="lineno"> 3415</span>&#160;    }</div><div class="line"><a name="l03416"></a><span class="lineno"> 3416</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03417"></a><span class="lineno"> 3417</span>&#160;        <span class="keywordflow">return</span> PushFront();</div><div class="line"><a name="l03418"></a><span class="lineno"> 3418</span>&#160;}</div><div class="line"><a name="l03419"></a><span class="lineno"> 3419</span>&#160;</div><div class="line"><a name="l03420"></a><span class="lineno"> 3420</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03421"></a><span class="lineno"> 3421</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertBefore(ItemType* pItem, <span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03422"></a><span class="lineno"> 3422</span>&#160;{</div><div class="line"><a name="l03423"></a><span class="lineno"> 3423</span>&#160;    ItemType* <span class="keyword">const</span> newItem = InsertBefore(pItem);</div><div class="line"><a name="l03424"></a><span class="lineno"> 3424</span>&#160;    newItem-&gt;Value = value;</div><div class="line"><a name="l03425"></a><span class="lineno"> 3425</span>&#160;    <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03426"></a><span class="lineno"> 3426</span>&#160;}</div><div class="line"><a name="l03427"></a><span class="lineno"> 3427</span>&#160;</div><div class="line"><a name="l03428"></a><span class="lineno"> 3428</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03429"></a><span class="lineno"> 3429</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertAfter(ItemType* pItem, <span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03430"></a><span class="lineno"> 3430</span>&#160;{</div><div class="line"><a name="l03431"></a><span class="lineno"> 3431</span>&#160;    ItemType* <span class="keyword">const</span> newItem = InsertAfter(pItem);</div><div class="line"><a name="l03432"></a><span class="lineno"> 3432</span>&#160;    newItem-&gt;Value = value;</div><div class="line"><a name="l03433"></a><span class="lineno"> 3433</span>&#160;    <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03434"></a><span class="lineno"> 3434</span>&#160;}</div><div class="line"><a name="l03435"></a><span class="lineno"> 3435</span>&#160;</div><div class="line"><a name="l03436"></a><span class="lineno"> 3436</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> AllocatorT&gt;</div><div class="line"><a name="l03437"></a><span class="lineno"> 3437</span>&#160;<span class="keyword">class </span>VmaList</div><div class="line"><a name="l03438"></a><span class="lineno"> 3438</span>&#160;{</div><div class="line"><a name="l03439"></a><span class="lineno"> 3439</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03440"></a><span class="lineno"> 3440</span>&#160;    <span class="keyword">class </span>iterator</div><div class="line"><a name="l03441"></a><span class="lineno"> 3441</span>&#160;    {</div><div class="line"><a name="l03442"></a><span class="lineno"> 3442</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l03443"></a><span class="lineno"> 3443</span>&#160;        iterator() :</div><div class="line"><a name="l03444"></a><span class="lineno"> 3444</span>&#160;            m_pList(VMA_NULL),</div><div class="line"><a name="l03445"></a><span class="lineno"> 3445</span>&#160;            m_pItem(VMA_NULL)</div><div class="line"><a name="l03446"></a><span class="lineno"> 3446</span>&#160;        {</div><div class="line"><a name="l03447"></a><span class="lineno"> 3447</span>&#160;        }</div><div class="line"><a name="l03448"></a><span class="lineno"> 3448</span>&#160;</div><div class="line"><a name="l03449"></a><span class="lineno"> 3449</span>&#160;        T&amp; operator*()<span class="keyword"> const</span></div><div class="line"><a name="l03450"></a><span class="lineno"> 3450</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03451"></a><span class="lineno"> 3451</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03452"></a><span class="lineno"> 3452</span>&#160;            <span class="keywordflow">return</span> m_pItem-&gt;Value;</div><div class="line"><a name="l03453"></a><span class="lineno"> 3453</span>&#160;        }</div><div class="line"><a name="l03454"></a><span class="lineno"> 3454</span>&#160;        T* operator-&gt;()<span class="keyword"> const</span></div><div class="line"><a name="l03455"></a><span class="lineno"> 3455</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03456"></a><span class="lineno"> 3456</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03457"></a><span class="lineno"> 3457</span>&#160;            <span class="keywordflow">return</span> &amp;m_pItem-&gt;Value;</div><div class="line"><a name="l03458"></a><span class="lineno"> 3458</span>&#160;        }</div><div class="line"><a name="l03459"></a><span class="lineno"> 3459</span>&#160;</div><div class="line"><a name="l03460"></a><span class="lineno"> 3460</span>&#160;        iterator&amp; operator++()</div><div class="line"><a name="l03461"></a><span class="lineno"> 3461</span>&#160;        {</div><div class="line"><a name="l03462"></a><span class="lineno"> 3462</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03463"></a><span class="lineno"> 3463</span>&#160;            m_pItem = m_pItem-&gt;pNext;</div><div class="line"><a name="l03464"></a><span class="lineno"> 3464</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l03465"></a><span class="lineno"> 3465</span>&#160;        }</div><div class="line"><a name="l03466"></a><span class="lineno"> 3466</span>&#160;        iterator&amp; operator--()</div><div class="line"><a name="l03467"></a><span class="lineno"> 3467</span>&#160;        {</div><div class="line"><a name="l03468"></a><span class="lineno"> 3468</span>&#160;            <span class="keywordflow">if</span>(m_pItem != VMA_NULL)</div><div class="line"><a name="l03469"></a><span class="lineno"> 3469</span>&#160;            {</div><div class="line"><a name="l03470"></a><span class="lineno"> 3470</span>&#160;                m_pItem = m_pItem-&gt;pPrev;</div><div class="line"><a name="l03471"></a><span class="lineno"> 3471</span>&#160;            }</div><div class="line"><a name="l03472"></a><span class="lineno"> 3472</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l03473"></a><span class="lineno"> 3473</span>&#160;            {</div><div class="line"><a name="l03474"></a><span class="lineno"> 3474</span>&#160;                VMA_HEAVY_ASSERT(!m_pList-&gt;IsEmpty());</div><div class="line"><a name="l03475"></a><span class="lineno"> 3475</span>&#160;                m_pItem = m_pList-&gt;Back();</div><div class="line"><a name="l03476"></a><span class="lineno"> 3476</span>&#160;            }</div><div class="line"><a name="l03477"></a><span class="lineno"> 3477</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l03478"></a><span class="lineno"> 3478</span>&#160;        }</div><div class="line"><a name="l03479"></a><span class="lineno"> 3479</span>&#160;</div><div class="line"><a name="l03480"></a><span class="lineno"> 3480</span>&#160;        iterator operator++(<span class="keywordtype">int</span>)</div><div class="line"><a name="l03481"></a><span class="lineno"> 3481</span>&#160;        {</div><div class="line"><a name="l03482"></a><span class="lineno"> 3482</span>&#160;            iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l03483"></a><span class="lineno"> 3483</span>&#160;            ++*<span class="keyword">this</span>;</div><div class="line"><a name="l03484"></a><span class="lineno"> 3484</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l03485"></a><span class="lineno"> 3485</span>&#160;        }</div><div class="line"><a name="l03486"></a><span class="lineno"> 3486</span>&#160;        iterator operator--(<span class="keywordtype">int</span>)</div><div class="line"><a name="l03487"></a><span class="lineno"> 3487</span>&#160;        {</div><div class="line"><a name="l03488"></a><span class="lineno"> 3488</span>&#160;            iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l03489"></a><span class="lineno"> 3489</span>&#160;            --*<span class="keyword">this</span>;</div><div class="line"><a name="l03490"></a><span class="lineno"> 3490</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l03491"></a><span class="lineno"> 3491</span>&#160;        }</div><div class="line"><a name="l03492"></a><span class="lineno"> 3492</span>&#160;</div><div class="line"><a name="l03493"></a><span class="lineno"> 3493</span>&#160;        <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03494"></a><span class="lineno"> 3494</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03495"></a><span class="lineno"> 3495</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l03496"></a><span class="lineno"> 3496</span>&#160;            <span class="keywordflow">return</span> m_pItem == rhs.m_pItem;</div><div class="line"><a name="l03497"></a><span class="lineno"> 3497</span>&#160;        }</div><div class="line"><a name="l03498"></a><span class="lineno"> 3498</span>&#160;        <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03499"></a><span class="lineno"> 3499</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03500"></a><span class="lineno"> 3500</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l03501"></a><span class="lineno"> 3501</span>&#160;            <span class="keywordflow">return</span> m_pItem != rhs.m_pItem;</div><div class="line"><a name="l03502"></a><span class="lineno"> 3502</span>&#160;        }</div><div class="line"><a name="l03503"></a><span class="lineno"> 3503</span>&#160;        </div><div class="line"><a name="l03504"></a><span class="lineno"> 3504</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l03505"></a><span class="lineno"> 3505</span>&#160;        VmaRawList&lt;T&gt;* m_pList;</div><div class="line"><a name="l03506"></a><span class="lineno"> 3506</span>&#160;        VmaListItem&lt;T&gt;* m_pItem;</div><div class="line"><a name="l03507"></a><span class="lineno"> 3507</span>&#160;</div><div class="line"><a name="l03508"></a><span class="lineno"> 3508</span>&#160;        iterator(VmaRawList&lt;T&gt;* pList, VmaListItem&lt;T&gt;* pItem) :</div><div class="line"><a name="l03509"></a><span class="lineno"> 3509</span>&#160;            m_pList(pList),</div><div class="line"><a name="l03510"></a><span class="lineno"> 3510</span>&#160;            m_pItem(pItem)</div><div class="line"><a name="l03511"></a><span class="lineno"> 3511</span>&#160;        {</div><div class="line"><a name="l03512"></a><span class="lineno"> 3512</span>&#160;        }</div><div class="line"><a name="l03513"></a><span class="lineno"> 3513</span>&#160;</div><div class="line"><a name="l03514"></a><span class="lineno"> 3514</span>&#160;        <span class="keyword">friend</span> <span class="keyword">class </span>VmaList&lt;T, AllocatorT&gt;;</div><div class="line"><a name="l03515"></a><span class="lineno"> 3515</span>&#160;    };</div><div class="line"><a name="l03516"></a><span class="lineno"> 3516</span>&#160;</div><div class="line"><a name="l03517"></a><span class="lineno"> 3517</span>&#160;    <span class="keyword">class </span>const_iterator</div><div class="line"><a name="l03518"></a><span class="lineno"> 3518</span>&#160;    {</div><div class="line"><a name="l03519"></a><span class="lineno"> 3519</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l03520"></a><span class="lineno"> 3520</span>&#160;        const_iterator() :</div><div class="line"><a name="l03521"></a><span class="lineno"> 3521</span>&#160;            m_pList(VMA_NULL),</div><div class="line"><a name="l03522"></a><span class="lineno"> 3522</span>&#160;            m_pItem(VMA_NULL)</div><div class="line"><a name="l03523"></a><span class="lineno"> 3523</span>&#160;        {</div><div class="line"><a name="l03524"></a><span class="lineno"> 3524</span>&#160;        }</div><div class="line"><a name="l03525"></a><span class="lineno"> 3525</span>&#160;</div><div class="line"><a name="l03526"></a><span class="lineno"> 3526</span>&#160;        const_iterator(<span class="keyword">const</span> iterator&amp; src) :</div><div class="line"><a name="l03527"></a><span class="lineno"> 3527</span>&#160;            m_pList(src.m_pList),</div><div class="line"><a name="l03528"></a><span class="lineno"> 3528</span>&#160;            m_pItem(src.m_pItem)</div><div class="line"><a name="l03529"></a><span class="lineno"> 3529</span>&#160;        {</div><div class="line"><a name="l03530"></a><span class="lineno"> 3530</span>&#160;        }</div><div class="line"><a name="l03531"></a><span class="lineno"> 3531</span>&#160;        </div><div class="line"><a name="l03532"></a><span class="lineno"> 3532</span>&#160;        <span class="keyword">const</span> T&amp; operator*()<span class="keyword"> const</span></div><div class="line"><a name="l03533"></a><span class="lineno"> 3533</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03534"></a><span class="lineno"> 3534</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03535"></a><span class="lineno"> 3535</span>&#160;            <span class="keywordflow">return</span> m_pItem-&gt;Value;</div><div class="line"><a name="l03536"></a><span class="lineno"> 3536</span>&#160;        }</div><div class="line"><a name="l03537"></a><span class="lineno"> 3537</span>&#160;        <span class="keyword">const</span> T* operator-&gt;()<span class="keyword"> const</span></div><div class="line"><a name="l03538"></a><span class="lineno"> 3538</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03539"></a><span class="lineno"> 3539</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03540"></a><span class="lineno"> 3540</span>&#160;            <span class="keywordflow">return</span> &amp;m_pItem-&gt;Value;</div><div class="line"><a name="l03541"></a><span class="lineno"> 3541</span>&#160;        }</div><div class="line"><a name="l03542"></a><span class="lineno"> 3542</span>&#160;</div><div class="line"><a name="l03543"></a><span class="lineno"> 3543</span>&#160;        const_iterator&amp; operator++()</div><div class="line"><a name="l03544"></a><span class="lineno"> 3544</span>&#160;        {</div><div class="line"><a name="l03545"></a><span class="lineno"> 3545</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03546"></a><span class="lineno"> 3546</span>&#160;            m_pItem = m_pItem-&gt;pNext;</div><div class="line"><a name="l03547"></a><span class="lineno"> 3547</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l03548"></a><span class="lineno"> 3548</span>&#160;        }</div><div class="line"><a name="l03549"></a><span class="lineno"> 3549</span>&#160;        const_iterator&amp; operator--()</div><div class="line"><a name="l03550"></a><span class="lineno"> 3550</span>&#160;        {</div><div class="line"><a name="l03551"></a><span class="lineno"> 3551</span>&#160;            <span class="keywordflow">if</span>(m_pItem != VMA_NULL)</div><div class="line"><a name="l03552"></a><span class="lineno"> 3552</span>&#160;            {</div><div class="line"><a name="l03553"></a><span class="lineno"> 3553</span>&#160;                m_pItem = m_pItem-&gt;pPrev;</div><div class="line"><a name="l03554"></a><span class="lineno"> 3554</span>&#160;            }</div><div class="line"><a name="l03555"></a><span class="lineno"> 3555</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l03556"></a><span class="lineno"> 3556</span>&#160;            {</div><div class="line"><a name="l03557"></a><span class="lineno"> 3557</span>&#160;                VMA_HEAVY_ASSERT(!m_pList-&gt;IsEmpty());</div><div class="line"><a name="l03558"></a><span class="lineno"> 3558</span>&#160;                m_pItem = m_pList-&gt;Back();</div><div class="line"><a name="l03559"></a><span class="lineno"> 3559</span>&#160;            }</div><div class="line"><a name="l03560"></a><span class="lineno"> 3560</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l03561"></a><span class="lineno"> 3561</span>&#160;        }</div><div class="line"><a name="l03562"></a><span class="lineno"> 3562</span>&#160;</div><div class="line"><a name="l03563"></a><span class="lineno"> 3563</span>&#160;        const_iterator operator++(<span class="keywordtype">int</span>)</div><div class="line"><a name="l03564"></a><span class="lineno"> 3564</span>&#160;        {</div><div class="line"><a name="l03565"></a><span class="lineno"> 3565</span>&#160;            const_iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l03566"></a><span class="lineno"> 3566</span>&#160;            ++*<span class="keyword">this</span>;</div><div class="line"><a name="l03567"></a><span class="lineno"> 3567</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l03568"></a><span class="lineno"> 3568</span>&#160;        }</div><div class="line"><a name="l03569"></a><span class="lineno"> 3569</span>&#160;        const_iterator operator--(<span class="keywordtype">int</span>)</div><div class="line"><a name="l03570"></a><span class="lineno"> 3570</span>&#160;        {</div><div class="line"><a name="l03571"></a><span class="lineno"> 3571</span>&#160;            const_iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l03572"></a><span class="lineno"> 3572</span>&#160;            --*<span class="keyword">this</span>;</div><div class="line"><a name="l03573"></a><span class="lineno"> 3573</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l03574"></a><span class="lineno"> 3574</span>&#160;        }</div><div class="line"><a name="l03575"></a><span class="lineno"> 3575</span>&#160;</div><div class="line"><a name="l03576"></a><span class="lineno"> 3576</span>&#160;        <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> const_iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03577"></a><span class="lineno"> 3577</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03578"></a><span class="lineno"> 3578</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l03579"></a><span class="lineno"> 3579</span>&#160;            <span class="keywordflow">return</span> m_pItem == rhs.m_pItem;</div><div class="line"><a name="l03580"></a><span class="lineno"> 3580</span>&#160;        }</div><div class="line"><a name="l03581"></a><span class="lineno"> 3581</span>&#160;        <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> const_iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03582"></a><span class="lineno"> 3582</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03583"></a><span class="lineno"> 3583</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l03584"></a><span class="lineno"> 3584</span>&#160;            <span class="keywordflow">return</span> m_pItem != rhs.m_pItem;</div><div class="line"><a name="l03585"></a><span class="lineno"> 3585</span>&#160;        }</div><div class="line"><a name="l03586"></a><span class="lineno"> 3586</span>&#160;        </div><div class="line"><a name="l03587"></a><span class="lineno"> 3587</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l03588"></a><span class="lineno"> 3588</span>&#160;        const_iterator(<span class="keyword">const</span> VmaRawList&lt;T&gt;* pList, <span class="keyword">const</span> VmaListItem&lt;T&gt;* pItem) :</div><div class="line"><a name="l03589"></a><span class="lineno"> 3589</span>&#160;            m_pList(pList),</div><div class="line"><a name="l03590"></a><span class="lineno"> 3590</span>&#160;            m_pItem(pItem)</div><div class="line"><a name="l03591"></a><span class="lineno"> 3591</span>&#160;        {</div><div class="line"><a name="l03592"></a><span class="lineno"> 3592</span>&#160;        }</div><div class="line"><a name="l03593"></a><span class="lineno"> 3593</span>&#160;</div><div class="line"><a name="l03594"></a><span class="lineno"> 3594</span>&#160;        <span class="keyword">const</span> VmaRawList&lt;T&gt;* m_pList;</div><div class="line"><a name="l03595"></a><span class="lineno"> 3595</span>&#160;        <span class="keyword">const</span> VmaListItem&lt;T&gt;* m_pItem;</div><div class="line"><a name="l03596"></a><span class="lineno"> 3596</span>&#160;</div><div class="line"><a name="l03597"></a><span class="lineno"> 3597</span>&#160;        <span class="keyword">friend</span> <span class="keyword">class </span>VmaList&lt;T, AllocatorT&gt;;</div><div class="line"><a name="l03598"></a><span class="lineno"> 3598</span>&#160;    };</div><div class="line"><a name="l03599"></a><span class="lineno"> 3599</span>&#160;</div><div class="line"><a name="l03600"></a><span class="lineno"> 3600</span>&#160;    VmaList(<span class="keyword">const</span> AllocatorT&amp; allocator) : m_RawList(allocator.m_pCallbacks) { }</div><div class="line"><a name="l03601"></a><span class="lineno"> 3601</span>&#160;</div><div class="line"><a name="l03602"></a><span class="lineno"> 3602</span>&#160;    <span class="keywordtype">bool</span> empty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_RawList.IsEmpty(); }</div><div class="line"><a name="l03603"></a><span class="lineno"> 3603</span>&#160;    <span class="keywordtype">size_t</span> size()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_RawList.GetCount(); }</div><div class="line"><a name="l03604"></a><span class="lineno"> 3604</span>&#160;</div><div class="line"><a name="l03605"></a><span class="lineno"> 3605</span>&#160;    iterator begin() { <span class="keywordflow">return</span> iterator(&amp;m_RawList, m_RawList.Front()); }</div><div class="line"><a name="l03606"></a><span class="lineno"> 3606</span>&#160;    iterator end() { <span class="keywordflow">return</span> iterator(&amp;m_RawList, VMA_NULL); }</div><div class="line"><a name="l03607"></a><span class="lineno"> 3607</span>&#160;</div><div class="line"><a name="l03608"></a><span class="lineno"> 3608</span>&#160;    const_iterator cbegin()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> const_iterator(&amp;m_RawList, m_RawList.Front()); }</div><div class="line"><a name="l03609"></a><span class="lineno"> 3609</span>&#160;    const_iterator cend()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> const_iterator(&amp;m_RawList, VMA_NULL); }</div><div class="line"><a name="l03610"></a><span class="lineno"> 3610</span>&#160;</div><div class="line"><a name="l03611"></a><span class="lineno"> 3611</span>&#160;    <span class="keywordtype">void</span> clear() { m_RawList.Clear(); }</div><div class="line"><a name="l03612"></a><span class="lineno"> 3612</span>&#160;    <span class="keywordtype">void</span> push_back(<span class="keyword">const</span> T&amp; value) { m_RawList.PushBack(value); }</div><div class="line"><a name="l03613"></a><span class="lineno"> 3613</span>&#160;    <span class="keywordtype">void</span> erase(iterator it) { m_RawList.Remove(it.m_pItem); }</div><div class="line"><a name="l03614"></a><span class="lineno"> 3614</span>&#160;    iterator insert(iterator it, <span class="keyword">const</span> T&amp; value) { <span class="keywordflow">return</span> iterator(&amp;m_RawList, m_RawList.InsertBefore(it.m_pItem, value)); }</div><div class="line"><a name="l03615"></a><span class="lineno"> 3615</span>&#160;</div><div class="line"><a name="l03616"></a><span class="lineno"> 3616</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03617"></a><span class="lineno"> 3617</span>&#160;    VmaRawList&lt;T&gt; m_RawList;</div><div class="line"><a name="l03618"></a><span class="lineno"> 3618</span>&#160;};</div><div class="line"><a name="l03619"></a><span class="lineno"> 3619</span>&#160;</div><div class="line"><a name="l03620"></a><span class="lineno"> 3620</span>&#160;<span class="preprocessor">#endif // #if VMA_USE_STL_LIST</span></div><div class="line"><a name="l03621"></a><span class="lineno"> 3621</span>&#160;</div><div class="line"><a name="l03623"></a><span class="lineno"> 3623</span>&#160;<span class="comment">// class VmaMap</span></div><div class="line"><a name="l03624"></a><span class="lineno"> 3624</span>&#160;</div><div class="line"><a name="l03625"></a><span class="lineno"> 3625</span>&#160;<span class="comment">// Unused in this version.</span></div><div class="line"><a name="l03626"></a><span class="lineno"> 3626</span>&#160;<span class="preprocessor">#if 0</span></div><div class="line"><a name="l03627"></a><span class="lineno"> 3627</span>&#160;</div><div class="line"><a name="l03628"></a><span class="lineno"> 3628</span>&#160;<span class="preprocessor">#if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l03629"></a><span class="lineno"> 3629</span>&#160;</div><div class="line"><a name="l03630"></a><span class="lineno"> 3630</span>&#160;<span class="preprocessor">#define VmaPair std::pair</span></div><div class="line"><a name="l03631"></a><span class="lineno"> 3631</span>&#160;</div><div class="line"><a name="l03632"></a><span class="lineno"> 3632</span>&#160;<span class="preprocessor">#define VMA_MAP_TYPE(KeyT, ValueT) \</span></div><div class="line"><a name="l03633"></a><span class="lineno"> 3633</span>&#160;<span class="preprocessor">    std::unordered_map&lt; KeyT, ValueT, std::hash&lt;KeyT&gt;, std::equal_to&lt;KeyT&gt;, VmaStlAllocator&lt; std::pair&lt;KeyT, ValueT&gt; &gt; &gt;</span></div><div class="line"><a name="l03634"></a><span class="lineno"> 3634</span>&#160;</div><div class="line"><a name="l03635"></a><span class="lineno"> 3635</span>&#160;<span class="preprocessor">#else // #if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l03636"></a><span class="lineno"> 3636</span>&#160;</div><div class="line"><a name="l03637"></a><span class="lineno"> 3637</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T1, <span class="keyword">typename</span> T2&gt;</div><div class="line"><a name="l03638"></a><span class="lineno"> 3638</span>&#160;<span class="keyword">struct </span>VmaPair</div><div class="line"><a name="l03639"></a><span class="lineno"> 3639</span>&#160;{</div><div class="line"><a name="l03640"></a><span class="lineno"> 3640</span>&#160;    T1 first;</div><div class="line"><a name="l03641"></a><span class="lineno"> 3641</span>&#160;    T2 second;</div><div class="line"><a name="l03642"></a><span class="lineno"> 3642</span>&#160;</div><div class="line"><a name="l03643"></a><span class="lineno"> 3643</span>&#160;    VmaPair() : first(), second() { }</div><div class="line"><a name="l03644"></a><span class="lineno"> 3644</span>&#160;    VmaPair(<span class="keyword">const</span> T1&amp; firstSrc, <span class="keyword">const</span> T2&amp; secondSrc) : first(firstSrc), second(secondSrc) { }</div><div class="line"><a name="l03645"></a><span class="lineno"> 3645</span>&#160;};</div><div class="line"><a name="l03646"></a><span class="lineno"> 3646</span>&#160;</div><div class="line"><a name="l03647"></a><span class="lineno"> 3647</span>&#160;<span class="comment">/* Class compatible with subset of interface of std::unordered_map.</span></div><div class="line"><a name="l03648"></a><span class="lineno"> 3648</span>&#160;<span class="comment">KeyT, ValueT must be POD because they will be stored in VmaVector.</span></div><div class="line"><a name="l03649"></a><span class="lineno"> 3649</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03650"></a><span class="lineno"> 3650</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l03651"></a><span class="lineno"> 3651</span>&#160;<span class="keyword">class </span>VmaMap</div><div class="line"><a name="l03652"></a><span class="lineno"> 3652</span>&#160;{</div><div class="line"><a name="l03653"></a><span class="lineno"> 3653</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03654"></a><span class="lineno"> 3654</span>&#160;    <span class="keyword">typedef</span> VmaPair&lt;KeyT, ValueT&gt; PairType;</div><div class="line"><a name="l03655"></a><span class="lineno"> 3655</span>&#160;    <span class="keyword">typedef</span> PairType* iterator;</div><div class="line"><a name="l03656"></a><span class="lineno"> 3656</span>&#160;</div><div class="line"><a name="l03657"></a><span class="lineno"> 3657</span>&#160;    VmaMap(<span class="keyword">const</span> VmaStlAllocator&lt;PairType&gt;&amp; allocator) : m_Vector(allocator) { }</div><div class="line"><a name="l03658"></a><span class="lineno"> 3658</span>&#160;</div><div class="line"><a name="l03659"></a><span class="lineno"> 3659</span>&#160;    iterator begin() { <span class="keywordflow">return</span> m_Vector.begin(); }</div><div class="line"><a name="l03660"></a><span class="lineno"> 3660</span>&#160;    iterator end() { <span class="keywordflow">return</span> m_Vector.end(); }</div><div class="line"><a name="l03661"></a><span class="lineno"> 3661</span>&#160;</div><div class="line"><a name="l03662"></a><span class="lineno"> 3662</span>&#160;    <span class="keywordtype">void</span> insert(<span class="keyword">const</span> PairType&amp; pair);</div><div class="line"><a name="l03663"></a><span class="lineno"> 3663</span>&#160;    iterator find(<span class="keyword">const</span> KeyT&amp; key);</div><div class="line"><a name="l03664"></a><span class="lineno"> 3664</span>&#160;    <span class="keywordtype">void</span> erase(iterator it);</div><div class="line"><a name="l03665"></a><span class="lineno"> 3665</span>&#160;    </div><div class="line"><a name="l03666"></a><span class="lineno"> 3666</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03667"></a><span class="lineno"> 3667</span>&#160;    VmaVector&lt; PairType, VmaStlAllocator&lt;PairType&gt; &gt; m_Vector;</div><div class="line"><a name="l03668"></a><span class="lineno"> 3668</span>&#160;};</div><div class="line"><a name="l03669"></a><span class="lineno"> 3669</span>&#160;</div><div class="line"><a name="l03670"></a><span class="lineno"> 3670</span>&#160;<span class="preprocessor">#define VMA_MAP_TYPE(KeyT, ValueT) VmaMap&lt;KeyT, ValueT&gt;</span></div><div class="line"><a name="l03671"></a><span class="lineno"> 3671</span>&#160;</div><div class="line"><a name="l03672"></a><span class="lineno"> 3672</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> FirstT, <span class="keyword">typename</span> SecondT&gt;</div><div class="line"><a name="l03673"></a><span class="lineno"> 3673</span>&#160;<span class="keyword">struct </span>VmaPairFirstLess</div><div class="line"><a name="l03674"></a><span class="lineno"> 3674</span>&#160;{</div><div class="line"><a name="l03675"></a><span class="lineno"> 3675</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> VmaPair&lt;FirstT, SecondT&gt;&amp; lhs, <span class="keyword">const</span> VmaPair&lt;FirstT, SecondT&gt;&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03676"></a><span class="lineno"> 3676</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03677"></a><span class="lineno"> 3677</span>&#160;        <span class="keywordflow">return</span> lhs.first &lt; rhs.first;</div><div class="line"><a name="l03678"></a><span class="lineno"> 3678</span>&#160;    }</div><div class="line"><a name="l03679"></a><span class="lineno"> 3679</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> VmaPair&lt;FirstT, SecondT&gt;&amp; lhs, <span class="keyword">const</span> FirstT&amp; rhsFirst)<span class="keyword"> const</span></div><div class="line"><a name="l03680"></a><span class="lineno"> 3680</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03681"></a><span class="lineno"> 3681</span>&#160;        <span class="keywordflow">return</span> lhs.first &lt; rhsFirst;</div><div class="line"><a name="l03682"></a><span class="lineno"> 3682</span>&#160;    }</div><div class="line"><a name="l03683"></a><span class="lineno"> 3683</span>&#160;};</div><div class="line"><a name="l03684"></a><span class="lineno"> 3684</span>&#160;</div><div class="line"><a name="l03685"></a><span class="lineno"> 3685</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l03686"></a><span class="lineno"> 3686</span>&#160;<span class="keywordtype">void</span> VmaMap&lt;KeyT, ValueT&gt;::insert(<span class="keyword">const</span> PairType&amp; pair)</div><div class="line"><a name="l03687"></a><span class="lineno"> 3687</span>&#160;{</div><div class="line"><a name="l03688"></a><span class="lineno"> 3688</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> indexToInsert = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l03689"></a><span class="lineno"> 3689</span>&#160;        m_Vector.data(),</div><div class="line"><a name="l03690"></a><span class="lineno"> 3690</span>&#160;        m_Vector.data() + m_Vector.size(),</div><div class="line"><a name="l03691"></a><span class="lineno"> 3691</span>&#160;        pair,</div><div class="line"><a name="l03692"></a><span class="lineno"> 3692</span>&#160;        VmaPairFirstLess&lt;KeyT, ValueT&gt;()) - m_Vector.data();</div><div class="line"><a name="l03693"></a><span class="lineno"> 3693</span>&#160;    VmaVectorInsert(m_Vector, indexToInsert, pair);</div><div class="line"><a name="l03694"></a><span class="lineno"> 3694</span>&#160;}</div><div class="line"><a name="l03695"></a><span class="lineno"> 3695</span>&#160;</div><div class="line"><a name="l03696"></a><span class="lineno"> 3696</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l03697"></a><span class="lineno"> 3697</span>&#160;VmaPair&lt;KeyT, ValueT&gt;* VmaMap&lt;KeyT, ValueT&gt;::find(<span class="keyword">const</span> KeyT&amp; key)</div><div class="line"><a name="l03698"></a><span class="lineno"> 3698</span>&#160;{</div><div class="line"><a name="l03699"></a><span class="lineno"> 3699</span>&#160;    PairType* it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l03700"></a><span class="lineno"> 3700</span>&#160;        m_Vector.data(),</div><div class="line"><a name="l03701"></a><span class="lineno"> 3701</span>&#160;        m_Vector.data() + m_Vector.size(),</div><div class="line"><a name="l03702"></a><span class="lineno"> 3702</span>&#160;        key,</div><div class="line"><a name="l03703"></a><span class="lineno"> 3703</span>&#160;        VmaPairFirstLess&lt;KeyT, ValueT&gt;());</div><div class="line"><a name="l03704"></a><span class="lineno"> 3704</span>&#160;    <span class="keywordflow">if</span>((it != m_Vector.end()) &amp;&amp; (it-&gt;first == key))</div><div class="line"><a name="l03705"></a><span class="lineno"> 3705</span>&#160;    {</div><div class="line"><a name="l03706"></a><span class="lineno"> 3706</span>&#160;        <span class="keywordflow">return</span> it;</div><div class="line"><a name="l03707"></a><span class="lineno"> 3707</span>&#160;    }</div><div class="line"><a name="l03708"></a><span class="lineno"> 3708</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03709"></a><span class="lineno"> 3709</span>&#160;    {</div><div class="line"><a name="l03710"></a><span class="lineno"> 3710</span>&#160;        <span class="keywordflow">return</span> m_Vector.end();</div><div class="line"><a name="l03711"></a><span class="lineno"> 3711</span>&#160;    }</div><div class="line"><a name="l03712"></a><span class="lineno"> 3712</span>&#160;}</div><div class="line"><a name="l03713"></a><span class="lineno"> 3713</span>&#160;</div><div class="line"><a name="l03714"></a><span class="lineno"> 3714</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l03715"></a><span class="lineno"> 3715</span>&#160;<span class="keywordtype">void</span> VmaMap&lt;KeyT, ValueT&gt;::erase(iterator it)</div><div class="line"><a name="l03716"></a><span class="lineno"> 3716</span>&#160;{</div><div class="line"><a name="l03717"></a><span class="lineno"> 3717</span>&#160;    VmaVectorRemove(m_Vector, it - m_Vector.begin());</div><div class="line"><a name="l03718"></a><span class="lineno"> 3718</span>&#160;}</div><div class="line"><a name="l03719"></a><span class="lineno"> 3719</span>&#160;</div><div class="line"><a name="l03720"></a><span class="lineno"> 3720</span>&#160;<span class="preprocessor">#endif // #if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l03721"></a><span class="lineno"> 3721</span>&#160;</div><div class="line"><a name="l03722"></a><span class="lineno"> 3722</span>&#160;<span class="preprocessor">#endif // #if 0</span></div><div class="line"><a name="l03723"></a><span class="lineno"> 3723</span>&#160;</div><div class="line"><a name="l03725"></a><span class="lineno"> 3725</span>&#160;</div><div class="line"><a name="l03726"></a><span class="lineno"> 3726</span>&#160;<span class="keyword">class </span>VmaDeviceMemoryBlock;</div><div class="line"><a name="l03727"></a><span class="lineno"> 3727</span>&#160;</div><div class="line"><a name="l03728"></a><span class="lineno"> 3728</span>&#160;<span class="keyword">struct </span>VmaAllocation_T</div><div class="line"><a name="l03729"></a><span class="lineno"> 3729</span>&#160;{</div><div class="line"><a name="l03730"></a><span class="lineno"> 3730</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03731"></a><span class="lineno"> 3731</span>&#160;    <span class="keyword">static</span> <span class="keyword">const</span> uint8_t MAP_COUNT_FLAG_PERSISTENT_MAP = 0x80;</div><div class="line"><a name="l03732"></a><span class="lineno"> 3732</span>&#160;</div><div class="line"><a name="l03733"></a><span class="lineno"> 3733</span>&#160;    <span class="keyword">enum</span> FLAGS</div><div class="line"><a name="l03734"></a><span class="lineno"> 3734</span>&#160;    {</div><div class="line"><a name="l03735"></a><span class="lineno"> 3735</span>&#160;        FLAG_USER_DATA_STRING = 0x01,</div><div class="line"><a name="l03736"></a><span class="lineno"> 3736</span>&#160;    };</div><div class="line"><a name="l03737"></a><span class="lineno"> 3737</span>&#160;</div><div class="line"><a name="l03738"></a><span class="lineno"> 3738</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03739"></a><span class="lineno"> 3739</span>&#160;    <span class="keyword">enum</span> ALLOCATION_TYPE</div><div class="line"><a name="l03740"></a><span class="lineno"> 3740</span>&#160;    {</div><div class="line"><a name="l03741"></a><span class="lineno"> 3741</span>&#160;        ALLOCATION_TYPE_NONE,</div><div class="line"><a name="l03742"></a><span class="lineno"> 3742</span>&#160;        ALLOCATION_TYPE_BLOCK,</div><div class="line"><a name="l03743"></a><span class="lineno"> 3743</span>&#160;        ALLOCATION_TYPE_DEDICATED,</div><div class="line"><a name="l03744"></a><span class="lineno"> 3744</span>&#160;    };</div><div class="line"><a name="l03745"></a><span class="lineno"> 3745</span>&#160;</div><div class="line"><a name="l03746"></a><span class="lineno"> 3746</span>&#160;    VmaAllocation_T(uint32_t currentFrameIndex, <span class="keywordtype">bool</span> userDataString) :</div><div class="line"><a name="l03747"></a><span class="lineno"> 3747</span>&#160;        m_Alignment(1),</div><div class="line"><a name="l03748"></a><span class="lineno"> 3748</span>&#160;        m_Size(0),</div><div class="line"><a name="l03749"></a><span class="lineno"> 3749</span>&#160;        m_pUserData(VMA_NULL),</div><div class="line"><a name="l03750"></a><span class="lineno"> 3750</span>&#160;        m_LastUseFrameIndex(currentFrameIndex),</div><div class="line"><a name="l03751"></a><span class="lineno"> 3751</span>&#160;        m_Type((uint8_t)ALLOCATION_TYPE_NONE),</div><div class="line"><a name="l03752"></a><span class="lineno"> 3752</span>&#160;        m_SuballocationType((uint8_t)VMA_SUBALLOCATION_TYPE_UNKNOWN),</div><div class="line"><a name="l03753"></a><span class="lineno"> 3753</span>&#160;        m_MapCount(0),</div><div class="line"><a name="l03754"></a><span class="lineno"> 3754</span>&#160;        m_Flags(userDataString ? (uint8_t)FLAG_USER_DATA_STRING : 0)</div><div class="line"><a name="l03755"></a><span class="lineno"> 3755</span>&#160;    {</div><div class="line"><a name="l03756"></a><span class="lineno"> 3756</span>&#160;    }</div><div class="line"><a name="l03757"></a><span class="lineno"> 3757</span>&#160;</div><div class="line"><a name="l03758"></a><span class="lineno"> 3758</span>&#160;    ~VmaAllocation_T()</div><div class="line"><a name="l03759"></a><span class="lineno"> 3759</span>&#160;    {</div><div class="line"><a name="l03760"></a><span class="lineno"> 3760</span>&#160;        VMA_ASSERT((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) == 0 &amp;&amp; <span class="stringliteral">&quot;Allocation was not unmapped before destruction.&quot;</span>);</div><div class="line"><a name="l03761"></a><span class="lineno"> 3761</span>&#160;</div><div class="line"><a name="l03762"></a><span class="lineno"> 3762</span>&#160;        <span class="comment">// Check if owned string was freed.</span></div><div class="line"><a name="l03763"></a><span class="lineno"> 3763</span>&#160;        VMA_ASSERT(m_pUserData == VMA_NULL);</div><div class="line"><a name="l03764"></a><span class="lineno"> 3764</span>&#160;    }</div><div class="line"><a name="l03765"></a><span class="lineno"> 3765</span>&#160;</div><div class="line"><a name="l03766"></a><span class="lineno"> 3766</span>&#160;    <span class="keywordtype">void</span> InitBlockAllocation(</div><div class="line"><a name="l03767"></a><span class="lineno"> 3767</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool,</div><div class="line"><a name="l03768"></a><span class="lineno"> 3768</span>&#160;        VmaDeviceMemoryBlock* block,</div><div class="line"><a name="l03769"></a><span class="lineno"> 3769</span>&#160;        VkDeviceSize offset,</div><div class="line"><a name="l03770"></a><span class="lineno"> 3770</span>&#160;        VkDeviceSize alignment,</div><div class="line"><a name="l03771"></a><span class="lineno"> 3771</span>&#160;        VkDeviceSize size,</div><div class="line"><a name="l03772"></a><span class="lineno"> 3772</span>&#160;        VmaSuballocationType suballocationType,</div><div class="line"><a name="l03773"></a><span class="lineno"> 3773</span>&#160;        <span class="keywordtype">bool</span> mapped,</div><div class="line"><a name="l03774"></a><span class="lineno"> 3774</span>&#160;        <span class="keywordtype">bool</span> canBecomeLost)</div><div class="line"><a name="l03775"></a><span class="lineno"> 3775</span>&#160;    {</div><div class="line"><a name="l03776"></a><span class="lineno"> 3776</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);</div><div class="line"><a name="l03777"></a><span class="lineno"> 3777</span>&#160;        VMA_ASSERT(block != VMA_NULL);</div><div class="line"><a name="l03778"></a><span class="lineno"> 3778</span>&#160;        m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK;</div><div class="line"><a name="l03779"></a><span class="lineno"> 3779</span>&#160;        m_Alignment = alignment;</div><div class="line"><a name="l03780"></a><span class="lineno"> 3780</span>&#160;        m_Size = size;</div><div class="line"><a name="l03781"></a><span class="lineno"> 3781</span>&#160;        m_MapCount = mapped ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0;</div><div class="line"><a name="l03782"></a><span class="lineno"> 3782</span>&#160;        m_SuballocationType = (uint8_t)suballocationType;</div><div class="line"><a name="l03783"></a><span class="lineno"> 3783</span>&#160;        m_BlockAllocation.m_hPool = hPool;</div><div class="line"><a name="l03784"></a><span class="lineno"> 3784</span>&#160;        m_BlockAllocation.m_Block = block;</div><div class="line"><a name="l03785"></a><span class="lineno"> 3785</span>&#160;        m_BlockAllocation.m_Offset = offset;</div><div class="line"><a name="l03786"></a><span class="lineno"> 3786</span>&#160;        m_BlockAllocation.m_CanBecomeLost = canBecomeLost;</div><div class="line"><a name="l03787"></a><span class="lineno"> 3787</span>&#160;    }</div><div class="line"><a name="l03788"></a><span class="lineno"> 3788</span>&#160;</div><div class="line"><a name="l03789"></a><span class="lineno"> 3789</span>&#160;    <span class="keywordtype">void</span> InitLost()</div><div class="line"><a name="l03790"></a><span class="lineno"> 3790</span>&#160;    {</div><div class="line"><a name="l03791"></a><span class="lineno"> 3791</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);</div><div class="line"><a name="l03792"></a><span class="lineno"> 3792</span>&#160;        VMA_ASSERT(m_LastUseFrameIndex.load() == VMA_FRAME_INDEX_LOST);</div><div class="line"><a name="l03793"></a><span class="lineno"> 3793</span>&#160;        m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK;</div><div class="line"><a name="l03794"></a><span class="lineno"> 3794</span>&#160;        m_BlockAllocation.m_hPool = VK_NULL_HANDLE;</div><div class="line"><a name="l03795"></a><span class="lineno"> 3795</span>&#160;        m_BlockAllocation.m_Block = VMA_NULL;</div><div class="line"><a name="l03796"></a><span class="lineno"> 3796</span>&#160;        m_BlockAllocation.m_Offset = 0;</div><div class="line"><a name="l03797"></a><span class="lineno"> 3797</span>&#160;        m_BlockAllocation.m_CanBecomeLost = <span class="keyword">true</span>;</div><div class="line"><a name="l03798"></a><span class="lineno"> 3798</span>&#160;    }</div><div class="line"><a name="l03799"></a><span class="lineno"> 3799</span>&#160;</div><div class="line"><a name="l03800"></a><span class="lineno"> 3800</span>&#160;    <span class="keywordtype">void</span> ChangeBlockAllocation(</div><div class="line"><a name="l03801"></a><span class="lineno"> 3801</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l03802"></a><span class="lineno"> 3802</span>&#160;        VmaDeviceMemoryBlock* block,</div><div class="line"><a name="l03803"></a><span class="lineno"> 3803</span>&#160;        VkDeviceSize offset);</div><div class="line"><a name="l03804"></a><span class="lineno"> 3804</span>&#160;</div><div class="line"><a name="l03805"></a><span class="lineno"> 3805</span>&#160;    <span class="comment">// pMappedData not null means allocation is created with MAPPED flag.</span></div><div class="line"><a name="l03806"></a><span class="lineno"> 3806</span>&#160;    <span class="keywordtype">void</span> InitDedicatedAllocation(</div><div class="line"><a name="l03807"></a><span class="lineno"> 3807</span>&#160;        uint32_t memoryTypeIndex,</div><div class="line"><a name="l03808"></a><span class="lineno"> 3808</span>&#160;        VkDeviceMemory hMemory,</div><div class="line"><a name="l03809"></a><span class="lineno"> 3809</span>&#160;        VmaSuballocationType suballocationType,</div><div class="line"><a name="l03810"></a><span class="lineno"> 3810</span>&#160;        <span class="keywordtype">void</span>* pMappedData,</div><div class="line"><a name="l03811"></a><span class="lineno"> 3811</span>&#160;        VkDeviceSize size)</div><div class="line"><a name="l03812"></a><span class="lineno"> 3812</span>&#160;    {</div><div class="line"><a name="l03813"></a><span class="lineno"> 3813</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);</div><div class="line"><a name="l03814"></a><span class="lineno"> 3814</span>&#160;        VMA_ASSERT(hMemory != VK_NULL_HANDLE);</div><div class="line"><a name="l03815"></a><span class="lineno"> 3815</span>&#160;        m_Type = (uint8_t)ALLOCATION_TYPE_DEDICATED;</div><div class="line"><a name="l03816"></a><span class="lineno"> 3816</span>&#160;        m_Alignment = 0;</div><div class="line"><a name="l03817"></a><span class="lineno"> 3817</span>&#160;        m_Size = size;</div><div class="line"><a name="l03818"></a><span class="lineno"> 3818</span>&#160;        m_SuballocationType = (uint8_t)suballocationType;</div><div class="line"><a name="l03819"></a><span class="lineno"> 3819</span>&#160;        m_MapCount = (pMappedData != VMA_NULL) ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0;</div><div class="line"><a name="l03820"></a><span class="lineno"> 3820</span>&#160;        m_DedicatedAllocation.m_MemoryTypeIndex = memoryTypeIndex;</div><div class="line"><a name="l03821"></a><span class="lineno"> 3821</span>&#160;        m_DedicatedAllocation.m_hMemory = hMemory;</div><div class="line"><a name="l03822"></a><span class="lineno"> 3822</span>&#160;        m_DedicatedAllocation.m_pMappedData = pMappedData;</div><div class="line"><a name="l03823"></a><span class="lineno"> 3823</span>&#160;    }</div><div class="line"><a name="l03824"></a><span class="lineno"> 3824</span>&#160;</div><div class="line"><a name="l03825"></a><span class="lineno"> 3825</span>&#160;    ALLOCATION_TYPE GetType()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (ALLOCATION_TYPE)m_Type; }</div><div class="line"><a name="l03826"></a><span class="lineno"> 3826</span>&#160;    VkDeviceSize GetAlignment()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Alignment; }</div><div class="line"><a name="l03827"></a><span class="lineno"> 3827</span>&#160;    VkDeviceSize GetSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Size; }</div><div class="line"><a name="l03828"></a><span class="lineno"> 3828</span>&#160;    <span class="keywordtype">bool</span> IsUserDataString()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (m_Flags &amp; FLAG_USER_DATA_STRING) != 0; }</div><div class="line"><a name="l03829"></a><span class="lineno"> 3829</span>&#160;    <span class="keywordtype">void</span>* GetUserData()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pUserData; }</div><div class="line"><a name="l03830"></a><span class="lineno"> 3830</span>&#160;    <span class="keywordtype">void</span> SetUserData(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>* pUserData);</div><div class="line"><a name="l03831"></a><span class="lineno"> 3831</span>&#160;    VmaSuballocationType GetSuballocationType()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (VmaSuballocationType)m_SuballocationType; }</div><div class="line"><a name="l03832"></a><span class="lineno"> 3832</span>&#160;</div><div class="line"><a name="l03833"></a><span class="lineno"> 3833</span>&#160;    VmaDeviceMemoryBlock* GetBlock()<span class="keyword"> const</span></div><div class="line"><a name="l03834"></a><span class="lineno"> 3834</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03835"></a><span class="lineno"> 3835</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l03836"></a><span class="lineno"> 3836</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Block;</div><div class="line"><a name="l03837"></a><span class="lineno"> 3837</span>&#160;    }</div><div class="line"><a name="l03838"></a><span class="lineno"> 3838</span>&#160;    VkDeviceSize GetOffset() <span class="keyword">const</span>;</div><div class="line"><a name="l03839"></a><span class="lineno"> 3839</span>&#160;    VkDeviceMemory GetMemory() <span class="keyword">const</span>;</div><div class="line"><a name="l03840"></a><span class="lineno"> 3840</span>&#160;    uint32_t GetMemoryTypeIndex() <span class="keyword">const</span>;</div><div class="line"><a name="l03841"></a><span class="lineno"> 3841</span>&#160;    <span class="keywordtype">bool</span> IsPersistentMap()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (m_MapCount &amp; MAP_COUNT_FLAG_PERSISTENT_MAP) != 0; }</div><div class="line"><a name="l03842"></a><span class="lineno"> 3842</span>&#160;    <span class="keywordtype">void</span>* GetMappedData() <span class="keyword">const</span>;</div><div class="line"><a name="l03843"></a><span class="lineno"> 3843</span>&#160;    <span class="keywordtype">bool</span> CanBecomeLost() <span class="keyword">const</span>;</div><div class="line"><a name="l03844"></a><span class="lineno"> 3844</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> GetPool() <span class="keyword">const</span>;</div><div class="line"><a name="l03845"></a><span class="lineno"> 3845</span>&#160;    </div><div class="line"><a name="l03846"></a><span class="lineno"> 3846</span>&#160;    uint32_t GetLastUseFrameIndex()<span class="keyword"> const</span></div><div class="line"><a name="l03847"></a><span class="lineno"> 3847</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03848"></a><span class="lineno"> 3848</span>&#160;        <span class="keywordflow">return</span> m_LastUseFrameIndex.load();</div><div class="line"><a name="l03849"></a><span class="lineno"> 3849</span>&#160;    }</div><div class="line"><a name="l03850"></a><span class="lineno"> 3850</span>&#160;    <span class="keywordtype">bool</span> CompareExchangeLastUseFrameIndex(uint32_t&amp; expected, uint32_t desired)</div><div class="line"><a name="l03851"></a><span class="lineno"> 3851</span>&#160;    {</div><div class="line"><a name="l03852"></a><span class="lineno"> 3852</span>&#160;        <span class="keywordflow">return</span> m_LastUseFrameIndex.compare_exchange_weak(expected, desired);</div><div class="line"><a name="l03853"></a><span class="lineno"> 3853</span>&#160;    }</div><div class="line"><a name="l03854"></a><span class="lineno"> 3854</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l03855"></a><span class="lineno"> 3855</span>&#160;<span class="comment">    - If hAllocation.LastUseFrameIndex + frameInUseCount &lt; allocator.CurrentFrameIndex,</span></div><div class="line"><a name="l03856"></a><span class="lineno"> 3856</span>&#160;<span class="comment">      makes it lost by setting LastUseFrameIndex = VMA_FRAME_INDEX_LOST and returns true.</span></div><div class="line"><a name="l03857"></a><span class="lineno"> 3857</span>&#160;<span class="comment">    - Else, returns false.</span></div><div class="line"><a name="l03858"></a><span class="lineno"> 3858</span>&#160;<span class="comment">    </span></div><div class="line"><a name="l03859"></a><span class="lineno"> 3859</span>&#160;<span class="comment">    If hAllocation is already lost, assert - you should not call it then.</span></div><div class="line"><a name="l03860"></a><span class="lineno"> 3860</span>&#160;<span class="comment">    If hAllocation was not created with CAN_BECOME_LOST_BIT, assert.</span></div><div class="line"><a name="l03861"></a><span class="lineno"> 3861</span>&#160;<span class="comment">    */</span></div><div class="line"><a name="l03862"></a><span class="lineno"> 3862</span>&#160;    <span class="keywordtype">bool</span> MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);</div><div class="line"><a name="l03863"></a><span class="lineno"> 3863</span>&#160;</div><div class="line"><a name="l03864"></a><span class="lineno"> 3864</span>&#160;    <span class="keywordtype">void</span> DedicatedAllocCalcStatsInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo)</div><div class="line"><a name="l03865"></a><span class="lineno"> 3865</span>&#160;    {</div><div class="line"><a name="l03866"></a><span class="lineno"> 3866</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l03867"></a><span class="lineno"> 3867</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> = 1;</div><div class="line"><a name="l03868"></a><span class="lineno"> 3868</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> = 1;</div><div class="line"><a name="l03869"></a><span class="lineno"> 3869</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> = 0;</div><div class="line"><a name="l03870"></a><span class="lineno"> 3870</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> = m_Size;</div><div class="line"><a name="l03871"></a><span class="lineno"> 3871</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> = 0;</div><div class="line"><a name="l03872"></a><span class="lineno"> 3872</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = m_Size;</div><div class="line"><a name="l03873"></a><span class="lineno"> 3873</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l03874"></a><span class="lineno"> 3874</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = 0;</div><div class="line"><a name="l03875"></a><span class="lineno"> 3875</span>&#160;    }</div><div class="line"><a name="l03876"></a><span class="lineno"> 3876</span>&#160;</div><div class="line"><a name="l03877"></a><span class="lineno"> 3877</span>&#160;    <span class="keywordtype">void</span> BlockAllocMap();</div><div class="line"><a name="l03878"></a><span class="lineno"> 3878</span>&#160;    <span class="keywordtype">void</span> BlockAllocUnmap();</div><div class="line"><a name="l03879"></a><span class="lineno"> 3879</span>&#160;    VkResult DedicatedAllocMap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l03880"></a><span class="lineno"> 3880</span>&#160;    <span class="keywordtype">void</span> DedicatedAllocUnmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l03881"></a><span class="lineno"> 3881</span>&#160;</div><div class="line"><a name="l03882"></a><span class="lineno"> 3882</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03883"></a><span class="lineno"> 3883</span>&#160;    VkDeviceSize m_Alignment;</div><div class="line"><a name="l03884"></a><span class="lineno"> 3884</span>&#160;    VkDeviceSize m_Size;</div><div class="line"><a name="l03885"></a><span class="lineno"> 3885</span>&#160;    <span class="keywordtype">void</span>* m_pUserData;</div><div class="line"><a name="l03886"></a><span class="lineno"> 3886</span>&#160;    VMA_ATOMIC_UINT32 m_LastUseFrameIndex;</div><div class="line"><a name="l03887"></a><span class="lineno"> 3887</span>&#160;    uint8_t m_Type; <span class="comment">// ALLOCATION_TYPE</span></div><div class="line"><a name="l03888"></a><span class="lineno"> 3888</span>&#160;    uint8_t m_SuballocationType; <span class="comment">// VmaSuballocationType</span></div><div class="line"><a name="l03889"></a><span class="lineno"> 3889</span>&#160;    <span class="comment">// Bit 0x80 is set when allocation was created with VMA_ALLOCATION_CREATE_MAPPED_BIT.</span></div><div class="line"><a name="l03890"></a><span class="lineno"> 3890</span>&#160;    <span class="comment">// Bits with mask 0x7F are reference counter for vmaMapMemory()/vmaUnmapMemory().</span></div><div class="line"><a name="l03891"></a><span class="lineno"> 3891</span>&#160;    uint8_t m_MapCount;</div><div class="line"><a name="l03892"></a><span class="lineno"> 3892</span>&#160;    uint8_t m_Flags; <span class="comment">// enum FLAGS</span></div><div class="line"><a name="l03893"></a><span class="lineno"> 3893</span>&#160;</div><div class="line"><a name="l03894"></a><span class="lineno"> 3894</span>&#160;    <span class="comment">// Allocation out of VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l03895"></a><span class="lineno"> 3895</span>&#160;    <span class="keyword">struct </span>BlockAllocation</div><div class="line"><a name="l03896"></a><span class="lineno"> 3896</span>&#160;    {</div><div class="line"><a name="l03897"></a><span class="lineno"> 3897</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> m_hPool; <span class="comment">// Null if belongs to general memory.</span></div><div class="line"><a name="l03898"></a><span class="lineno"> 3898</span>&#160;        VmaDeviceMemoryBlock* m_Block;</div><div class="line"><a name="l03899"></a><span class="lineno"> 3899</span>&#160;        VkDeviceSize m_Offset;</div><div class="line"><a name="l03900"></a><span class="lineno"> 3900</span>&#160;        <span class="keywordtype">bool</span> m_CanBecomeLost;</div><div class="line"><a name="l03901"></a><span class="lineno"> 3901</span>&#160;    };</div><div class="line"><a name="l03902"></a><span class="lineno"> 3902</span>&#160;</div><div class="line"><a name="l03903"></a><span class="lineno"> 3903</span>&#160;    <span class="comment">// Allocation for an object that has its own private VkDeviceMemory.</span></div><div class="line"><a name="l03904"></a><span class="lineno"> 3904</span>&#160;    <span class="keyword">struct </span>DedicatedAllocation</div><div class="line"><a name="l03905"></a><span class="lineno"> 3905</span>&#160;    {</div><div class="line"><a name="l03906"></a><span class="lineno"> 3906</span>&#160;        uint32_t m_MemoryTypeIndex;</div><div class="line"><a name="l03907"></a><span class="lineno"> 3907</span>&#160;        VkDeviceMemory m_hMemory;</div><div class="line"><a name="l03908"></a><span class="lineno"> 3908</span>&#160;        <span class="keywordtype">void</span>* m_pMappedData; <span class="comment">// Not null means memory is mapped.</span></div><div class="line"><a name="l03909"></a><span class="lineno"> 3909</span>&#160;    };</div><div class="line"><a name="l03910"></a><span class="lineno"> 3910</span>&#160;</div><div class="line"><a name="l03911"></a><span class="lineno"> 3911</span>&#160;    <span class="keyword">union</span></div><div class="line"><a name="l03912"></a><span class="lineno"> 3912</span>&#160;    {</div><div class="line"><a name="l03913"></a><span class="lineno"> 3913</span>&#160;        <span class="comment">// Allocation out of VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l03914"></a><span class="lineno"> 3914</span>&#160;        BlockAllocation m_BlockAllocation;</div><div class="line"><a name="l03915"></a><span class="lineno"> 3915</span>&#160;        <span class="comment">// Allocation for an object that has its own private VkDeviceMemory.</span></div><div class="line"><a name="l03916"></a><span class="lineno"> 3916</span>&#160;        DedicatedAllocation m_DedicatedAllocation;</div><div class="line"><a name="l03917"></a><span class="lineno"> 3917</span>&#160;    };</div><div class="line"><a name="l03918"></a><span class="lineno"> 3918</span>&#160;</div><div class="line"><a name="l03919"></a><span class="lineno"> 3919</span>&#160;    <span class="keywordtype">void</span> FreeUserDataString(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l03920"></a><span class="lineno"> 3920</span>&#160;};</div><div class="line"><a name="l03921"></a><span class="lineno"> 3921</span>&#160;</div><div class="line"><a name="l03922"></a><span class="lineno"> 3922</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l03923"></a><span class="lineno"> 3923</span>&#160;<span class="comment">Represents a region of VmaDeviceMemoryBlock that is either assigned and returned as</span></div><div class="line"><a name="l03924"></a><span class="lineno"> 3924</span>&#160;<span class="comment">allocated memory block or free.</span></div><div class="line"><a name="l03925"></a><span class="lineno"> 3925</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03926"></a><span class="lineno"> 3926</span>&#160;<span class="keyword">struct </span>VmaSuballocation</div><div class="line"><a name="l03927"></a><span class="lineno"> 3927</span>&#160;{</div><div class="line"><a name="l03928"></a><span class="lineno"> 3928</span>&#160;    VkDeviceSize offset;</div><div class="line"><a name="l03929"></a><span class="lineno"> 3929</span>&#160;    VkDeviceSize size;</div><div class="line"><a name="l03930"></a><span class="lineno"> 3930</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation;</div><div class="line"><a name="l03931"></a><span class="lineno"> 3931</span>&#160;    VmaSuballocationType type;</div><div class="line"><a name="l03932"></a><span class="lineno"> 3932</span>&#160;};</div><div class="line"><a name="l03933"></a><span class="lineno"> 3933</span>&#160;</div><div class="line"><a name="l03934"></a><span class="lineno"> 3934</span>&#160;<span class="keyword">typedef</span> VmaList&lt; VmaSuballocation, VmaStlAllocator&lt;VmaSuballocation&gt; &gt; VmaSuballocationList;</div><div class="line"><a name="l03935"></a><span class="lineno"> 3935</span>&#160;</div><div class="line"><a name="l03936"></a><span class="lineno"> 3936</span>&#160;<span class="comment">// Cost of one additional allocation lost, as equivalent in bytes.</span></div><div class="line"><a name="l03937"></a><span class="lineno"> 3937</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> VkDeviceSize VMA_LOST_ALLOCATION_COST = 1048576;</div><div class="line"><a name="l03938"></a><span class="lineno"> 3938</span>&#160;</div><div class="line"><a name="l03939"></a><span class="lineno"> 3939</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l03940"></a><span class="lineno"> 3940</span>&#160;<span class="comment">Parameters of planned allocation inside a VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l03941"></a><span class="lineno"> 3941</span>&#160;<span class="comment"></span></div><div class="line"><a name="l03942"></a><span class="lineno"> 3942</span>&#160;<span class="comment">If canMakeOtherLost was false:</span></div><div class="line"><a name="l03943"></a><span class="lineno"> 3943</span>&#160;<span class="comment">- item points to a FREE suballocation.</span></div><div class="line"><a name="l03944"></a><span class="lineno"> 3944</span>&#160;<span class="comment">- itemsToMakeLostCount is 0.</span></div><div class="line"><a name="l03945"></a><span class="lineno"> 3945</span>&#160;<span class="comment"></span></div><div class="line"><a name="l03946"></a><span class="lineno"> 3946</span>&#160;<span class="comment">If canMakeOtherLost was true:</span></div><div class="line"><a name="l03947"></a><span class="lineno"> 3947</span>&#160;<span class="comment">- item points to first of sequence of suballocations, which are either FREE,</span></div><div class="line"><a name="l03948"></a><span class="lineno"> 3948</span>&#160;<span class="comment">  or point to VmaAllocations that can become lost.</span></div><div class="line"><a name="l03949"></a><span class="lineno"> 3949</span>&#160;<span class="comment">- itemsToMakeLostCount is the number of VmaAllocations that need to be made lost for</span></div><div class="line"><a name="l03950"></a><span class="lineno"> 3950</span>&#160;<span class="comment">  the requested allocation to succeed.</span></div><div class="line"><a name="l03951"></a><span class="lineno"> 3951</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03952"></a><span class="lineno"> 3952</span>&#160;<span class="keyword">struct </span>VmaAllocationRequest</div><div class="line"><a name="l03953"></a><span class="lineno"> 3953</span>&#160;{</div><div class="line"><a name="l03954"></a><span class="lineno"> 3954</span>&#160;    VkDeviceSize offset;</div><div class="line"><a name="l03955"></a><span class="lineno"> 3955</span>&#160;    VkDeviceSize sumFreeSize; <span class="comment">// Sum size of free items that overlap with proposed allocation.</span></div><div class="line"><a name="l03956"></a><span class="lineno"> 3956</span>&#160;    VkDeviceSize sumItemSize; <span class="comment">// Sum size of items to make lost that overlap with proposed allocation.</span></div><div class="line"><a name="l03957"></a><span class="lineno"> 3957</span>&#160;    VmaSuballocationList::iterator item;</div><div class="line"><a name="l03958"></a><span class="lineno"> 3958</span>&#160;    <span class="keywordtype">size_t</span> itemsToMakeLostCount;</div><div class="line"><a name="l03959"></a><span class="lineno"> 3959</span>&#160;</div><div class="line"><a name="l03960"></a><span class="lineno"> 3960</span>&#160;    VkDeviceSize CalcCost()<span class="keyword"> const</span></div><div class="line"><a name="l03961"></a><span class="lineno"> 3961</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03962"></a><span class="lineno"> 3962</span>&#160;        <span class="keywordflow">return</span> sumItemSize + itemsToMakeLostCount * VMA_LOST_ALLOCATION_COST;</div><div class="line"><a name="l03963"></a><span class="lineno"> 3963</span>&#160;    }</div><div class="line"><a name="l03964"></a><span class="lineno"> 3964</span>&#160;};</div><div class="line"><a name="l03965"></a><span class="lineno"> 3965</span>&#160;</div><div class="line"><a name="l03966"></a><span class="lineno"> 3966</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l03967"></a><span class="lineno"> 3967</span>&#160;<span class="comment">Data structure used for bookkeeping of allocations and unused ranges of memory</span></div><div class="line"><a name="l03968"></a><span class="lineno"> 3968</span>&#160;<span class="comment">in a single VkDeviceMemory block.</span></div><div class="line"><a name="l03969"></a><span class="lineno"> 3969</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03970"></a><span class="lineno"> 3970</span>&#160;<span class="keyword">class </span>VmaBlockMetadata</div><div class="line"><a name="l03971"></a><span class="lineno"> 3971</span>&#160;{</div><div class="line"><a name="l03972"></a><span class="lineno"> 3972</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03973"></a><span class="lineno"> 3973</span>&#160;    VmaBlockMetadata(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l03974"></a><span class="lineno"> 3974</span>&#160;    ~VmaBlockMetadata();</div><div class="line"><a name="l03975"></a><span class="lineno"> 3975</span>&#160;    <span class="keywordtype">void</span> Init(VkDeviceSize size);</div><div class="line"><a name="l03976"></a><span class="lineno"> 3976</span>&#160;</div><div class="line"><a name="l03977"></a><span class="lineno"> 3977</span>&#160;    <span class="comment">// Validates all data structures inside this object. If not valid, returns false.</span></div><div class="line"><a name="l03978"></a><span class="lineno"> 3978</span>&#160;    <span class="keywordtype">bool</span> Validate() <span class="keyword">const</span>;</div><div class="line"><a name="l03979"></a><span class="lineno"> 3979</span>&#160;    VkDeviceSize GetSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Size; }</div><div class="line"><a name="l03980"></a><span class="lineno"> 3980</span>&#160;    <span class="keywordtype">size_t</span> GetAllocationCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Suballocations.size() - m_FreeCount; }</div><div class="line"><a name="l03981"></a><span class="lineno"> 3981</span>&#160;    VkDeviceSize GetSumFreeSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_SumFreeSize; }</div><div class="line"><a name="l03982"></a><span class="lineno"> 3982</span>&#160;    VkDeviceSize GetUnusedRangeSizeMax() <span class="keyword">const</span>;</div><div class="line"><a name="l03983"></a><span class="lineno"> 3983</span>&#160;    <span class="comment">// Returns true if this block is empty - contains only single free suballocation.</span></div><div class="line"><a name="l03984"></a><span class="lineno"> 3984</span>&#160;    <span class="keywordtype">bool</span> IsEmpty() <span class="keyword">const</span>;</div><div class="line"><a name="l03985"></a><span class="lineno"> 3985</span>&#160;</div><div class="line"><a name="l03986"></a><span class="lineno"> 3986</span>&#160;    <span class="keywordtype">void</span> CalcAllocationStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo) <span class="keyword">const</span>;</div><div class="line"><a name="l03987"></a><span class="lineno"> 3987</span>&#160;    <span class="keywordtype">void</span> AddPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>&amp; inoutStats) <span class="keyword">const</span>;</div><div class="line"><a name="l03988"></a><span class="lineno"> 3988</span>&#160;</div><div class="line"><a name="l03989"></a><span class="lineno"> 3989</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l03990"></a><span class="lineno"> 3990</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json) <span class="keyword">const</span>;</div><div class="line"><a name="l03991"></a><span class="lineno"> 3991</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l03992"></a><span class="lineno"> 3992</span>&#160;</div><div class="line"><a name="l03993"></a><span class="lineno"> 3993</span>&#160;    <span class="comment">// Creates trivial request for case when block is empty.</span></div><div class="line"><a name="l03994"></a><span class="lineno"> 3994</span>&#160;    <span class="keywordtype">void</span> CreateFirstAllocationRequest(VmaAllocationRequest* pAllocationRequest);</div><div class="line"><a name="l03995"></a><span class="lineno"> 3995</span>&#160;</div><div class="line"><a name="l03996"></a><span class="lineno"> 3996</span>&#160;    <span class="comment">// Tries to find a place for suballocation with given parameters inside this block.</span></div><div class="line"><a name="l03997"></a><span class="lineno"> 3997</span>&#160;    <span class="comment">// If succeeded, fills pAllocationRequest and returns true.</span></div><div class="line"><a name="l03998"></a><span class="lineno"> 3998</span>&#160;    <span class="comment">// If failed, returns false.</span></div><div class="line"><a name="l03999"></a><span class="lineno"> 3999</span>&#160;    <span class="keywordtype">bool</span> CreateAllocationRequest(</div><div class="line"><a name="l04000"></a><span class="lineno"> 4000</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04001"></a><span class="lineno"> 4001</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04002"></a><span class="lineno"> 4002</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04003"></a><span class="lineno"> 4003</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04004"></a><span class="lineno"> 4004</span>&#160;        VkDeviceSize allocAlignment,</div><div class="line"><a name="l04005"></a><span class="lineno"> 4005</span>&#160;        VmaSuballocationType allocType,</div><div class="line"><a name="l04006"></a><span class="lineno"> 4006</span>&#160;        <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l04007"></a><span class="lineno"> 4007</span>&#160;        VmaAllocationRequest* pAllocationRequest);</div><div class="line"><a name="l04008"></a><span class="lineno"> 4008</span>&#160;</div><div class="line"><a name="l04009"></a><span class="lineno"> 4009</span>&#160;    <span class="keywordtype">bool</span> MakeRequestedAllocationsLost(</div><div class="line"><a name="l04010"></a><span class="lineno"> 4010</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04011"></a><span class="lineno"> 4011</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04012"></a><span class="lineno"> 4012</span>&#160;        VmaAllocationRequest* pAllocationRequest);</div><div class="line"><a name="l04013"></a><span class="lineno"> 4013</span>&#160;</div><div class="line"><a name="l04014"></a><span class="lineno"> 4014</span>&#160;    uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);</div><div class="line"><a name="l04015"></a><span class="lineno"> 4015</span>&#160;</div><div class="line"><a name="l04016"></a><span class="lineno"> 4016</span>&#160;    <span class="comment">// Makes actual allocation based on request. Request must already be checked and valid.</span></div><div class="line"><a name="l04017"></a><span class="lineno"> 4017</span>&#160;    <span class="keywordtype">void</span> Alloc(</div><div class="line"><a name="l04018"></a><span class="lineno"> 4018</span>&#160;        <span class="keyword">const</span> VmaAllocationRequest&amp; request,</div><div class="line"><a name="l04019"></a><span class="lineno"> 4019</span>&#160;        VmaSuballocationType type,</div><div class="line"><a name="l04020"></a><span class="lineno"> 4020</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04021"></a><span class="lineno"> 4021</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l04022"></a><span class="lineno"> 4022</span>&#160;</div><div class="line"><a name="l04023"></a><span class="lineno"> 4023</span>&#160;    <span class="comment">// Frees suballocation assigned to given memory region.</span></div><div class="line"><a name="l04024"></a><span class="lineno"> 4024</span>&#160;    <span class="keywordtype">void</span> Free(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l04025"></a><span class="lineno"> 4025</span>&#160;    <span class="keywordtype">void</span> FreeAtOffset(VkDeviceSize offset);</div><div class="line"><a name="l04026"></a><span class="lineno"> 4026</span>&#160;</div><div class="line"><a name="l04027"></a><span class="lineno"> 4027</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04028"></a><span class="lineno"> 4028</span>&#160;    VkDeviceSize m_Size;</div><div class="line"><a name="l04029"></a><span class="lineno"> 4029</span>&#160;    uint32_t m_FreeCount;</div><div class="line"><a name="l04030"></a><span class="lineno"> 4030</span>&#160;    VkDeviceSize m_SumFreeSize;</div><div class="line"><a name="l04031"></a><span class="lineno"> 4031</span>&#160;    VmaSuballocationList m_Suballocations;</div><div class="line"><a name="l04032"></a><span class="lineno"> 4032</span>&#160;    <span class="comment">// Suballocations that are free and have size greater than certain threshold.</span></div><div class="line"><a name="l04033"></a><span class="lineno"> 4033</span>&#160;    <span class="comment">// Sorted by size, ascending.</span></div><div class="line"><a name="l04034"></a><span class="lineno"> 4034</span>&#160;    VmaVector&lt; VmaSuballocationList::iterator, VmaStlAllocator&lt; VmaSuballocationList::iterator &gt; &gt; m_FreeSuballocationsBySize;</div><div class="line"><a name="l04035"></a><span class="lineno"> 4035</span>&#160;</div><div class="line"><a name="l04036"></a><span class="lineno"> 4036</span>&#160;    <span class="keywordtype">bool</span> ValidateFreeSuballocationList() <span class="keyword">const</span>;</div><div class="line"><a name="l04037"></a><span class="lineno"> 4037</span>&#160;</div><div class="line"><a name="l04038"></a><span class="lineno"> 4038</span>&#160;    <span class="comment">// Checks if requested suballocation with given parameters can be placed in given pFreeSuballocItem.</span></div><div class="line"><a name="l04039"></a><span class="lineno"> 4039</span>&#160;    <span class="comment">// If yes, fills pOffset and returns true. If no, returns false.</span></div><div class="line"><a name="l04040"></a><span class="lineno"> 4040</span>&#160;    <span class="keywordtype">bool</span> CheckAllocation(</div><div class="line"><a name="l04041"></a><span class="lineno"> 4041</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04042"></a><span class="lineno"> 4042</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04043"></a><span class="lineno"> 4043</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04044"></a><span class="lineno"> 4044</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04045"></a><span class="lineno"> 4045</span>&#160;        VkDeviceSize allocAlignment,</div><div class="line"><a name="l04046"></a><span class="lineno"> 4046</span>&#160;        VmaSuballocationType allocType,</div><div class="line"><a name="l04047"></a><span class="lineno"> 4047</span>&#160;        VmaSuballocationList::const_iterator suballocItem,</div><div class="line"><a name="l04048"></a><span class="lineno"> 4048</span>&#160;        <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l04049"></a><span class="lineno"> 4049</span>&#160;        VkDeviceSize* pOffset,</div><div class="line"><a name="l04050"></a><span class="lineno"> 4050</span>&#160;        <span class="keywordtype">size_t</span>* itemsToMakeLostCount,</div><div class="line"><a name="l04051"></a><span class="lineno"> 4051</span>&#160;        VkDeviceSize* pSumFreeSize,</div><div class="line"><a name="l04052"></a><span class="lineno"> 4052</span>&#160;        VkDeviceSize* pSumItemSize) <span class="keyword">const</span>;</div><div class="line"><a name="l04053"></a><span class="lineno"> 4053</span>&#160;    <span class="comment">// Given free suballocation, it merges it with following one, which must also be free.</span></div><div class="line"><a name="l04054"></a><span class="lineno"> 4054</span>&#160;    <span class="keywordtype">void</span> MergeFreeWithNext(VmaSuballocationList::iterator item);</div><div class="line"><a name="l04055"></a><span class="lineno"> 4055</span>&#160;    <span class="comment">// Releases given suballocation, making it free.</span></div><div class="line"><a name="l04056"></a><span class="lineno"> 4056</span>&#160;    <span class="comment">// Merges it with adjacent free suballocations if applicable.</span></div><div class="line"><a name="l04057"></a><span class="lineno"> 4057</span>&#160;    <span class="comment">// Returns iterator to new free suballocation at this place.</span></div><div class="line"><a name="l04058"></a><span class="lineno"> 4058</span>&#160;    VmaSuballocationList::iterator FreeSuballocation(VmaSuballocationList::iterator suballocItem);</div><div class="line"><a name="l04059"></a><span class="lineno"> 4059</span>&#160;    <span class="comment">// Given free suballocation, it inserts it into sorted list of</span></div><div class="line"><a name="l04060"></a><span class="lineno"> 4060</span>&#160;    <span class="comment">// m_FreeSuballocationsBySize if it&#39;s suitable.</span></div><div class="line"><a name="l04061"></a><span class="lineno"> 4061</span>&#160;    <span class="keywordtype">void</span> RegisterFreeSuballocation(VmaSuballocationList::iterator item);</div><div class="line"><a name="l04062"></a><span class="lineno"> 4062</span>&#160;    <span class="comment">// Given free suballocation, it removes it from sorted list of</span></div><div class="line"><a name="l04063"></a><span class="lineno"> 4063</span>&#160;    <span class="comment">// m_FreeSuballocationsBySize if it&#39;s suitable.</span></div><div class="line"><a name="l04064"></a><span class="lineno"> 4064</span>&#160;    <span class="keywordtype">void</span> UnregisterFreeSuballocation(VmaSuballocationList::iterator item);</div><div class="line"><a name="l04065"></a><span class="lineno"> 4065</span>&#160;};</div><div class="line"><a name="l04066"></a><span class="lineno"> 4066</span>&#160;</div><div class="line"><a name="l04067"></a><span class="lineno"> 4067</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04068"></a><span class="lineno"> 4068</span>&#160;<span class="comment">Represents a single block of device memory (`VkDeviceMemory`) with all the</span></div><div class="line"><a name="l04069"></a><span class="lineno"> 4069</span>&#160;<span class="comment">data about its regions (aka suballocations, #VmaAllocation), assigned and free.</span></div><div class="line"><a name="l04070"></a><span class="lineno"> 4070</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04071"></a><span class="lineno"> 4071</span>&#160;<span class="comment">Thread-safety: This class must be externally synchronized.</span></div><div class="line"><a name="l04072"></a><span class="lineno"> 4072</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04073"></a><span class="lineno"> 4073</span>&#160;<span class="keyword">class </span>VmaDeviceMemoryBlock</div><div class="line"><a name="l04074"></a><span class="lineno"> 4074</span>&#160;{</div><div class="line"><a name="l04075"></a><span class="lineno"> 4075</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04076"></a><span class="lineno"> 4076</span>&#160;    VmaBlockMetadata m_Metadata;</div><div class="line"><a name="l04077"></a><span class="lineno"> 4077</span>&#160;</div><div class="line"><a name="l04078"></a><span class="lineno"> 4078</span>&#160;    VmaDeviceMemoryBlock(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04079"></a><span class="lineno"> 4079</span>&#160;</div><div class="line"><a name="l04080"></a><span class="lineno"> 4080</span>&#160;    ~VmaDeviceMemoryBlock()</div><div class="line"><a name="l04081"></a><span class="lineno"> 4081</span>&#160;    {</div><div class="line"><a name="l04082"></a><span class="lineno"> 4082</span>&#160;        VMA_ASSERT(m_MapCount == 0 &amp;&amp; <span class="stringliteral">&quot;VkDeviceMemory block is being destroyed while it is still mapped.&quot;</span>);</div><div class="line"><a name="l04083"></a><span class="lineno"> 4083</span>&#160;        VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);</div><div class="line"><a name="l04084"></a><span class="lineno"> 4084</span>&#160;    }</div><div class="line"><a name="l04085"></a><span class="lineno"> 4085</span>&#160;</div><div class="line"><a name="l04086"></a><span class="lineno"> 4086</span>&#160;    <span class="comment">// Always call after construction.</span></div><div class="line"><a name="l04087"></a><span class="lineno"> 4087</span>&#160;    <span class="keywordtype">void</span> Init(</div><div class="line"><a name="l04088"></a><span class="lineno"> 4088</span>&#160;        uint32_t newMemoryTypeIndex,</div><div class="line"><a name="l04089"></a><span class="lineno"> 4089</span>&#160;        VkDeviceMemory newMemory,</div><div class="line"><a name="l04090"></a><span class="lineno"> 4090</span>&#160;        VkDeviceSize newSize);</div><div class="line"><a name="l04091"></a><span class="lineno"> 4091</span>&#160;    <span class="comment">// Always call before destruction.</span></div><div class="line"><a name="l04092"></a><span class="lineno"> 4092</span>&#160;    <span class="keywordtype">void</span> Destroy(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator);</div><div class="line"><a name="l04093"></a><span class="lineno"> 4093</span>&#160;    </div><div class="line"><a name="l04094"></a><span class="lineno"> 4094</span>&#160;    VkDeviceMemory GetDeviceMemory()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_hMemory; }</div><div class="line"><a name="l04095"></a><span class="lineno"> 4095</span>&#160;    uint32_t GetMemoryTypeIndex()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemoryTypeIndex; }</div><div class="line"><a name="l04096"></a><span class="lineno"> 4096</span>&#160;    <span class="keywordtype">void</span>* GetMappedData()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pMappedData; }</div><div class="line"><a name="l04097"></a><span class="lineno"> 4097</span>&#160;</div><div class="line"><a name="l04098"></a><span class="lineno"> 4098</span>&#160;    <span class="comment">// Validates all data structures inside this object. If not valid, returns false.</span></div><div class="line"><a name="l04099"></a><span class="lineno"> 4099</span>&#160;    <span class="keywordtype">bool</span> Validate() <span class="keyword">const</span>;</div><div class="line"><a name="l04100"></a><span class="lineno"> 4100</span>&#160;</div><div class="line"><a name="l04101"></a><span class="lineno"> 4101</span>&#160;    <span class="comment">// ppData can be null.</span></div><div class="line"><a name="l04102"></a><span class="lineno"> 4102</span>&#160;    VkResult Map(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count, <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l04103"></a><span class="lineno"> 4103</span>&#160;    <span class="keywordtype">void</span> Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count);</div><div class="line"><a name="l04104"></a><span class="lineno"> 4104</span>&#160;</div><div class="line"><a name="l04105"></a><span class="lineno"> 4105</span>&#160;    VkResult BindBufferMemory(</div><div class="line"><a name="l04106"></a><span class="lineno"> 4106</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04107"></a><span class="lineno"> 4107</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l04108"></a><span class="lineno"> 4108</span>&#160;        VkBuffer hBuffer);</div><div class="line"><a name="l04109"></a><span class="lineno"> 4109</span>&#160;    VkResult BindImageMemory(</div><div class="line"><a name="l04110"></a><span class="lineno"> 4110</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04111"></a><span class="lineno"> 4111</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l04112"></a><span class="lineno"> 4112</span>&#160;        VkImage hImage);</div><div class="line"><a name="l04113"></a><span class="lineno"> 4113</span>&#160;</div><div class="line"><a name="l04114"></a><span class="lineno"> 4114</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04115"></a><span class="lineno"> 4115</span>&#160;    uint32_t m_MemoryTypeIndex;</div><div class="line"><a name="l04116"></a><span class="lineno"> 4116</span>&#160;    VkDeviceMemory m_hMemory;</div><div class="line"><a name="l04117"></a><span class="lineno"> 4117</span>&#160;</div><div class="line"><a name="l04118"></a><span class="lineno"> 4118</span>&#160;    <span class="comment">// Protects access to m_hMemory so it&#39;s not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.</span></div><div class="line"><a name="l04119"></a><span class="lineno"> 4119</span>&#160;    <span class="comment">// Also protects m_MapCount, m_pMappedData.</span></div><div class="line"><a name="l04120"></a><span class="lineno"> 4120</span>&#160;    VMA_MUTEX m_Mutex;</div><div class="line"><a name="l04121"></a><span class="lineno"> 4121</span>&#160;    uint32_t m_MapCount;</div><div class="line"><a name="l04122"></a><span class="lineno"> 4122</span>&#160;    <span class="keywordtype">void</span>* m_pMappedData;</div><div class="line"><a name="l04123"></a><span class="lineno"> 4123</span>&#160;};</div><div class="line"><a name="l04124"></a><span class="lineno"> 4124</span>&#160;</div><div class="line"><a name="l04125"></a><span class="lineno"> 4125</span>&#160;<span class="keyword">struct </span>VmaPointerLess</div><div class="line"><a name="l04126"></a><span class="lineno"> 4126</span>&#160;{</div><div class="line"><a name="l04127"></a><span class="lineno"> 4127</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> <span class="keywordtype">void</span>* lhs, <span class="keyword">const</span> <span class="keywordtype">void</span>* rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04128"></a><span class="lineno"> 4128</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04129"></a><span class="lineno"> 4129</span>&#160;        <span class="keywordflow">return</span> lhs &lt; rhs;</div><div class="line"><a name="l04130"></a><span class="lineno"> 4130</span>&#160;    }</div><div class="line"><a name="l04131"></a><span class="lineno"> 4131</span>&#160;};</div><div class="line"><a name="l04132"></a><span class="lineno"> 4132</span>&#160;</div><div class="line"><a name="l04133"></a><span class="lineno"> 4133</span>&#160;<span class="keyword">class </span>VmaDefragmentator;</div><div class="line"><a name="l04134"></a><span class="lineno"> 4134</span>&#160;</div><div class="line"><a name="l04135"></a><span class="lineno"> 4135</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04136"></a><span class="lineno"> 4136</span>&#160;<span class="comment">Sequence of VmaDeviceMemoryBlock. Represents memory blocks allocated for a specific</span></div><div class="line"><a name="l04137"></a><span class="lineno"> 4137</span>&#160;<span class="comment">Vulkan memory type.</span></div><div class="line"><a name="l04138"></a><span class="lineno"> 4138</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04139"></a><span class="lineno"> 4139</span>&#160;<span class="comment">Synchronized internally with a mutex.</span></div><div class="line"><a name="l04140"></a><span class="lineno"> 4140</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04141"></a><span class="lineno"> 4141</span>&#160;<span class="keyword">struct </span>VmaBlockVector</div><div class="line"><a name="l04142"></a><span class="lineno"> 4142</span>&#160;{</div><div class="line"><a name="l04143"></a><span class="lineno"> 4143</span>&#160;    VmaBlockVector(</div><div class="line"><a name="l04144"></a><span class="lineno"> 4144</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04145"></a><span class="lineno"> 4145</span>&#160;        uint32_t memoryTypeIndex,</div><div class="line"><a name="l04146"></a><span class="lineno"> 4146</span>&#160;        VkDeviceSize preferredBlockSize,</div><div class="line"><a name="l04147"></a><span class="lineno"> 4147</span>&#160;        <span class="keywordtype">size_t</span> minBlockCount,</div><div class="line"><a name="l04148"></a><span class="lineno"> 4148</span>&#160;        <span class="keywordtype">size_t</span> maxBlockCount,</div><div class="line"><a name="l04149"></a><span class="lineno"> 4149</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04150"></a><span class="lineno"> 4150</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04151"></a><span class="lineno"> 4151</span>&#160;        <span class="keywordtype">bool</span> isCustomPool);</div><div class="line"><a name="l04152"></a><span class="lineno"> 4152</span>&#160;    ~VmaBlockVector();</div><div class="line"><a name="l04153"></a><span class="lineno"> 4153</span>&#160;</div><div class="line"><a name="l04154"></a><span class="lineno"> 4154</span>&#160;    VkResult CreateMinBlocks();</div><div class="line"><a name="l04155"></a><span class="lineno"> 4155</span>&#160;</div><div class="line"><a name="l04156"></a><span class="lineno"> 4156</span>&#160;    uint32_t GetMemoryTypeIndex()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemoryTypeIndex; }</div><div class="line"><a name="l04157"></a><span class="lineno"> 4157</span>&#160;    VkDeviceSize GetPreferredBlockSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_PreferredBlockSize; }</div><div class="line"><a name="l04158"></a><span class="lineno"> 4158</span>&#160;    VkDeviceSize GetBufferImageGranularity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_BufferImageGranularity; }</div><div class="line"><a name="l04159"></a><span class="lineno"> 4159</span>&#160;    uint32_t GetFrameInUseCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_FrameInUseCount; }</div><div class="line"><a name="l04160"></a><span class="lineno"> 4160</span>&#160;</div><div class="line"><a name="l04161"></a><span class="lineno"> 4161</span>&#160;    <span class="keywordtype">void</span> GetPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pStats);</div><div class="line"><a name="l04162"></a><span class="lineno"> 4162</span>&#160;</div><div class="line"><a name="l04163"></a><span class="lineno"> 4163</span>&#160;    <span class="keywordtype">bool</span> IsEmpty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Blocks.empty(); }</div><div class="line"><a name="l04164"></a><span class="lineno"> 4164</span>&#160;</div><div class="line"><a name="l04165"></a><span class="lineno"> 4165</span>&#160;    VkResult Allocate(</div><div class="line"><a name="l04166"></a><span class="lineno"> 4166</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> hCurrentPool,</div><div class="line"><a name="l04167"></a><span class="lineno"> 4167</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04168"></a><span class="lineno"> 4168</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l04169"></a><span class="lineno"> 4169</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l04170"></a><span class="lineno"> 4170</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l04171"></a><span class="lineno"> 4171</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l04172"></a><span class="lineno"> 4172</span>&#160;</div><div class="line"><a name="l04173"></a><span class="lineno"> 4173</span>&#160;    <span class="keywordtype">void</span> Free(</div><div class="line"><a name="l04174"></a><span class="lineno"> 4174</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l04175"></a><span class="lineno"> 4175</span>&#160;</div><div class="line"><a name="l04176"></a><span class="lineno"> 4176</span>&#160;    <span class="comment">// Adds statistics of this BlockVector to pStats.</span></div><div class="line"><a name="l04177"></a><span class="lineno"> 4177</span>&#160;    <span class="keywordtype">void</span> AddStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats);</div><div class="line"><a name="l04178"></a><span class="lineno"> 4178</span>&#160;</div><div class="line"><a name="l04179"></a><span class="lineno"> 4179</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04180"></a><span class="lineno"> 4180</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json);</div><div class="line"><a name="l04181"></a><span class="lineno"> 4181</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04182"></a><span class="lineno"> 4182</span>&#160;</div><div class="line"><a name="l04183"></a><span class="lineno"> 4183</span>&#160;    <span class="keywordtype">void</span> MakePoolAllocationsLost(</div><div class="line"><a name="l04184"></a><span class="lineno"> 4184</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04185"></a><span class="lineno"> 4185</span>&#160;        <span class="keywordtype">size_t</span>* pLostAllocationCount);</div><div class="line"><a name="l04186"></a><span class="lineno"> 4186</span>&#160;</div><div class="line"><a name="l04187"></a><span class="lineno"> 4187</span>&#160;    VmaDefragmentator* EnsureDefragmentator(</div><div class="line"><a name="l04188"></a><span class="lineno"> 4188</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04189"></a><span class="lineno"> 4189</span>&#160;        uint32_t currentFrameIndex);</div><div class="line"><a name="l04190"></a><span class="lineno"> 4190</span>&#160;</div><div class="line"><a name="l04191"></a><span class="lineno"> 4191</span>&#160;    VkResult Defragment(</div><div class="line"><a name="l04192"></a><span class="lineno"> 4192</span>&#160;        <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats,</div><div class="line"><a name="l04193"></a><span class="lineno"> 4193</span>&#160;        VkDeviceSize&amp; maxBytesToMove,</div><div class="line"><a name="l04194"></a><span class="lineno"> 4194</span>&#160;        uint32_t&amp; maxAllocationsToMove);</div><div class="line"><a name="l04195"></a><span class="lineno"> 4195</span>&#160;</div><div class="line"><a name="l04196"></a><span class="lineno"> 4196</span>&#160;    <span class="keywordtype">void</span> DestroyDefragmentator();</div><div class="line"><a name="l04197"></a><span class="lineno"> 4197</span>&#160;</div><div class="line"><a name="l04198"></a><span class="lineno"> 4198</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04199"></a><span class="lineno"> 4199</span>&#160;    <span class="keyword">friend</span> <span class="keyword">class </span>VmaDefragmentator;</div><div class="line"><a name="l04200"></a><span class="lineno"> 4200</span>&#160;</div><div class="line"><a name="l04201"></a><span class="lineno"> 4201</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> m_hAllocator;</div><div class="line"><a name="l04202"></a><span class="lineno"> 4202</span>&#160;    <span class="keyword">const</span> uint32_t m_MemoryTypeIndex;</div><div class="line"><a name="l04203"></a><span class="lineno"> 4203</span>&#160;    <span class="keyword">const</span> VkDeviceSize m_PreferredBlockSize;</div><div class="line"><a name="l04204"></a><span class="lineno"> 4204</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> m_MinBlockCount;</div><div class="line"><a name="l04205"></a><span class="lineno"> 4205</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> m_MaxBlockCount;</div><div class="line"><a name="l04206"></a><span class="lineno"> 4206</span>&#160;    <span class="keyword">const</span> VkDeviceSize m_BufferImageGranularity;</div><div class="line"><a name="l04207"></a><span class="lineno"> 4207</span>&#160;    <span class="keyword">const</span> uint32_t m_FrameInUseCount;</div><div class="line"><a name="l04208"></a><span class="lineno"> 4208</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> m_IsCustomPool;</div><div class="line"><a name="l04209"></a><span class="lineno"> 4209</span>&#160;    VMA_MUTEX m_Mutex;</div><div class="line"><a name="l04210"></a><span class="lineno"> 4210</span>&#160;    <span class="comment">// Incrementally sorted by sumFreeSize, ascending.</span></div><div class="line"><a name="l04211"></a><span class="lineno"> 4211</span>&#160;    VmaVector&lt; VmaDeviceMemoryBlock*, VmaStlAllocator&lt;VmaDeviceMemoryBlock*&gt; &gt; m_Blocks;</div><div class="line"><a name="l04212"></a><span class="lineno"> 4212</span>&#160;    <span class="comment">/* There can be at most one allocation that is completely empty - a</span></div><div class="line"><a name="l04213"></a><span class="lineno"> 4213</span>&#160;<span class="comment">    hysteresis to avoid pessimistic case of alternating creation and destruction</span></div><div class="line"><a name="l04214"></a><span class="lineno"> 4214</span>&#160;<span class="comment">    of a VkDeviceMemory. */</span></div><div class="line"><a name="l04215"></a><span class="lineno"> 4215</span>&#160;    <span class="keywordtype">bool</span> m_HasEmptyBlock;</div><div class="line"><a name="l04216"></a><span class="lineno"> 4216</span>&#160;    VmaDefragmentator* m_pDefragmentator;</div><div class="line"><a name="l04217"></a><span class="lineno"> 4217</span>&#160;</div><div class="line"><a name="l04218"></a><span class="lineno"> 4218</span>&#160;    <span class="keywordtype">size_t</span> CalcMaxBlockSize() <span class="keyword">const</span>;</div><div class="line"><a name="l04219"></a><span class="lineno"> 4219</span>&#160;</div><div class="line"><a name="l04220"></a><span class="lineno"> 4220</span>&#160;    <span class="comment">// Finds and removes given block from vector.</span></div><div class="line"><a name="l04221"></a><span class="lineno"> 4221</span>&#160;    <span class="keywordtype">void</span> Remove(VmaDeviceMemoryBlock* pBlock);</div><div class="line"><a name="l04222"></a><span class="lineno"> 4222</span>&#160;</div><div class="line"><a name="l04223"></a><span class="lineno"> 4223</span>&#160;    <span class="comment">// Performs single step in sorting m_Blocks. They may not be fully sorted</span></div><div class="line"><a name="l04224"></a><span class="lineno"> 4224</span>&#160;    <span class="comment">// after this call.</span></div><div class="line"><a name="l04225"></a><span class="lineno"> 4225</span>&#160;    <span class="keywordtype">void</span> IncrementallySortBlocks();</div><div class="line"><a name="l04226"></a><span class="lineno"> 4226</span>&#160;</div><div class="line"><a name="l04227"></a><span class="lineno"> 4227</span>&#160;    VkResult CreateBlock(VkDeviceSize blockSize, <span class="keywordtype">size_t</span>* pNewBlockIndex);</div><div class="line"><a name="l04228"></a><span class="lineno"> 4228</span>&#160;};</div><div class="line"><a name="l04229"></a><span class="lineno"> 4229</span>&#160;</div><div class="line"><a name="l04230"></a><span class="lineno"> 4230</span>&#160;<span class="keyword">struct </span>VmaPool_T</div><div class="line"><a name="l04231"></a><span class="lineno"> 4231</span>&#160;{</div><div class="line"><a name="l04232"></a><span class="lineno"> 4232</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04233"></a><span class="lineno"> 4233</span>&#160;    VmaBlockVector m_BlockVector;</div><div class="line"><a name="l04234"></a><span class="lineno"> 4234</span>&#160;</div><div class="line"><a name="l04235"></a><span class="lineno"> 4235</span>&#160;    <span class="comment">// Takes ownership.</span></div><div class="line"><a name="l04236"></a><span class="lineno"> 4236</span>&#160;    VmaPool_T(</div><div class="line"><a name="l04237"></a><span class="lineno"> 4237</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04238"></a><span class="lineno"> 4238</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&amp; createInfo);</div><div class="line"><a name="l04239"></a><span class="lineno"> 4239</span>&#160;    ~VmaPool_T();</div><div class="line"><a name="l04240"></a><span class="lineno"> 4240</span>&#160;</div><div class="line"><a name="l04241"></a><span class="lineno"> 4241</span>&#160;    VmaBlockVector&amp; GetBlockVector() { <span class="keywordflow">return</span> m_BlockVector; }</div><div class="line"><a name="l04242"></a><span class="lineno"> 4242</span>&#160;</div><div class="line"><a name="l04243"></a><span class="lineno"> 4243</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04244"></a><span class="lineno"> 4244</span>&#160;    <span class="comment">//void PrintDetailedMap(class VmaStringBuilder&amp; sb);</span></div><div class="line"><a name="l04245"></a><span class="lineno"> 4245</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04246"></a><span class="lineno"> 4246</span>&#160;};</div><div class="line"><a name="l04247"></a><span class="lineno"> 4247</span>&#160;</div><div class="line"><a name="l04248"></a><span class="lineno"> 4248</span>&#160;<span class="keyword">class </span>VmaDefragmentator</div><div class="line"><a name="l04249"></a><span class="lineno"> 4249</span>&#160;{</div><div class="line"><a name="l04250"></a><span class="lineno"> 4250</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> m_hAllocator;</div><div class="line"><a name="l04251"></a><span class="lineno"> 4251</span>&#160;    VmaBlockVector* <span class="keyword">const</span> m_pBlockVector;</div><div class="line"><a name="l04252"></a><span class="lineno"> 4252</span>&#160;    uint32_t m_CurrentFrameIndex;</div><div class="line"><a name="l04253"></a><span class="lineno"> 4253</span>&#160;    VkDeviceSize m_BytesMoved;</div><div class="line"><a name="l04254"></a><span class="lineno"> 4254</span>&#160;    uint32_t m_AllocationsMoved;</div><div class="line"><a name="l04255"></a><span class="lineno"> 4255</span>&#160;</div><div class="line"><a name="l04256"></a><span class="lineno"> 4256</span>&#160;    <span class="keyword">struct </span>AllocationInfo</div><div class="line"><a name="l04257"></a><span class="lineno"> 4257</span>&#160;    {</div><div class="line"><a name="l04258"></a><span class="lineno"> 4258</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> m_hAllocation;</div><div class="line"><a name="l04259"></a><span class="lineno"> 4259</span>&#160;        VkBool32* m_pChanged;</div><div class="line"><a name="l04260"></a><span class="lineno"> 4260</span>&#160;</div><div class="line"><a name="l04261"></a><span class="lineno"> 4261</span>&#160;        AllocationInfo() :</div><div class="line"><a name="l04262"></a><span class="lineno"> 4262</span>&#160;            m_hAllocation(VK_NULL_HANDLE),</div><div class="line"><a name="l04263"></a><span class="lineno"> 4263</span>&#160;            m_pChanged(VMA_NULL)</div><div class="line"><a name="l04264"></a><span class="lineno"> 4264</span>&#160;        {</div><div class="line"><a name="l04265"></a><span class="lineno"> 4265</span>&#160;        }</div><div class="line"><a name="l04266"></a><span class="lineno"> 4266</span>&#160;    };</div><div class="line"><a name="l04267"></a><span class="lineno"> 4267</span>&#160;</div><div class="line"><a name="l04268"></a><span class="lineno"> 4268</span>&#160;    <span class="keyword">struct </span>AllocationInfoSizeGreater</div><div class="line"><a name="l04269"></a><span class="lineno"> 4269</span>&#160;    {</div><div class="line"><a name="l04270"></a><span class="lineno"> 4270</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> AllocationInfo&amp; lhs, <span class="keyword">const</span> AllocationInfo&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04271"></a><span class="lineno"> 4271</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04272"></a><span class="lineno"> 4272</span>&#160;            <span class="keywordflow">return</span> lhs.m_hAllocation-&gt;GetSize() &gt; rhs.m_hAllocation-&gt;GetSize();</div><div class="line"><a name="l04273"></a><span class="lineno"> 4273</span>&#160;        }</div><div class="line"><a name="l04274"></a><span class="lineno"> 4274</span>&#160;    };</div><div class="line"><a name="l04275"></a><span class="lineno"> 4275</span>&#160;</div><div class="line"><a name="l04276"></a><span class="lineno"> 4276</span>&#160;    <span class="comment">// Used between AddAllocation and Defragment.</span></div><div class="line"><a name="l04277"></a><span class="lineno"> 4277</span>&#160;    VmaVector&lt; AllocationInfo, VmaStlAllocator&lt;AllocationInfo&gt; &gt; m_Allocations;</div><div class="line"><a name="l04278"></a><span class="lineno"> 4278</span>&#160;</div><div class="line"><a name="l04279"></a><span class="lineno"> 4279</span>&#160;    <span class="keyword">struct </span>BlockInfo</div><div class="line"><a name="l04280"></a><span class="lineno"> 4280</span>&#160;    {</div><div class="line"><a name="l04281"></a><span class="lineno"> 4281</span>&#160;        VmaDeviceMemoryBlock* m_pBlock;</div><div class="line"><a name="l04282"></a><span class="lineno"> 4282</span>&#160;        <span class="keywordtype">bool</span> m_HasNonMovableAllocations;</div><div class="line"><a name="l04283"></a><span class="lineno"> 4283</span>&#160;        VmaVector&lt; AllocationInfo, VmaStlAllocator&lt;AllocationInfo&gt; &gt; m_Allocations;</div><div class="line"><a name="l04284"></a><span class="lineno"> 4284</span>&#160;</div><div class="line"><a name="l04285"></a><span class="lineno"> 4285</span>&#160;        BlockInfo(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks) :</div><div class="line"><a name="l04286"></a><span class="lineno"> 4286</span>&#160;            m_pBlock(VMA_NULL),</div><div class="line"><a name="l04287"></a><span class="lineno"> 4287</span>&#160;            m_HasNonMovableAllocations(true),</div><div class="line"><a name="l04288"></a><span class="lineno"> 4288</span>&#160;            m_Allocations(pAllocationCallbacks),</div><div class="line"><a name="l04289"></a><span class="lineno"> 4289</span>&#160;            m_pMappedDataForDefragmentation(VMA_NULL)</div><div class="line"><a name="l04290"></a><span class="lineno"> 4290</span>&#160;        {</div><div class="line"><a name="l04291"></a><span class="lineno"> 4291</span>&#160;        }</div><div class="line"><a name="l04292"></a><span class="lineno"> 4292</span>&#160;</div><div class="line"><a name="l04293"></a><span class="lineno"> 4293</span>&#160;        <span class="keywordtype">void</span> CalcHasNonMovableAllocations()</div><div class="line"><a name="l04294"></a><span class="lineno"> 4294</span>&#160;        {</div><div class="line"><a name="l04295"></a><span class="lineno"> 4295</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> blockAllocCount = m_pBlock-&gt;m_Metadata.GetAllocationCount();</div><div class="line"><a name="l04296"></a><span class="lineno"> 4296</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> defragmentAllocCount = m_Allocations.size();</div><div class="line"><a name="l04297"></a><span class="lineno"> 4297</span>&#160;            m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount;</div><div class="line"><a name="l04298"></a><span class="lineno"> 4298</span>&#160;        }</div><div class="line"><a name="l04299"></a><span class="lineno"> 4299</span>&#160;</div><div class="line"><a name="l04300"></a><span class="lineno"> 4300</span>&#160;        <span class="keywordtype">void</span> SortAllocationsBySizeDescecnding()</div><div class="line"><a name="l04301"></a><span class="lineno"> 4301</span>&#160;        {</div><div class="line"><a name="l04302"></a><span class="lineno"> 4302</span>&#160;            VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater());</div><div class="line"><a name="l04303"></a><span class="lineno"> 4303</span>&#160;        }</div><div class="line"><a name="l04304"></a><span class="lineno"> 4304</span>&#160;</div><div class="line"><a name="l04305"></a><span class="lineno"> 4305</span>&#160;        VkResult EnsureMapping(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppMappedData);</div><div class="line"><a name="l04306"></a><span class="lineno"> 4306</span>&#160;        <span class="keywordtype">void</span> Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04307"></a><span class="lineno"> 4307</span>&#160;</div><div class="line"><a name="l04308"></a><span class="lineno"> 4308</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l04309"></a><span class="lineno"> 4309</span>&#160;        <span class="comment">// Not null if mapped for defragmentation only, not originally mapped.</span></div><div class="line"><a name="l04310"></a><span class="lineno"> 4310</span>&#160;        <span class="keywordtype">void</span>* m_pMappedDataForDefragmentation;</div><div class="line"><a name="l04311"></a><span class="lineno"> 4311</span>&#160;    };</div><div class="line"><a name="l04312"></a><span class="lineno"> 4312</span>&#160;</div><div class="line"><a name="l04313"></a><span class="lineno"> 4313</span>&#160;    <span class="keyword">struct </span>BlockPointerLess</div><div class="line"><a name="l04314"></a><span class="lineno"> 4314</span>&#160;    {</div><div class="line"><a name="l04315"></a><span class="lineno"> 4315</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> BlockInfo* pLhsBlockInfo, <span class="keyword">const</span> VmaDeviceMemoryBlock* pRhsBlock)<span class="keyword"> const</span></div><div class="line"><a name="l04316"></a><span class="lineno"> 4316</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04317"></a><span class="lineno"> 4317</span>&#160;            <span class="keywordflow">return</span> pLhsBlockInfo-&gt;m_pBlock &lt; pRhsBlock;</div><div class="line"><a name="l04318"></a><span class="lineno"> 4318</span>&#160;        }</div><div class="line"><a name="l04319"></a><span class="lineno"> 4319</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> BlockInfo* pLhsBlockInfo, <span class="keyword">const</span> BlockInfo* pRhsBlockInfo)<span class="keyword"> const</span></div><div class="line"><a name="l04320"></a><span class="lineno"> 4320</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04321"></a><span class="lineno"> 4321</span>&#160;            <span class="keywordflow">return</span> pLhsBlockInfo-&gt;m_pBlock &lt; pRhsBlockInfo-&gt;m_pBlock;</div><div class="line"><a name="l04322"></a><span class="lineno"> 4322</span>&#160;        }</div><div class="line"><a name="l04323"></a><span class="lineno"> 4323</span>&#160;    };</div><div class="line"><a name="l04324"></a><span class="lineno"> 4324</span>&#160;</div><div class="line"><a name="l04325"></a><span class="lineno"> 4325</span>&#160;    <span class="comment">// 1. Blocks with some non-movable allocations go first.</span></div><div class="line"><a name="l04326"></a><span class="lineno"> 4326</span>&#160;    <span class="comment">// 2. Blocks with smaller sumFreeSize go first.</span></div><div class="line"><a name="l04327"></a><span class="lineno"> 4327</span>&#160;    <span class="keyword">struct </span>BlockInfoCompareMoveDestination</div><div class="line"><a name="l04328"></a><span class="lineno"> 4328</span>&#160;    {</div><div class="line"><a name="l04329"></a><span class="lineno"> 4329</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> BlockInfo* pLhsBlockInfo, <span class="keyword">const</span> BlockInfo* pRhsBlockInfo)<span class="keyword"> const</span></div><div class="line"><a name="l04330"></a><span class="lineno"> 4330</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04331"></a><span class="lineno"> 4331</span>&#160;            <span class="keywordflow">if</span>(pLhsBlockInfo-&gt;m_HasNonMovableAllocations &amp;&amp; !pRhsBlockInfo-&gt;m_HasNonMovableAllocations)</div><div class="line"><a name="l04332"></a><span class="lineno"> 4332</span>&#160;            {</div><div class="line"><a name="l04333"></a><span class="lineno"> 4333</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l04334"></a><span class="lineno"> 4334</span>&#160;            }</div><div class="line"><a name="l04335"></a><span class="lineno"> 4335</span>&#160;            <span class="keywordflow">if</span>(!pLhsBlockInfo-&gt;m_HasNonMovableAllocations &amp;&amp; pRhsBlockInfo-&gt;m_HasNonMovableAllocations)</div><div class="line"><a name="l04336"></a><span class="lineno"> 4336</span>&#160;            {</div><div class="line"><a name="l04337"></a><span class="lineno"> 4337</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l04338"></a><span class="lineno"> 4338</span>&#160;            }</div><div class="line"><a name="l04339"></a><span class="lineno"> 4339</span>&#160;            <span class="keywordflow">if</span>(pLhsBlockInfo-&gt;m_pBlock-&gt;m_Metadata.GetSumFreeSize() &lt; pRhsBlockInfo-&gt;m_pBlock-&gt;m_Metadata.GetSumFreeSize())</div><div class="line"><a name="l04340"></a><span class="lineno"> 4340</span>&#160;            {</div><div class="line"><a name="l04341"></a><span class="lineno"> 4341</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l04342"></a><span class="lineno"> 4342</span>&#160;            }</div><div class="line"><a name="l04343"></a><span class="lineno"> 4343</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l04344"></a><span class="lineno"> 4344</span>&#160;        }</div><div class="line"><a name="l04345"></a><span class="lineno"> 4345</span>&#160;    };</div><div class="line"><a name="l04346"></a><span class="lineno"> 4346</span>&#160;</div><div class="line"><a name="l04347"></a><span class="lineno"> 4347</span>&#160;    <span class="keyword">typedef</span> VmaVector&lt; BlockInfo*, VmaStlAllocator&lt;BlockInfo*&gt; &gt; BlockInfoVector;</div><div class="line"><a name="l04348"></a><span class="lineno"> 4348</span>&#160;    BlockInfoVector m_Blocks;</div><div class="line"><a name="l04349"></a><span class="lineno"> 4349</span>&#160;</div><div class="line"><a name="l04350"></a><span class="lineno"> 4350</span>&#160;    VkResult DefragmentRound(</div><div class="line"><a name="l04351"></a><span class="lineno"> 4351</span>&#160;        VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l04352"></a><span class="lineno"> 4352</span>&#160;        uint32_t maxAllocationsToMove);</div><div class="line"><a name="l04353"></a><span class="lineno"> 4353</span>&#160;</div><div class="line"><a name="l04354"></a><span class="lineno"> 4354</span>&#160;    <span class="keyword">static</span> <span class="keywordtype">bool</span> MoveMakesSense(</div><div class="line"><a name="l04355"></a><span class="lineno"> 4355</span>&#160;        <span class="keywordtype">size_t</span> dstBlockIndex, VkDeviceSize dstOffset,</div><div class="line"><a name="l04356"></a><span class="lineno"> 4356</span>&#160;        <span class="keywordtype">size_t</span> srcBlockIndex, VkDeviceSize srcOffset);</div><div class="line"><a name="l04357"></a><span class="lineno"> 4357</span>&#160;</div><div class="line"><a name="l04358"></a><span class="lineno"> 4358</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04359"></a><span class="lineno"> 4359</span>&#160;    VmaDefragmentator(</div><div class="line"><a name="l04360"></a><span class="lineno"> 4360</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04361"></a><span class="lineno"> 4361</span>&#160;        VmaBlockVector* pBlockVector,</div><div class="line"><a name="l04362"></a><span class="lineno"> 4362</span>&#160;        uint32_t currentFrameIndex);</div><div class="line"><a name="l04363"></a><span class="lineno"> 4363</span>&#160;</div><div class="line"><a name="l04364"></a><span class="lineno"> 4364</span>&#160;    ~VmaDefragmentator();</div><div class="line"><a name="l04365"></a><span class="lineno"> 4365</span>&#160;</div><div class="line"><a name="l04366"></a><span class="lineno"> 4366</span>&#160;    VkDeviceSize GetBytesMoved()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_BytesMoved; }</div><div class="line"><a name="l04367"></a><span class="lineno"> 4367</span>&#160;    uint32_t GetAllocationsMoved()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_AllocationsMoved; }</div><div class="line"><a name="l04368"></a><span class="lineno"> 4368</span>&#160;</div><div class="line"><a name="l04369"></a><span class="lineno"> 4369</span>&#160;    <span class="keywordtype">void</span> AddAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc, VkBool32* pChanged);</div><div class="line"><a name="l04370"></a><span class="lineno"> 4370</span>&#160;</div><div class="line"><a name="l04371"></a><span class="lineno"> 4371</span>&#160;    VkResult Defragment(</div><div class="line"><a name="l04372"></a><span class="lineno"> 4372</span>&#160;        VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l04373"></a><span class="lineno"> 4373</span>&#160;        uint32_t maxAllocationsToMove);</div><div class="line"><a name="l04374"></a><span class="lineno"> 4374</span>&#160;};</div><div class="line"><a name="l04375"></a><span class="lineno"> 4375</span>&#160;</div><div class="line"><a name="l04376"></a><span class="lineno"> 4376</span>&#160;<span class="comment">// Main allocator object.</span></div><div class="line"><a name="l04377"></a><span class="lineno"> 4377</span>&#160;<span class="keyword">struct </span>VmaAllocator_T</div><div class="line"><a name="l04378"></a><span class="lineno"> 4378</span>&#160;{</div><div class="line"><a name="l04379"></a><span class="lineno"> 4379</span>&#160;    <span class="keywordtype">bool</span> m_UseMutex;</div><div class="line"><a name="l04380"></a><span class="lineno"> 4380</span>&#160;    <span class="keywordtype">bool</span> m_UseKhrDedicatedAllocation;</div><div class="line"><a name="l04381"></a><span class="lineno"> 4381</span>&#160;    VkDevice m_hDevice;</div><div class="line"><a name="l04382"></a><span class="lineno"> 4382</span>&#160;    <span class="keywordtype">bool</span> m_AllocationCallbacksSpecified;</div><div class="line"><a name="l04383"></a><span class="lineno"> 4383</span>&#160;    VkAllocationCallbacks m_AllocationCallbacks;</div><div class="line"><a name="l04384"></a><span class="lineno"> 4384</span>&#160;    <a class="code" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a> m_DeviceMemoryCallbacks;</div><div class="line"><a name="l04385"></a><span class="lineno"> 4385</span>&#160;    </div><div class="line"><a name="l04386"></a><span class="lineno"> 4386</span>&#160;    <span class="comment">// Number of bytes free out of limit, or VK_WHOLE_SIZE if not limit for that heap.</span></div><div class="line"><a name="l04387"></a><span class="lineno"> 4387</span>&#160;    VkDeviceSize m_HeapSizeLimit[VK_MAX_MEMORY_HEAPS];</div><div class="line"><a name="l04388"></a><span class="lineno"> 4388</span>&#160;    VMA_MUTEX m_HeapSizeLimitMutex;</div><div class="line"><a name="l04389"></a><span class="lineno"> 4389</span>&#160;</div><div class="line"><a name="l04390"></a><span class="lineno"> 4390</span>&#160;    VkPhysicalDeviceProperties m_PhysicalDeviceProperties;</div><div class="line"><a name="l04391"></a><span class="lineno"> 4391</span>&#160;    VkPhysicalDeviceMemoryProperties m_MemProps;</div><div class="line"><a name="l04392"></a><span class="lineno"> 4392</span>&#160;</div><div class="line"><a name="l04393"></a><span class="lineno"> 4393</span>&#160;    <span class="comment">// Default pools.</span></div><div class="line"><a name="l04394"></a><span class="lineno"> 4394</span>&#160;    VmaBlockVector* m_pBlockVectors[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l04395"></a><span class="lineno"> 4395</span>&#160;</div><div class="line"><a name="l04396"></a><span class="lineno"> 4396</span>&#160;    <span class="comment">// Each vector is sorted by memory (handle value).</span></div><div class="line"><a name="l04397"></a><span class="lineno"> 4397</span>&#160;    <span class="keyword">typedef</span> VmaVector&lt; VmaAllocation, VmaStlAllocator&lt;VmaAllocation&gt; &gt; AllocationVectorType;</div><div class="line"><a name="l04398"></a><span class="lineno"> 4398</span>&#160;    AllocationVectorType* m_pDedicatedAllocations[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l04399"></a><span class="lineno"> 4399</span>&#160;    VMA_MUTEX m_DedicatedAllocationsMutex[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l04400"></a><span class="lineno"> 4400</span>&#160;</div><div class="line"><a name="l04401"></a><span class="lineno"> 4401</span>&#160;    VmaAllocator_T(<span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo);</div><div class="line"><a name="l04402"></a><span class="lineno"> 4402</span>&#160;    ~VmaAllocator_T();</div><div class="line"><a name="l04403"></a><span class="lineno"> 4403</span>&#160;</div><div class="line"><a name="l04404"></a><span class="lineno"> 4404</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* GetAllocationCallbacks()<span class="keyword"> const</span></div><div class="line"><a name="l04405"></a><span class="lineno"> 4405</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04406"></a><span class="lineno"> 4406</span>&#160;        <span class="keywordflow">return</span> m_AllocationCallbacksSpecified ? &amp;m_AllocationCallbacks : 0;</div><div class="line"><a name="l04407"></a><span class="lineno"> 4407</span>&#160;    }</div><div class="line"><a name="l04408"></a><span class="lineno"> 4408</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>&amp; GetVulkanFunctions()<span class="keyword"> const</span></div><div class="line"><a name="l04409"></a><span class="lineno"> 4409</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04410"></a><span class="lineno"> 4410</span>&#160;        <span class="keywordflow">return</span> m_VulkanFunctions;</div><div class="line"><a name="l04411"></a><span class="lineno"> 4411</span>&#160;    }</div><div class="line"><a name="l04412"></a><span class="lineno"> 4412</span>&#160;</div><div class="line"><a name="l04413"></a><span class="lineno"> 4413</span>&#160;    VkDeviceSize GetBufferImageGranularity()<span class="keyword"> const</span></div><div class="line"><a name="l04414"></a><span class="lineno"> 4414</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04415"></a><span class="lineno"> 4415</span>&#160;        <span class="keywordflow">return</span> VMA_MAX(</div><div class="line"><a name="l04416"></a><span class="lineno"> 4416</span>&#160;            static_cast&lt;VkDeviceSize&gt;(VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY),</div><div class="line"><a name="l04417"></a><span class="lineno"> 4417</span>&#160;            m_PhysicalDeviceProperties.limits.bufferImageGranularity);</div><div class="line"><a name="l04418"></a><span class="lineno"> 4418</span>&#160;    }</div><div class="line"><a name="l04419"></a><span class="lineno"> 4419</span>&#160;</div><div class="line"><a name="l04420"></a><span class="lineno"> 4420</span>&#160;    uint32_t GetMemoryHeapCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemProps.memoryHeapCount; }</div><div class="line"><a name="l04421"></a><span class="lineno"> 4421</span>&#160;    uint32_t GetMemoryTypeCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemProps.memoryTypeCount; }</div><div class="line"><a name="l04422"></a><span class="lineno"> 4422</span>&#160;</div><div class="line"><a name="l04423"></a><span class="lineno"> 4423</span>&#160;    uint32_t MemoryTypeIndexToHeapIndex(uint32_t memTypeIndex)<span class="keyword"> const</span></div><div class="line"><a name="l04424"></a><span class="lineno"> 4424</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04425"></a><span class="lineno"> 4425</span>&#160;        VMA_ASSERT(memTypeIndex &lt; m_MemProps.memoryTypeCount);</div><div class="line"><a name="l04426"></a><span class="lineno"> 4426</span>&#160;        <span class="keywordflow">return</span> m_MemProps.memoryTypes[memTypeIndex].heapIndex;</div><div class="line"><a name="l04427"></a><span class="lineno"> 4427</span>&#160;    }</div><div class="line"><a name="l04428"></a><span class="lineno"> 4428</span>&#160;</div><div class="line"><a name="l04429"></a><span class="lineno"> 4429</span>&#160;    <span class="keywordtype">void</span> GetBufferMemoryRequirements(</div><div class="line"><a name="l04430"></a><span class="lineno"> 4430</span>&#160;        VkBuffer hBuffer,</div><div class="line"><a name="l04431"></a><span class="lineno"> 4431</span>&#160;        VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l04432"></a><span class="lineno"> 4432</span>&#160;        <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l04433"></a><span class="lineno"> 4433</span>&#160;        <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation) <span class="keyword">const</span>;</div><div class="line"><a name="l04434"></a><span class="lineno"> 4434</span>&#160;    <span class="keywordtype">void</span> GetImageMemoryRequirements(</div><div class="line"><a name="l04435"></a><span class="lineno"> 4435</span>&#160;        VkImage hImage,</div><div class="line"><a name="l04436"></a><span class="lineno"> 4436</span>&#160;        VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l04437"></a><span class="lineno"> 4437</span>&#160;        <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l04438"></a><span class="lineno"> 4438</span>&#160;        <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation) <span class="keyword">const</span>;</div><div class="line"><a name="l04439"></a><span class="lineno"> 4439</span>&#160;</div><div class="line"><a name="l04440"></a><span class="lineno"> 4440</span>&#160;    <span class="comment">// Main allocation function.</span></div><div class="line"><a name="l04441"></a><span class="lineno"> 4441</span>&#160;    VkResult AllocateMemory(</div><div class="line"><a name="l04442"></a><span class="lineno"> 4442</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l04443"></a><span class="lineno"> 4443</span>&#160;        <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l04444"></a><span class="lineno"> 4444</span>&#160;        <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l04445"></a><span class="lineno"> 4445</span>&#160;        VkBuffer dedicatedBuffer,</div><div class="line"><a name="l04446"></a><span class="lineno"> 4446</span>&#160;        VkImage dedicatedImage,</div><div class="line"><a name="l04447"></a><span class="lineno"> 4447</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l04448"></a><span class="lineno"> 4448</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l04449"></a><span class="lineno"> 4449</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l04450"></a><span class="lineno"> 4450</span>&#160;</div><div class="line"><a name="l04451"></a><span class="lineno"> 4451</span>&#160;    <span class="comment">// Main deallocation function.</span></div><div class="line"><a name="l04452"></a><span class="lineno"> 4452</span>&#160;    <span class="keywordtype">void</span> FreeMemory(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l04453"></a><span class="lineno"> 4453</span>&#160;</div><div class="line"><a name="l04454"></a><span class="lineno"> 4454</span>&#160;    <span class="keywordtype">void</span> CalculateStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats);</div><div class="line"><a name="l04455"></a><span class="lineno"> 4455</span>&#160;</div><div class="line"><a name="l04456"></a><span class="lineno"> 4456</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04457"></a><span class="lineno"> 4457</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json);</div><div class="line"><a name="l04458"></a><span class="lineno"> 4458</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04459"></a><span class="lineno"> 4459</span>&#160;</div><div class="line"><a name="l04460"></a><span class="lineno"> 4460</span>&#160;    VkResult Defragment(</div><div class="line"><a name="l04461"></a><span class="lineno"> 4461</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l04462"></a><span class="lineno"> 4462</span>&#160;        <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l04463"></a><span class="lineno"> 4463</span>&#160;        VkBool32* pAllocationsChanged,</div><div class="line"><a name="l04464"></a><span class="lineno"> 4464</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>* pDefragmentationInfo,</div><div class="line"><a name="l04465"></a><span class="lineno"> 4465</span>&#160;        <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats);</div><div class="line"><a name="l04466"></a><span class="lineno"> 4466</span>&#160;</div><div class="line"><a name="l04467"></a><span class="lineno"> 4467</span>&#160;    <span class="keywordtype">void</span> GetAllocationInfo(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l04468"></a><span class="lineno"> 4468</span>&#160;    <span class="keywordtype">bool</span> TouchAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l04469"></a><span class="lineno"> 4469</span>&#160;</div><div class="line"><a name="l04470"></a><span class="lineno"> 4470</span>&#160;    VkResult CreatePool(<span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo, <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool);</div><div class="line"><a name="l04471"></a><span class="lineno"> 4471</span>&#160;    <span class="keywordtype">void</span> DestroyPool(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l04472"></a><span class="lineno"> 4472</span>&#160;    <span class="keywordtype">void</span> GetPoolStats(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool, <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats);</div><div class="line"><a name="l04473"></a><span class="lineno"> 4473</span>&#160;</div><div class="line"><a name="l04474"></a><span class="lineno"> 4474</span>&#160;    <span class="keywordtype">void</span> SetCurrentFrameIndex(uint32_t frameIndex);</div><div class="line"><a name="l04475"></a><span class="lineno"> 4475</span>&#160;</div><div class="line"><a name="l04476"></a><span class="lineno"> 4476</span>&#160;    <span class="keywordtype">void</span> MakePoolAllocationsLost(</div><div class="line"><a name="l04477"></a><span class="lineno"> 4477</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool,</div><div class="line"><a name="l04478"></a><span class="lineno"> 4478</span>&#160;        <span class="keywordtype">size_t</span>* pLostAllocationCount);</div><div class="line"><a name="l04479"></a><span class="lineno"> 4479</span>&#160;</div><div class="line"><a name="l04480"></a><span class="lineno"> 4480</span>&#160;    <span class="keywordtype">void</span> CreateLostAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l04481"></a><span class="lineno"> 4481</span>&#160;</div><div class="line"><a name="l04482"></a><span class="lineno"> 4482</span>&#160;    VkResult AllocateVulkanMemory(<span class="keyword">const</span> VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory);</div><div class="line"><a name="l04483"></a><span class="lineno"> 4483</span>&#160;    <span class="keywordtype">void</span> FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory);</div><div class="line"><a name="l04484"></a><span class="lineno"> 4484</span>&#160;</div><div class="line"><a name="l04485"></a><span class="lineno"> 4485</span>&#160;    VkResult Map(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l04486"></a><span class="lineno"> 4486</span>&#160;    <span class="keywordtype">void</span> Unmap(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l04487"></a><span class="lineno"> 4487</span>&#160;</div><div class="line"><a name="l04488"></a><span class="lineno"> 4488</span>&#160;    VkResult BindBufferMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkBuffer hBuffer);</div><div class="line"><a name="l04489"></a><span class="lineno"> 4489</span>&#160;    VkResult BindImageMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkImage hImage);</div><div class="line"><a name="l04490"></a><span class="lineno"> 4490</span>&#160;</div><div class="line"><a name="l04491"></a><span class="lineno"> 4491</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04492"></a><span class="lineno"> 4492</span>&#160;    VkDeviceSize m_PreferredLargeHeapBlockSize;</div><div class="line"><a name="l04493"></a><span class="lineno"> 4493</span>&#160;</div><div class="line"><a name="l04494"></a><span class="lineno"> 4494</span>&#160;    VkPhysicalDevice m_PhysicalDevice;</div><div class="line"><a name="l04495"></a><span class="lineno"> 4495</span>&#160;    VMA_ATOMIC_UINT32 m_CurrentFrameIndex;</div><div class="line"><a name="l04496"></a><span class="lineno"> 4496</span>&#160;    </div><div class="line"><a name="l04497"></a><span class="lineno"> 4497</span>&#160;    VMA_MUTEX m_PoolsMutex;</div><div class="line"><a name="l04498"></a><span class="lineno"> 4498</span>&#160;    <span class="comment">// Protected by m_PoolsMutex. Sorted by pointer value.</span></div><div class="line"><a name="l04499"></a><span class="lineno"> 4499</span>&#160;    VmaVector&lt;VmaPool, VmaStlAllocator&lt;VmaPool&gt; &gt; m_Pools;</div><div class="line"><a name="l04500"></a><span class="lineno"> 4500</span>&#160;</div><div class="line"><a name="l04501"></a><span class="lineno"> 4501</span>&#160;    <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a> m_VulkanFunctions;</div><div class="line"><a name="l04502"></a><span class="lineno"> 4502</span>&#160;</div><div class="line"><a name="l04503"></a><span class="lineno"> 4503</span>&#160;    <span class="keywordtype">void</span> ImportVulkanFunctions(<span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>* pVulkanFunctions);</div><div class="line"><a name="l04504"></a><span class="lineno"> 4504</span>&#160;</div><div class="line"><a name="l04505"></a><span class="lineno"> 4505</span>&#160;    VkDeviceSize CalcPreferredBlockSize(uint32_t memTypeIndex);</div><div class="line"><a name="l04506"></a><span class="lineno"> 4506</span>&#160;</div><div class="line"><a name="l04507"></a><span class="lineno"> 4507</span>&#160;    VkResult AllocateMemoryOfType(</div><div class="line"><a name="l04508"></a><span class="lineno"> 4508</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l04509"></a><span class="lineno"> 4509</span>&#160;        <span class="keywordtype">bool</span> dedicatedAllocation,</div><div class="line"><a name="l04510"></a><span class="lineno"> 4510</span>&#160;        VkBuffer dedicatedBuffer,</div><div class="line"><a name="l04511"></a><span class="lineno"> 4511</span>&#160;        VkImage dedicatedImage,</div><div class="line"><a name="l04512"></a><span class="lineno"> 4512</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l04513"></a><span class="lineno"> 4513</span>&#160;        uint32_t memTypeIndex,</div><div class="line"><a name="l04514"></a><span class="lineno"> 4514</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l04515"></a><span class="lineno"> 4515</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l04516"></a><span class="lineno"> 4516</span>&#160;</div><div class="line"><a name="l04517"></a><span class="lineno"> 4517</span>&#160;    <span class="comment">// Allocates and registers new VkDeviceMemory specifically for single allocation.</span></div><div class="line"><a name="l04518"></a><span class="lineno"> 4518</span>&#160;    VkResult AllocateDedicatedMemory(</div><div class="line"><a name="l04519"></a><span class="lineno"> 4519</span>&#160;        VkDeviceSize size,</div><div class="line"><a name="l04520"></a><span class="lineno"> 4520</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l04521"></a><span class="lineno"> 4521</span>&#160;        uint32_t memTypeIndex,</div><div class="line"><a name="l04522"></a><span class="lineno"> 4522</span>&#160;        <span class="keywordtype">bool</span> map,</div><div class="line"><a name="l04523"></a><span class="lineno"> 4523</span>&#160;        <span class="keywordtype">bool</span> isUserDataString,</div><div class="line"><a name="l04524"></a><span class="lineno"> 4524</span>&#160;        <span class="keywordtype">void</span>* pUserData,</div><div class="line"><a name="l04525"></a><span class="lineno"> 4525</span>&#160;        VkBuffer dedicatedBuffer,</div><div class="line"><a name="l04526"></a><span class="lineno"> 4526</span>&#160;        VkImage dedicatedImage,</div><div class="line"><a name="l04527"></a><span class="lineno"> 4527</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l04528"></a><span class="lineno"> 4528</span>&#160;</div><div class="line"><a name="l04529"></a><span class="lineno"> 4529</span>&#160;    <span class="comment">// Tries to free pMemory as Dedicated Memory. Returns true if found and freed.</span></div><div class="line"><a name="l04530"></a><span class="lineno"> 4530</span>&#160;    <span class="keywordtype">void</span> FreeDedicatedMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l04531"></a><span class="lineno"> 4531</span>&#160;};</div><div class="line"><a name="l04532"></a><span class="lineno"> 4532</span>&#160;</div><div class="line"><a name="l04534"></a><span class="lineno"> 4534</span>&#160;<span class="comment">// Memory allocation #2 after VmaAllocator_T definition</span></div><div class="line"><a name="l04535"></a><span class="lineno"> 4535</span>&#160;</div><div class="line"><a name="l04536"></a><span class="lineno"> 4536</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span>* VmaMalloc(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment)</div><div class="line"><a name="l04537"></a><span class="lineno"> 4537</span>&#160;{</div><div class="line"><a name="l04538"></a><span class="lineno"> 4538</span>&#160;    <span class="keywordflow">return</span> VmaMalloc(&amp;hAllocator-&gt;m_AllocationCallbacks, size, alignment);</div><div class="line"><a name="l04539"></a><span class="lineno"> 4539</span>&#160;}</div><div class="line"><a name="l04540"></a><span class="lineno"> 4540</span>&#160;</div><div class="line"><a name="l04541"></a><span class="lineno"> 4541</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaFree(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l04542"></a><span class="lineno"> 4542</span>&#160;{</div><div class="line"><a name="l04543"></a><span class="lineno"> 4543</span>&#160;    VmaFree(&amp;hAllocator-&gt;m_AllocationCallbacks, ptr);</div><div class="line"><a name="l04544"></a><span class="lineno"> 4544</span>&#160;}</div><div class="line"><a name="l04545"></a><span class="lineno"> 4545</span>&#160;</div><div class="line"><a name="l04546"></a><span class="lineno"> 4546</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l04547"></a><span class="lineno"> 4547</span>&#160;<span class="keyword">static</span> T* VmaAllocate(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l04548"></a><span class="lineno"> 4548</span>&#160;{</div><div class="line"><a name="l04549"></a><span class="lineno"> 4549</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(hAllocator, <span class="keyword">sizeof</span>(T), VMA_ALIGN_OF(T));</div><div class="line"><a name="l04550"></a><span class="lineno"> 4550</span>&#160;}</div><div class="line"><a name="l04551"></a><span class="lineno"> 4551</span>&#160;</div><div class="line"><a name="l04552"></a><span class="lineno"> 4552</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l04553"></a><span class="lineno"> 4553</span>&#160;<span class="keyword">static</span> T* VmaAllocateArray(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l04554"></a><span class="lineno"> 4554</span>&#160;{</div><div class="line"><a name="l04555"></a><span class="lineno"> 4555</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(hAllocator, <span class="keyword">sizeof</span>(T) * count, VMA_ALIGN_OF(T));</div><div class="line"><a name="l04556"></a><span class="lineno"> 4556</span>&#160;}</div><div class="line"><a name="l04557"></a><span class="lineno"> 4557</span>&#160;</div><div class="line"><a name="l04558"></a><span class="lineno"> 4558</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l04559"></a><span class="lineno"> 4559</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, T* ptr)</div><div class="line"><a name="l04560"></a><span class="lineno"> 4560</span>&#160;{</div><div class="line"><a name="l04561"></a><span class="lineno"> 4561</span>&#160;    <span class="keywordflow">if</span>(ptr != VMA_NULL)</div><div class="line"><a name="l04562"></a><span class="lineno"> 4562</span>&#160;    {</div><div class="line"><a name="l04563"></a><span class="lineno"> 4563</span>&#160;        ptr-&gt;~T();</div><div class="line"><a name="l04564"></a><span class="lineno"> 4564</span>&#160;        VmaFree(hAllocator, ptr);</div><div class="line"><a name="l04565"></a><span class="lineno"> 4565</span>&#160;    }</div><div class="line"><a name="l04566"></a><span class="lineno"> 4566</span>&#160;}</div><div class="line"><a name="l04567"></a><span class="lineno"> 4567</span>&#160;</div><div class="line"><a name="l04568"></a><span class="lineno"> 4568</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l04569"></a><span class="lineno"> 4569</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete_array(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, T* ptr, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l04570"></a><span class="lineno"> 4570</span>&#160;{</div><div class="line"><a name="l04571"></a><span class="lineno"> 4571</span>&#160;    <span class="keywordflow">if</span>(ptr != VMA_NULL)</div><div class="line"><a name="l04572"></a><span class="lineno"> 4572</span>&#160;    {</div><div class="line"><a name="l04573"></a><span class="lineno"> 4573</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = count; i--; )</div><div class="line"><a name="l04574"></a><span class="lineno"> 4574</span>&#160;            ptr[i].~T();</div><div class="line"><a name="l04575"></a><span class="lineno"> 4575</span>&#160;        VmaFree(hAllocator, ptr);</div><div class="line"><a name="l04576"></a><span class="lineno"> 4576</span>&#160;    }</div><div class="line"><a name="l04577"></a><span class="lineno"> 4577</span>&#160;}</div><div class="line"><a name="l04578"></a><span class="lineno"> 4578</span>&#160;</div><div class="line"><a name="l04580"></a><span class="lineno"> 4580</span>&#160;<span class="comment">// VmaStringBuilder</span></div><div class="line"><a name="l04581"></a><span class="lineno"> 4581</span>&#160;</div><div class="line"><a name="l04582"></a><span class="lineno"> 4582</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04583"></a><span class="lineno"> 4583</span>&#160;</div><div class="line"><a name="l04584"></a><span class="lineno"> 4584</span>&#160;<span class="keyword">class </span>VmaStringBuilder</div><div class="line"><a name="l04585"></a><span class="lineno"> 4585</span>&#160;{</div><div class="line"><a name="l04586"></a><span class="lineno"> 4586</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04587"></a><span class="lineno"> 4587</span>&#160;    VmaStringBuilder(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> alloc) : m_Data(VmaStlAllocator&lt;char&gt;(alloc-&gt;GetAllocationCallbacks())) { }</div><div class="line"><a name="l04588"></a><span class="lineno"> 4588</span>&#160;    <span class="keywordtype">size_t</span> GetLength()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Data.size(); }</div><div class="line"><a name="l04589"></a><span class="lineno"> 4589</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">char</span>* GetData()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Data.data(); }</div><div class="line"><a name="l04590"></a><span class="lineno"> 4590</span>&#160;</div><div class="line"><a name="l04591"></a><span class="lineno"> 4591</span>&#160;    <span class="keywordtype">void</span> Add(<span class="keywordtype">char</span> ch) { m_Data.push_back(ch); }</div><div class="line"><a name="l04592"></a><span class="lineno"> 4592</span>&#160;    <span class="keywordtype">void</span> Add(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr);</div><div class="line"><a name="l04593"></a><span class="lineno"> 4593</span>&#160;    <span class="keywordtype">void</span> AddNewLine() { Add(<span class="charliteral">&#39;\n&#39;</span>); }</div><div class="line"><a name="l04594"></a><span class="lineno"> 4594</span>&#160;    <span class="keywordtype">void</span> AddNumber(uint32_t num);</div><div class="line"><a name="l04595"></a><span class="lineno"> 4595</span>&#160;    <span class="keywordtype">void</span> AddNumber(uint64_t num);</div><div class="line"><a name="l04596"></a><span class="lineno"> 4596</span>&#160;    <span class="keywordtype">void</span> AddPointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr);</div><div class="line"><a name="l04597"></a><span class="lineno"> 4597</span>&#160;</div><div class="line"><a name="l04598"></a><span class="lineno"> 4598</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04599"></a><span class="lineno"> 4599</span>&#160;    VmaVector&lt; char, VmaStlAllocator&lt;char&gt; &gt; m_Data;</div><div class="line"><a name="l04600"></a><span class="lineno"> 4600</span>&#160;};</div><div class="line"><a name="l04601"></a><span class="lineno"> 4601</span>&#160;</div><div class="line"><a name="l04602"></a><span class="lineno"> 4602</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::Add(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l04603"></a><span class="lineno"> 4603</span>&#160;{</div><div class="line"><a name="l04604"></a><span class="lineno"> 4604</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> strLen = strlen(pStr);</div><div class="line"><a name="l04605"></a><span class="lineno"> 4605</span>&#160;    <span class="keywordflow">if</span>(strLen &gt; 0)</div><div class="line"><a name="l04606"></a><span class="lineno"> 4606</span>&#160;    {</div><div class="line"><a name="l04607"></a><span class="lineno"> 4607</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldCount = m_Data.size();</div><div class="line"><a name="l04608"></a><span class="lineno"> 4608</span>&#160;        m_Data.resize(oldCount + strLen);</div><div class="line"><a name="l04609"></a><span class="lineno"> 4609</span>&#160;        memcpy(m_Data.data() + oldCount, pStr, strLen);</div><div class="line"><a name="l04610"></a><span class="lineno"> 4610</span>&#160;    }</div><div class="line"><a name="l04611"></a><span class="lineno"> 4611</span>&#160;}</div><div class="line"><a name="l04612"></a><span class="lineno"> 4612</span>&#160;</div><div class="line"><a name="l04613"></a><span class="lineno"> 4613</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::AddNumber(uint32_t num)</div><div class="line"><a name="l04614"></a><span class="lineno"> 4614</span>&#160;{</div><div class="line"><a name="l04615"></a><span class="lineno"> 4615</span>&#160;    <span class="keywordtype">char</span> buf[11];</div><div class="line"><a name="l04616"></a><span class="lineno"> 4616</span>&#160;    VmaUint32ToStr(buf, <span class="keyword">sizeof</span>(buf), num);</div><div class="line"><a name="l04617"></a><span class="lineno"> 4617</span>&#160;    Add(buf);</div><div class="line"><a name="l04618"></a><span class="lineno"> 4618</span>&#160;}</div><div class="line"><a name="l04619"></a><span class="lineno"> 4619</span>&#160;</div><div class="line"><a name="l04620"></a><span class="lineno"> 4620</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::AddNumber(uint64_t num)</div><div class="line"><a name="l04621"></a><span class="lineno"> 4621</span>&#160;{</div><div class="line"><a name="l04622"></a><span class="lineno"> 4622</span>&#160;    <span class="keywordtype">char</span> buf[21];</div><div class="line"><a name="l04623"></a><span class="lineno"> 4623</span>&#160;    VmaUint64ToStr(buf, <span class="keyword">sizeof</span>(buf), num);</div><div class="line"><a name="l04624"></a><span class="lineno"> 4624</span>&#160;    Add(buf);</div><div class="line"><a name="l04625"></a><span class="lineno"> 4625</span>&#160;}</div><div class="line"><a name="l04626"></a><span class="lineno"> 4626</span>&#160;</div><div class="line"><a name="l04627"></a><span class="lineno"> 4627</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::AddPointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l04628"></a><span class="lineno"> 4628</span>&#160;{</div><div class="line"><a name="l04629"></a><span class="lineno"> 4629</span>&#160;    <span class="keywordtype">char</span> buf[21];</div><div class="line"><a name="l04630"></a><span class="lineno"> 4630</span>&#160;    VmaPtrToStr(buf, <span class="keyword">sizeof</span>(buf), ptr);</div><div class="line"><a name="l04631"></a><span class="lineno"> 4631</span>&#160;    Add(buf);</div><div class="line"><a name="l04632"></a><span class="lineno"> 4632</span>&#160;}</div><div class="line"><a name="l04633"></a><span class="lineno"> 4633</span>&#160;</div><div class="line"><a name="l04634"></a><span class="lineno"> 4634</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04635"></a><span class="lineno"> 4635</span>&#160;</div><div class="line"><a name="l04637"></a><span class="lineno"> 4637</span>&#160;<span class="comment">// VmaJsonWriter</span></div><div class="line"><a name="l04638"></a><span class="lineno"> 4638</span>&#160;</div><div class="line"><a name="l04639"></a><span class="lineno"> 4639</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04640"></a><span class="lineno"> 4640</span>&#160;</div><div class="line"><a name="l04641"></a><span class="lineno"> 4641</span>&#160;<span class="keyword">class </span>VmaJsonWriter</div><div class="line"><a name="l04642"></a><span class="lineno"> 4642</span>&#160;{</div><div class="line"><a name="l04643"></a><span class="lineno"> 4643</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04644"></a><span class="lineno"> 4644</span>&#160;    VmaJsonWriter(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder&amp; sb);</div><div class="line"><a name="l04645"></a><span class="lineno"> 4645</span>&#160;    ~VmaJsonWriter();</div><div class="line"><a name="l04646"></a><span class="lineno"> 4646</span>&#160;</div><div class="line"><a name="l04647"></a><span class="lineno"> 4647</span>&#160;    <span class="keywordtype">void</span> BeginObject(<span class="keywordtype">bool</span> singleLine = <span class="keyword">false</span>);</div><div class="line"><a name="l04648"></a><span class="lineno"> 4648</span>&#160;    <span class="keywordtype">void</span> EndObject();</div><div class="line"><a name="l04649"></a><span class="lineno"> 4649</span>&#160;    </div><div class="line"><a name="l04650"></a><span class="lineno"> 4650</span>&#160;    <span class="keywordtype">void</span> BeginArray(<span class="keywordtype">bool</span> singleLine = <span class="keyword">false</span>);</div><div class="line"><a name="l04651"></a><span class="lineno"> 4651</span>&#160;    <span class="keywordtype">void</span> EndArray();</div><div class="line"><a name="l04652"></a><span class="lineno"> 4652</span>&#160;    </div><div class="line"><a name="l04653"></a><span class="lineno"> 4653</span>&#160;    <span class="keywordtype">void</span> WriteString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr);</div><div class="line"><a name="l04654"></a><span class="lineno"> 4654</span>&#160;    <span class="keywordtype">void</span> BeginString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr = VMA_NULL);</div><div class="line"><a name="l04655"></a><span class="lineno"> 4655</span>&#160;    <span class="keywordtype">void</span> ContinueString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr);</div><div class="line"><a name="l04656"></a><span class="lineno"> 4656</span>&#160;    <span class="keywordtype">void</span> ContinueString(uint32_t n);</div><div class="line"><a name="l04657"></a><span class="lineno"> 4657</span>&#160;    <span class="keywordtype">void</span> ContinueString(uint64_t n);</div><div class="line"><a name="l04658"></a><span class="lineno"> 4658</span>&#160;    <span class="keywordtype">void</span> ContinueString_Pointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr);</div><div class="line"><a name="l04659"></a><span class="lineno"> 4659</span>&#160;    <span class="keywordtype">void</span> EndString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr = VMA_NULL);</div><div class="line"><a name="l04660"></a><span class="lineno"> 4660</span>&#160;    </div><div class="line"><a name="l04661"></a><span class="lineno"> 4661</span>&#160;    <span class="keywordtype">void</span> WriteNumber(uint32_t n);</div><div class="line"><a name="l04662"></a><span class="lineno"> 4662</span>&#160;    <span class="keywordtype">void</span> WriteNumber(uint64_t n);</div><div class="line"><a name="l04663"></a><span class="lineno"> 4663</span>&#160;    <span class="keywordtype">void</span> WriteBool(<span class="keywordtype">bool</span> b);</div><div class="line"><a name="l04664"></a><span class="lineno"> 4664</span>&#160;    <span class="keywordtype">void</span> WriteNull();</div><div class="line"><a name="l04665"></a><span class="lineno"> 4665</span>&#160;</div><div class="line"><a name="l04666"></a><span class="lineno"> 4666</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04667"></a><span class="lineno"> 4667</span>&#160;    <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span>* <span class="keyword">const</span> INDENT;</div><div class="line"><a name="l04668"></a><span class="lineno"> 4668</span>&#160;</div><div class="line"><a name="l04669"></a><span class="lineno"> 4669</span>&#160;    <span class="keyword">enum</span> COLLECTION_TYPE</div><div class="line"><a name="l04670"></a><span class="lineno"> 4670</span>&#160;    {</div><div class="line"><a name="l04671"></a><span class="lineno"> 4671</span>&#160;        COLLECTION_TYPE_OBJECT,</div><div class="line"><a name="l04672"></a><span class="lineno"> 4672</span>&#160;        COLLECTION_TYPE_ARRAY,</div><div class="line"><a name="l04673"></a><span class="lineno"> 4673</span>&#160;    };</div><div class="line"><a name="l04674"></a><span class="lineno"> 4674</span>&#160;    <span class="keyword">struct </span>StackItem</div><div class="line"><a name="l04675"></a><span class="lineno"> 4675</span>&#160;    {</div><div class="line"><a name="l04676"></a><span class="lineno"> 4676</span>&#160;        COLLECTION_TYPE type;</div><div class="line"><a name="l04677"></a><span class="lineno"> 4677</span>&#160;        uint32_t valueCount;</div><div class="line"><a name="l04678"></a><span class="lineno"> 4678</span>&#160;        <span class="keywordtype">bool</span> singleLineMode;</div><div class="line"><a name="l04679"></a><span class="lineno"> 4679</span>&#160;    };</div><div class="line"><a name="l04680"></a><span class="lineno"> 4680</span>&#160;</div><div class="line"><a name="l04681"></a><span class="lineno"> 4681</span>&#160;    VmaStringBuilder&amp; m_SB;</div><div class="line"><a name="l04682"></a><span class="lineno"> 4682</span>&#160;    VmaVector&lt; StackItem, VmaStlAllocator&lt;StackItem&gt; &gt; m_Stack;</div><div class="line"><a name="l04683"></a><span class="lineno"> 4683</span>&#160;    <span class="keywordtype">bool</span> m_InsideString;</div><div class="line"><a name="l04684"></a><span class="lineno"> 4684</span>&#160;</div><div class="line"><a name="l04685"></a><span class="lineno"> 4685</span>&#160;    <span class="keywordtype">void</span> BeginValue(<span class="keywordtype">bool</span> isString);</div><div class="line"><a name="l04686"></a><span class="lineno"> 4686</span>&#160;    <span class="keywordtype">void</span> WriteIndent(<span class="keywordtype">bool</span> oneLess = <span class="keyword">false</span>);</div><div class="line"><a name="l04687"></a><span class="lineno"> 4687</span>&#160;};</div><div class="line"><a name="l04688"></a><span class="lineno"> 4688</span>&#160;</div><div class="line"><a name="l04689"></a><span class="lineno"> 4689</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span>* <span class="keyword">const</span> VmaJsonWriter::INDENT = <span class="stringliteral">&quot;  &quot;</span>;</div><div class="line"><a name="l04690"></a><span class="lineno"> 4690</span>&#160;</div><div class="line"><a name="l04691"></a><span class="lineno"> 4691</span>&#160;VmaJsonWriter::VmaJsonWriter(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder&amp; sb) :</div><div class="line"><a name="l04692"></a><span class="lineno"> 4692</span>&#160;    m_SB(sb),</div><div class="line"><a name="l04693"></a><span class="lineno"> 4693</span>&#160;    m_Stack(VmaStlAllocator&lt;StackItem&gt;(pAllocationCallbacks)),</div><div class="line"><a name="l04694"></a><span class="lineno"> 4694</span>&#160;    m_InsideString(false)</div><div class="line"><a name="l04695"></a><span class="lineno"> 4695</span>&#160;{</div><div class="line"><a name="l04696"></a><span class="lineno"> 4696</span>&#160;}</div><div class="line"><a name="l04697"></a><span class="lineno"> 4697</span>&#160;</div><div class="line"><a name="l04698"></a><span class="lineno"> 4698</span>&#160;VmaJsonWriter::~VmaJsonWriter()</div><div class="line"><a name="l04699"></a><span class="lineno"> 4699</span>&#160;{</div><div class="line"><a name="l04700"></a><span class="lineno"> 4700</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04701"></a><span class="lineno"> 4701</span>&#160;    VMA_ASSERT(m_Stack.empty());</div><div class="line"><a name="l04702"></a><span class="lineno"> 4702</span>&#160;}</div><div class="line"><a name="l04703"></a><span class="lineno"> 4703</span>&#160;</div><div class="line"><a name="l04704"></a><span class="lineno"> 4704</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginObject(<span class="keywordtype">bool</span> singleLine)</div><div class="line"><a name="l04705"></a><span class="lineno"> 4705</span>&#160;{</div><div class="line"><a name="l04706"></a><span class="lineno"> 4706</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04707"></a><span class="lineno"> 4707</span>&#160;</div><div class="line"><a name="l04708"></a><span class="lineno"> 4708</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l04709"></a><span class="lineno"> 4709</span>&#160;    m_SB.Add(<span class="charliteral">&#39;{&#39;</span>);</div><div class="line"><a name="l04710"></a><span class="lineno"> 4710</span>&#160;</div><div class="line"><a name="l04711"></a><span class="lineno"> 4711</span>&#160;    StackItem item;</div><div class="line"><a name="l04712"></a><span class="lineno"> 4712</span>&#160;    item.type = COLLECTION_TYPE_OBJECT;</div><div class="line"><a name="l04713"></a><span class="lineno"> 4713</span>&#160;    item.valueCount = 0;</div><div class="line"><a name="l04714"></a><span class="lineno"> 4714</span>&#160;    item.singleLineMode = singleLine;</div><div class="line"><a name="l04715"></a><span class="lineno"> 4715</span>&#160;    m_Stack.push_back(item);</div><div class="line"><a name="l04716"></a><span class="lineno"> 4716</span>&#160;}</div><div class="line"><a name="l04717"></a><span class="lineno"> 4717</span>&#160;</div><div class="line"><a name="l04718"></a><span class="lineno"> 4718</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::EndObject()</div><div class="line"><a name="l04719"></a><span class="lineno"> 4719</span>&#160;{</div><div class="line"><a name="l04720"></a><span class="lineno"> 4720</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04721"></a><span class="lineno"> 4721</span>&#160;</div><div class="line"><a name="l04722"></a><span class="lineno"> 4722</span>&#160;    WriteIndent(<span class="keyword">true</span>);</div><div class="line"><a name="l04723"></a><span class="lineno"> 4723</span>&#160;    m_SB.Add(<span class="charliteral">&#39;}&#39;</span>);</div><div class="line"><a name="l04724"></a><span class="lineno"> 4724</span>&#160;</div><div class="line"><a name="l04725"></a><span class="lineno"> 4725</span>&#160;    VMA_ASSERT(!m_Stack.empty() &amp;&amp; m_Stack.back().type == COLLECTION_TYPE_OBJECT);</div><div class="line"><a name="l04726"></a><span class="lineno"> 4726</span>&#160;    m_Stack.pop_back();</div><div class="line"><a name="l04727"></a><span class="lineno"> 4727</span>&#160;}</div><div class="line"><a name="l04728"></a><span class="lineno"> 4728</span>&#160;</div><div class="line"><a name="l04729"></a><span class="lineno"> 4729</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginArray(<span class="keywordtype">bool</span> singleLine)</div><div class="line"><a name="l04730"></a><span class="lineno"> 4730</span>&#160;{</div><div class="line"><a name="l04731"></a><span class="lineno"> 4731</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04732"></a><span class="lineno"> 4732</span>&#160;</div><div class="line"><a name="l04733"></a><span class="lineno"> 4733</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l04734"></a><span class="lineno"> 4734</span>&#160;    m_SB.Add(<span class="charliteral">&#39;[&#39;</span>);</div><div class="line"><a name="l04735"></a><span class="lineno"> 4735</span>&#160;</div><div class="line"><a name="l04736"></a><span class="lineno"> 4736</span>&#160;    StackItem item;</div><div class="line"><a name="l04737"></a><span class="lineno"> 4737</span>&#160;    item.type = COLLECTION_TYPE_ARRAY;</div><div class="line"><a name="l04738"></a><span class="lineno"> 4738</span>&#160;    item.valueCount = 0;</div><div class="line"><a name="l04739"></a><span class="lineno"> 4739</span>&#160;    item.singleLineMode = singleLine;</div><div class="line"><a name="l04740"></a><span class="lineno"> 4740</span>&#160;    m_Stack.push_back(item);</div><div class="line"><a name="l04741"></a><span class="lineno"> 4741</span>&#160;}</div><div class="line"><a name="l04742"></a><span class="lineno"> 4742</span>&#160;</div><div class="line"><a name="l04743"></a><span class="lineno"> 4743</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::EndArray()</div><div class="line"><a name="l04744"></a><span class="lineno"> 4744</span>&#160;{</div><div class="line"><a name="l04745"></a><span class="lineno"> 4745</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04746"></a><span class="lineno"> 4746</span>&#160;</div><div class="line"><a name="l04747"></a><span class="lineno"> 4747</span>&#160;    WriteIndent(<span class="keyword">true</span>);</div><div class="line"><a name="l04748"></a><span class="lineno"> 4748</span>&#160;    m_SB.Add(<span class="charliteral">&#39;]&#39;</span>);</div><div class="line"><a name="l04749"></a><span class="lineno"> 4749</span>&#160;</div><div class="line"><a name="l04750"></a><span class="lineno"> 4750</span>&#160;    VMA_ASSERT(!m_Stack.empty() &amp;&amp; m_Stack.back().type == COLLECTION_TYPE_ARRAY);</div><div class="line"><a name="l04751"></a><span class="lineno"> 4751</span>&#160;    m_Stack.pop_back();</div><div class="line"><a name="l04752"></a><span class="lineno"> 4752</span>&#160;}</div><div class="line"><a name="l04753"></a><span class="lineno"> 4753</span>&#160;</div><div class="line"><a name="l04754"></a><span class="lineno"> 4754</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l04755"></a><span class="lineno"> 4755</span>&#160;{</div><div class="line"><a name="l04756"></a><span class="lineno"> 4756</span>&#160;    BeginString(pStr);</div><div class="line"><a name="l04757"></a><span class="lineno"> 4757</span>&#160;    EndString();</div><div class="line"><a name="l04758"></a><span class="lineno"> 4758</span>&#160;}</div><div class="line"><a name="l04759"></a><span class="lineno"> 4759</span>&#160;</div><div class="line"><a name="l04760"></a><span class="lineno"> 4760</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l04761"></a><span class="lineno"> 4761</span>&#160;{</div><div class="line"><a name="l04762"></a><span class="lineno"> 4762</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04763"></a><span class="lineno"> 4763</span>&#160;</div><div class="line"><a name="l04764"></a><span class="lineno"> 4764</span>&#160;    BeginValue(<span class="keyword">true</span>);</div><div class="line"><a name="l04765"></a><span class="lineno"> 4765</span>&#160;    m_SB.Add(<span class="charliteral">&#39;&quot;&#39;</span>);</div><div class="line"><a name="l04766"></a><span class="lineno"> 4766</span>&#160;    m_InsideString = <span class="keyword">true</span>;</div><div class="line"><a name="l04767"></a><span class="lineno"> 4767</span>&#160;    <span class="keywordflow">if</span>(pStr != VMA_NULL &amp;&amp; pStr[0] != <span class="charliteral">&#39;\0&#39;</span>)</div><div class="line"><a name="l04768"></a><span class="lineno"> 4768</span>&#160;    {</div><div class="line"><a name="l04769"></a><span class="lineno"> 4769</span>&#160;        ContinueString(pStr);</div><div class="line"><a name="l04770"></a><span class="lineno"> 4770</span>&#160;    }</div><div class="line"><a name="l04771"></a><span class="lineno"> 4771</span>&#160;}</div><div class="line"><a name="l04772"></a><span class="lineno"> 4772</span>&#160;</div><div class="line"><a name="l04773"></a><span class="lineno"> 4773</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l04774"></a><span class="lineno"> 4774</span>&#160;{</div><div class="line"><a name="l04775"></a><span class="lineno"> 4775</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l04776"></a><span class="lineno"> 4776</span>&#160;</div><div class="line"><a name="l04777"></a><span class="lineno"> 4777</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> strLen = strlen(pStr);</div><div class="line"><a name="l04778"></a><span class="lineno"> 4778</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; strLen; ++i)</div><div class="line"><a name="l04779"></a><span class="lineno"> 4779</span>&#160;    {</div><div class="line"><a name="l04780"></a><span class="lineno"> 4780</span>&#160;        <span class="keywordtype">char</span> ch = pStr[i];</div><div class="line"><a name="l04781"></a><span class="lineno"> 4781</span>&#160;        <span class="keywordflow">if</span>(ch == <span class="charliteral">&#39;\&#39;&#39;</span>)</div><div class="line"><a name="l04782"></a><span class="lineno"> 4782</span>&#160;        {</div><div class="line"><a name="l04783"></a><span class="lineno"> 4783</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\\\&quot;</span>);</div><div class="line"><a name="l04784"></a><span class="lineno"> 4784</span>&#160;        }</div><div class="line"><a name="l04785"></a><span class="lineno"> 4785</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(ch == <span class="charliteral">&#39;&quot;&#39;</span>)</div><div class="line"><a name="l04786"></a><span class="lineno"> 4786</span>&#160;        {</div><div class="line"><a name="l04787"></a><span class="lineno"> 4787</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\\&quot;&quot;</span>);</div><div class="line"><a name="l04788"></a><span class="lineno"> 4788</span>&#160;        }</div><div class="line"><a name="l04789"></a><span class="lineno"> 4789</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(ch &gt;= 32)</div><div class="line"><a name="l04790"></a><span class="lineno"> 4790</span>&#160;        {</div><div class="line"><a name="l04791"></a><span class="lineno"> 4791</span>&#160;            m_SB.Add(ch);</div><div class="line"><a name="l04792"></a><span class="lineno"> 4792</span>&#160;        }</div><div class="line"><a name="l04793"></a><span class="lineno"> 4793</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">switch</span>(ch)</div><div class="line"><a name="l04794"></a><span class="lineno"> 4794</span>&#160;        {</div><div class="line"><a name="l04795"></a><span class="lineno"> 4795</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\b&#39;</span>:</div><div class="line"><a name="l04796"></a><span class="lineno"> 4796</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\b&quot;</span>);</div><div class="line"><a name="l04797"></a><span class="lineno"> 4797</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l04798"></a><span class="lineno"> 4798</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\f&#39;</span>:</div><div class="line"><a name="l04799"></a><span class="lineno"> 4799</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\f&quot;</span>);</div><div class="line"><a name="l04800"></a><span class="lineno"> 4800</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l04801"></a><span class="lineno"> 4801</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\n&#39;</span>:</div><div class="line"><a name="l04802"></a><span class="lineno"> 4802</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\n&quot;</span>);</div><div class="line"><a name="l04803"></a><span class="lineno"> 4803</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l04804"></a><span class="lineno"> 4804</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\r&#39;</span>:</div><div class="line"><a name="l04805"></a><span class="lineno"> 4805</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\r&quot;</span>);</div><div class="line"><a name="l04806"></a><span class="lineno"> 4806</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l04807"></a><span class="lineno"> 4807</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\t&#39;</span>:</div><div class="line"><a name="l04808"></a><span class="lineno"> 4808</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\t&quot;</span>);</div><div class="line"><a name="l04809"></a><span class="lineno"> 4809</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l04810"></a><span class="lineno"> 4810</span>&#160;        <span class="keywordflow">default</span>:</div><div class="line"><a name="l04811"></a><span class="lineno"> 4811</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Character not currently supported.&quot;</span>);</div><div class="line"><a name="l04812"></a><span class="lineno"> 4812</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l04813"></a><span class="lineno"> 4813</span>&#160;        }</div><div class="line"><a name="l04814"></a><span class="lineno"> 4814</span>&#160;    }</div><div class="line"><a name="l04815"></a><span class="lineno"> 4815</span>&#160;}</div><div class="line"><a name="l04816"></a><span class="lineno"> 4816</span>&#160;</div><div class="line"><a name="l04817"></a><span class="lineno"> 4817</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString(uint32_t n)</div><div class="line"><a name="l04818"></a><span class="lineno"> 4818</span>&#160;{</div><div class="line"><a name="l04819"></a><span class="lineno"> 4819</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l04820"></a><span class="lineno"> 4820</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l04821"></a><span class="lineno"> 4821</span>&#160;}</div><div class="line"><a name="l04822"></a><span class="lineno"> 4822</span>&#160;</div><div class="line"><a name="l04823"></a><span class="lineno"> 4823</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString(uint64_t n)</div><div class="line"><a name="l04824"></a><span class="lineno"> 4824</span>&#160;{</div><div class="line"><a name="l04825"></a><span class="lineno"> 4825</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l04826"></a><span class="lineno"> 4826</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l04827"></a><span class="lineno"> 4827</span>&#160;}</div><div class="line"><a name="l04828"></a><span class="lineno"> 4828</span>&#160;</div><div class="line"><a name="l04829"></a><span class="lineno"> 4829</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString_Pointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l04830"></a><span class="lineno"> 4830</span>&#160;{</div><div class="line"><a name="l04831"></a><span class="lineno"> 4831</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l04832"></a><span class="lineno"> 4832</span>&#160;    m_SB.AddPointer(ptr);</div><div class="line"><a name="l04833"></a><span class="lineno"> 4833</span>&#160;}</div><div class="line"><a name="l04834"></a><span class="lineno"> 4834</span>&#160;</div><div class="line"><a name="l04835"></a><span class="lineno"> 4835</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::EndString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l04836"></a><span class="lineno"> 4836</span>&#160;{</div><div class="line"><a name="l04837"></a><span class="lineno"> 4837</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l04838"></a><span class="lineno"> 4838</span>&#160;    <span class="keywordflow">if</span>(pStr != VMA_NULL &amp;&amp; pStr[0] != <span class="charliteral">&#39;\0&#39;</span>)</div><div class="line"><a name="l04839"></a><span class="lineno"> 4839</span>&#160;    {</div><div class="line"><a name="l04840"></a><span class="lineno"> 4840</span>&#160;        ContinueString(pStr);</div><div class="line"><a name="l04841"></a><span class="lineno"> 4841</span>&#160;    }</div><div class="line"><a name="l04842"></a><span class="lineno"> 4842</span>&#160;    m_SB.Add(<span class="charliteral">&#39;&quot;&#39;</span>);</div><div class="line"><a name="l04843"></a><span class="lineno"> 4843</span>&#160;    m_InsideString = <span class="keyword">false</span>;</div><div class="line"><a name="l04844"></a><span class="lineno"> 4844</span>&#160;}</div><div class="line"><a name="l04845"></a><span class="lineno"> 4845</span>&#160;</div><div class="line"><a name="l04846"></a><span class="lineno"> 4846</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteNumber(uint32_t n)</div><div class="line"><a name="l04847"></a><span class="lineno"> 4847</span>&#160;{</div><div class="line"><a name="l04848"></a><span class="lineno"> 4848</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04849"></a><span class="lineno"> 4849</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l04850"></a><span class="lineno"> 4850</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l04851"></a><span class="lineno"> 4851</span>&#160;}</div><div class="line"><a name="l04852"></a><span class="lineno"> 4852</span>&#160;</div><div class="line"><a name="l04853"></a><span class="lineno"> 4853</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteNumber(uint64_t n)</div><div class="line"><a name="l04854"></a><span class="lineno"> 4854</span>&#160;{</div><div class="line"><a name="l04855"></a><span class="lineno"> 4855</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04856"></a><span class="lineno"> 4856</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l04857"></a><span class="lineno"> 4857</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l04858"></a><span class="lineno"> 4858</span>&#160;}</div><div class="line"><a name="l04859"></a><span class="lineno"> 4859</span>&#160;</div><div class="line"><a name="l04860"></a><span class="lineno"> 4860</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteBool(<span class="keywordtype">bool</span> b)</div><div class="line"><a name="l04861"></a><span class="lineno"> 4861</span>&#160;{</div><div class="line"><a name="l04862"></a><span class="lineno"> 4862</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04863"></a><span class="lineno"> 4863</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l04864"></a><span class="lineno"> 4864</span>&#160;    m_SB.Add(b ? <span class="stringliteral">&quot;true&quot;</span> : <span class="stringliteral">&quot;false&quot;</span>);</div><div class="line"><a name="l04865"></a><span class="lineno"> 4865</span>&#160;}</div><div class="line"><a name="l04866"></a><span class="lineno"> 4866</span>&#160;</div><div class="line"><a name="l04867"></a><span class="lineno"> 4867</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteNull()</div><div class="line"><a name="l04868"></a><span class="lineno"> 4868</span>&#160;{</div><div class="line"><a name="l04869"></a><span class="lineno"> 4869</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l04870"></a><span class="lineno"> 4870</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l04871"></a><span class="lineno"> 4871</span>&#160;    m_SB.Add(<span class="stringliteral">&quot;null&quot;</span>);</div><div class="line"><a name="l04872"></a><span class="lineno"> 4872</span>&#160;}</div><div class="line"><a name="l04873"></a><span class="lineno"> 4873</span>&#160;</div><div class="line"><a name="l04874"></a><span class="lineno"> 4874</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginValue(<span class="keywordtype">bool</span> isString)</div><div class="line"><a name="l04875"></a><span class="lineno"> 4875</span>&#160;{</div><div class="line"><a name="l04876"></a><span class="lineno"> 4876</span>&#160;    <span class="keywordflow">if</span>(!m_Stack.empty())</div><div class="line"><a name="l04877"></a><span class="lineno"> 4877</span>&#160;    {</div><div class="line"><a name="l04878"></a><span class="lineno"> 4878</span>&#160;        StackItem&amp; currItem = m_Stack.back();</div><div class="line"><a name="l04879"></a><span class="lineno"> 4879</span>&#160;        <span class="keywordflow">if</span>(currItem.type == COLLECTION_TYPE_OBJECT &amp;&amp;</div><div class="line"><a name="l04880"></a><span class="lineno"> 4880</span>&#160;            currItem.valueCount % 2 == 0)</div><div class="line"><a name="l04881"></a><span class="lineno"> 4881</span>&#160;        {</div><div class="line"><a name="l04882"></a><span class="lineno"> 4882</span>&#160;            VMA_ASSERT(isString);</div><div class="line"><a name="l04883"></a><span class="lineno"> 4883</span>&#160;        }</div><div class="line"><a name="l04884"></a><span class="lineno"> 4884</span>&#160;</div><div class="line"><a name="l04885"></a><span class="lineno"> 4885</span>&#160;        <span class="keywordflow">if</span>(currItem.type == COLLECTION_TYPE_OBJECT &amp;&amp;</div><div class="line"><a name="l04886"></a><span class="lineno"> 4886</span>&#160;            currItem.valueCount % 2 != 0)</div><div class="line"><a name="l04887"></a><span class="lineno"> 4887</span>&#160;        {</div><div class="line"><a name="l04888"></a><span class="lineno"> 4888</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;: &quot;</span>);</div><div class="line"><a name="l04889"></a><span class="lineno"> 4889</span>&#160;        }</div><div class="line"><a name="l04890"></a><span class="lineno"> 4890</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(currItem.valueCount &gt; 0)</div><div class="line"><a name="l04891"></a><span class="lineno"> 4891</span>&#160;        {</div><div class="line"><a name="l04892"></a><span class="lineno"> 4892</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;, &quot;</span>);</div><div class="line"><a name="l04893"></a><span class="lineno"> 4893</span>&#160;            WriteIndent();</div><div class="line"><a name="l04894"></a><span class="lineno"> 4894</span>&#160;        }</div><div class="line"><a name="l04895"></a><span class="lineno"> 4895</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l04896"></a><span class="lineno"> 4896</span>&#160;        {</div><div class="line"><a name="l04897"></a><span class="lineno"> 4897</span>&#160;            WriteIndent();</div><div class="line"><a name="l04898"></a><span class="lineno"> 4898</span>&#160;        }</div><div class="line"><a name="l04899"></a><span class="lineno"> 4899</span>&#160;        ++currItem.valueCount;</div><div class="line"><a name="l04900"></a><span class="lineno"> 4900</span>&#160;    }</div><div class="line"><a name="l04901"></a><span class="lineno"> 4901</span>&#160;}</div><div class="line"><a name="l04902"></a><span class="lineno"> 4902</span>&#160;</div><div class="line"><a name="l04903"></a><span class="lineno"> 4903</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteIndent(<span class="keywordtype">bool</span> oneLess)</div><div class="line"><a name="l04904"></a><span class="lineno"> 4904</span>&#160;{</div><div class="line"><a name="l04905"></a><span class="lineno"> 4905</span>&#160;    <span class="keywordflow">if</span>(!m_Stack.empty() &amp;&amp; !m_Stack.back().singleLineMode)</div><div class="line"><a name="l04906"></a><span class="lineno"> 4906</span>&#160;    {</div><div class="line"><a name="l04907"></a><span class="lineno"> 4907</span>&#160;        m_SB.AddNewLine();</div><div class="line"><a name="l04908"></a><span class="lineno"> 4908</span>&#160;        </div><div class="line"><a name="l04909"></a><span class="lineno"> 4909</span>&#160;        <span class="keywordtype">size_t</span> count = m_Stack.size();</div><div class="line"><a name="l04910"></a><span class="lineno"> 4910</span>&#160;        <span class="keywordflow">if</span>(count &gt; 0 &amp;&amp; oneLess)</div><div class="line"><a name="l04911"></a><span class="lineno"> 4911</span>&#160;        {</div><div class="line"><a name="l04912"></a><span class="lineno"> 4912</span>&#160;            --count;</div><div class="line"><a name="l04913"></a><span class="lineno"> 4913</span>&#160;        }</div><div class="line"><a name="l04914"></a><span class="lineno"> 4914</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; count; ++i)</div><div class="line"><a name="l04915"></a><span class="lineno"> 4915</span>&#160;        {</div><div class="line"><a name="l04916"></a><span class="lineno"> 4916</span>&#160;            m_SB.Add(INDENT);</div><div class="line"><a name="l04917"></a><span class="lineno"> 4917</span>&#160;        }</div><div class="line"><a name="l04918"></a><span class="lineno"> 4918</span>&#160;    }</div><div class="line"><a name="l04919"></a><span class="lineno"> 4919</span>&#160;}</div><div class="line"><a name="l04920"></a><span class="lineno"> 4920</span>&#160;</div><div class="line"><a name="l04921"></a><span class="lineno"> 4921</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04922"></a><span class="lineno"> 4922</span>&#160;</div><div class="line"><a name="l04924"></a><span class="lineno"> 4924</span>&#160;</div><div class="line"><a name="l04925"></a><span class="lineno"> 4925</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::SetUserData(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>* pUserData)</div><div class="line"><a name="l04926"></a><span class="lineno"> 4926</span>&#160;{</div><div class="line"><a name="l04927"></a><span class="lineno"> 4927</span>&#160;    <span class="keywordflow">if</span>(IsUserDataString())</div><div class="line"><a name="l04928"></a><span class="lineno"> 4928</span>&#160;    {</div><div class="line"><a name="l04929"></a><span class="lineno"> 4929</span>&#160;        VMA_ASSERT(pUserData == VMA_NULL || pUserData != m_pUserData);</div><div class="line"><a name="l04930"></a><span class="lineno"> 4930</span>&#160;</div><div class="line"><a name="l04931"></a><span class="lineno"> 4931</span>&#160;        FreeUserDataString(hAllocator);</div><div class="line"><a name="l04932"></a><span class="lineno"> 4932</span>&#160;</div><div class="line"><a name="l04933"></a><span class="lineno"> 4933</span>&#160;        <span class="keywordflow">if</span>(pUserData != VMA_NULL)</div><div class="line"><a name="l04934"></a><span class="lineno"> 4934</span>&#160;        {</div><div class="line"><a name="l04935"></a><span class="lineno"> 4935</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">char</span>* <span class="keyword">const</span> newStrSrc = (<span class="keywordtype">char</span>*)pUserData;</div><div class="line"><a name="l04936"></a><span class="lineno"> 4936</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> newStrLen = strlen(newStrSrc);</div><div class="line"><a name="l04937"></a><span class="lineno"> 4937</span>&#160;            <span class="keywordtype">char</span>* <span class="keyword">const</span> newStrDst = vma_new_array(hAllocator, <span class="keywordtype">char</span>, newStrLen + 1);</div><div class="line"><a name="l04938"></a><span class="lineno"> 4938</span>&#160;            memcpy(newStrDst, newStrSrc, newStrLen + 1);</div><div class="line"><a name="l04939"></a><span class="lineno"> 4939</span>&#160;            m_pUserData = newStrDst;</div><div class="line"><a name="l04940"></a><span class="lineno"> 4940</span>&#160;        }</div><div class="line"><a name="l04941"></a><span class="lineno"> 4941</span>&#160;    }</div><div class="line"><a name="l04942"></a><span class="lineno"> 4942</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l04943"></a><span class="lineno"> 4943</span>&#160;    {</div><div class="line"><a name="l04944"></a><span class="lineno"> 4944</span>&#160;        m_pUserData = pUserData;</div><div class="line"><a name="l04945"></a><span class="lineno"> 4945</span>&#160;    }</div><div class="line"><a name="l04946"></a><span class="lineno"> 4946</span>&#160;}</div><div class="line"><a name="l04947"></a><span class="lineno"> 4947</span>&#160;</div><div class="line"><a name="l04948"></a><span class="lineno"> 4948</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::ChangeBlockAllocation(</div><div class="line"><a name="l04949"></a><span class="lineno"> 4949</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04950"></a><span class="lineno"> 4950</span>&#160;    VmaDeviceMemoryBlock* block,</div><div class="line"><a name="l04951"></a><span class="lineno"> 4951</span>&#160;    VkDeviceSize offset)</div><div class="line"><a name="l04952"></a><span class="lineno"> 4952</span>&#160;{</div><div class="line"><a name="l04953"></a><span class="lineno"> 4953</span>&#160;    VMA_ASSERT(block != VMA_NULL);</div><div class="line"><a name="l04954"></a><span class="lineno"> 4954</span>&#160;    VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l04955"></a><span class="lineno"> 4955</span>&#160;</div><div class="line"><a name="l04956"></a><span class="lineno"> 4956</span>&#160;    <span class="comment">// Move mapping reference counter from old block to new block.</span></div><div class="line"><a name="l04957"></a><span class="lineno"> 4957</span>&#160;    <span class="keywordflow">if</span>(block != m_BlockAllocation.m_Block)</div><div class="line"><a name="l04958"></a><span class="lineno"> 4958</span>&#160;    {</div><div class="line"><a name="l04959"></a><span class="lineno"> 4959</span>&#160;        uint32_t mapRefCount = m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP;</div><div class="line"><a name="l04960"></a><span class="lineno"> 4960</span>&#160;        <span class="keywordflow">if</span>(IsPersistentMap())</div><div class="line"><a name="l04961"></a><span class="lineno"> 4961</span>&#160;            ++mapRefCount;</div><div class="line"><a name="l04962"></a><span class="lineno"> 4962</span>&#160;        m_BlockAllocation.m_Block-&gt;Unmap(hAllocator, mapRefCount);</div><div class="line"><a name="l04963"></a><span class="lineno"> 4963</span>&#160;        block-&gt;Map(hAllocator, mapRefCount, VMA_NULL);</div><div class="line"><a name="l04964"></a><span class="lineno"> 4964</span>&#160;    }</div><div class="line"><a name="l04965"></a><span class="lineno"> 4965</span>&#160;</div><div class="line"><a name="l04966"></a><span class="lineno"> 4966</span>&#160;    m_BlockAllocation.m_Block = block;</div><div class="line"><a name="l04967"></a><span class="lineno"> 4967</span>&#160;    m_BlockAllocation.m_Offset = offset;</div><div class="line"><a name="l04968"></a><span class="lineno"> 4968</span>&#160;}</div><div class="line"><a name="l04969"></a><span class="lineno"> 4969</span>&#160;</div><div class="line"><a name="l04970"></a><span class="lineno"> 4970</span>&#160;VkDeviceSize VmaAllocation_T::GetOffset()<span class="keyword"> const</span></div><div class="line"><a name="l04971"></a><span class="lineno"> 4971</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l04972"></a><span class="lineno"> 4972</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l04973"></a><span class="lineno"> 4973</span>&#160;    {</div><div class="line"><a name="l04974"></a><span class="lineno"> 4974</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l04975"></a><span class="lineno"> 4975</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Offset;</div><div class="line"><a name="l04976"></a><span class="lineno"> 4976</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l04977"></a><span class="lineno"> 4977</span>&#160;        <span class="keywordflow">return</span> 0;</div><div class="line"><a name="l04978"></a><span class="lineno"> 4978</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l04979"></a><span class="lineno"> 4979</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l04980"></a><span class="lineno"> 4980</span>&#160;        <span class="keywordflow">return</span> 0;</div><div class="line"><a name="l04981"></a><span class="lineno"> 4981</span>&#160;    }</div><div class="line"><a name="l04982"></a><span class="lineno"> 4982</span>&#160;}</div><div class="line"><a name="l04983"></a><span class="lineno"> 4983</span>&#160;</div><div class="line"><a name="l04984"></a><span class="lineno"> 4984</span>&#160;VkDeviceMemory VmaAllocation_T::GetMemory()<span class="keyword"> const</span></div><div class="line"><a name="l04985"></a><span class="lineno"> 4985</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l04986"></a><span class="lineno"> 4986</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l04987"></a><span class="lineno"> 4987</span>&#160;    {</div><div class="line"><a name="l04988"></a><span class="lineno"> 4988</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l04989"></a><span class="lineno"> 4989</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Block-&gt;GetDeviceMemory();</div><div class="line"><a name="l04990"></a><span class="lineno"> 4990</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l04991"></a><span class="lineno"> 4991</span>&#160;        <span class="keywordflow">return</span> m_DedicatedAllocation.m_hMemory;</div><div class="line"><a name="l04992"></a><span class="lineno"> 4992</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l04993"></a><span class="lineno"> 4993</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l04994"></a><span class="lineno"> 4994</span>&#160;        <span class="keywordflow">return</span> VK_NULL_HANDLE;</div><div class="line"><a name="l04995"></a><span class="lineno"> 4995</span>&#160;    }</div><div class="line"><a name="l04996"></a><span class="lineno"> 4996</span>&#160;}</div><div class="line"><a name="l04997"></a><span class="lineno"> 4997</span>&#160;</div><div class="line"><a name="l04998"></a><span class="lineno"> 4998</span>&#160;uint32_t VmaAllocation_T::GetMemoryTypeIndex()<span class="keyword"> const</span></div><div class="line"><a name="l04999"></a><span class="lineno"> 4999</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05000"></a><span class="lineno"> 5000</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l05001"></a><span class="lineno"> 5001</span>&#160;    {</div><div class="line"><a name="l05002"></a><span class="lineno"> 5002</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l05003"></a><span class="lineno"> 5003</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Block-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l05004"></a><span class="lineno"> 5004</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l05005"></a><span class="lineno"> 5005</span>&#160;        <span class="keywordflow">return</span> m_DedicatedAllocation.m_MemoryTypeIndex;</div><div class="line"><a name="l05006"></a><span class="lineno"> 5006</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l05007"></a><span class="lineno"> 5007</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l05008"></a><span class="lineno"> 5008</span>&#160;        <span class="keywordflow">return</span> UINT32_MAX;</div><div class="line"><a name="l05009"></a><span class="lineno"> 5009</span>&#160;    }</div><div class="line"><a name="l05010"></a><span class="lineno"> 5010</span>&#160;}</div><div class="line"><a name="l05011"></a><span class="lineno"> 5011</span>&#160;</div><div class="line"><a name="l05012"></a><span class="lineno"> 5012</span>&#160;<span class="keywordtype">void</span>* VmaAllocation_T::GetMappedData()<span class="keyword"> const</span></div><div class="line"><a name="l05013"></a><span class="lineno"> 5013</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05014"></a><span class="lineno"> 5014</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l05015"></a><span class="lineno"> 5015</span>&#160;    {</div><div class="line"><a name="l05016"></a><span class="lineno"> 5016</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l05017"></a><span class="lineno"> 5017</span>&#160;        <span class="keywordflow">if</span>(m_MapCount != 0)</div><div class="line"><a name="l05018"></a><span class="lineno"> 5018</span>&#160;        {</div><div class="line"><a name="l05019"></a><span class="lineno"> 5019</span>&#160;            <span class="keywordtype">void</span>* pBlockData = m_BlockAllocation.m_Block-&gt;GetMappedData();</div><div class="line"><a name="l05020"></a><span class="lineno"> 5020</span>&#160;            VMA_ASSERT(pBlockData != VMA_NULL);</div><div class="line"><a name="l05021"></a><span class="lineno"> 5021</span>&#160;            <span class="keywordflow">return</span> (<span class="keywordtype">char</span>*)pBlockData + m_BlockAllocation.m_Offset;</div><div class="line"><a name="l05022"></a><span class="lineno"> 5022</span>&#160;        }</div><div class="line"><a name="l05023"></a><span class="lineno"> 5023</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05024"></a><span class="lineno"> 5024</span>&#160;        {</div><div class="line"><a name="l05025"></a><span class="lineno"> 5025</span>&#160;            <span class="keywordflow">return</span> VMA_NULL;</div><div class="line"><a name="l05026"></a><span class="lineno"> 5026</span>&#160;        }</div><div class="line"><a name="l05027"></a><span class="lineno"> 5027</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l05028"></a><span class="lineno"> 5028</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l05029"></a><span class="lineno"> 5029</span>&#160;        VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0));</div><div class="line"><a name="l05030"></a><span class="lineno"> 5030</span>&#160;        <span class="keywordflow">return</span> m_DedicatedAllocation.m_pMappedData;</div><div class="line"><a name="l05031"></a><span class="lineno"> 5031</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l05032"></a><span class="lineno"> 5032</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l05033"></a><span class="lineno"> 5033</span>&#160;        <span class="keywordflow">return</span> VMA_NULL;</div><div class="line"><a name="l05034"></a><span class="lineno"> 5034</span>&#160;    }</div><div class="line"><a name="l05035"></a><span class="lineno"> 5035</span>&#160;}</div><div class="line"><a name="l05036"></a><span class="lineno"> 5036</span>&#160;</div><div class="line"><a name="l05037"></a><span class="lineno"> 5037</span>&#160;<span class="keywordtype">bool</span> VmaAllocation_T::CanBecomeLost()<span class="keyword"> const</span></div><div class="line"><a name="l05038"></a><span class="lineno"> 5038</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05039"></a><span class="lineno"> 5039</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l05040"></a><span class="lineno"> 5040</span>&#160;    {</div><div class="line"><a name="l05041"></a><span class="lineno"> 5041</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l05042"></a><span class="lineno"> 5042</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_CanBecomeLost;</div><div class="line"><a name="l05043"></a><span class="lineno"> 5043</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l05044"></a><span class="lineno"> 5044</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05045"></a><span class="lineno"> 5045</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l05046"></a><span class="lineno"> 5046</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l05047"></a><span class="lineno"> 5047</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05048"></a><span class="lineno"> 5048</span>&#160;    }</div><div class="line"><a name="l05049"></a><span class="lineno"> 5049</span>&#160;}</div><div class="line"><a name="l05050"></a><span class="lineno"> 5050</span>&#160;</div><div class="line"><a name="l05051"></a><span class="lineno"> 5051</span>&#160;<a class="code" href="struct_vma_pool.html">VmaPool</a> VmaAllocation_T::GetPool()<span class="keyword"> const</span></div><div class="line"><a name="l05052"></a><span class="lineno"> 5052</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05053"></a><span class="lineno"> 5053</span>&#160;    VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l05054"></a><span class="lineno"> 5054</span>&#160;    <span class="keywordflow">return</span> m_BlockAllocation.m_hPool;</div><div class="line"><a name="l05055"></a><span class="lineno"> 5055</span>&#160;}</div><div class="line"><a name="l05056"></a><span class="lineno"> 5056</span>&#160;</div><div class="line"><a name="l05057"></a><span class="lineno"> 5057</span>&#160;<span class="keywordtype">bool</span> VmaAllocation_T::MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)</div><div class="line"><a name="l05058"></a><span class="lineno"> 5058</span>&#160;{</div><div class="line"><a name="l05059"></a><span class="lineno"> 5059</span>&#160;    VMA_ASSERT(CanBecomeLost());</div><div class="line"><a name="l05060"></a><span class="lineno"> 5060</span>&#160;</div><div class="line"><a name="l05061"></a><span class="lineno"> 5061</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l05062"></a><span class="lineno"> 5062</span>&#160;<span class="comment">    Warning: This is a carefully designed algorithm.</span></div><div class="line"><a name="l05063"></a><span class="lineno"> 5063</span>&#160;<span class="comment">    Do not modify unless you really know what you&#39;re doing :)</span></div><div class="line"><a name="l05064"></a><span class="lineno"> 5064</span>&#160;<span class="comment">    */</span></div><div class="line"><a name="l05065"></a><span class="lineno"> 5065</span>&#160;    uint32_t localLastUseFrameIndex = GetLastUseFrameIndex();</div><div class="line"><a name="l05066"></a><span class="lineno"> 5066</span>&#160;    <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l05067"></a><span class="lineno"> 5067</span>&#160;    {</div><div class="line"><a name="l05068"></a><span class="lineno"> 5068</span>&#160;        <span class="keywordflow">if</span>(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l05069"></a><span class="lineno"> 5069</span>&#160;        {</div><div class="line"><a name="l05070"></a><span class="lineno"> 5070</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l05071"></a><span class="lineno"> 5071</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05072"></a><span class="lineno"> 5072</span>&#160;        }</div><div class="line"><a name="l05073"></a><span class="lineno"> 5073</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(localLastUseFrameIndex + frameInUseCount &gt;= currentFrameIndex)</div><div class="line"><a name="l05074"></a><span class="lineno"> 5074</span>&#160;        {</div><div class="line"><a name="l05075"></a><span class="lineno"> 5075</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05076"></a><span class="lineno"> 5076</span>&#160;        }</div><div class="line"><a name="l05077"></a><span class="lineno"> 5077</span>&#160;        <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l05078"></a><span class="lineno"> 5078</span>&#160;        {</div><div class="line"><a name="l05079"></a><span class="lineno"> 5079</span>&#160;            <span class="keywordflow">if</span>(CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, VMA_FRAME_INDEX_LOST))</div><div class="line"><a name="l05080"></a><span class="lineno"> 5080</span>&#160;            {</div><div class="line"><a name="l05081"></a><span class="lineno"> 5081</span>&#160;                <span class="comment">// Setting hAllocation.LastUseFrameIndex atomic to VMA_FRAME_INDEX_LOST is enough to mark it as LOST.</span></div><div class="line"><a name="l05082"></a><span class="lineno"> 5082</span>&#160;                <span class="comment">// Calling code just needs to unregister this allocation in owning VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l05083"></a><span class="lineno"> 5083</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05084"></a><span class="lineno"> 5084</span>&#160;            }</div><div class="line"><a name="l05085"></a><span class="lineno"> 5085</span>&#160;        }</div><div class="line"><a name="l05086"></a><span class="lineno"> 5086</span>&#160;    }</div><div class="line"><a name="l05087"></a><span class="lineno"> 5087</span>&#160;}</div><div class="line"><a name="l05088"></a><span class="lineno"> 5088</span>&#160;</div><div class="line"><a name="l05089"></a><span class="lineno"> 5089</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::FreeUserDataString(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l05090"></a><span class="lineno"> 5090</span>&#160;{</div><div class="line"><a name="l05091"></a><span class="lineno"> 5091</span>&#160;    VMA_ASSERT(IsUserDataString());</div><div class="line"><a name="l05092"></a><span class="lineno"> 5092</span>&#160;    <span class="keywordflow">if</span>(m_pUserData != VMA_NULL)</div><div class="line"><a name="l05093"></a><span class="lineno"> 5093</span>&#160;    {</div><div class="line"><a name="l05094"></a><span class="lineno"> 5094</span>&#160;        <span class="keywordtype">char</span>* <span class="keyword">const</span> oldStr = (<span class="keywordtype">char</span>*)m_pUserData;</div><div class="line"><a name="l05095"></a><span class="lineno"> 5095</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldStrLen = strlen(oldStr);</div><div class="line"><a name="l05096"></a><span class="lineno"> 5096</span>&#160;        vma_delete_array(hAllocator, oldStr, oldStrLen + 1);</div><div class="line"><a name="l05097"></a><span class="lineno"> 5097</span>&#160;        m_pUserData = VMA_NULL;</div><div class="line"><a name="l05098"></a><span class="lineno"> 5098</span>&#160;    }</div><div class="line"><a name="l05099"></a><span class="lineno"> 5099</span>&#160;}</div><div class="line"><a name="l05100"></a><span class="lineno"> 5100</span>&#160;</div><div class="line"><a name="l05101"></a><span class="lineno"> 5101</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::BlockAllocMap()</div><div class="line"><a name="l05102"></a><span class="lineno"> 5102</span>&#160;{</div><div class="line"><a name="l05103"></a><span class="lineno"> 5103</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l05104"></a><span class="lineno"> 5104</span>&#160;</div><div class="line"><a name="l05105"></a><span class="lineno"> 5105</span>&#160;    <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) &lt; 0x7F)</div><div class="line"><a name="l05106"></a><span class="lineno"> 5106</span>&#160;    {</div><div class="line"><a name="l05107"></a><span class="lineno"> 5107</span>&#160;        ++m_MapCount;</div><div class="line"><a name="l05108"></a><span class="lineno"> 5108</span>&#160;    }</div><div class="line"><a name="l05109"></a><span class="lineno"> 5109</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l05110"></a><span class="lineno"> 5110</span>&#160;    {</div><div class="line"><a name="l05111"></a><span class="lineno"> 5111</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Allocation mapped too many times simultaneously.&quot;</span>);</div><div class="line"><a name="l05112"></a><span class="lineno"> 5112</span>&#160;    }</div><div class="line"><a name="l05113"></a><span class="lineno"> 5113</span>&#160;}</div><div class="line"><a name="l05114"></a><span class="lineno"> 5114</span>&#160;</div><div class="line"><a name="l05115"></a><span class="lineno"> 5115</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::BlockAllocUnmap()</div><div class="line"><a name="l05116"></a><span class="lineno"> 5116</span>&#160;{</div><div class="line"><a name="l05117"></a><span class="lineno"> 5117</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l05118"></a><span class="lineno"> 5118</span>&#160;</div><div class="line"><a name="l05119"></a><span class="lineno"> 5119</span>&#160;    <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) != 0)</div><div class="line"><a name="l05120"></a><span class="lineno"> 5120</span>&#160;    {</div><div class="line"><a name="l05121"></a><span class="lineno"> 5121</span>&#160;        --m_MapCount;</div><div class="line"><a name="l05122"></a><span class="lineno"> 5122</span>&#160;    }</div><div class="line"><a name="l05123"></a><span class="lineno"> 5123</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l05124"></a><span class="lineno"> 5124</span>&#160;    {</div><div class="line"><a name="l05125"></a><span class="lineno"> 5125</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Unmapping allocation not previously mapped.&quot;</span>);</div><div class="line"><a name="l05126"></a><span class="lineno"> 5126</span>&#160;    }</div><div class="line"><a name="l05127"></a><span class="lineno"> 5127</span>&#160;}</div><div class="line"><a name="l05128"></a><span class="lineno"> 5128</span>&#160;</div><div class="line"><a name="l05129"></a><span class="lineno"> 5129</span>&#160;VkResult VmaAllocation_T::DedicatedAllocMap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l05130"></a><span class="lineno"> 5130</span>&#160;{</div><div class="line"><a name="l05131"></a><span class="lineno"> 5131</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l05132"></a><span class="lineno"> 5132</span>&#160;</div><div class="line"><a name="l05133"></a><span class="lineno"> 5133</span>&#160;    <span class="keywordflow">if</span>(m_MapCount != 0)</div><div class="line"><a name="l05134"></a><span class="lineno"> 5134</span>&#160;    {</div><div class="line"><a name="l05135"></a><span class="lineno"> 5135</span>&#160;        <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) &lt; 0x7F)</div><div class="line"><a name="l05136"></a><span class="lineno"> 5136</span>&#160;        {</div><div class="line"><a name="l05137"></a><span class="lineno"> 5137</span>&#160;            VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL);</div><div class="line"><a name="l05138"></a><span class="lineno"> 5138</span>&#160;            *ppData = m_DedicatedAllocation.m_pMappedData;</div><div class="line"><a name="l05139"></a><span class="lineno"> 5139</span>&#160;            ++m_MapCount;</div><div class="line"><a name="l05140"></a><span class="lineno"> 5140</span>&#160;            <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l05141"></a><span class="lineno"> 5141</span>&#160;        }</div><div class="line"><a name="l05142"></a><span class="lineno"> 5142</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05143"></a><span class="lineno"> 5143</span>&#160;        {</div><div class="line"><a name="l05144"></a><span class="lineno"> 5144</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Dedicated allocation mapped too many times simultaneously.&quot;</span>);</div><div class="line"><a name="l05145"></a><span class="lineno"> 5145</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_MEMORY_MAP_FAILED;</div><div class="line"><a name="l05146"></a><span class="lineno"> 5146</span>&#160;        }</div><div class="line"><a name="l05147"></a><span class="lineno"> 5147</span>&#160;    }</div><div class="line"><a name="l05148"></a><span class="lineno"> 5148</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l05149"></a><span class="lineno"> 5149</span>&#160;    {</div><div class="line"><a name="l05150"></a><span class="lineno"> 5150</span>&#160;        VkResult result = (*hAllocator-&gt;GetVulkanFunctions().vkMapMemory)(</div><div class="line"><a name="l05151"></a><span class="lineno"> 5151</span>&#160;            hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l05152"></a><span class="lineno"> 5152</span>&#160;            m_DedicatedAllocation.m_hMemory,</div><div class="line"><a name="l05153"></a><span class="lineno"> 5153</span>&#160;            0, <span class="comment">// offset</span></div><div class="line"><a name="l05154"></a><span class="lineno"> 5154</span>&#160;            VK_WHOLE_SIZE,</div><div class="line"><a name="l05155"></a><span class="lineno"> 5155</span>&#160;            0, <span class="comment">// flags</span></div><div class="line"><a name="l05156"></a><span class="lineno"> 5156</span>&#160;            ppData);</div><div class="line"><a name="l05157"></a><span class="lineno"> 5157</span>&#160;        <span class="keywordflow">if</span>(result == VK_SUCCESS)</div><div class="line"><a name="l05158"></a><span class="lineno"> 5158</span>&#160;        {</div><div class="line"><a name="l05159"></a><span class="lineno"> 5159</span>&#160;            m_DedicatedAllocation.m_pMappedData = *ppData;</div><div class="line"><a name="l05160"></a><span class="lineno"> 5160</span>&#160;            m_MapCount = 1;</div><div class="line"><a name="l05161"></a><span class="lineno"> 5161</span>&#160;        }</div><div class="line"><a name="l05162"></a><span class="lineno"> 5162</span>&#160;        <span class="keywordflow">return</span> result;</div><div class="line"><a name="l05163"></a><span class="lineno"> 5163</span>&#160;    }</div><div class="line"><a name="l05164"></a><span class="lineno"> 5164</span>&#160;}</div><div class="line"><a name="l05165"></a><span class="lineno"> 5165</span>&#160;</div><div class="line"><a name="l05166"></a><span class="lineno"> 5166</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::DedicatedAllocUnmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l05167"></a><span class="lineno"> 5167</span>&#160;{</div><div class="line"><a name="l05168"></a><span class="lineno"> 5168</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l05169"></a><span class="lineno"> 5169</span>&#160;</div><div class="line"><a name="l05170"></a><span class="lineno"> 5170</span>&#160;    <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) != 0)</div><div class="line"><a name="l05171"></a><span class="lineno"> 5171</span>&#160;    {</div><div class="line"><a name="l05172"></a><span class="lineno"> 5172</span>&#160;        --m_MapCount;</div><div class="line"><a name="l05173"></a><span class="lineno"> 5173</span>&#160;        <span class="keywordflow">if</span>(m_MapCount == 0)</div><div class="line"><a name="l05174"></a><span class="lineno"> 5174</span>&#160;        {</div><div class="line"><a name="l05175"></a><span class="lineno"> 5175</span>&#160;            m_DedicatedAllocation.m_pMappedData = VMA_NULL;</div><div class="line"><a name="l05176"></a><span class="lineno"> 5176</span>&#160;            (*hAllocator-&gt;GetVulkanFunctions().vkUnmapMemory)(</div><div class="line"><a name="l05177"></a><span class="lineno"> 5177</span>&#160;                hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l05178"></a><span class="lineno"> 5178</span>&#160;                m_DedicatedAllocation.m_hMemory);</div><div class="line"><a name="l05179"></a><span class="lineno"> 5179</span>&#160;        }</div><div class="line"><a name="l05180"></a><span class="lineno"> 5180</span>&#160;    }</div><div class="line"><a name="l05181"></a><span class="lineno"> 5181</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l05182"></a><span class="lineno"> 5182</span>&#160;    {</div><div class="line"><a name="l05183"></a><span class="lineno"> 5183</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Unmapping dedicated allocation not previously mapped.&quot;</span>);</div><div class="line"><a name="l05184"></a><span class="lineno"> 5184</span>&#160;    }</div><div class="line"><a name="l05185"></a><span class="lineno"> 5185</span>&#160;}</div><div class="line"><a name="l05186"></a><span class="lineno"> 5186</span>&#160;</div><div class="line"><a name="l05187"></a><span class="lineno"> 5187</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05188"></a><span class="lineno"> 5188</span>&#160;</div><div class="line"><a name="l05189"></a><span class="lineno"> 5189</span>&#160;<span class="comment">// Correspond to values of enum VmaSuballocationType.</span></div><div class="line"><a name="l05190"></a><span class="lineno"> 5190</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span>* VMA_SUBALLOCATION_TYPE_NAMES[] = {</div><div class="line"><a name="l05191"></a><span class="lineno"> 5191</span>&#160;    <span class="stringliteral">&quot;FREE&quot;</span>,</div><div class="line"><a name="l05192"></a><span class="lineno"> 5192</span>&#160;    <span class="stringliteral">&quot;UNKNOWN&quot;</span>,</div><div class="line"><a name="l05193"></a><span class="lineno"> 5193</span>&#160;    <span class="stringliteral">&quot;BUFFER&quot;</span>,</div><div class="line"><a name="l05194"></a><span class="lineno"> 5194</span>&#160;    <span class="stringliteral">&quot;IMAGE_UNKNOWN&quot;</span>,</div><div class="line"><a name="l05195"></a><span class="lineno"> 5195</span>&#160;    <span class="stringliteral">&quot;IMAGE_LINEAR&quot;</span>,</div><div class="line"><a name="l05196"></a><span class="lineno"> 5196</span>&#160;    <span class="stringliteral">&quot;IMAGE_OPTIMAL&quot;</span>,</div><div class="line"><a name="l05197"></a><span class="lineno"> 5197</span>&#160;};</div><div class="line"><a name="l05198"></a><span class="lineno"> 5198</span>&#160;</div><div class="line"><a name="l05199"></a><span class="lineno"> 5199</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaPrintStatInfo(VmaJsonWriter&amp; json, <span class="keyword">const</span> <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; stat)</div><div class="line"><a name="l05200"></a><span class="lineno"> 5200</span>&#160;{</div><div class="line"><a name="l05201"></a><span class="lineno"> 5201</span>&#160;    json.BeginObject();</div><div class="line"><a name="l05202"></a><span class="lineno"> 5202</span>&#160;</div><div class="line"><a name="l05203"></a><span class="lineno"> 5203</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Blocks&quot;</span>);</div><div class="line"><a name="l05204"></a><span class="lineno"> 5204</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a>);</div><div class="line"><a name="l05205"></a><span class="lineno"> 5205</span>&#160;</div><div class="line"><a name="l05206"></a><span class="lineno"> 5206</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Allocations&quot;</span>);</div><div class="line"><a name="l05207"></a><span class="lineno"> 5207</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>);</div><div class="line"><a name="l05208"></a><span class="lineno"> 5208</span>&#160;</div><div class="line"><a name="l05209"></a><span class="lineno"> 5209</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedRanges&quot;</span>);</div><div class="line"><a name="l05210"></a><span class="lineno"> 5210</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>);</div><div class="line"><a name="l05211"></a><span class="lineno"> 5211</span>&#160;</div><div class="line"><a name="l05212"></a><span class="lineno"> 5212</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UsedBytes&quot;</span>);</div><div class="line"><a name="l05213"></a><span class="lineno"> 5213</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>);</div><div class="line"><a name="l05214"></a><span class="lineno"> 5214</span>&#160;</div><div class="line"><a name="l05215"></a><span class="lineno"> 5215</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedBytes&quot;</span>);</div><div class="line"><a name="l05216"></a><span class="lineno"> 5216</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>);</div><div class="line"><a name="l05217"></a><span class="lineno"> 5217</span>&#160;</div><div class="line"><a name="l05218"></a><span class="lineno"> 5218</span>&#160;    <span class="keywordflow">if</span>(stat.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> &gt; 1)</div><div class="line"><a name="l05219"></a><span class="lineno"> 5219</span>&#160;    {</div><div class="line"><a name="l05220"></a><span class="lineno"> 5220</span>&#160;        json.WriteString(<span class="stringliteral">&quot;AllocationSize&quot;</span>);</div><div class="line"><a name="l05221"></a><span class="lineno"> 5221</span>&#160;        json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l05222"></a><span class="lineno"> 5222</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Min&quot;</span>);</div><div class="line"><a name="l05223"></a><span class="lineno"> 5223</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>);</div><div class="line"><a name="l05224"></a><span class="lineno"> 5224</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Avg&quot;</span>);</div><div class="line"><a name="l05225"></a><span class="lineno"> 5225</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a1081a039964e566c672e7a2347f9e599">allocationSizeAvg</a>);</div><div class="line"><a name="l05226"></a><span class="lineno"> 5226</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Max&quot;</span>);</div><div class="line"><a name="l05227"></a><span class="lineno"> 5227</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>);</div><div class="line"><a name="l05228"></a><span class="lineno"> 5228</span>&#160;        json.EndObject();</div><div class="line"><a name="l05229"></a><span class="lineno"> 5229</span>&#160;    }</div><div class="line"><a name="l05230"></a><span class="lineno"> 5230</span>&#160;</div><div class="line"><a name="l05231"></a><span class="lineno"> 5231</span>&#160;    <span class="keywordflow">if</span>(stat.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> &gt; 1)</div><div class="line"><a name="l05232"></a><span class="lineno"> 5232</span>&#160;    {</div><div class="line"><a name="l05233"></a><span class="lineno"> 5233</span>&#160;        json.WriteString(<span class="stringliteral">&quot;UnusedRangeSize&quot;</span>);</div><div class="line"><a name="l05234"></a><span class="lineno"> 5234</span>&#160;        json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l05235"></a><span class="lineno"> 5235</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Min&quot;</span>);</div><div class="line"><a name="l05236"></a><span class="lineno"> 5236</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>);</div><div class="line"><a name="l05237"></a><span class="lineno"> 5237</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Avg&quot;</span>);</div><div class="line"><a name="l05238"></a><span class="lineno"> 5238</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a2f9b3452af90c9768a30b7fb6ae194fc">unusedRangeSizeAvg</a>);</div><div class="line"><a name="l05239"></a><span class="lineno"> 5239</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Max&quot;</span>);</div><div class="line"><a name="l05240"></a><span class="lineno"> 5240</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>);</div><div class="line"><a name="l05241"></a><span class="lineno"> 5241</span>&#160;        json.EndObject();</div><div class="line"><a name="l05242"></a><span class="lineno"> 5242</span>&#160;    }</div><div class="line"><a name="l05243"></a><span class="lineno"> 5243</span>&#160;</div><div class="line"><a name="l05244"></a><span class="lineno"> 5244</span>&#160;    json.EndObject();</div><div class="line"><a name="l05245"></a><span class="lineno"> 5245</span>&#160;}</div><div class="line"><a name="l05246"></a><span class="lineno"> 5246</span>&#160;</div><div class="line"><a name="l05247"></a><span class="lineno"> 5247</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05248"></a><span class="lineno"> 5248</span>&#160;</div><div class="line"><a name="l05249"></a><span class="lineno"> 5249</span>&#160;<span class="keyword">struct </span>VmaSuballocationItemSizeLess</div><div class="line"><a name="l05250"></a><span class="lineno"> 5250</span>&#160;{</div><div class="line"><a name="l05251"></a><span class="lineno"> 5251</span>&#160;    <span class="keywordtype">bool</span> operator()(</div><div class="line"><a name="l05252"></a><span class="lineno"> 5252</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator lhs,</div><div class="line"><a name="l05253"></a><span class="lineno"> 5253</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator rhs)<span class="keyword"> const</span></div><div class="line"><a name="l05254"></a><span class="lineno"> 5254</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05255"></a><span class="lineno"> 5255</span>&#160;        <span class="keywordflow">return</span> lhs-&gt;size &lt; rhs-&gt;size;</div><div class="line"><a name="l05256"></a><span class="lineno"> 5256</span>&#160;    }</div><div class="line"><a name="l05257"></a><span class="lineno"> 5257</span>&#160;    <span class="keywordtype">bool</span> operator()(</div><div class="line"><a name="l05258"></a><span class="lineno"> 5258</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator lhs,</div><div class="line"><a name="l05259"></a><span class="lineno"> 5259</span>&#160;        VkDeviceSize rhsSize)<span class="keyword"> const</span></div><div class="line"><a name="l05260"></a><span class="lineno"> 5260</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05261"></a><span class="lineno"> 5261</span>&#160;        <span class="keywordflow">return</span> lhs-&gt;size &lt; rhsSize;</div><div class="line"><a name="l05262"></a><span class="lineno"> 5262</span>&#160;    }</div><div class="line"><a name="l05263"></a><span class="lineno"> 5263</span>&#160;};</div><div class="line"><a name="l05264"></a><span class="lineno"> 5264</span>&#160;</div><div class="line"><a name="l05266"></a><span class="lineno"> 5266</span>&#160;<span class="comment">// class VmaBlockMetadata</span></div><div class="line"><a name="l05267"></a><span class="lineno"> 5267</span>&#160;</div><div class="line"><a name="l05268"></a><span class="lineno"> 5268</span>&#160;VmaBlockMetadata::VmaBlockMetadata(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator) :</div><div class="line"><a name="l05269"></a><span class="lineno"> 5269</span>&#160;    m_Size(0),</div><div class="line"><a name="l05270"></a><span class="lineno"> 5270</span>&#160;    m_FreeCount(0),</div><div class="line"><a name="l05271"></a><span class="lineno"> 5271</span>&#160;    m_SumFreeSize(0),</div><div class="line"><a name="l05272"></a><span class="lineno"> 5272</span>&#160;    m_Suballocations(VmaStlAllocator&lt;VmaSuballocation&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l05273"></a><span class="lineno"> 5273</span>&#160;    m_FreeSuballocationsBySize(VmaStlAllocator&lt;VmaSuballocationList::iterator&gt;(hAllocator-&gt;GetAllocationCallbacks()))</div><div class="line"><a name="l05274"></a><span class="lineno"> 5274</span>&#160;{</div><div class="line"><a name="l05275"></a><span class="lineno"> 5275</span>&#160;}</div><div class="line"><a name="l05276"></a><span class="lineno"> 5276</span>&#160;</div><div class="line"><a name="l05277"></a><span class="lineno"> 5277</span>&#160;VmaBlockMetadata::~VmaBlockMetadata()</div><div class="line"><a name="l05278"></a><span class="lineno"> 5278</span>&#160;{</div><div class="line"><a name="l05279"></a><span class="lineno"> 5279</span>&#160;}</div><div class="line"><a name="l05280"></a><span class="lineno"> 5280</span>&#160;</div><div class="line"><a name="l05281"></a><span class="lineno"> 5281</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::Init(VkDeviceSize size)</div><div class="line"><a name="l05282"></a><span class="lineno"> 5282</span>&#160;{</div><div class="line"><a name="l05283"></a><span class="lineno"> 5283</span>&#160;    m_Size = size;</div><div class="line"><a name="l05284"></a><span class="lineno"> 5284</span>&#160;    m_FreeCount = 1;</div><div class="line"><a name="l05285"></a><span class="lineno"> 5285</span>&#160;    m_SumFreeSize = size;</div><div class="line"><a name="l05286"></a><span class="lineno"> 5286</span>&#160;</div><div class="line"><a name="l05287"></a><span class="lineno"> 5287</span>&#160;    VmaSuballocation suballoc = {};</div><div class="line"><a name="l05288"></a><span class="lineno"> 5288</span>&#160;    suballoc.offset = 0;</div><div class="line"><a name="l05289"></a><span class="lineno"> 5289</span>&#160;    suballoc.size = size;</div><div class="line"><a name="l05290"></a><span class="lineno"> 5290</span>&#160;    suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l05291"></a><span class="lineno"> 5291</span>&#160;    suballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l05292"></a><span class="lineno"> 5292</span>&#160;</div><div class="line"><a name="l05293"></a><span class="lineno"> 5293</span>&#160;    m_Suballocations.push_back(suballoc);</div><div class="line"><a name="l05294"></a><span class="lineno"> 5294</span>&#160;    VmaSuballocationList::iterator suballocItem = m_Suballocations.end();</div><div class="line"><a name="l05295"></a><span class="lineno"> 5295</span>&#160;    --suballocItem;</div><div class="line"><a name="l05296"></a><span class="lineno"> 5296</span>&#160;    m_FreeSuballocationsBySize.push_back(suballocItem);</div><div class="line"><a name="l05297"></a><span class="lineno"> 5297</span>&#160;}</div><div class="line"><a name="l05298"></a><span class="lineno"> 5298</span>&#160;</div><div class="line"><a name="l05299"></a><span class="lineno"> 5299</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata::Validate()<span class="keyword"> const</span></div><div class="line"><a name="l05300"></a><span class="lineno"> 5300</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05301"></a><span class="lineno"> 5301</span>&#160;    <span class="keywordflow">if</span>(m_Suballocations.empty())</div><div class="line"><a name="l05302"></a><span class="lineno"> 5302</span>&#160;    {</div><div class="line"><a name="l05303"></a><span class="lineno"> 5303</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05304"></a><span class="lineno"> 5304</span>&#160;    }</div><div class="line"><a name="l05305"></a><span class="lineno"> 5305</span>&#160;    </div><div class="line"><a name="l05306"></a><span class="lineno"> 5306</span>&#160;    <span class="comment">// Expected offset of new suballocation as calculates from previous ones.</span></div><div class="line"><a name="l05307"></a><span class="lineno"> 5307</span>&#160;    VkDeviceSize calculatedOffset = 0;</div><div class="line"><a name="l05308"></a><span class="lineno"> 5308</span>&#160;    <span class="comment">// Expected number of free suballocations as calculated from traversing their list.</span></div><div class="line"><a name="l05309"></a><span class="lineno"> 5309</span>&#160;    uint32_t calculatedFreeCount = 0;</div><div class="line"><a name="l05310"></a><span class="lineno"> 5310</span>&#160;    <span class="comment">// Expected sum size of free suballocations as calculated from traversing their list.</span></div><div class="line"><a name="l05311"></a><span class="lineno"> 5311</span>&#160;    VkDeviceSize calculatedSumFreeSize = 0;</div><div class="line"><a name="l05312"></a><span class="lineno"> 5312</span>&#160;    <span class="comment">// Expected number of free suballocations that should be registered in</span></div><div class="line"><a name="l05313"></a><span class="lineno"> 5313</span>&#160;    <span class="comment">// m_FreeSuballocationsBySize calculated from traversing their list.</span></div><div class="line"><a name="l05314"></a><span class="lineno"> 5314</span>&#160;    <span class="keywordtype">size_t</span> freeSuballocationsToRegister = 0;</div><div class="line"><a name="l05315"></a><span class="lineno"> 5315</span>&#160;    <span class="comment">// True if previous visisted suballocation was free.</span></div><div class="line"><a name="l05316"></a><span class="lineno"> 5316</span>&#160;    <span class="keywordtype">bool</span> prevFree = <span class="keyword">false</span>;</div><div class="line"><a name="l05317"></a><span class="lineno"> 5317</span>&#160;</div><div class="line"><a name="l05318"></a><span class="lineno"> 5318</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();</div><div class="line"><a name="l05319"></a><span class="lineno"> 5319</span>&#160;        suballocItem != m_Suballocations.cend();</div><div class="line"><a name="l05320"></a><span class="lineno"> 5320</span>&#160;        ++suballocItem)</div><div class="line"><a name="l05321"></a><span class="lineno"> 5321</span>&#160;    {</div><div class="line"><a name="l05322"></a><span class="lineno"> 5322</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; subAlloc = *suballocItem;</div><div class="line"><a name="l05323"></a><span class="lineno"> 5323</span>&#160;        </div><div class="line"><a name="l05324"></a><span class="lineno"> 5324</span>&#160;        <span class="comment">// Actual offset of this suballocation doesn&#39;t match expected one.</span></div><div class="line"><a name="l05325"></a><span class="lineno"> 5325</span>&#160;        <span class="keywordflow">if</span>(subAlloc.offset != calculatedOffset)</div><div class="line"><a name="l05326"></a><span class="lineno"> 5326</span>&#160;        {</div><div class="line"><a name="l05327"></a><span class="lineno"> 5327</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05328"></a><span class="lineno"> 5328</span>&#160;        }</div><div class="line"><a name="l05329"></a><span class="lineno"> 5329</span>&#160;</div><div class="line"><a name="l05330"></a><span class="lineno"> 5330</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">bool</span> currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l05331"></a><span class="lineno"> 5331</span>&#160;        <span class="comment">// Two adjacent free suballocations are invalid. They should be merged.</span></div><div class="line"><a name="l05332"></a><span class="lineno"> 5332</span>&#160;        <span class="keywordflow">if</span>(prevFree &amp;&amp; currFree)</div><div class="line"><a name="l05333"></a><span class="lineno"> 5333</span>&#160;        {</div><div class="line"><a name="l05334"></a><span class="lineno"> 5334</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05335"></a><span class="lineno"> 5335</span>&#160;        }</div><div class="line"><a name="l05336"></a><span class="lineno"> 5336</span>&#160;</div><div class="line"><a name="l05337"></a><span class="lineno"> 5337</span>&#160;        <span class="keywordflow">if</span>(currFree != (subAlloc.hAllocation == VK_NULL_HANDLE))</div><div class="line"><a name="l05338"></a><span class="lineno"> 5338</span>&#160;        {</div><div class="line"><a name="l05339"></a><span class="lineno"> 5339</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05340"></a><span class="lineno"> 5340</span>&#160;        }</div><div class="line"><a name="l05341"></a><span class="lineno"> 5341</span>&#160;</div><div class="line"><a name="l05342"></a><span class="lineno"> 5342</span>&#160;        <span class="keywordflow">if</span>(currFree)</div><div class="line"><a name="l05343"></a><span class="lineno"> 5343</span>&#160;        {</div><div class="line"><a name="l05344"></a><span class="lineno"> 5344</span>&#160;            calculatedSumFreeSize += subAlloc.size;</div><div class="line"><a name="l05345"></a><span class="lineno"> 5345</span>&#160;            ++calculatedFreeCount;</div><div class="line"><a name="l05346"></a><span class="lineno"> 5346</span>&#160;            <span class="keywordflow">if</span>(subAlloc.size &gt;= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l05347"></a><span class="lineno"> 5347</span>&#160;            {</div><div class="line"><a name="l05348"></a><span class="lineno"> 5348</span>&#160;                ++freeSuballocationsToRegister;</div><div class="line"><a name="l05349"></a><span class="lineno"> 5349</span>&#160;            }</div><div class="line"><a name="l05350"></a><span class="lineno"> 5350</span>&#160;        }</div><div class="line"><a name="l05351"></a><span class="lineno"> 5351</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05352"></a><span class="lineno"> 5352</span>&#160;        {</div><div class="line"><a name="l05353"></a><span class="lineno"> 5353</span>&#160;            <span class="keywordflow">if</span>(subAlloc.hAllocation-&gt;GetOffset() != subAlloc.offset)</div><div class="line"><a name="l05354"></a><span class="lineno"> 5354</span>&#160;            {</div><div class="line"><a name="l05355"></a><span class="lineno"> 5355</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05356"></a><span class="lineno"> 5356</span>&#160;            }</div><div class="line"><a name="l05357"></a><span class="lineno"> 5357</span>&#160;            <span class="keywordflow">if</span>(subAlloc.hAllocation-&gt;GetSize() != subAlloc.size)</div><div class="line"><a name="l05358"></a><span class="lineno"> 5358</span>&#160;            {</div><div class="line"><a name="l05359"></a><span class="lineno"> 5359</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05360"></a><span class="lineno"> 5360</span>&#160;            }</div><div class="line"><a name="l05361"></a><span class="lineno"> 5361</span>&#160;        }</div><div class="line"><a name="l05362"></a><span class="lineno"> 5362</span>&#160;</div><div class="line"><a name="l05363"></a><span class="lineno"> 5363</span>&#160;        calculatedOffset += subAlloc.size;</div><div class="line"><a name="l05364"></a><span class="lineno"> 5364</span>&#160;        prevFree = currFree;</div><div class="line"><a name="l05365"></a><span class="lineno"> 5365</span>&#160;    }</div><div class="line"><a name="l05366"></a><span class="lineno"> 5366</span>&#160;</div><div class="line"><a name="l05367"></a><span class="lineno"> 5367</span>&#160;    <span class="comment">// Number of free suballocations registered in m_FreeSuballocationsBySize doesn&#39;t</span></div><div class="line"><a name="l05368"></a><span class="lineno"> 5368</span>&#160;    <span class="comment">// match expected one.</span></div><div class="line"><a name="l05369"></a><span class="lineno"> 5369</span>&#160;    <span class="keywordflow">if</span>(m_FreeSuballocationsBySize.size() != freeSuballocationsToRegister)</div><div class="line"><a name="l05370"></a><span class="lineno"> 5370</span>&#160;    {</div><div class="line"><a name="l05371"></a><span class="lineno"> 5371</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05372"></a><span class="lineno"> 5372</span>&#160;    }</div><div class="line"><a name="l05373"></a><span class="lineno"> 5373</span>&#160;</div><div class="line"><a name="l05374"></a><span class="lineno"> 5374</span>&#160;    VkDeviceSize lastSize = 0;</div><div class="line"><a name="l05375"></a><span class="lineno"> 5375</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_FreeSuballocationsBySize.size(); ++i)</div><div class="line"><a name="l05376"></a><span class="lineno"> 5376</span>&#160;    {</div><div class="line"><a name="l05377"></a><span class="lineno"> 5377</span>&#160;        VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i];</div><div class="line"><a name="l05378"></a><span class="lineno"> 5378</span>&#160;        </div><div class="line"><a name="l05379"></a><span class="lineno"> 5379</span>&#160;        <span class="comment">// Only free suballocations can be registered in m_FreeSuballocationsBySize.</span></div><div class="line"><a name="l05380"></a><span class="lineno"> 5380</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l05381"></a><span class="lineno"> 5381</span>&#160;        {</div><div class="line"><a name="l05382"></a><span class="lineno"> 5382</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05383"></a><span class="lineno"> 5383</span>&#160;        }</div><div class="line"><a name="l05384"></a><span class="lineno"> 5384</span>&#160;        <span class="comment">// They must be sorted by size ascending.</span></div><div class="line"><a name="l05385"></a><span class="lineno"> 5385</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;size &lt; lastSize)</div><div class="line"><a name="l05386"></a><span class="lineno"> 5386</span>&#160;        {</div><div class="line"><a name="l05387"></a><span class="lineno"> 5387</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05388"></a><span class="lineno"> 5388</span>&#160;        }</div><div class="line"><a name="l05389"></a><span class="lineno"> 5389</span>&#160;</div><div class="line"><a name="l05390"></a><span class="lineno"> 5390</span>&#160;        lastSize = suballocItem-&gt;size;</div><div class="line"><a name="l05391"></a><span class="lineno"> 5391</span>&#160;    }</div><div class="line"><a name="l05392"></a><span class="lineno"> 5392</span>&#160;</div><div class="line"><a name="l05393"></a><span class="lineno"> 5393</span>&#160;    <span class="comment">// Check if totals match calculacted values.</span></div><div class="line"><a name="l05394"></a><span class="lineno"> 5394</span>&#160;    <span class="keywordflow">if</span>(!ValidateFreeSuballocationList() ||</div><div class="line"><a name="l05395"></a><span class="lineno"> 5395</span>&#160;        (calculatedOffset != m_Size) ||</div><div class="line"><a name="l05396"></a><span class="lineno"> 5396</span>&#160;        (calculatedSumFreeSize != m_SumFreeSize) ||</div><div class="line"><a name="l05397"></a><span class="lineno"> 5397</span>&#160;        (calculatedFreeCount != m_FreeCount))</div><div class="line"><a name="l05398"></a><span class="lineno"> 5398</span>&#160;    {</div><div class="line"><a name="l05399"></a><span class="lineno"> 5399</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05400"></a><span class="lineno"> 5400</span>&#160;    }</div><div class="line"><a name="l05401"></a><span class="lineno"> 5401</span>&#160;</div><div class="line"><a name="l05402"></a><span class="lineno"> 5402</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05403"></a><span class="lineno"> 5403</span>&#160;}</div><div class="line"><a name="l05404"></a><span class="lineno"> 5404</span>&#160;</div><div class="line"><a name="l05405"></a><span class="lineno"> 5405</span>&#160;VkDeviceSize VmaBlockMetadata::GetUnusedRangeSizeMax()<span class="keyword"> const</span></div><div class="line"><a name="l05406"></a><span class="lineno"> 5406</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05407"></a><span class="lineno"> 5407</span>&#160;    <span class="keywordflow">if</span>(!m_FreeSuballocationsBySize.empty())</div><div class="line"><a name="l05408"></a><span class="lineno"> 5408</span>&#160;    {</div><div class="line"><a name="l05409"></a><span class="lineno"> 5409</span>&#160;        <span class="keywordflow">return</span> m_FreeSuballocationsBySize.back()-&gt;size;</div><div class="line"><a name="l05410"></a><span class="lineno"> 5410</span>&#160;    }</div><div class="line"><a name="l05411"></a><span class="lineno"> 5411</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l05412"></a><span class="lineno"> 5412</span>&#160;    {</div><div class="line"><a name="l05413"></a><span class="lineno"> 5413</span>&#160;        <span class="keywordflow">return</span> 0;</div><div class="line"><a name="l05414"></a><span class="lineno"> 5414</span>&#160;    }</div><div class="line"><a name="l05415"></a><span class="lineno"> 5415</span>&#160;}</div><div class="line"><a name="l05416"></a><span class="lineno"> 5416</span>&#160;</div><div class="line"><a name="l05417"></a><span class="lineno"> 5417</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata::IsEmpty()<span class="keyword"> const</span></div><div class="line"><a name="l05418"></a><span class="lineno"> 5418</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05419"></a><span class="lineno"> 5419</span>&#160;    <span class="keywordflow">return</span> (m_Suballocations.size() == 1) &amp;&amp; (m_FreeCount == 1);</div><div class="line"><a name="l05420"></a><span class="lineno"> 5420</span>&#160;}</div><div class="line"><a name="l05421"></a><span class="lineno"> 5421</span>&#160;</div><div class="line"><a name="l05422"></a><span class="lineno"> 5422</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::CalcAllocationStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo)<span class="keyword"> const</span></div><div class="line"><a name="l05423"></a><span class="lineno"> 5423</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05424"></a><span class="lineno"> 5424</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> = 1;</div><div class="line"><a name="l05425"></a><span class="lineno"> 5425</span>&#160;</div><div class="line"><a name="l05426"></a><span class="lineno"> 5426</span>&#160;    <span class="keyword">const</span> uint32_t rangeCount = (uint32_t)m_Suballocations.size();</div><div class="line"><a name="l05427"></a><span class="lineno"> 5427</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> = rangeCount - m_FreeCount;</div><div class="line"><a name="l05428"></a><span class="lineno"> 5428</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> = m_FreeCount;</div><div class="line"><a name="l05429"></a><span class="lineno"> 5429</span>&#160;    </div><div class="line"><a name="l05430"></a><span class="lineno"> 5430</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> = m_SumFreeSize;</div><div class="line"><a name="l05431"></a><span class="lineno"> 5431</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> = m_Size - outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>;</div><div class="line"><a name="l05432"></a><span class="lineno"> 5432</span>&#160;</div><div class="line"><a name="l05433"></a><span class="lineno"> 5433</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l05434"></a><span class="lineno"> 5434</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = 0;</div><div class="line"><a name="l05435"></a><span class="lineno"> 5435</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l05436"></a><span class="lineno"> 5436</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = 0;</div><div class="line"><a name="l05437"></a><span class="lineno"> 5437</span>&#160;</div><div class="line"><a name="l05438"></a><span class="lineno"> 5438</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();</div><div class="line"><a name="l05439"></a><span class="lineno"> 5439</span>&#160;        suballocItem != m_Suballocations.cend();</div><div class="line"><a name="l05440"></a><span class="lineno"> 5440</span>&#160;        ++suballocItem)</div><div class="line"><a name="l05441"></a><span class="lineno"> 5441</span>&#160;    {</div><div class="line"><a name="l05442"></a><span class="lineno"> 5442</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l05443"></a><span class="lineno"> 5443</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l05444"></a><span class="lineno"> 5444</span>&#160;        {</div><div class="line"><a name="l05445"></a><span class="lineno"> 5445</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, suballoc.size);</div><div class="line"><a name="l05446"></a><span class="lineno"> 5446</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = VMA_MAX(outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>, suballoc.size);</div><div class="line"><a name="l05447"></a><span class="lineno"> 5447</span>&#160;        }</div><div class="line"><a name="l05448"></a><span class="lineno"> 5448</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05449"></a><span class="lineno"> 5449</span>&#160;        {</div><div class="line"><a name="l05450"></a><span class="lineno"> 5450</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, suballoc.size);</div><div class="line"><a name="l05451"></a><span class="lineno"> 5451</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MAX(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, suballoc.size);</div><div class="line"><a name="l05452"></a><span class="lineno"> 5452</span>&#160;        }</div><div class="line"><a name="l05453"></a><span class="lineno"> 5453</span>&#160;    }</div><div class="line"><a name="l05454"></a><span class="lineno"> 5454</span>&#160;}</div><div class="line"><a name="l05455"></a><span class="lineno"> 5455</span>&#160;</div><div class="line"><a name="l05456"></a><span class="lineno"> 5456</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::AddPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>&amp; inoutStats)<span class="keyword"> const</span></div><div class="line"><a name="l05457"></a><span class="lineno"> 5457</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05458"></a><span class="lineno"> 5458</span>&#160;    <span class="keyword">const</span> uint32_t rangeCount = (uint32_t)m_Suballocations.size();</div><div class="line"><a name="l05459"></a><span class="lineno"> 5459</span>&#160;</div><div class="line"><a name="l05460"></a><span class="lineno"> 5460</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a> += m_Size;</div><div class="line"><a name="l05461"></a><span class="lineno"> 5461</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += m_SumFreeSize;</div><div class="line"><a name="l05462"></a><span class="lineno"> 5462</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a> += rangeCount - m_FreeCount;</div><div class="line"><a name="l05463"></a><span class="lineno"> 5463</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a> += m_FreeCount;</div><div class="line"><a name="l05464"></a><span class="lineno"> 5464</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, GetUnusedRangeSizeMax());</div><div class="line"><a name="l05465"></a><span class="lineno"> 5465</span>&#160;}</div><div class="line"><a name="l05466"></a><span class="lineno"> 5466</span>&#160;</div><div class="line"><a name="l05467"></a><span class="lineno"> 5467</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05468"></a><span class="lineno"> 5468</span>&#160;</div><div class="line"><a name="l05469"></a><span class="lineno"> 5469</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json)<span class="keyword"> const</span></div><div class="line"><a name="l05470"></a><span class="lineno"> 5470</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05471"></a><span class="lineno"> 5471</span>&#160;    json.BeginObject();</div><div class="line"><a name="l05472"></a><span class="lineno"> 5472</span>&#160;</div><div class="line"><a name="l05473"></a><span class="lineno"> 5473</span>&#160;    json.WriteString(<span class="stringliteral">&quot;TotalBytes&quot;</span>);</div><div class="line"><a name="l05474"></a><span class="lineno"> 5474</span>&#160;    json.WriteNumber(m_Size);</div><div class="line"><a name="l05475"></a><span class="lineno"> 5475</span>&#160;</div><div class="line"><a name="l05476"></a><span class="lineno"> 5476</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedBytes&quot;</span>);</div><div class="line"><a name="l05477"></a><span class="lineno"> 5477</span>&#160;    json.WriteNumber(m_SumFreeSize);</div><div class="line"><a name="l05478"></a><span class="lineno"> 5478</span>&#160;</div><div class="line"><a name="l05479"></a><span class="lineno"> 5479</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Allocations&quot;</span>);</div><div class="line"><a name="l05480"></a><span class="lineno"> 5480</span>&#160;    json.WriteNumber((uint64_t)m_Suballocations.size() - m_FreeCount);</div><div class="line"><a name="l05481"></a><span class="lineno"> 5481</span>&#160;</div><div class="line"><a name="l05482"></a><span class="lineno"> 5482</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedRanges&quot;</span>);</div><div class="line"><a name="l05483"></a><span class="lineno"> 5483</span>&#160;    json.WriteNumber(m_FreeCount);</div><div class="line"><a name="l05484"></a><span class="lineno"> 5484</span>&#160;</div><div class="line"><a name="l05485"></a><span class="lineno"> 5485</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Suballocations&quot;</span>);</div><div class="line"><a name="l05486"></a><span class="lineno"> 5486</span>&#160;    json.BeginArray();</div><div class="line"><a name="l05487"></a><span class="lineno"> 5487</span>&#160;    <span class="keywordtype">size_t</span> i = 0;</div><div class="line"><a name="l05488"></a><span class="lineno"> 5488</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();</div><div class="line"><a name="l05489"></a><span class="lineno"> 5489</span>&#160;        suballocItem != m_Suballocations.cend();</div><div class="line"><a name="l05490"></a><span class="lineno"> 5490</span>&#160;        ++suballocItem, ++i)</div><div class="line"><a name="l05491"></a><span class="lineno"> 5491</span>&#160;    {</div><div class="line"><a name="l05492"></a><span class="lineno"> 5492</span>&#160;        json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l05493"></a><span class="lineno"> 5493</span>&#160;        </div><div class="line"><a name="l05494"></a><span class="lineno"> 5494</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Type&quot;</span>);</div><div class="line"><a name="l05495"></a><span class="lineno"> 5495</span>&#160;        json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[suballocItem-&gt;type]);</div><div class="line"><a name="l05496"></a><span class="lineno"> 5496</span>&#160;</div><div class="line"><a name="l05497"></a><span class="lineno"> 5497</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Size&quot;</span>);</div><div class="line"><a name="l05498"></a><span class="lineno"> 5498</span>&#160;        json.WriteNumber(suballocItem-&gt;size);</div><div class="line"><a name="l05499"></a><span class="lineno"> 5499</span>&#160;</div><div class="line"><a name="l05500"></a><span class="lineno"> 5500</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Offset&quot;</span>);</div><div class="line"><a name="l05501"></a><span class="lineno"> 5501</span>&#160;        json.WriteNumber(suballocItem-&gt;offset);</div><div class="line"><a name="l05502"></a><span class="lineno"> 5502</span>&#160;</div><div class="line"><a name="l05503"></a><span class="lineno"> 5503</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l05504"></a><span class="lineno"> 5504</span>&#160;        {</div><div class="line"><a name="l05505"></a><span class="lineno"> 5505</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">void</span>* pUserData = suballocItem-&gt;hAllocation-&gt;GetUserData();</div><div class="line"><a name="l05506"></a><span class="lineno"> 5506</span>&#160;            <span class="keywordflow">if</span>(pUserData != VMA_NULL)</div><div class="line"><a name="l05507"></a><span class="lineno"> 5507</span>&#160;            {</div><div class="line"><a name="l05508"></a><span class="lineno"> 5508</span>&#160;                json.WriteString(<span class="stringliteral">&quot;UserData&quot;</span>);</div><div class="line"><a name="l05509"></a><span class="lineno"> 5509</span>&#160;                <span class="keywordflow">if</span>(suballocItem-&gt;hAllocation-&gt;IsUserDataString())</div><div class="line"><a name="l05510"></a><span class="lineno"> 5510</span>&#160;                {</div><div class="line"><a name="l05511"></a><span class="lineno"> 5511</span>&#160;                    json.WriteString((<span class="keyword">const</span> <span class="keywordtype">char</span>*)pUserData);</div><div class="line"><a name="l05512"></a><span class="lineno"> 5512</span>&#160;                }</div><div class="line"><a name="l05513"></a><span class="lineno"> 5513</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l05514"></a><span class="lineno"> 5514</span>&#160;                {</div><div class="line"><a name="l05515"></a><span class="lineno"> 5515</span>&#160;                    json.BeginString();</div><div class="line"><a name="l05516"></a><span class="lineno"> 5516</span>&#160;                    json.ContinueString_Pointer(pUserData);</div><div class="line"><a name="l05517"></a><span class="lineno"> 5517</span>&#160;                    json.EndString();</div><div class="line"><a name="l05518"></a><span class="lineno"> 5518</span>&#160;                }</div><div class="line"><a name="l05519"></a><span class="lineno"> 5519</span>&#160;            }</div><div class="line"><a name="l05520"></a><span class="lineno"> 5520</span>&#160;        }</div><div class="line"><a name="l05521"></a><span class="lineno"> 5521</span>&#160;</div><div class="line"><a name="l05522"></a><span class="lineno"> 5522</span>&#160;        json.EndObject();</div><div class="line"><a name="l05523"></a><span class="lineno"> 5523</span>&#160;    }</div><div class="line"><a name="l05524"></a><span class="lineno"> 5524</span>&#160;    json.EndArray();</div><div class="line"><a name="l05525"></a><span class="lineno"> 5525</span>&#160;</div><div class="line"><a name="l05526"></a><span class="lineno"> 5526</span>&#160;    json.EndObject();</div><div class="line"><a name="l05527"></a><span class="lineno"> 5527</span>&#160;}</div><div class="line"><a name="l05528"></a><span class="lineno"> 5528</span>&#160;</div><div class="line"><a name="l05529"></a><span class="lineno"> 5529</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05530"></a><span class="lineno"> 5530</span>&#160;</div><div class="line"><a name="l05531"></a><span class="lineno"> 5531</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l05532"></a><span class="lineno"> 5532</span>&#160;<span class="comment">How many suitable free suballocations to analyze before choosing best one.</span></div><div class="line"><a name="l05533"></a><span class="lineno"> 5533</span>&#160;<span class="comment">- Set to 1 to use First-Fit algorithm - first suitable free suballocation will</span></div><div class="line"><a name="l05534"></a><span class="lineno"> 5534</span>&#160;<span class="comment">  be chosen.</span></div><div class="line"><a name="l05535"></a><span class="lineno"> 5535</span>&#160;<span class="comment">- Set to UINT32_MAX to use Best-Fit/Worst-Fit algorithm - all suitable free</span></div><div class="line"><a name="l05536"></a><span class="lineno"> 5536</span>&#160;<span class="comment">  suballocations will be analized and best one will be chosen.</span></div><div class="line"><a name="l05537"></a><span class="lineno"> 5537</span>&#160;<span class="comment">- Any other value is also acceptable.</span></div><div class="line"><a name="l05538"></a><span class="lineno"> 5538</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l05539"></a><span class="lineno"> 5539</span>&#160;<span class="comment">//static const uint32_t MAX_SUITABLE_SUBALLOCATIONS_TO_CHECK = 8;</span></div><div class="line"><a name="l05540"></a><span class="lineno"> 5540</span>&#160;</div><div class="line"><a name="l05541"></a><span class="lineno"> 5541</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::CreateFirstAllocationRequest(VmaAllocationRequest* pAllocationRequest)</div><div class="line"><a name="l05542"></a><span class="lineno"> 5542</span>&#160;{</div><div class="line"><a name="l05543"></a><span class="lineno"> 5543</span>&#160;    VMA_ASSERT(IsEmpty());</div><div class="line"><a name="l05544"></a><span class="lineno"> 5544</span>&#160;    pAllocationRequest-&gt;offset = 0;</div><div class="line"><a name="l05545"></a><span class="lineno"> 5545</span>&#160;    pAllocationRequest-&gt;sumFreeSize = m_SumFreeSize;</div><div class="line"><a name="l05546"></a><span class="lineno"> 5546</span>&#160;    pAllocationRequest-&gt;sumItemSize = 0;</div><div class="line"><a name="l05547"></a><span class="lineno"> 5547</span>&#160;    pAllocationRequest-&gt;item = m_Suballocations.begin();</div><div class="line"><a name="l05548"></a><span class="lineno"> 5548</span>&#160;    pAllocationRequest-&gt;itemsToMakeLostCount = 0;</div><div class="line"><a name="l05549"></a><span class="lineno"> 5549</span>&#160;}</div><div class="line"><a name="l05550"></a><span class="lineno"> 5550</span>&#160;</div><div class="line"><a name="l05551"></a><span class="lineno"> 5551</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata::CreateAllocationRequest(</div><div class="line"><a name="l05552"></a><span class="lineno"> 5552</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l05553"></a><span class="lineno"> 5553</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l05554"></a><span class="lineno"> 5554</span>&#160;    VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l05555"></a><span class="lineno"> 5555</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l05556"></a><span class="lineno"> 5556</span>&#160;    VkDeviceSize allocAlignment,</div><div class="line"><a name="l05557"></a><span class="lineno"> 5557</span>&#160;    VmaSuballocationType allocType,</div><div class="line"><a name="l05558"></a><span class="lineno"> 5558</span>&#160;    <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l05559"></a><span class="lineno"> 5559</span>&#160;    VmaAllocationRequest* pAllocationRequest)</div><div class="line"><a name="l05560"></a><span class="lineno"> 5560</span>&#160;{</div><div class="line"><a name="l05561"></a><span class="lineno"> 5561</span>&#160;    VMA_ASSERT(allocSize &gt; 0);</div><div class="line"><a name="l05562"></a><span class="lineno"> 5562</span>&#160;    VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l05563"></a><span class="lineno"> 5563</span>&#160;    VMA_ASSERT(pAllocationRequest != VMA_NULL);</div><div class="line"><a name="l05564"></a><span class="lineno"> 5564</span>&#160;    VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l05565"></a><span class="lineno"> 5565</span>&#160;</div><div class="line"><a name="l05566"></a><span class="lineno"> 5566</span>&#160;    <span class="comment">// There is not enough total free space in this block to fullfill the request: Early return.</span></div><div class="line"><a name="l05567"></a><span class="lineno"> 5567</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost == <span class="keyword">false</span> &amp;&amp; m_SumFreeSize &lt; allocSize)</div><div class="line"><a name="l05568"></a><span class="lineno"> 5568</span>&#160;    {</div><div class="line"><a name="l05569"></a><span class="lineno"> 5569</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05570"></a><span class="lineno"> 5570</span>&#160;    }</div><div class="line"><a name="l05571"></a><span class="lineno"> 5571</span>&#160;</div><div class="line"><a name="l05572"></a><span class="lineno"> 5572</span>&#160;    <span class="comment">// New algorithm, efficiently searching freeSuballocationsBySize.</span></div><div class="line"><a name="l05573"></a><span class="lineno"> 5573</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> freeSuballocCount = m_FreeSuballocationsBySize.size();</div><div class="line"><a name="l05574"></a><span class="lineno"> 5574</span>&#160;    <span class="keywordflow">if</span>(freeSuballocCount &gt; 0)</div><div class="line"><a name="l05575"></a><span class="lineno"> 5575</span>&#160;    {</div><div class="line"><a name="l05576"></a><span class="lineno"> 5576</span>&#160;        <span class="keywordflow">if</span>(VMA_BEST_FIT)</div><div class="line"><a name="l05577"></a><span class="lineno"> 5577</span>&#160;        {</div><div class="line"><a name="l05578"></a><span class="lineno"> 5578</span>&#160;            <span class="comment">// Find first free suballocation with size not less than allocSize.</span></div><div class="line"><a name="l05579"></a><span class="lineno"> 5579</span>&#160;            VmaSuballocationList::iterator* <span class="keyword">const</span> it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l05580"></a><span class="lineno"> 5580</span>&#160;                m_FreeSuballocationsBySize.data(),</div><div class="line"><a name="l05581"></a><span class="lineno"> 5581</span>&#160;                m_FreeSuballocationsBySize.data() + freeSuballocCount,</div><div class="line"><a name="l05582"></a><span class="lineno"> 5582</span>&#160;                allocSize,</div><div class="line"><a name="l05583"></a><span class="lineno"> 5583</span>&#160;                VmaSuballocationItemSizeLess());</div><div class="line"><a name="l05584"></a><span class="lineno"> 5584</span>&#160;            <span class="keywordtype">size_t</span> index = it - m_FreeSuballocationsBySize.data();</div><div class="line"><a name="l05585"></a><span class="lineno"> 5585</span>&#160;            <span class="keywordflow">for</span>(; index &lt; freeSuballocCount; ++index)</div><div class="line"><a name="l05586"></a><span class="lineno"> 5586</span>&#160;            {</div><div class="line"><a name="l05587"></a><span class="lineno"> 5587</span>&#160;                <span class="keywordflow">if</span>(CheckAllocation(</div><div class="line"><a name="l05588"></a><span class="lineno"> 5588</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l05589"></a><span class="lineno"> 5589</span>&#160;                    frameInUseCount,</div><div class="line"><a name="l05590"></a><span class="lineno"> 5590</span>&#160;                    bufferImageGranularity,</div><div class="line"><a name="l05591"></a><span class="lineno"> 5591</span>&#160;                    allocSize,</div><div class="line"><a name="l05592"></a><span class="lineno"> 5592</span>&#160;                    allocAlignment,</div><div class="line"><a name="l05593"></a><span class="lineno"> 5593</span>&#160;                    allocType,</div><div class="line"><a name="l05594"></a><span class="lineno"> 5594</span>&#160;                    m_FreeSuballocationsBySize[index],</div><div class="line"><a name="l05595"></a><span class="lineno"> 5595</span>&#160;                    <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l05596"></a><span class="lineno"> 5596</span>&#160;                    &amp;pAllocationRequest-&gt;offset,</div><div class="line"><a name="l05597"></a><span class="lineno"> 5597</span>&#160;                    &amp;pAllocationRequest-&gt;itemsToMakeLostCount,</div><div class="line"><a name="l05598"></a><span class="lineno"> 5598</span>&#160;                    &amp;pAllocationRequest-&gt;sumFreeSize,</div><div class="line"><a name="l05599"></a><span class="lineno"> 5599</span>&#160;                    &amp;pAllocationRequest-&gt;sumItemSize))</div><div class="line"><a name="l05600"></a><span class="lineno"> 5600</span>&#160;                {</div><div class="line"><a name="l05601"></a><span class="lineno"> 5601</span>&#160;                    pAllocationRequest-&gt;item = m_FreeSuballocationsBySize[index];</div><div class="line"><a name="l05602"></a><span class="lineno"> 5602</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05603"></a><span class="lineno"> 5603</span>&#160;                }</div><div class="line"><a name="l05604"></a><span class="lineno"> 5604</span>&#160;            }</div><div class="line"><a name="l05605"></a><span class="lineno"> 5605</span>&#160;        }</div><div class="line"><a name="l05606"></a><span class="lineno"> 5606</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05607"></a><span class="lineno"> 5607</span>&#160;        {</div><div class="line"><a name="l05608"></a><span class="lineno"> 5608</span>&#160;            <span class="comment">// Search staring from biggest suballocations.</span></div><div class="line"><a name="l05609"></a><span class="lineno"> 5609</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> index = freeSuballocCount; index--; )</div><div class="line"><a name="l05610"></a><span class="lineno"> 5610</span>&#160;            {</div><div class="line"><a name="l05611"></a><span class="lineno"> 5611</span>&#160;                <span class="keywordflow">if</span>(CheckAllocation(</div><div class="line"><a name="l05612"></a><span class="lineno"> 5612</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l05613"></a><span class="lineno"> 5613</span>&#160;                    frameInUseCount,</div><div class="line"><a name="l05614"></a><span class="lineno"> 5614</span>&#160;                    bufferImageGranularity,</div><div class="line"><a name="l05615"></a><span class="lineno"> 5615</span>&#160;                    allocSize,</div><div class="line"><a name="l05616"></a><span class="lineno"> 5616</span>&#160;                    allocAlignment,</div><div class="line"><a name="l05617"></a><span class="lineno"> 5617</span>&#160;                    allocType,</div><div class="line"><a name="l05618"></a><span class="lineno"> 5618</span>&#160;                    m_FreeSuballocationsBySize[index],</div><div class="line"><a name="l05619"></a><span class="lineno"> 5619</span>&#160;                    <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l05620"></a><span class="lineno"> 5620</span>&#160;                    &amp;pAllocationRequest-&gt;offset,</div><div class="line"><a name="l05621"></a><span class="lineno"> 5621</span>&#160;                    &amp;pAllocationRequest-&gt;itemsToMakeLostCount,</div><div class="line"><a name="l05622"></a><span class="lineno"> 5622</span>&#160;                    &amp;pAllocationRequest-&gt;sumFreeSize,</div><div class="line"><a name="l05623"></a><span class="lineno"> 5623</span>&#160;                    &amp;pAllocationRequest-&gt;sumItemSize))</div><div class="line"><a name="l05624"></a><span class="lineno"> 5624</span>&#160;                {</div><div class="line"><a name="l05625"></a><span class="lineno"> 5625</span>&#160;                    pAllocationRequest-&gt;item = m_FreeSuballocationsBySize[index];</div><div class="line"><a name="l05626"></a><span class="lineno"> 5626</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05627"></a><span class="lineno"> 5627</span>&#160;                }</div><div class="line"><a name="l05628"></a><span class="lineno"> 5628</span>&#160;            }</div><div class="line"><a name="l05629"></a><span class="lineno"> 5629</span>&#160;        }</div><div class="line"><a name="l05630"></a><span class="lineno"> 5630</span>&#160;    }</div><div class="line"><a name="l05631"></a><span class="lineno"> 5631</span>&#160;</div><div class="line"><a name="l05632"></a><span class="lineno"> 5632</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost)</div><div class="line"><a name="l05633"></a><span class="lineno"> 5633</span>&#160;    {</div><div class="line"><a name="l05634"></a><span class="lineno"> 5634</span>&#160;        <span class="comment">// Brute-force algorithm. TODO: Come up with something better.</span></div><div class="line"><a name="l05635"></a><span class="lineno"> 5635</span>&#160;</div><div class="line"><a name="l05636"></a><span class="lineno"> 5636</span>&#160;        pAllocationRequest-&gt;sumFreeSize = VK_WHOLE_SIZE;</div><div class="line"><a name="l05637"></a><span class="lineno"> 5637</span>&#160;        pAllocationRequest-&gt;sumItemSize = VK_WHOLE_SIZE;</div><div class="line"><a name="l05638"></a><span class="lineno"> 5638</span>&#160;</div><div class="line"><a name="l05639"></a><span class="lineno"> 5639</span>&#160;        VmaAllocationRequest tmpAllocRequest = {};</div><div class="line"><a name="l05640"></a><span class="lineno"> 5640</span>&#160;        <span class="keywordflow">for</span>(VmaSuballocationList::iterator suballocIt = m_Suballocations.begin();</div><div class="line"><a name="l05641"></a><span class="lineno"> 5641</span>&#160;            suballocIt != m_Suballocations.end();</div><div class="line"><a name="l05642"></a><span class="lineno"> 5642</span>&#160;            ++suballocIt)</div><div class="line"><a name="l05643"></a><span class="lineno"> 5643</span>&#160;        {</div><div class="line"><a name="l05644"></a><span class="lineno"> 5644</span>&#160;            <span class="keywordflow">if</span>(suballocIt-&gt;type == VMA_SUBALLOCATION_TYPE_FREE ||</div><div class="line"><a name="l05645"></a><span class="lineno"> 5645</span>&#160;                suballocIt-&gt;hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l05646"></a><span class="lineno"> 5646</span>&#160;            {</div><div class="line"><a name="l05647"></a><span class="lineno"> 5647</span>&#160;                <span class="keywordflow">if</span>(CheckAllocation(</div><div class="line"><a name="l05648"></a><span class="lineno"> 5648</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l05649"></a><span class="lineno"> 5649</span>&#160;                    frameInUseCount,</div><div class="line"><a name="l05650"></a><span class="lineno"> 5650</span>&#160;                    bufferImageGranularity,</div><div class="line"><a name="l05651"></a><span class="lineno"> 5651</span>&#160;                    allocSize,</div><div class="line"><a name="l05652"></a><span class="lineno"> 5652</span>&#160;                    allocAlignment,</div><div class="line"><a name="l05653"></a><span class="lineno"> 5653</span>&#160;                    allocType,</div><div class="line"><a name="l05654"></a><span class="lineno"> 5654</span>&#160;                    suballocIt,</div><div class="line"><a name="l05655"></a><span class="lineno"> 5655</span>&#160;                    canMakeOtherLost,</div><div class="line"><a name="l05656"></a><span class="lineno"> 5656</span>&#160;                    &amp;tmpAllocRequest.offset,</div><div class="line"><a name="l05657"></a><span class="lineno"> 5657</span>&#160;                    &amp;tmpAllocRequest.itemsToMakeLostCount,</div><div class="line"><a name="l05658"></a><span class="lineno"> 5658</span>&#160;                    &amp;tmpAllocRequest.sumFreeSize,</div><div class="line"><a name="l05659"></a><span class="lineno"> 5659</span>&#160;                    &amp;tmpAllocRequest.sumItemSize))</div><div class="line"><a name="l05660"></a><span class="lineno"> 5660</span>&#160;                {</div><div class="line"><a name="l05661"></a><span class="lineno"> 5661</span>&#160;                    tmpAllocRequest.item = suballocIt;</div><div class="line"><a name="l05662"></a><span class="lineno"> 5662</span>&#160;</div><div class="line"><a name="l05663"></a><span class="lineno"> 5663</span>&#160;                    <span class="keywordflow">if</span>(tmpAllocRequest.CalcCost() &lt; pAllocationRequest-&gt;CalcCost())</div><div class="line"><a name="l05664"></a><span class="lineno"> 5664</span>&#160;                    {</div><div class="line"><a name="l05665"></a><span class="lineno"> 5665</span>&#160;                        *pAllocationRequest = tmpAllocRequest;</div><div class="line"><a name="l05666"></a><span class="lineno"> 5666</span>&#160;                    }</div><div class="line"><a name="l05667"></a><span class="lineno"> 5667</span>&#160;                }</div><div class="line"><a name="l05668"></a><span class="lineno"> 5668</span>&#160;            }</div><div class="line"><a name="l05669"></a><span class="lineno"> 5669</span>&#160;        }</div><div class="line"><a name="l05670"></a><span class="lineno"> 5670</span>&#160;</div><div class="line"><a name="l05671"></a><span class="lineno"> 5671</span>&#160;        <span class="keywordflow">if</span>(pAllocationRequest-&gt;sumItemSize != VK_WHOLE_SIZE)</div><div class="line"><a name="l05672"></a><span class="lineno"> 5672</span>&#160;        {</div><div class="line"><a name="l05673"></a><span class="lineno"> 5673</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05674"></a><span class="lineno"> 5674</span>&#160;        }</div><div class="line"><a name="l05675"></a><span class="lineno"> 5675</span>&#160;    }</div><div class="line"><a name="l05676"></a><span class="lineno"> 5676</span>&#160;</div><div class="line"><a name="l05677"></a><span class="lineno"> 5677</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05678"></a><span class="lineno"> 5678</span>&#160;}</div><div class="line"><a name="l05679"></a><span class="lineno"> 5679</span>&#160;</div><div class="line"><a name="l05680"></a><span class="lineno"> 5680</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata::MakeRequestedAllocationsLost(</div><div class="line"><a name="l05681"></a><span class="lineno"> 5681</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l05682"></a><span class="lineno"> 5682</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l05683"></a><span class="lineno"> 5683</span>&#160;    VmaAllocationRequest* pAllocationRequest)</div><div class="line"><a name="l05684"></a><span class="lineno"> 5684</span>&#160;{</div><div class="line"><a name="l05685"></a><span class="lineno"> 5685</span>&#160;    <span class="keywordflow">while</span>(pAllocationRequest-&gt;itemsToMakeLostCount &gt; 0)</div><div class="line"><a name="l05686"></a><span class="lineno"> 5686</span>&#160;    {</div><div class="line"><a name="l05687"></a><span class="lineno"> 5687</span>&#160;        <span class="keywordflow">if</span>(pAllocationRequest-&gt;item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l05688"></a><span class="lineno"> 5688</span>&#160;        {</div><div class="line"><a name="l05689"></a><span class="lineno"> 5689</span>&#160;            ++pAllocationRequest-&gt;item;</div><div class="line"><a name="l05690"></a><span class="lineno"> 5690</span>&#160;        }</div><div class="line"><a name="l05691"></a><span class="lineno"> 5691</span>&#160;        VMA_ASSERT(pAllocationRequest-&gt;item != m_Suballocations.end());</div><div class="line"><a name="l05692"></a><span class="lineno"> 5692</span>&#160;        VMA_ASSERT(pAllocationRequest-&gt;item-&gt;hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l05693"></a><span class="lineno"> 5693</span>&#160;        VMA_ASSERT(pAllocationRequest-&gt;item-&gt;hAllocation-&gt;CanBecomeLost());</div><div class="line"><a name="l05694"></a><span class="lineno"> 5694</span>&#160;        <span class="keywordflow">if</span>(pAllocationRequest-&gt;item-&gt;hAllocation-&gt;MakeLost(currentFrameIndex, frameInUseCount))</div><div class="line"><a name="l05695"></a><span class="lineno"> 5695</span>&#160;        {</div><div class="line"><a name="l05696"></a><span class="lineno"> 5696</span>&#160;            pAllocationRequest-&gt;item = FreeSuballocation(pAllocationRequest-&gt;item);</div><div class="line"><a name="l05697"></a><span class="lineno"> 5697</span>&#160;            --pAllocationRequest-&gt;itemsToMakeLostCount;</div><div class="line"><a name="l05698"></a><span class="lineno"> 5698</span>&#160;        }</div><div class="line"><a name="l05699"></a><span class="lineno"> 5699</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05700"></a><span class="lineno"> 5700</span>&#160;        {</div><div class="line"><a name="l05701"></a><span class="lineno"> 5701</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05702"></a><span class="lineno"> 5702</span>&#160;        }</div><div class="line"><a name="l05703"></a><span class="lineno"> 5703</span>&#160;    }</div><div class="line"><a name="l05704"></a><span class="lineno"> 5704</span>&#160;</div><div class="line"><a name="l05705"></a><span class="lineno"> 5705</span>&#160;    VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l05706"></a><span class="lineno"> 5706</span>&#160;    VMA_ASSERT(pAllocationRequest-&gt;item != m_Suballocations.end());</div><div class="line"><a name="l05707"></a><span class="lineno"> 5707</span>&#160;    VMA_ASSERT(pAllocationRequest-&gt;item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l05708"></a><span class="lineno"> 5708</span>&#160;    </div><div class="line"><a name="l05709"></a><span class="lineno"> 5709</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05710"></a><span class="lineno"> 5710</span>&#160;}</div><div class="line"><a name="l05711"></a><span class="lineno"> 5711</span>&#160;</div><div class="line"><a name="l05712"></a><span class="lineno"> 5712</span>&#160;uint32_t VmaBlockMetadata::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)</div><div class="line"><a name="l05713"></a><span class="lineno"> 5713</span>&#160;{</div><div class="line"><a name="l05714"></a><span class="lineno"> 5714</span>&#160;    uint32_t lostAllocationCount = 0;</div><div class="line"><a name="l05715"></a><span class="lineno"> 5715</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::iterator it = m_Suballocations.begin();</div><div class="line"><a name="l05716"></a><span class="lineno"> 5716</span>&#160;        it != m_Suballocations.end();</div><div class="line"><a name="l05717"></a><span class="lineno"> 5717</span>&#160;        ++it)</div><div class="line"><a name="l05718"></a><span class="lineno"> 5718</span>&#160;    {</div><div class="line"><a name="l05719"></a><span class="lineno"> 5719</span>&#160;        <span class="keywordflow">if</span>(it-&gt;type != VMA_SUBALLOCATION_TYPE_FREE &amp;&amp;</div><div class="line"><a name="l05720"></a><span class="lineno"> 5720</span>&#160;            it-&gt;hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l05721"></a><span class="lineno"> 5721</span>&#160;            it-&gt;hAllocation-&gt;MakeLost(currentFrameIndex, frameInUseCount))</div><div class="line"><a name="l05722"></a><span class="lineno"> 5722</span>&#160;        {</div><div class="line"><a name="l05723"></a><span class="lineno"> 5723</span>&#160;            it = FreeSuballocation(it);</div><div class="line"><a name="l05724"></a><span class="lineno"> 5724</span>&#160;            ++lostAllocationCount;</div><div class="line"><a name="l05725"></a><span class="lineno"> 5725</span>&#160;        }</div><div class="line"><a name="l05726"></a><span class="lineno"> 5726</span>&#160;    }</div><div class="line"><a name="l05727"></a><span class="lineno"> 5727</span>&#160;    <span class="keywordflow">return</span> lostAllocationCount;</div><div class="line"><a name="l05728"></a><span class="lineno"> 5728</span>&#160;}</div><div class="line"><a name="l05729"></a><span class="lineno"> 5729</span>&#160;</div><div class="line"><a name="l05730"></a><span class="lineno"> 5730</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::Alloc(</div><div class="line"><a name="l05731"></a><span class="lineno"> 5731</span>&#160;    <span class="keyword">const</span> VmaAllocationRequest&amp; request,</div><div class="line"><a name="l05732"></a><span class="lineno"> 5732</span>&#160;    VmaSuballocationType type,</div><div class="line"><a name="l05733"></a><span class="lineno"> 5733</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l05734"></a><span class="lineno"> 5734</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l05735"></a><span class="lineno"> 5735</span>&#160;{</div><div class="line"><a name="l05736"></a><span class="lineno"> 5736</span>&#160;    VMA_ASSERT(request.item != m_Suballocations.end());</div><div class="line"><a name="l05737"></a><span class="lineno"> 5737</span>&#160;    VmaSuballocation&amp; suballoc = *request.item;</div><div class="line"><a name="l05738"></a><span class="lineno"> 5738</span>&#160;    <span class="comment">// Given suballocation is a free block.</span></div><div class="line"><a name="l05739"></a><span class="lineno"> 5739</span>&#160;    VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l05740"></a><span class="lineno"> 5740</span>&#160;    <span class="comment">// Given offset is inside this suballocation.</span></div><div class="line"><a name="l05741"></a><span class="lineno"> 5741</span>&#160;    VMA_ASSERT(request.offset &gt;= suballoc.offset);</div><div class="line"><a name="l05742"></a><span class="lineno"> 5742</span>&#160;    <span class="keyword">const</span> VkDeviceSize paddingBegin = request.offset - suballoc.offset;</div><div class="line"><a name="l05743"></a><span class="lineno"> 5743</span>&#160;    VMA_ASSERT(suballoc.size &gt;= paddingBegin + allocSize);</div><div class="line"><a name="l05744"></a><span class="lineno"> 5744</span>&#160;    <span class="keyword">const</span> VkDeviceSize paddingEnd = suballoc.size - paddingBegin - allocSize;</div><div class="line"><a name="l05745"></a><span class="lineno"> 5745</span>&#160;</div><div class="line"><a name="l05746"></a><span class="lineno"> 5746</span>&#160;    <span class="comment">// Unregister this free suballocation from m_FreeSuballocationsBySize and update</span></div><div class="line"><a name="l05747"></a><span class="lineno"> 5747</span>&#160;    <span class="comment">// it to become used.</span></div><div class="line"><a name="l05748"></a><span class="lineno"> 5748</span>&#160;    UnregisterFreeSuballocation(request.item);</div><div class="line"><a name="l05749"></a><span class="lineno"> 5749</span>&#160;</div><div class="line"><a name="l05750"></a><span class="lineno"> 5750</span>&#160;    suballoc.offset = request.offset;</div><div class="line"><a name="l05751"></a><span class="lineno"> 5751</span>&#160;    suballoc.size = allocSize;</div><div class="line"><a name="l05752"></a><span class="lineno"> 5752</span>&#160;    suballoc.type = type;</div><div class="line"><a name="l05753"></a><span class="lineno"> 5753</span>&#160;    suballoc.hAllocation = hAllocation;</div><div class="line"><a name="l05754"></a><span class="lineno"> 5754</span>&#160;</div><div class="line"><a name="l05755"></a><span class="lineno"> 5755</span>&#160;    <span class="comment">// If there are any free bytes remaining at the end, insert new free suballocation after current one.</span></div><div class="line"><a name="l05756"></a><span class="lineno"> 5756</span>&#160;    <span class="keywordflow">if</span>(paddingEnd)</div><div class="line"><a name="l05757"></a><span class="lineno"> 5757</span>&#160;    {</div><div class="line"><a name="l05758"></a><span class="lineno"> 5758</span>&#160;        VmaSuballocation paddingSuballoc = {};</div><div class="line"><a name="l05759"></a><span class="lineno"> 5759</span>&#160;        paddingSuballoc.offset = request.offset + allocSize;</div><div class="line"><a name="l05760"></a><span class="lineno"> 5760</span>&#160;        paddingSuballoc.size = paddingEnd;</div><div class="line"><a name="l05761"></a><span class="lineno"> 5761</span>&#160;        paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l05762"></a><span class="lineno"> 5762</span>&#160;        VmaSuballocationList::iterator next = request.item;</div><div class="line"><a name="l05763"></a><span class="lineno"> 5763</span>&#160;        ++next;</div><div class="line"><a name="l05764"></a><span class="lineno"> 5764</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator paddingEndItem =</div><div class="line"><a name="l05765"></a><span class="lineno"> 5765</span>&#160;            m_Suballocations.insert(next, paddingSuballoc);</div><div class="line"><a name="l05766"></a><span class="lineno"> 5766</span>&#160;        RegisterFreeSuballocation(paddingEndItem);</div><div class="line"><a name="l05767"></a><span class="lineno"> 5767</span>&#160;    }</div><div class="line"><a name="l05768"></a><span class="lineno"> 5768</span>&#160;</div><div class="line"><a name="l05769"></a><span class="lineno"> 5769</span>&#160;    <span class="comment">// If there are any free bytes remaining at the beginning, insert new free suballocation before current one.</span></div><div class="line"><a name="l05770"></a><span class="lineno"> 5770</span>&#160;    <span class="keywordflow">if</span>(paddingBegin)</div><div class="line"><a name="l05771"></a><span class="lineno"> 5771</span>&#160;    {</div><div class="line"><a name="l05772"></a><span class="lineno"> 5772</span>&#160;        VmaSuballocation paddingSuballoc = {};</div><div class="line"><a name="l05773"></a><span class="lineno"> 5773</span>&#160;        paddingSuballoc.offset = request.offset - paddingBegin;</div><div class="line"><a name="l05774"></a><span class="lineno"> 5774</span>&#160;        paddingSuballoc.size = paddingBegin;</div><div class="line"><a name="l05775"></a><span class="lineno"> 5775</span>&#160;        paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l05776"></a><span class="lineno"> 5776</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator paddingBeginItem =</div><div class="line"><a name="l05777"></a><span class="lineno"> 5777</span>&#160;            m_Suballocations.insert(request.item, paddingSuballoc);</div><div class="line"><a name="l05778"></a><span class="lineno"> 5778</span>&#160;        RegisterFreeSuballocation(paddingBeginItem);</div><div class="line"><a name="l05779"></a><span class="lineno"> 5779</span>&#160;    }</div><div class="line"><a name="l05780"></a><span class="lineno"> 5780</span>&#160;</div><div class="line"><a name="l05781"></a><span class="lineno"> 5781</span>&#160;    <span class="comment">// Update totals.</span></div><div class="line"><a name="l05782"></a><span class="lineno"> 5782</span>&#160;    m_FreeCount = m_FreeCount - 1;</div><div class="line"><a name="l05783"></a><span class="lineno"> 5783</span>&#160;    <span class="keywordflow">if</span>(paddingBegin &gt; 0)</div><div class="line"><a name="l05784"></a><span class="lineno"> 5784</span>&#160;    {</div><div class="line"><a name="l05785"></a><span class="lineno"> 5785</span>&#160;        ++m_FreeCount;</div><div class="line"><a name="l05786"></a><span class="lineno"> 5786</span>&#160;    }</div><div class="line"><a name="l05787"></a><span class="lineno"> 5787</span>&#160;    <span class="keywordflow">if</span>(paddingEnd &gt; 0)</div><div class="line"><a name="l05788"></a><span class="lineno"> 5788</span>&#160;    {</div><div class="line"><a name="l05789"></a><span class="lineno"> 5789</span>&#160;        ++m_FreeCount;</div><div class="line"><a name="l05790"></a><span class="lineno"> 5790</span>&#160;    }</div><div class="line"><a name="l05791"></a><span class="lineno"> 5791</span>&#160;    m_SumFreeSize -= allocSize;</div><div class="line"><a name="l05792"></a><span class="lineno"> 5792</span>&#160;}</div><div class="line"><a name="l05793"></a><span class="lineno"> 5793</span>&#160;</div><div class="line"><a name="l05794"></a><span class="lineno"> 5794</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::Free(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l05795"></a><span class="lineno"> 5795</span>&#160;{</div><div class="line"><a name="l05796"></a><span class="lineno"> 5796</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();</div><div class="line"><a name="l05797"></a><span class="lineno"> 5797</span>&#160;        suballocItem != m_Suballocations.end();</div><div class="line"><a name="l05798"></a><span class="lineno"> 5798</span>&#160;        ++suballocItem)</div><div class="line"><a name="l05799"></a><span class="lineno"> 5799</span>&#160;    {</div><div class="line"><a name="l05800"></a><span class="lineno"> 5800</span>&#160;        VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l05801"></a><span class="lineno"> 5801</span>&#160;        <span class="keywordflow">if</span>(suballoc.hAllocation == allocation)</div><div class="line"><a name="l05802"></a><span class="lineno"> 5802</span>&#160;        {</div><div class="line"><a name="l05803"></a><span class="lineno"> 5803</span>&#160;            FreeSuballocation(suballocItem);</div><div class="line"><a name="l05804"></a><span class="lineno"> 5804</span>&#160;            VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l05805"></a><span class="lineno"> 5805</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l05806"></a><span class="lineno"> 5806</span>&#160;        }</div><div class="line"><a name="l05807"></a><span class="lineno"> 5807</span>&#160;    }</div><div class="line"><a name="l05808"></a><span class="lineno"> 5808</span>&#160;    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Not found!&quot;</span>);</div><div class="line"><a name="l05809"></a><span class="lineno"> 5809</span>&#160;}</div><div class="line"><a name="l05810"></a><span class="lineno"> 5810</span>&#160;</div><div class="line"><a name="l05811"></a><span class="lineno"> 5811</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::FreeAtOffset(VkDeviceSize offset)</div><div class="line"><a name="l05812"></a><span class="lineno"> 5812</span>&#160;{</div><div class="line"><a name="l05813"></a><span class="lineno"> 5813</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();</div><div class="line"><a name="l05814"></a><span class="lineno"> 5814</span>&#160;        suballocItem != m_Suballocations.end();</div><div class="line"><a name="l05815"></a><span class="lineno"> 5815</span>&#160;        ++suballocItem)</div><div class="line"><a name="l05816"></a><span class="lineno"> 5816</span>&#160;    {</div><div class="line"><a name="l05817"></a><span class="lineno"> 5817</span>&#160;        VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l05818"></a><span class="lineno"> 5818</span>&#160;        <span class="keywordflow">if</span>(suballoc.offset == offset)</div><div class="line"><a name="l05819"></a><span class="lineno"> 5819</span>&#160;        {</div><div class="line"><a name="l05820"></a><span class="lineno"> 5820</span>&#160;            FreeSuballocation(suballocItem);</div><div class="line"><a name="l05821"></a><span class="lineno"> 5821</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l05822"></a><span class="lineno"> 5822</span>&#160;        }</div><div class="line"><a name="l05823"></a><span class="lineno"> 5823</span>&#160;    }</div><div class="line"><a name="l05824"></a><span class="lineno"> 5824</span>&#160;    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Not found!&quot;</span>);</div><div class="line"><a name="l05825"></a><span class="lineno"> 5825</span>&#160;}</div><div class="line"><a name="l05826"></a><span class="lineno"> 5826</span>&#160;</div><div class="line"><a name="l05827"></a><span class="lineno"> 5827</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata::ValidateFreeSuballocationList()<span class="keyword"> const</span></div><div class="line"><a name="l05828"></a><span class="lineno"> 5828</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05829"></a><span class="lineno"> 5829</span>&#160;    VkDeviceSize lastSize = 0;</div><div class="line"><a name="l05830"></a><span class="lineno"> 5830</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0, count = m_FreeSuballocationsBySize.size(); i &lt; count; ++i)</div><div class="line"><a name="l05831"></a><span class="lineno"> 5831</span>&#160;    {</div><div class="line"><a name="l05832"></a><span class="lineno"> 5832</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i];</div><div class="line"><a name="l05833"></a><span class="lineno"> 5833</span>&#160;</div><div class="line"><a name="l05834"></a><span class="lineno"> 5834</span>&#160;        <span class="keywordflow">if</span>(it-&gt;type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l05835"></a><span class="lineno"> 5835</span>&#160;        {</div><div class="line"><a name="l05836"></a><span class="lineno"> 5836</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l05837"></a><span class="lineno"> 5837</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05838"></a><span class="lineno"> 5838</span>&#160;        }</div><div class="line"><a name="l05839"></a><span class="lineno"> 5839</span>&#160;        <span class="keywordflow">if</span>(it-&gt;size &lt; VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l05840"></a><span class="lineno"> 5840</span>&#160;        {</div><div class="line"><a name="l05841"></a><span class="lineno"> 5841</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l05842"></a><span class="lineno"> 5842</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05843"></a><span class="lineno"> 5843</span>&#160;        }</div><div class="line"><a name="l05844"></a><span class="lineno"> 5844</span>&#160;        <span class="keywordflow">if</span>(it-&gt;size &lt; lastSize)</div><div class="line"><a name="l05845"></a><span class="lineno"> 5845</span>&#160;        {</div><div class="line"><a name="l05846"></a><span class="lineno"> 5846</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l05847"></a><span class="lineno"> 5847</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05848"></a><span class="lineno"> 5848</span>&#160;        }</div><div class="line"><a name="l05849"></a><span class="lineno"> 5849</span>&#160;</div><div class="line"><a name="l05850"></a><span class="lineno"> 5850</span>&#160;        lastSize = it-&gt;size;</div><div class="line"><a name="l05851"></a><span class="lineno"> 5851</span>&#160;    }</div><div class="line"><a name="l05852"></a><span class="lineno"> 5852</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05853"></a><span class="lineno"> 5853</span>&#160;}</div><div class="line"><a name="l05854"></a><span class="lineno"> 5854</span>&#160;</div><div class="line"><a name="l05855"></a><span class="lineno"> 5855</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata::CheckAllocation(</div><div class="line"><a name="l05856"></a><span class="lineno"> 5856</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l05857"></a><span class="lineno"> 5857</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l05858"></a><span class="lineno"> 5858</span>&#160;    VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l05859"></a><span class="lineno"> 5859</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l05860"></a><span class="lineno"> 5860</span>&#160;    VkDeviceSize allocAlignment,</div><div class="line"><a name="l05861"></a><span class="lineno"> 5861</span>&#160;    VmaSuballocationType allocType,</div><div class="line"><a name="l05862"></a><span class="lineno"> 5862</span>&#160;    VmaSuballocationList::const_iterator suballocItem,</div><div class="line"><a name="l05863"></a><span class="lineno"> 5863</span>&#160;    <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l05864"></a><span class="lineno"> 5864</span>&#160;    VkDeviceSize* pOffset,</div><div class="line"><a name="l05865"></a><span class="lineno"> 5865</span>&#160;    <span class="keywordtype">size_t</span>* itemsToMakeLostCount,</div><div class="line"><a name="l05866"></a><span class="lineno"> 5866</span>&#160;    VkDeviceSize* pSumFreeSize,</div><div class="line"><a name="l05867"></a><span class="lineno"> 5867</span>&#160;    VkDeviceSize* pSumItemSize)<span class="keyword"> const</span></div><div class="line"><a name="l05868"></a><span class="lineno"> 5868</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05869"></a><span class="lineno"> 5869</span>&#160;    VMA_ASSERT(allocSize &gt; 0);</div><div class="line"><a name="l05870"></a><span class="lineno"> 5870</span>&#160;    VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l05871"></a><span class="lineno"> 5871</span>&#160;    VMA_ASSERT(suballocItem != m_Suballocations.cend());</div><div class="line"><a name="l05872"></a><span class="lineno"> 5872</span>&#160;    VMA_ASSERT(pOffset != VMA_NULL);</div><div class="line"><a name="l05873"></a><span class="lineno"> 5873</span>&#160;    </div><div class="line"><a name="l05874"></a><span class="lineno"> 5874</span>&#160;    *itemsToMakeLostCount = 0;</div><div class="line"><a name="l05875"></a><span class="lineno"> 5875</span>&#160;    *pSumFreeSize = 0;</div><div class="line"><a name="l05876"></a><span class="lineno"> 5876</span>&#160;    *pSumItemSize = 0;</div><div class="line"><a name="l05877"></a><span class="lineno"> 5877</span>&#160;</div><div class="line"><a name="l05878"></a><span class="lineno"> 5878</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost)</div><div class="line"><a name="l05879"></a><span class="lineno"> 5879</span>&#160;    {</div><div class="line"><a name="l05880"></a><span class="lineno"> 5880</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l05881"></a><span class="lineno"> 5881</span>&#160;        {</div><div class="line"><a name="l05882"></a><span class="lineno"> 5882</span>&#160;            *pSumFreeSize = suballocItem-&gt;size;</div><div class="line"><a name="l05883"></a><span class="lineno"> 5883</span>&#160;        }</div><div class="line"><a name="l05884"></a><span class="lineno"> 5884</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05885"></a><span class="lineno"> 5885</span>&#160;        {</div><div class="line"><a name="l05886"></a><span class="lineno"> 5886</span>&#160;            <span class="keywordflow">if</span>(suballocItem-&gt;hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l05887"></a><span class="lineno"> 5887</span>&#160;                suballocItem-&gt;hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l05888"></a><span class="lineno"> 5888</span>&#160;            {</div><div class="line"><a name="l05889"></a><span class="lineno"> 5889</span>&#160;                ++*itemsToMakeLostCount;</div><div class="line"><a name="l05890"></a><span class="lineno"> 5890</span>&#160;                *pSumItemSize = suballocItem-&gt;size;</div><div class="line"><a name="l05891"></a><span class="lineno"> 5891</span>&#160;            }</div><div class="line"><a name="l05892"></a><span class="lineno"> 5892</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l05893"></a><span class="lineno"> 5893</span>&#160;            {</div><div class="line"><a name="l05894"></a><span class="lineno"> 5894</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05895"></a><span class="lineno"> 5895</span>&#160;            }</div><div class="line"><a name="l05896"></a><span class="lineno"> 5896</span>&#160;        }</div><div class="line"><a name="l05897"></a><span class="lineno"> 5897</span>&#160;</div><div class="line"><a name="l05898"></a><span class="lineno"> 5898</span>&#160;        <span class="comment">// Remaining size is too small for this request: Early return.</span></div><div class="line"><a name="l05899"></a><span class="lineno"> 5899</span>&#160;        <span class="keywordflow">if</span>(m_Size - suballocItem-&gt;offset &lt; allocSize)</div><div class="line"><a name="l05900"></a><span class="lineno"> 5900</span>&#160;        {</div><div class="line"><a name="l05901"></a><span class="lineno"> 5901</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05902"></a><span class="lineno"> 5902</span>&#160;        }</div><div class="line"><a name="l05903"></a><span class="lineno"> 5903</span>&#160;</div><div class="line"><a name="l05904"></a><span class="lineno"> 5904</span>&#160;        <span class="comment">// Start from offset equal to beginning of this suballocation.</span></div><div class="line"><a name="l05905"></a><span class="lineno"> 5905</span>&#160;        *pOffset = suballocItem-&gt;offset;</div><div class="line"><a name="l05906"></a><span class="lineno"> 5906</span>&#160;    </div><div class="line"><a name="l05907"></a><span class="lineno"> 5907</span>&#160;        <span class="comment">// Apply VMA_DEBUG_MARGIN at the beginning.</span></div><div class="line"><a name="l05908"></a><span class="lineno"> 5908</span>&#160;        <span class="keywordflow">if</span>((VMA_DEBUG_MARGIN &gt; 0) &amp;&amp; suballocItem != m_Suballocations.cbegin())</div><div class="line"><a name="l05909"></a><span class="lineno"> 5909</span>&#160;        {</div><div class="line"><a name="l05910"></a><span class="lineno"> 5910</span>&#160;            *pOffset += VMA_DEBUG_MARGIN;</div><div class="line"><a name="l05911"></a><span class="lineno"> 5911</span>&#160;        }</div><div class="line"><a name="l05912"></a><span class="lineno"> 5912</span>&#160;    </div><div class="line"><a name="l05913"></a><span class="lineno"> 5913</span>&#160;        <span class="comment">// Apply alignment.</span></div><div class="line"><a name="l05914"></a><span class="lineno"> 5914</span>&#160;        <span class="keyword">const</span> VkDeviceSize alignment = VMA_MAX(allocAlignment, static_cast&lt;VkDeviceSize&gt;(VMA_DEBUG_ALIGNMENT));</div><div class="line"><a name="l05915"></a><span class="lineno"> 5915</span>&#160;        *pOffset = VmaAlignUp(*pOffset, alignment);</div><div class="line"><a name="l05916"></a><span class="lineno"> 5916</span>&#160;</div><div class="line"><a name="l05917"></a><span class="lineno"> 5917</span>&#160;        <span class="comment">// Check previous suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l05918"></a><span class="lineno"> 5918</span>&#160;        <span class="comment">// Make bigger alignment if necessary.</span></div><div class="line"><a name="l05919"></a><span class="lineno"> 5919</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l05920"></a><span class="lineno"> 5920</span>&#160;        {</div><div class="line"><a name="l05921"></a><span class="lineno"> 5921</span>&#160;            <span class="keywordtype">bool</span> bufferImageGranularityConflict = <span class="keyword">false</span>;</div><div class="line"><a name="l05922"></a><span class="lineno"> 5922</span>&#160;            VmaSuballocationList::const_iterator prevSuballocItem = suballocItem;</div><div class="line"><a name="l05923"></a><span class="lineno"> 5923</span>&#160;            <span class="keywordflow">while</span>(prevSuballocItem != m_Suballocations.cbegin())</div><div class="line"><a name="l05924"></a><span class="lineno"> 5924</span>&#160;            {</div><div class="line"><a name="l05925"></a><span class="lineno"> 5925</span>&#160;                --prevSuballocItem;</div><div class="line"><a name="l05926"></a><span class="lineno"> 5926</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; prevSuballoc = *prevSuballocItem;</div><div class="line"><a name="l05927"></a><span class="lineno"> 5927</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, *pOffset, bufferImageGranularity))</div><div class="line"><a name="l05928"></a><span class="lineno"> 5928</span>&#160;                {</div><div class="line"><a name="l05929"></a><span class="lineno"> 5929</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))</div><div class="line"><a name="l05930"></a><span class="lineno"> 5930</span>&#160;                    {</div><div class="line"><a name="l05931"></a><span class="lineno"> 5931</span>&#160;                        bufferImageGranularityConflict = <span class="keyword">true</span>;</div><div class="line"><a name="l05932"></a><span class="lineno"> 5932</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l05933"></a><span class="lineno"> 5933</span>&#160;                    }</div><div class="line"><a name="l05934"></a><span class="lineno"> 5934</span>&#160;                }</div><div class="line"><a name="l05935"></a><span class="lineno"> 5935</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l05936"></a><span class="lineno"> 5936</span>&#160;                    <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l05937"></a><span class="lineno"> 5937</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l05938"></a><span class="lineno"> 5938</span>&#160;            }</div><div class="line"><a name="l05939"></a><span class="lineno"> 5939</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularityConflict)</div><div class="line"><a name="l05940"></a><span class="lineno"> 5940</span>&#160;            {</div><div class="line"><a name="l05941"></a><span class="lineno"> 5941</span>&#160;                *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity);</div><div class="line"><a name="l05942"></a><span class="lineno"> 5942</span>&#160;            }</div><div class="line"><a name="l05943"></a><span class="lineno"> 5943</span>&#160;        }</div><div class="line"><a name="l05944"></a><span class="lineno"> 5944</span>&#160;    </div><div class="line"><a name="l05945"></a><span class="lineno"> 5945</span>&#160;        <span class="comment">// Now that we have final *pOffset, check if we are past suballocItem.</span></div><div class="line"><a name="l05946"></a><span class="lineno"> 5946</span>&#160;        <span class="comment">// If yes, return false - this function should be called for another suballocItem as starting point.</span></div><div class="line"><a name="l05947"></a><span class="lineno"> 5947</span>&#160;        <span class="keywordflow">if</span>(*pOffset &gt;= suballocItem-&gt;offset + suballocItem-&gt;size)</div><div class="line"><a name="l05948"></a><span class="lineno"> 5948</span>&#160;        {</div><div class="line"><a name="l05949"></a><span class="lineno"> 5949</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05950"></a><span class="lineno"> 5950</span>&#160;        }</div><div class="line"><a name="l05951"></a><span class="lineno"> 5951</span>&#160;    </div><div class="line"><a name="l05952"></a><span class="lineno"> 5952</span>&#160;        <span class="comment">// Calculate padding at the beginning based on current offset.</span></div><div class="line"><a name="l05953"></a><span class="lineno"> 5953</span>&#160;        <span class="keyword">const</span> VkDeviceSize paddingBegin = *pOffset - suballocItem-&gt;offset;</div><div class="line"><a name="l05954"></a><span class="lineno"> 5954</span>&#160;</div><div class="line"><a name="l05955"></a><span class="lineno"> 5955</span>&#160;        <span class="comment">// Calculate required margin at the end if this is not last suballocation.</span></div><div class="line"><a name="l05956"></a><span class="lineno"> 5956</span>&#160;        VmaSuballocationList::const_iterator next = suballocItem;</div><div class="line"><a name="l05957"></a><span class="lineno"> 5957</span>&#160;        ++next;</div><div class="line"><a name="l05958"></a><span class="lineno"> 5958</span>&#160;        <span class="keyword">const</span> VkDeviceSize requiredEndMargin =</div><div class="line"><a name="l05959"></a><span class="lineno"> 5959</span>&#160;            (next != m_Suballocations.cend()) ? VMA_DEBUG_MARGIN : 0;</div><div class="line"><a name="l05960"></a><span class="lineno"> 5960</span>&#160;</div><div class="line"><a name="l05961"></a><span class="lineno"> 5961</span>&#160;        <span class="keyword">const</span> VkDeviceSize totalSize = paddingBegin + allocSize + requiredEndMargin;</div><div class="line"><a name="l05962"></a><span class="lineno"> 5962</span>&#160;        <span class="comment">// Another early return check.</span></div><div class="line"><a name="l05963"></a><span class="lineno"> 5963</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;offset + totalSize &gt; m_Size)</div><div class="line"><a name="l05964"></a><span class="lineno"> 5964</span>&#160;        {</div><div class="line"><a name="l05965"></a><span class="lineno"> 5965</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05966"></a><span class="lineno"> 5966</span>&#160;        }</div><div class="line"><a name="l05967"></a><span class="lineno"> 5967</span>&#160;</div><div class="line"><a name="l05968"></a><span class="lineno"> 5968</span>&#160;        <span class="comment">// Advance lastSuballocItem until desired size is reached.</span></div><div class="line"><a name="l05969"></a><span class="lineno"> 5969</span>&#160;        <span class="comment">// Update itemsToMakeLostCount.</span></div><div class="line"><a name="l05970"></a><span class="lineno"> 5970</span>&#160;        VmaSuballocationList::const_iterator lastSuballocItem = suballocItem;</div><div class="line"><a name="l05971"></a><span class="lineno"> 5971</span>&#160;        <span class="keywordflow">if</span>(totalSize &gt; suballocItem-&gt;size)</div><div class="line"><a name="l05972"></a><span class="lineno"> 5972</span>&#160;        {</div><div class="line"><a name="l05973"></a><span class="lineno"> 5973</span>&#160;            VkDeviceSize remainingSize = totalSize - suballocItem-&gt;size;</div><div class="line"><a name="l05974"></a><span class="lineno"> 5974</span>&#160;            <span class="keywordflow">while</span>(remainingSize &gt; 0)</div><div class="line"><a name="l05975"></a><span class="lineno"> 5975</span>&#160;            {</div><div class="line"><a name="l05976"></a><span class="lineno"> 5976</span>&#160;                ++lastSuballocItem;</div><div class="line"><a name="l05977"></a><span class="lineno"> 5977</span>&#160;                <span class="keywordflow">if</span>(lastSuballocItem == m_Suballocations.cend())</div><div class="line"><a name="l05978"></a><span class="lineno"> 5978</span>&#160;                {</div><div class="line"><a name="l05979"></a><span class="lineno"> 5979</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05980"></a><span class="lineno"> 5980</span>&#160;                }</div><div class="line"><a name="l05981"></a><span class="lineno"> 5981</span>&#160;                <span class="keywordflow">if</span>(lastSuballocItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l05982"></a><span class="lineno"> 5982</span>&#160;                {</div><div class="line"><a name="l05983"></a><span class="lineno"> 5983</span>&#160;                    *pSumFreeSize += lastSuballocItem-&gt;size;</div><div class="line"><a name="l05984"></a><span class="lineno"> 5984</span>&#160;                }</div><div class="line"><a name="l05985"></a><span class="lineno"> 5985</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l05986"></a><span class="lineno"> 5986</span>&#160;                {</div><div class="line"><a name="l05987"></a><span class="lineno"> 5987</span>&#160;                    VMA_ASSERT(lastSuballocItem-&gt;hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l05988"></a><span class="lineno"> 5988</span>&#160;                    <span class="keywordflow">if</span>(lastSuballocItem-&gt;hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l05989"></a><span class="lineno"> 5989</span>&#160;                        lastSuballocItem-&gt;hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l05990"></a><span class="lineno"> 5990</span>&#160;                    {</div><div class="line"><a name="l05991"></a><span class="lineno"> 5991</span>&#160;                        ++*itemsToMakeLostCount;</div><div class="line"><a name="l05992"></a><span class="lineno"> 5992</span>&#160;                        *pSumItemSize += lastSuballocItem-&gt;size;</div><div class="line"><a name="l05993"></a><span class="lineno"> 5993</span>&#160;                    }</div><div class="line"><a name="l05994"></a><span class="lineno"> 5994</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l05995"></a><span class="lineno"> 5995</span>&#160;                    {</div><div class="line"><a name="l05996"></a><span class="lineno"> 5996</span>&#160;                        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05997"></a><span class="lineno"> 5997</span>&#160;                    }</div><div class="line"><a name="l05998"></a><span class="lineno"> 5998</span>&#160;                }</div><div class="line"><a name="l05999"></a><span class="lineno"> 5999</span>&#160;                remainingSize = (lastSuballocItem-&gt;size &lt; remainingSize) ?</div><div class="line"><a name="l06000"></a><span class="lineno"> 6000</span>&#160;                    remainingSize - lastSuballocItem-&gt;size : 0;</div><div class="line"><a name="l06001"></a><span class="lineno"> 6001</span>&#160;            }</div><div class="line"><a name="l06002"></a><span class="lineno"> 6002</span>&#160;        }</div><div class="line"><a name="l06003"></a><span class="lineno"> 6003</span>&#160;</div><div class="line"><a name="l06004"></a><span class="lineno"> 6004</span>&#160;        <span class="comment">// Check next suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l06005"></a><span class="lineno"> 6005</span>&#160;        <span class="comment">// If conflict exists, we must mark more allocations lost or fail.</span></div><div class="line"><a name="l06006"></a><span class="lineno"> 6006</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l06007"></a><span class="lineno"> 6007</span>&#160;        {</div><div class="line"><a name="l06008"></a><span class="lineno"> 6008</span>&#160;            VmaSuballocationList::const_iterator nextSuballocItem = lastSuballocItem;</div><div class="line"><a name="l06009"></a><span class="lineno"> 6009</span>&#160;            ++nextSuballocItem;</div><div class="line"><a name="l06010"></a><span class="lineno"> 6010</span>&#160;            <span class="keywordflow">while</span>(nextSuballocItem != m_Suballocations.cend())</div><div class="line"><a name="l06011"></a><span class="lineno"> 6011</span>&#160;            {</div><div class="line"><a name="l06012"></a><span class="lineno"> 6012</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; nextSuballoc = *nextSuballocItem;</div><div class="line"><a name="l06013"></a><span class="lineno"> 6013</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(*pOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l06014"></a><span class="lineno"> 6014</span>&#160;                {</div><div class="line"><a name="l06015"></a><span class="lineno"> 6015</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))</div><div class="line"><a name="l06016"></a><span class="lineno"> 6016</span>&#160;                    {</div><div class="line"><a name="l06017"></a><span class="lineno"> 6017</span>&#160;                        VMA_ASSERT(nextSuballoc.hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l06018"></a><span class="lineno"> 6018</span>&#160;                        <span class="keywordflow">if</span>(nextSuballoc.hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l06019"></a><span class="lineno"> 6019</span>&#160;                            nextSuballoc.hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l06020"></a><span class="lineno"> 6020</span>&#160;                        {</div><div class="line"><a name="l06021"></a><span class="lineno"> 6021</span>&#160;                            ++*itemsToMakeLostCount;</div><div class="line"><a name="l06022"></a><span class="lineno"> 6022</span>&#160;                        }</div><div class="line"><a name="l06023"></a><span class="lineno"> 6023</span>&#160;                        <span class="keywordflow">else</span></div><div class="line"><a name="l06024"></a><span class="lineno"> 6024</span>&#160;                        {</div><div class="line"><a name="l06025"></a><span class="lineno"> 6025</span>&#160;                            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06026"></a><span class="lineno"> 6026</span>&#160;                        }</div><div class="line"><a name="l06027"></a><span class="lineno"> 6027</span>&#160;                    }</div><div class="line"><a name="l06028"></a><span class="lineno"> 6028</span>&#160;                }</div><div class="line"><a name="l06029"></a><span class="lineno"> 6029</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l06030"></a><span class="lineno"> 6030</span>&#160;                {</div><div class="line"><a name="l06031"></a><span class="lineno"> 6031</span>&#160;                    <span class="comment">// Already on next page.</span></div><div class="line"><a name="l06032"></a><span class="lineno"> 6032</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l06033"></a><span class="lineno"> 6033</span>&#160;                }</div><div class="line"><a name="l06034"></a><span class="lineno"> 6034</span>&#160;                ++nextSuballocItem;</div><div class="line"><a name="l06035"></a><span class="lineno"> 6035</span>&#160;            }</div><div class="line"><a name="l06036"></a><span class="lineno"> 6036</span>&#160;        }</div><div class="line"><a name="l06037"></a><span class="lineno"> 6037</span>&#160;    }</div><div class="line"><a name="l06038"></a><span class="lineno"> 6038</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06039"></a><span class="lineno"> 6039</span>&#160;    {</div><div class="line"><a name="l06040"></a><span class="lineno"> 6040</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l06041"></a><span class="lineno"> 6041</span>&#160;        VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06042"></a><span class="lineno"> 6042</span>&#160;</div><div class="line"><a name="l06043"></a><span class="lineno"> 6043</span>&#160;        *pSumFreeSize = suballoc.size;</div><div class="line"><a name="l06044"></a><span class="lineno"> 6044</span>&#160;</div><div class="line"><a name="l06045"></a><span class="lineno"> 6045</span>&#160;        <span class="comment">// Size of this suballocation is too small for this request: Early return.</span></div><div class="line"><a name="l06046"></a><span class="lineno"> 6046</span>&#160;        <span class="keywordflow">if</span>(suballoc.size &lt; allocSize)</div><div class="line"><a name="l06047"></a><span class="lineno"> 6047</span>&#160;        {</div><div class="line"><a name="l06048"></a><span class="lineno"> 6048</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06049"></a><span class="lineno"> 6049</span>&#160;        }</div><div class="line"><a name="l06050"></a><span class="lineno"> 6050</span>&#160;</div><div class="line"><a name="l06051"></a><span class="lineno"> 6051</span>&#160;        <span class="comment">// Start from offset equal to beginning of this suballocation.</span></div><div class="line"><a name="l06052"></a><span class="lineno"> 6052</span>&#160;        *pOffset = suballoc.offset;</div><div class="line"><a name="l06053"></a><span class="lineno"> 6053</span>&#160;    </div><div class="line"><a name="l06054"></a><span class="lineno"> 6054</span>&#160;        <span class="comment">// Apply VMA_DEBUG_MARGIN at the beginning.</span></div><div class="line"><a name="l06055"></a><span class="lineno"> 6055</span>&#160;        <span class="keywordflow">if</span>((VMA_DEBUG_MARGIN &gt; 0) &amp;&amp; suballocItem != m_Suballocations.cbegin())</div><div class="line"><a name="l06056"></a><span class="lineno"> 6056</span>&#160;        {</div><div class="line"><a name="l06057"></a><span class="lineno"> 6057</span>&#160;            *pOffset += VMA_DEBUG_MARGIN;</div><div class="line"><a name="l06058"></a><span class="lineno"> 6058</span>&#160;        }</div><div class="line"><a name="l06059"></a><span class="lineno"> 6059</span>&#160;    </div><div class="line"><a name="l06060"></a><span class="lineno"> 6060</span>&#160;        <span class="comment">// Apply alignment.</span></div><div class="line"><a name="l06061"></a><span class="lineno"> 6061</span>&#160;        <span class="keyword">const</span> VkDeviceSize alignment = VMA_MAX(allocAlignment, static_cast&lt;VkDeviceSize&gt;(VMA_DEBUG_ALIGNMENT));</div><div class="line"><a name="l06062"></a><span class="lineno"> 6062</span>&#160;        *pOffset = VmaAlignUp(*pOffset, alignment);</div><div class="line"><a name="l06063"></a><span class="lineno"> 6063</span>&#160;    </div><div class="line"><a name="l06064"></a><span class="lineno"> 6064</span>&#160;        <span class="comment">// Check previous suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l06065"></a><span class="lineno"> 6065</span>&#160;        <span class="comment">// Make bigger alignment if necessary.</span></div><div class="line"><a name="l06066"></a><span class="lineno"> 6066</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l06067"></a><span class="lineno"> 6067</span>&#160;        {</div><div class="line"><a name="l06068"></a><span class="lineno"> 6068</span>&#160;            <span class="keywordtype">bool</span> bufferImageGranularityConflict = <span class="keyword">false</span>;</div><div class="line"><a name="l06069"></a><span class="lineno"> 6069</span>&#160;            VmaSuballocationList::const_iterator prevSuballocItem = suballocItem;</div><div class="line"><a name="l06070"></a><span class="lineno"> 6070</span>&#160;            <span class="keywordflow">while</span>(prevSuballocItem != m_Suballocations.cbegin())</div><div class="line"><a name="l06071"></a><span class="lineno"> 6071</span>&#160;            {</div><div class="line"><a name="l06072"></a><span class="lineno"> 6072</span>&#160;                --prevSuballocItem;</div><div class="line"><a name="l06073"></a><span class="lineno"> 6073</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; prevSuballoc = *prevSuballocItem;</div><div class="line"><a name="l06074"></a><span class="lineno"> 6074</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, *pOffset, bufferImageGranularity))</div><div class="line"><a name="l06075"></a><span class="lineno"> 6075</span>&#160;                {</div><div class="line"><a name="l06076"></a><span class="lineno"> 6076</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))</div><div class="line"><a name="l06077"></a><span class="lineno"> 6077</span>&#160;                    {</div><div class="line"><a name="l06078"></a><span class="lineno"> 6078</span>&#160;                        bufferImageGranularityConflict = <span class="keyword">true</span>;</div><div class="line"><a name="l06079"></a><span class="lineno"> 6079</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l06080"></a><span class="lineno"> 6080</span>&#160;                    }</div><div class="line"><a name="l06081"></a><span class="lineno"> 6081</span>&#160;                }</div><div class="line"><a name="l06082"></a><span class="lineno"> 6082</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l06083"></a><span class="lineno"> 6083</span>&#160;                    <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l06084"></a><span class="lineno"> 6084</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l06085"></a><span class="lineno"> 6085</span>&#160;            }</div><div class="line"><a name="l06086"></a><span class="lineno"> 6086</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularityConflict)</div><div class="line"><a name="l06087"></a><span class="lineno"> 6087</span>&#160;            {</div><div class="line"><a name="l06088"></a><span class="lineno"> 6088</span>&#160;                *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity);</div><div class="line"><a name="l06089"></a><span class="lineno"> 6089</span>&#160;            }</div><div class="line"><a name="l06090"></a><span class="lineno"> 6090</span>&#160;        }</div><div class="line"><a name="l06091"></a><span class="lineno"> 6091</span>&#160;    </div><div class="line"><a name="l06092"></a><span class="lineno"> 6092</span>&#160;        <span class="comment">// Calculate padding at the beginning based on current offset.</span></div><div class="line"><a name="l06093"></a><span class="lineno"> 6093</span>&#160;        <span class="keyword">const</span> VkDeviceSize paddingBegin = *pOffset - suballoc.offset;</div><div class="line"><a name="l06094"></a><span class="lineno"> 6094</span>&#160;</div><div class="line"><a name="l06095"></a><span class="lineno"> 6095</span>&#160;        <span class="comment">// Calculate required margin at the end if this is not last suballocation.</span></div><div class="line"><a name="l06096"></a><span class="lineno"> 6096</span>&#160;        VmaSuballocationList::const_iterator next = suballocItem;</div><div class="line"><a name="l06097"></a><span class="lineno"> 6097</span>&#160;        ++next;</div><div class="line"><a name="l06098"></a><span class="lineno"> 6098</span>&#160;        <span class="keyword">const</span> VkDeviceSize requiredEndMargin =</div><div class="line"><a name="l06099"></a><span class="lineno"> 6099</span>&#160;            (next != m_Suballocations.cend()) ? VMA_DEBUG_MARGIN : 0;</div><div class="line"><a name="l06100"></a><span class="lineno"> 6100</span>&#160;</div><div class="line"><a name="l06101"></a><span class="lineno"> 6101</span>&#160;        <span class="comment">// Fail if requested size plus margin before and after is bigger than size of this suballocation.</span></div><div class="line"><a name="l06102"></a><span class="lineno"> 6102</span>&#160;        <span class="keywordflow">if</span>(paddingBegin + allocSize + requiredEndMargin &gt; suballoc.size)</div><div class="line"><a name="l06103"></a><span class="lineno"> 6103</span>&#160;        {</div><div class="line"><a name="l06104"></a><span class="lineno"> 6104</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06105"></a><span class="lineno"> 6105</span>&#160;        }</div><div class="line"><a name="l06106"></a><span class="lineno"> 6106</span>&#160;</div><div class="line"><a name="l06107"></a><span class="lineno"> 6107</span>&#160;        <span class="comment">// Check next suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l06108"></a><span class="lineno"> 6108</span>&#160;        <span class="comment">// If conflict exists, allocation cannot be made here.</span></div><div class="line"><a name="l06109"></a><span class="lineno"> 6109</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l06110"></a><span class="lineno"> 6110</span>&#160;        {</div><div class="line"><a name="l06111"></a><span class="lineno"> 6111</span>&#160;            VmaSuballocationList::const_iterator nextSuballocItem = suballocItem;</div><div class="line"><a name="l06112"></a><span class="lineno"> 6112</span>&#160;            ++nextSuballocItem;</div><div class="line"><a name="l06113"></a><span class="lineno"> 6113</span>&#160;            <span class="keywordflow">while</span>(nextSuballocItem != m_Suballocations.cend())</div><div class="line"><a name="l06114"></a><span class="lineno"> 6114</span>&#160;            {</div><div class="line"><a name="l06115"></a><span class="lineno"> 6115</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; nextSuballoc = *nextSuballocItem;</div><div class="line"><a name="l06116"></a><span class="lineno"> 6116</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(*pOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l06117"></a><span class="lineno"> 6117</span>&#160;                {</div><div class="line"><a name="l06118"></a><span class="lineno"> 6118</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))</div><div class="line"><a name="l06119"></a><span class="lineno"> 6119</span>&#160;                    {</div><div class="line"><a name="l06120"></a><span class="lineno"> 6120</span>&#160;                        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06121"></a><span class="lineno"> 6121</span>&#160;                    }</div><div class="line"><a name="l06122"></a><span class="lineno"> 6122</span>&#160;                }</div><div class="line"><a name="l06123"></a><span class="lineno"> 6123</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l06124"></a><span class="lineno"> 6124</span>&#160;                {</div><div class="line"><a name="l06125"></a><span class="lineno"> 6125</span>&#160;                    <span class="comment">// Already on next page.</span></div><div class="line"><a name="l06126"></a><span class="lineno"> 6126</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l06127"></a><span class="lineno"> 6127</span>&#160;                }</div><div class="line"><a name="l06128"></a><span class="lineno"> 6128</span>&#160;                ++nextSuballocItem;</div><div class="line"><a name="l06129"></a><span class="lineno"> 6129</span>&#160;            }</div><div class="line"><a name="l06130"></a><span class="lineno"> 6130</span>&#160;        }</div><div class="line"><a name="l06131"></a><span class="lineno"> 6131</span>&#160;    }</div><div class="line"><a name="l06132"></a><span class="lineno"> 6132</span>&#160;</div><div class="line"><a name="l06133"></a><span class="lineno"> 6133</span>&#160;    <span class="comment">// All tests passed: Success. pOffset is already filled.</span></div><div class="line"><a name="l06134"></a><span class="lineno"> 6134</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06135"></a><span class="lineno"> 6135</span>&#160;}</div><div class="line"><a name="l06136"></a><span class="lineno"> 6136</span>&#160;</div><div class="line"><a name="l06137"></a><span class="lineno"> 6137</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::MergeFreeWithNext(VmaSuballocationList::iterator item)</div><div class="line"><a name="l06138"></a><span class="lineno"> 6138</span>&#160;{</div><div class="line"><a name="l06139"></a><span class="lineno"> 6139</span>&#160;    VMA_ASSERT(item != m_Suballocations.end());</div><div class="line"><a name="l06140"></a><span class="lineno"> 6140</span>&#160;    VMA_ASSERT(item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06141"></a><span class="lineno"> 6141</span>&#160;    </div><div class="line"><a name="l06142"></a><span class="lineno"> 6142</span>&#160;    VmaSuballocationList::iterator nextItem = item;</div><div class="line"><a name="l06143"></a><span class="lineno"> 6143</span>&#160;    ++nextItem;</div><div class="line"><a name="l06144"></a><span class="lineno"> 6144</span>&#160;    VMA_ASSERT(nextItem != m_Suballocations.end());</div><div class="line"><a name="l06145"></a><span class="lineno"> 6145</span>&#160;    VMA_ASSERT(nextItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06146"></a><span class="lineno"> 6146</span>&#160;</div><div class="line"><a name="l06147"></a><span class="lineno"> 6147</span>&#160;    item-&gt;size += nextItem-&gt;size;</div><div class="line"><a name="l06148"></a><span class="lineno"> 6148</span>&#160;    --m_FreeCount;</div><div class="line"><a name="l06149"></a><span class="lineno"> 6149</span>&#160;    m_Suballocations.erase(nextItem);</div><div class="line"><a name="l06150"></a><span class="lineno"> 6150</span>&#160;}</div><div class="line"><a name="l06151"></a><span class="lineno"> 6151</span>&#160;</div><div class="line"><a name="l06152"></a><span class="lineno"> 6152</span>&#160;VmaSuballocationList::iterator VmaBlockMetadata::FreeSuballocation(VmaSuballocationList::iterator suballocItem)</div><div class="line"><a name="l06153"></a><span class="lineno"> 6153</span>&#160;{</div><div class="line"><a name="l06154"></a><span class="lineno"> 6154</span>&#160;    <span class="comment">// Change this suballocation to be marked as free.</span></div><div class="line"><a name="l06155"></a><span class="lineno"> 6155</span>&#160;    VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l06156"></a><span class="lineno"> 6156</span>&#160;    suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l06157"></a><span class="lineno"> 6157</span>&#160;    suballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l06158"></a><span class="lineno"> 6158</span>&#160;    </div><div class="line"><a name="l06159"></a><span class="lineno"> 6159</span>&#160;    <span class="comment">// Update totals.</span></div><div class="line"><a name="l06160"></a><span class="lineno"> 6160</span>&#160;    ++m_FreeCount;</div><div class="line"><a name="l06161"></a><span class="lineno"> 6161</span>&#160;    m_SumFreeSize += suballoc.size;</div><div class="line"><a name="l06162"></a><span class="lineno"> 6162</span>&#160;</div><div class="line"><a name="l06163"></a><span class="lineno"> 6163</span>&#160;    <span class="comment">// Merge with previous and/or next suballocation if it&#39;s also free.</span></div><div class="line"><a name="l06164"></a><span class="lineno"> 6164</span>&#160;    <span class="keywordtype">bool</span> mergeWithNext = <span class="keyword">false</span>;</div><div class="line"><a name="l06165"></a><span class="lineno"> 6165</span>&#160;    <span class="keywordtype">bool</span> mergeWithPrev = <span class="keyword">false</span>;</div><div class="line"><a name="l06166"></a><span class="lineno"> 6166</span>&#160;    </div><div class="line"><a name="l06167"></a><span class="lineno"> 6167</span>&#160;    VmaSuballocationList::iterator nextItem = suballocItem;</div><div class="line"><a name="l06168"></a><span class="lineno"> 6168</span>&#160;    ++nextItem;</div><div class="line"><a name="l06169"></a><span class="lineno"> 6169</span>&#160;    <span class="keywordflow">if</span>((nextItem != m_Suballocations.end()) &amp;&amp; (nextItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE))</div><div class="line"><a name="l06170"></a><span class="lineno"> 6170</span>&#160;    {</div><div class="line"><a name="l06171"></a><span class="lineno"> 6171</span>&#160;        mergeWithNext = <span class="keyword">true</span>;</div><div class="line"><a name="l06172"></a><span class="lineno"> 6172</span>&#160;    }</div><div class="line"><a name="l06173"></a><span class="lineno"> 6173</span>&#160;</div><div class="line"><a name="l06174"></a><span class="lineno"> 6174</span>&#160;    VmaSuballocationList::iterator prevItem = suballocItem;</div><div class="line"><a name="l06175"></a><span class="lineno"> 6175</span>&#160;    <span class="keywordflow">if</span>(suballocItem != m_Suballocations.begin())</div><div class="line"><a name="l06176"></a><span class="lineno"> 6176</span>&#160;    {</div><div class="line"><a name="l06177"></a><span class="lineno"> 6177</span>&#160;        --prevItem;</div><div class="line"><a name="l06178"></a><span class="lineno"> 6178</span>&#160;        <span class="keywordflow">if</span>(prevItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06179"></a><span class="lineno"> 6179</span>&#160;        {</div><div class="line"><a name="l06180"></a><span class="lineno"> 6180</span>&#160;            mergeWithPrev = <span class="keyword">true</span>;</div><div class="line"><a name="l06181"></a><span class="lineno"> 6181</span>&#160;        }</div><div class="line"><a name="l06182"></a><span class="lineno"> 6182</span>&#160;    }</div><div class="line"><a name="l06183"></a><span class="lineno"> 6183</span>&#160;</div><div class="line"><a name="l06184"></a><span class="lineno"> 6184</span>&#160;    <span class="keywordflow">if</span>(mergeWithNext)</div><div class="line"><a name="l06185"></a><span class="lineno"> 6185</span>&#160;    {</div><div class="line"><a name="l06186"></a><span class="lineno"> 6186</span>&#160;        UnregisterFreeSuballocation(nextItem);</div><div class="line"><a name="l06187"></a><span class="lineno"> 6187</span>&#160;        MergeFreeWithNext(suballocItem);</div><div class="line"><a name="l06188"></a><span class="lineno"> 6188</span>&#160;    }</div><div class="line"><a name="l06189"></a><span class="lineno"> 6189</span>&#160;</div><div class="line"><a name="l06190"></a><span class="lineno"> 6190</span>&#160;    <span class="keywordflow">if</span>(mergeWithPrev)</div><div class="line"><a name="l06191"></a><span class="lineno"> 6191</span>&#160;    {</div><div class="line"><a name="l06192"></a><span class="lineno"> 6192</span>&#160;        UnregisterFreeSuballocation(prevItem);</div><div class="line"><a name="l06193"></a><span class="lineno"> 6193</span>&#160;        MergeFreeWithNext(prevItem);</div><div class="line"><a name="l06194"></a><span class="lineno"> 6194</span>&#160;        RegisterFreeSuballocation(prevItem);</div><div class="line"><a name="l06195"></a><span class="lineno"> 6195</span>&#160;        <span class="keywordflow">return</span> prevItem;</div><div class="line"><a name="l06196"></a><span class="lineno"> 6196</span>&#160;    }</div><div class="line"><a name="l06197"></a><span class="lineno"> 6197</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06198"></a><span class="lineno"> 6198</span>&#160;    {</div><div class="line"><a name="l06199"></a><span class="lineno"> 6199</span>&#160;        RegisterFreeSuballocation(suballocItem);</div><div class="line"><a name="l06200"></a><span class="lineno"> 6200</span>&#160;        <span class="keywordflow">return</span> suballocItem;</div><div class="line"><a name="l06201"></a><span class="lineno"> 6201</span>&#160;    }</div><div class="line"><a name="l06202"></a><span class="lineno"> 6202</span>&#160;}</div><div class="line"><a name="l06203"></a><span class="lineno"> 6203</span>&#160;</div><div class="line"><a name="l06204"></a><span class="lineno"> 6204</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::RegisterFreeSuballocation(VmaSuballocationList::iterator item)</div><div class="line"><a name="l06205"></a><span class="lineno"> 6205</span>&#160;{</div><div class="line"><a name="l06206"></a><span class="lineno"> 6206</span>&#160;    VMA_ASSERT(item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06207"></a><span class="lineno"> 6207</span>&#160;    VMA_ASSERT(item-&gt;size &gt; 0);</div><div class="line"><a name="l06208"></a><span class="lineno"> 6208</span>&#160;</div><div class="line"><a name="l06209"></a><span class="lineno"> 6209</span>&#160;    <span class="comment">// You may want to enable this validation at the beginning or at the end of</span></div><div class="line"><a name="l06210"></a><span class="lineno"> 6210</span>&#160;    <span class="comment">// this function, depending on what do you want to check.</span></div><div class="line"><a name="l06211"></a><span class="lineno"> 6211</span>&#160;    VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</div><div class="line"><a name="l06212"></a><span class="lineno"> 6212</span>&#160;</div><div class="line"><a name="l06213"></a><span class="lineno"> 6213</span>&#160;    <span class="keywordflow">if</span>(item-&gt;size &gt;= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l06214"></a><span class="lineno"> 6214</span>&#160;    {</div><div class="line"><a name="l06215"></a><span class="lineno"> 6215</span>&#160;        <span class="keywordflow">if</span>(m_FreeSuballocationsBySize.empty())</div><div class="line"><a name="l06216"></a><span class="lineno"> 6216</span>&#160;        {</div><div class="line"><a name="l06217"></a><span class="lineno"> 6217</span>&#160;            m_FreeSuballocationsBySize.push_back(item);</div><div class="line"><a name="l06218"></a><span class="lineno"> 6218</span>&#160;        }</div><div class="line"><a name="l06219"></a><span class="lineno"> 6219</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06220"></a><span class="lineno"> 6220</span>&#160;        {</div><div class="line"><a name="l06221"></a><span class="lineno"> 6221</span>&#160;            VmaVectorInsertSorted&lt;VmaSuballocationItemSizeLess&gt;(m_FreeSuballocationsBySize, item);</div><div class="line"><a name="l06222"></a><span class="lineno"> 6222</span>&#160;        }</div><div class="line"><a name="l06223"></a><span class="lineno"> 6223</span>&#160;    }</div><div class="line"><a name="l06224"></a><span class="lineno"> 6224</span>&#160;</div><div class="line"><a name="l06225"></a><span class="lineno"> 6225</span>&#160;    <span class="comment">//VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</span></div><div class="line"><a name="l06226"></a><span class="lineno"> 6226</span>&#160;}</div><div class="line"><a name="l06227"></a><span class="lineno"> 6227</span>&#160;</div><div class="line"><a name="l06228"></a><span class="lineno"> 6228</span>&#160;</div><div class="line"><a name="l06229"></a><span class="lineno"> 6229</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::UnregisterFreeSuballocation(VmaSuballocationList::iterator item)</div><div class="line"><a name="l06230"></a><span class="lineno"> 6230</span>&#160;{</div><div class="line"><a name="l06231"></a><span class="lineno"> 6231</span>&#160;    VMA_ASSERT(item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06232"></a><span class="lineno"> 6232</span>&#160;    VMA_ASSERT(item-&gt;size &gt; 0);</div><div class="line"><a name="l06233"></a><span class="lineno"> 6233</span>&#160;</div><div class="line"><a name="l06234"></a><span class="lineno"> 6234</span>&#160;    <span class="comment">// You may want to enable this validation at the beginning or at the end of</span></div><div class="line"><a name="l06235"></a><span class="lineno"> 6235</span>&#160;    <span class="comment">// this function, depending on what do you want to check.</span></div><div class="line"><a name="l06236"></a><span class="lineno"> 6236</span>&#160;    VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</div><div class="line"><a name="l06237"></a><span class="lineno"> 6237</span>&#160;</div><div class="line"><a name="l06238"></a><span class="lineno"> 6238</span>&#160;    <span class="keywordflow">if</span>(item-&gt;size &gt;= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l06239"></a><span class="lineno"> 6239</span>&#160;    {</div><div class="line"><a name="l06240"></a><span class="lineno"> 6240</span>&#160;        VmaSuballocationList::iterator* <span class="keyword">const</span> it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l06241"></a><span class="lineno"> 6241</span>&#160;            m_FreeSuballocationsBySize.data(),</div><div class="line"><a name="l06242"></a><span class="lineno"> 6242</span>&#160;            m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(),</div><div class="line"><a name="l06243"></a><span class="lineno"> 6243</span>&#160;            item,</div><div class="line"><a name="l06244"></a><span class="lineno"> 6244</span>&#160;            VmaSuballocationItemSizeLess());</div><div class="line"><a name="l06245"></a><span class="lineno"> 6245</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> index = it - m_FreeSuballocationsBySize.data();</div><div class="line"><a name="l06246"></a><span class="lineno"> 6246</span>&#160;            index &lt; m_FreeSuballocationsBySize.size();</div><div class="line"><a name="l06247"></a><span class="lineno"> 6247</span>&#160;            ++index)</div><div class="line"><a name="l06248"></a><span class="lineno"> 6248</span>&#160;        {</div><div class="line"><a name="l06249"></a><span class="lineno"> 6249</span>&#160;            <span class="keywordflow">if</span>(m_FreeSuballocationsBySize[index] == item)</div><div class="line"><a name="l06250"></a><span class="lineno"> 6250</span>&#160;            {</div><div class="line"><a name="l06251"></a><span class="lineno"> 6251</span>&#160;                VmaVectorRemove(m_FreeSuballocationsBySize, index);</div><div class="line"><a name="l06252"></a><span class="lineno"> 6252</span>&#160;                <span class="keywordflow">return</span>;</div><div class="line"><a name="l06253"></a><span class="lineno"> 6253</span>&#160;            }</div><div class="line"><a name="l06254"></a><span class="lineno"> 6254</span>&#160;            VMA_ASSERT((m_FreeSuballocationsBySize[index]-&gt;size == item-&gt;size) &amp;&amp; <span class="stringliteral">&quot;Not found.&quot;</span>);</div><div class="line"><a name="l06255"></a><span class="lineno"> 6255</span>&#160;        }</div><div class="line"><a name="l06256"></a><span class="lineno"> 6256</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Not found.&quot;</span>);</div><div class="line"><a name="l06257"></a><span class="lineno"> 6257</span>&#160;    }</div><div class="line"><a name="l06258"></a><span class="lineno"> 6258</span>&#160;</div><div class="line"><a name="l06259"></a><span class="lineno"> 6259</span>&#160;    <span class="comment">//VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</span></div><div class="line"><a name="l06260"></a><span class="lineno"> 6260</span>&#160;}</div><div class="line"><a name="l06261"></a><span class="lineno"> 6261</span>&#160;</div><div class="line"><a name="l06263"></a><span class="lineno"> 6263</span>&#160;<span class="comment">// class VmaDeviceMemoryBlock</span></div><div class="line"><a name="l06264"></a><span class="lineno"> 6264</span>&#160;</div><div class="line"><a name="l06265"></a><span class="lineno"> 6265</span>&#160;VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator) :</div><div class="line"><a name="l06266"></a><span class="lineno"> 6266</span>&#160;    m_Metadata(hAllocator),</div><div class="line"><a name="l06267"></a><span class="lineno"> 6267</span>&#160;    m_MemoryTypeIndex(UINT32_MAX),</div><div class="line"><a name="l06268"></a><span class="lineno"> 6268</span>&#160;    m_hMemory(VK_NULL_HANDLE),</div><div class="line"><a name="l06269"></a><span class="lineno"> 6269</span>&#160;    m_MapCount(0),</div><div class="line"><a name="l06270"></a><span class="lineno"> 6270</span>&#160;    m_pMappedData(VMA_NULL)</div><div class="line"><a name="l06271"></a><span class="lineno"> 6271</span>&#160;{</div><div class="line"><a name="l06272"></a><span class="lineno"> 6272</span>&#160;}</div><div class="line"><a name="l06273"></a><span class="lineno"> 6273</span>&#160;</div><div class="line"><a name="l06274"></a><span class="lineno"> 6274</span>&#160;<span class="keywordtype">void</span> VmaDeviceMemoryBlock::Init(</div><div class="line"><a name="l06275"></a><span class="lineno"> 6275</span>&#160;    uint32_t newMemoryTypeIndex,</div><div class="line"><a name="l06276"></a><span class="lineno"> 6276</span>&#160;    VkDeviceMemory newMemory,</div><div class="line"><a name="l06277"></a><span class="lineno"> 6277</span>&#160;    VkDeviceSize newSize)</div><div class="line"><a name="l06278"></a><span class="lineno"> 6278</span>&#160;{</div><div class="line"><a name="l06279"></a><span class="lineno"> 6279</span>&#160;    VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);</div><div class="line"><a name="l06280"></a><span class="lineno"> 6280</span>&#160;</div><div class="line"><a name="l06281"></a><span class="lineno"> 6281</span>&#160;    m_MemoryTypeIndex = newMemoryTypeIndex;</div><div class="line"><a name="l06282"></a><span class="lineno"> 6282</span>&#160;    m_hMemory = newMemory;</div><div class="line"><a name="l06283"></a><span class="lineno"> 6283</span>&#160;</div><div class="line"><a name="l06284"></a><span class="lineno"> 6284</span>&#160;    m_Metadata.Init(newSize);</div><div class="line"><a name="l06285"></a><span class="lineno"> 6285</span>&#160;}</div><div class="line"><a name="l06286"></a><span class="lineno"> 6286</span>&#160;</div><div class="line"><a name="l06287"></a><span class="lineno"> 6287</span>&#160;<span class="keywordtype">void</span> VmaDeviceMemoryBlock::Destroy(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator)</div><div class="line"><a name="l06288"></a><span class="lineno"> 6288</span>&#160;{</div><div class="line"><a name="l06289"></a><span class="lineno"> 6289</span>&#160;    <span class="comment">// This is the most important assert in the entire library.</span></div><div class="line"><a name="l06290"></a><span class="lineno"> 6290</span>&#160;    <span class="comment">// Hitting it means you have some memory leak - unreleased VmaAllocation objects.</span></div><div class="line"><a name="l06291"></a><span class="lineno"> 6291</span>&#160;    VMA_ASSERT(m_Metadata.IsEmpty() &amp;&amp; <span class="stringliteral">&quot;Some allocations were not freed before destruction of this memory block!&quot;</span>);</div><div class="line"><a name="l06292"></a><span class="lineno"> 6292</span>&#160;    </div><div class="line"><a name="l06293"></a><span class="lineno"> 6293</span>&#160;    VMA_ASSERT(m_hMemory != VK_NULL_HANDLE);</div><div class="line"><a name="l06294"></a><span class="lineno"> 6294</span>&#160;    allocator-&gt;FreeVulkanMemory(m_MemoryTypeIndex, m_Metadata.GetSize(), m_hMemory);</div><div class="line"><a name="l06295"></a><span class="lineno"> 6295</span>&#160;    m_hMemory = VK_NULL_HANDLE;</div><div class="line"><a name="l06296"></a><span class="lineno"> 6296</span>&#160;}</div><div class="line"><a name="l06297"></a><span class="lineno"> 6297</span>&#160;</div><div class="line"><a name="l06298"></a><span class="lineno"> 6298</span>&#160;<span class="keywordtype">bool</span> VmaDeviceMemoryBlock::Validate()<span class="keyword"> const</span></div><div class="line"><a name="l06299"></a><span class="lineno"> 6299</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06300"></a><span class="lineno"> 6300</span>&#160;    <span class="keywordflow">if</span>((m_hMemory == VK_NULL_HANDLE) ||</div><div class="line"><a name="l06301"></a><span class="lineno"> 6301</span>&#160;        (m_Metadata.GetSize() == 0))</div><div class="line"><a name="l06302"></a><span class="lineno"> 6302</span>&#160;    {</div><div class="line"><a name="l06303"></a><span class="lineno"> 6303</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06304"></a><span class="lineno"> 6304</span>&#160;    }</div><div class="line"><a name="l06305"></a><span class="lineno"> 6305</span>&#160;    </div><div class="line"><a name="l06306"></a><span class="lineno"> 6306</span>&#160;    <span class="keywordflow">return</span> m_Metadata.Validate();</div><div class="line"><a name="l06307"></a><span class="lineno"> 6307</span>&#160;}</div><div class="line"><a name="l06308"></a><span class="lineno"> 6308</span>&#160;</div><div class="line"><a name="l06309"></a><span class="lineno"> 6309</span>&#160;VkResult VmaDeviceMemoryBlock::Map(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count, <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l06310"></a><span class="lineno"> 6310</span>&#160;{</div><div class="line"><a name="l06311"></a><span class="lineno"> 6311</span>&#160;    <span class="keywordflow">if</span>(count == 0)</div><div class="line"><a name="l06312"></a><span class="lineno"> 6312</span>&#160;    {</div><div class="line"><a name="l06313"></a><span class="lineno"> 6313</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06314"></a><span class="lineno"> 6314</span>&#160;    }</div><div class="line"><a name="l06315"></a><span class="lineno"> 6315</span>&#160;</div><div class="line"><a name="l06316"></a><span class="lineno"> 6316</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06317"></a><span class="lineno"> 6317</span>&#160;    <span class="keywordflow">if</span>(m_MapCount != 0)</div><div class="line"><a name="l06318"></a><span class="lineno"> 6318</span>&#160;    {</div><div class="line"><a name="l06319"></a><span class="lineno"> 6319</span>&#160;        m_MapCount += count;</div><div class="line"><a name="l06320"></a><span class="lineno"> 6320</span>&#160;        VMA_ASSERT(m_pMappedData != VMA_NULL);</div><div class="line"><a name="l06321"></a><span class="lineno"> 6321</span>&#160;        <span class="keywordflow">if</span>(ppData != VMA_NULL)</div><div class="line"><a name="l06322"></a><span class="lineno"> 6322</span>&#160;        {</div><div class="line"><a name="l06323"></a><span class="lineno"> 6323</span>&#160;            *ppData = m_pMappedData;</div><div class="line"><a name="l06324"></a><span class="lineno"> 6324</span>&#160;        }</div><div class="line"><a name="l06325"></a><span class="lineno"> 6325</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06326"></a><span class="lineno"> 6326</span>&#160;    }</div><div class="line"><a name="l06327"></a><span class="lineno"> 6327</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06328"></a><span class="lineno"> 6328</span>&#160;    {</div><div class="line"><a name="l06329"></a><span class="lineno"> 6329</span>&#160;        VkResult result = (*hAllocator-&gt;GetVulkanFunctions().vkMapMemory)(</div><div class="line"><a name="l06330"></a><span class="lineno"> 6330</span>&#160;            hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l06331"></a><span class="lineno"> 6331</span>&#160;            m_hMemory,</div><div class="line"><a name="l06332"></a><span class="lineno"> 6332</span>&#160;            0, <span class="comment">// offset</span></div><div class="line"><a name="l06333"></a><span class="lineno"> 6333</span>&#160;            VK_WHOLE_SIZE,</div><div class="line"><a name="l06334"></a><span class="lineno"> 6334</span>&#160;            0, <span class="comment">// flags</span></div><div class="line"><a name="l06335"></a><span class="lineno"> 6335</span>&#160;            &amp;m_pMappedData);</div><div class="line"><a name="l06336"></a><span class="lineno"> 6336</span>&#160;        <span class="keywordflow">if</span>(result == VK_SUCCESS)</div><div class="line"><a name="l06337"></a><span class="lineno"> 6337</span>&#160;        {</div><div class="line"><a name="l06338"></a><span class="lineno"> 6338</span>&#160;            <span class="keywordflow">if</span>(ppData != VMA_NULL)</div><div class="line"><a name="l06339"></a><span class="lineno"> 6339</span>&#160;            {</div><div class="line"><a name="l06340"></a><span class="lineno"> 6340</span>&#160;                *ppData = m_pMappedData;</div><div class="line"><a name="l06341"></a><span class="lineno"> 6341</span>&#160;            }</div><div class="line"><a name="l06342"></a><span class="lineno"> 6342</span>&#160;            m_MapCount = count;</div><div class="line"><a name="l06343"></a><span class="lineno"> 6343</span>&#160;        }</div><div class="line"><a name="l06344"></a><span class="lineno"> 6344</span>&#160;        <span class="keywordflow">return</span> result;</div><div class="line"><a name="l06345"></a><span class="lineno"> 6345</span>&#160;    }</div><div class="line"><a name="l06346"></a><span class="lineno"> 6346</span>&#160;}</div><div class="line"><a name="l06347"></a><span class="lineno"> 6347</span>&#160;</div><div class="line"><a name="l06348"></a><span class="lineno"> 6348</span>&#160;<span class="keywordtype">void</span> VmaDeviceMemoryBlock::Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count)</div><div class="line"><a name="l06349"></a><span class="lineno"> 6349</span>&#160;{</div><div class="line"><a name="l06350"></a><span class="lineno"> 6350</span>&#160;    <span class="keywordflow">if</span>(count == 0)</div><div class="line"><a name="l06351"></a><span class="lineno"> 6351</span>&#160;    {</div><div class="line"><a name="l06352"></a><span class="lineno"> 6352</span>&#160;        <span class="keywordflow">return</span>;</div><div class="line"><a name="l06353"></a><span class="lineno"> 6353</span>&#160;    }</div><div class="line"><a name="l06354"></a><span class="lineno"> 6354</span>&#160;</div><div class="line"><a name="l06355"></a><span class="lineno"> 6355</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06356"></a><span class="lineno"> 6356</span>&#160;    <span class="keywordflow">if</span>(m_MapCount &gt;= count)</div><div class="line"><a name="l06357"></a><span class="lineno"> 6357</span>&#160;    {</div><div class="line"><a name="l06358"></a><span class="lineno"> 6358</span>&#160;        m_MapCount -= count;</div><div class="line"><a name="l06359"></a><span class="lineno"> 6359</span>&#160;        <span class="keywordflow">if</span>(m_MapCount == 0)</div><div class="line"><a name="l06360"></a><span class="lineno"> 6360</span>&#160;        {</div><div class="line"><a name="l06361"></a><span class="lineno"> 6361</span>&#160;            m_pMappedData = VMA_NULL;</div><div class="line"><a name="l06362"></a><span class="lineno"> 6362</span>&#160;            (*hAllocator-&gt;GetVulkanFunctions().vkUnmapMemory)(hAllocator-&gt;m_hDevice, m_hMemory);</div><div class="line"><a name="l06363"></a><span class="lineno"> 6363</span>&#160;        }</div><div class="line"><a name="l06364"></a><span class="lineno"> 6364</span>&#160;    }</div><div class="line"><a name="l06365"></a><span class="lineno"> 6365</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06366"></a><span class="lineno"> 6366</span>&#160;    {</div><div class="line"><a name="l06367"></a><span class="lineno"> 6367</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;VkDeviceMemory block is being unmapped while it was not previously mapped.&quot;</span>);</div><div class="line"><a name="l06368"></a><span class="lineno"> 6368</span>&#160;    }</div><div class="line"><a name="l06369"></a><span class="lineno"> 6369</span>&#160;}</div><div class="line"><a name="l06370"></a><span class="lineno"> 6370</span>&#160;</div><div class="line"><a name="l06371"></a><span class="lineno"> 6371</span>&#160;VkResult VmaDeviceMemoryBlock::BindBufferMemory(</div><div class="line"><a name="l06372"></a><span class="lineno"> 6372</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l06373"></a><span class="lineno"> 6373</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l06374"></a><span class="lineno"> 6374</span>&#160;    VkBuffer hBuffer)</div><div class="line"><a name="l06375"></a><span class="lineno"> 6375</span>&#160;{</div><div class="line"><a name="l06376"></a><span class="lineno"> 6376</span>&#160;    VMA_ASSERT(hAllocation-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &amp;&amp;</div><div class="line"><a name="l06377"></a><span class="lineno"> 6377</span>&#160;        hAllocation-&gt;GetBlock() == <span class="keyword">this</span>);</div><div class="line"><a name="l06378"></a><span class="lineno"> 6378</span>&#160;    <span class="comment">// This lock is important so that we don&#39;t call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.</span></div><div class="line"><a name="l06379"></a><span class="lineno"> 6379</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06380"></a><span class="lineno"> 6380</span>&#160;    <span class="keywordflow">return</span> hAllocator-&gt;GetVulkanFunctions().vkBindBufferMemory(</div><div class="line"><a name="l06381"></a><span class="lineno"> 6381</span>&#160;        hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l06382"></a><span class="lineno"> 6382</span>&#160;        hBuffer,</div><div class="line"><a name="l06383"></a><span class="lineno"> 6383</span>&#160;        m_hMemory,</div><div class="line"><a name="l06384"></a><span class="lineno"> 6384</span>&#160;        hAllocation-&gt;GetOffset());</div><div class="line"><a name="l06385"></a><span class="lineno"> 6385</span>&#160;}</div><div class="line"><a name="l06386"></a><span class="lineno"> 6386</span>&#160;</div><div class="line"><a name="l06387"></a><span class="lineno"> 6387</span>&#160;VkResult VmaDeviceMemoryBlock::BindImageMemory(</div><div class="line"><a name="l06388"></a><span class="lineno"> 6388</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l06389"></a><span class="lineno"> 6389</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l06390"></a><span class="lineno"> 6390</span>&#160;    VkImage hImage)</div><div class="line"><a name="l06391"></a><span class="lineno"> 6391</span>&#160;{</div><div class="line"><a name="l06392"></a><span class="lineno"> 6392</span>&#160;    VMA_ASSERT(hAllocation-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &amp;&amp;</div><div class="line"><a name="l06393"></a><span class="lineno"> 6393</span>&#160;        hAllocation-&gt;GetBlock() == <span class="keyword">this</span>);</div><div class="line"><a name="l06394"></a><span class="lineno"> 6394</span>&#160;    <span class="comment">// This lock is important so that we don&#39;t call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.</span></div><div class="line"><a name="l06395"></a><span class="lineno"> 6395</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06396"></a><span class="lineno"> 6396</span>&#160;    <span class="keywordflow">return</span> hAllocator-&gt;GetVulkanFunctions().vkBindImageMemory(</div><div class="line"><a name="l06397"></a><span class="lineno"> 6397</span>&#160;        hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l06398"></a><span class="lineno"> 6398</span>&#160;        hImage,</div><div class="line"><a name="l06399"></a><span class="lineno"> 6399</span>&#160;        m_hMemory,</div><div class="line"><a name="l06400"></a><span class="lineno"> 6400</span>&#160;        hAllocation-&gt;GetOffset());</div><div class="line"><a name="l06401"></a><span class="lineno"> 6401</span>&#160;}</div><div class="line"><a name="l06402"></a><span class="lineno"> 6402</span>&#160;</div><div class="line"><a name="l06403"></a><span class="lineno"> 6403</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> InitStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo)</div><div class="line"><a name="l06404"></a><span class="lineno"> 6404</span>&#160;{</div><div class="line"><a name="l06405"></a><span class="lineno"> 6405</span>&#160;    memset(&amp;outInfo, 0, <span class="keyword">sizeof</span>(outInfo));</div><div class="line"><a name="l06406"></a><span class="lineno"> 6406</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l06407"></a><span class="lineno"> 6407</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l06408"></a><span class="lineno"> 6408</span>&#160;}</div><div class="line"><a name="l06409"></a><span class="lineno"> 6409</span>&#160;</div><div class="line"><a name="l06410"></a><span class="lineno"> 6410</span>&#160;<span class="comment">// Adds statistics srcInfo into inoutInfo, like: inoutInfo += srcInfo.</span></div><div class="line"><a name="l06411"></a><span class="lineno"> 6411</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaAddStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; inoutInfo, <span class="keyword">const</span> <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; srcInfo)</div><div class="line"><a name="l06412"></a><span class="lineno"> 6412</span>&#160;{</div><div class="line"><a name="l06413"></a><span class="lineno"> 6413</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a>;</div><div class="line"><a name="l06414"></a><span class="lineno"> 6414</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>;</div><div class="line"><a name="l06415"></a><span class="lineno"> 6415</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l06416"></a><span class="lineno"> 6416</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>;</div><div class="line"><a name="l06417"></a><span class="lineno"> 6417</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>;</div><div class="line"><a name="l06418"></a><span class="lineno"> 6418</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = VMA_MIN(inoutInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>);</div><div class="line"><a name="l06419"></a><span class="lineno"> 6419</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = VMA_MAX(inoutInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>);</div><div class="line"><a name="l06420"></a><span class="lineno"> 6420</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(inoutInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>);</div><div class="line"><a name="l06421"></a><span class="lineno"> 6421</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MAX(inoutInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>);</div><div class="line"><a name="l06422"></a><span class="lineno"> 6422</span>&#160;}</div><div class="line"><a name="l06423"></a><span class="lineno"> 6423</span>&#160;</div><div class="line"><a name="l06424"></a><span class="lineno"> 6424</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaPostprocessCalcStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; inoutInfo)</div><div class="line"><a name="l06425"></a><span class="lineno"> 6425</span>&#160;{</div><div class="line"><a name="l06426"></a><span class="lineno"> 6426</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a1081a039964e566c672e7a2347f9e599">allocationSizeAvg</a> = (inoutInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> &gt; 0) ?</div><div class="line"><a name="l06427"></a><span class="lineno"> 6427</span>&#160;        VmaRoundDiv&lt;VkDeviceSize&gt;(inoutInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>, inoutInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>) : 0;</div><div class="line"><a name="l06428"></a><span class="lineno"> 6428</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a2f9b3452af90c9768a30b7fb6ae194fc">unusedRangeSizeAvg</a> = (inoutInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> &gt; 0) ?</div><div class="line"><a name="l06429"></a><span class="lineno"> 6429</span>&#160;        VmaRoundDiv&lt;VkDeviceSize&gt;(inoutInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>, inoutInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>) : 0;</div><div class="line"><a name="l06430"></a><span class="lineno"> 6430</span>&#160;}</div><div class="line"><a name="l06431"></a><span class="lineno"> 6431</span>&#160;</div><div class="line"><a name="l06432"></a><span class="lineno"> 6432</span>&#160;VmaPool_T::VmaPool_T(</div><div class="line"><a name="l06433"></a><span class="lineno"> 6433</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l06434"></a><span class="lineno"> 6434</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&amp; createInfo) :</div><div class="line"><a name="l06435"></a><span class="lineno"> 6435</span>&#160;    m_BlockVector(</div><div class="line"><a name="l06436"></a><span class="lineno"> 6436</span>&#160;        hAllocator,</div><div class="line"><a name="l06437"></a><span class="lineno"> 6437</span>&#160;        createInfo.memoryTypeIndex,</div><div class="line"><a name="l06438"></a><span class="lineno"> 6438</span>&#160;        createInfo.blockSize,</div><div class="line"><a name="l06439"></a><span class="lineno"> 6439</span>&#160;        createInfo.minBlockCount,</div><div class="line"><a name="l06440"></a><span class="lineno"> 6440</span>&#160;        createInfo.maxBlockCount,</div><div class="line"><a name="l06441"></a><span class="lineno"> 6441</span>&#160;        (createInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a>) != 0 ? 1 : hAllocator-&gt;GetBufferImageGranularity(),</div><div class="line"><a name="l06442"></a><span class="lineno"> 6442</span>&#160;        createInfo.frameInUseCount,</div><div class="line"><a name="l06443"></a><span class="lineno"> 6443</span>&#160;        true) <span class="comment">// isCustomPool</span></div><div class="line"><a name="l06444"></a><span class="lineno"> 6444</span>&#160;{</div><div class="line"><a name="l06445"></a><span class="lineno"> 6445</span>&#160;}</div><div class="line"><a name="l06446"></a><span class="lineno"> 6446</span>&#160;</div><div class="line"><a name="l06447"></a><span class="lineno"> 6447</span>&#160;VmaPool_T::~VmaPool_T()</div><div class="line"><a name="l06448"></a><span class="lineno"> 6448</span>&#160;{</div><div class="line"><a name="l06449"></a><span class="lineno"> 6449</span>&#160;}</div><div class="line"><a name="l06450"></a><span class="lineno"> 6450</span>&#160;</div><div class="line"><a name="l06451"></a><span class="lineno"> 6451</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06452"></a><span class="lineno"> 6452</span>&#160;</div><div class="line"><a name="l06453"></a><span class="lineno"> 6453</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06454"></a><span class="lineno"> 6454</span>&#160;</div><div class="line"><a name="l06455"></a><span class="lineno"> 6455</span>&#160;VmaBlockVector::VmaBlockVector(</div><div class="line"><a name="l06456"></a><span class="lineno"> 6456</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l06457"></a><span class="lineno"> 6457</span>&#160;    uint32_t memoryTypeIndex,</div><div class="line"><a name="l06458"></a><span class="lineno"> 6458</span>&#160;    VkDeviceSize preferredBlockSize,</div><div class="line"><a name="l06459"></a><span class="lineno"> 6459</span>&#160;    <span class="keywordtype">size_t</span> minBlockCount,</div><div class="line"><a name="l06460"></a><span class="lineno"> 6460</span>&#160;    <span class="keywordtype">size_t</span> maxBlockCount,</div><div class="line"><a name="l06461"></a><span class="lineno"> 6461</span>&#160;    VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l06462"></a><span class="lineno"> 6462</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l06463"></a><span class="lineno"> 6463</span>&#160;    <span class="keywordtype">bool</span> isCustomPool) :</div><div class="line"><a name="l06464"></a><span class="lineno"> 6464</span>&#160;    m_hAllocator(hAllocator),</div><div class="line"><a name="l06465"></a><span class="lineno"> 6465</span>&#160;    m_MemoryTypeIndex(memoryTypeIndex),</div><div class="line"><a name="l06466"></a><span class="lineno"> 6466</span>&#160;    m_PreferredBlockSize(preferredBlockSize),</div><div class="line"><a name="l06467"></a><span class="lineno"> 6467</span>&#160;    m_MinBlockCount(minBlockCount),</div><div class="line"><a name="l06468"></a><span class="lineno"> 6468</span>&#160;    m_MaxBlockCount(maxBlockCount),</div><div class="line"><a name="l06469"></a><span class="lineno"> 6469</span>&#160;    m_BufferImageGranularity(bufferImageGranularity),</div><div class="line"><a name="l06470"></a><span class="lineno"> 6470</span>&#160;    m_FrameInUseCount(frameInUseCount),</div><div class="line"><a name="l06471"></a><span class="lineno"> 6471</span>&#160;    m_IsCustomPool(isCustomPool),</div><div class="line"><a name="l06472"></a><span class="lineno"> 6472</span>&#160;    m_Blocks(VmaStlAllocator&lt;VmaDeviceMemoryBlock*&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l06473"></a><span class="lineno"> 6473</span>&#160;    m_HasEmptyBlock(false),</div><div class="line"><a name="l06474"></a><span class="lineno"> 6474</span>&#160;    m_pDefragmentator(VMA_NULL)</div><div class="line"><a name="l06475"></a><span class="lineno"> 6475</span>&#160;{</div><div class="line"><a name="l06476"></a><span class="lineno"> 6476</span>&#160;}</div><div class="line"><a name="l06477"></a><span class="lineno"> 6477</span>&#160;</div><div class="line"><a name="l06478"></a><span class="lineno"> 6478</span>&#160;VmaBlockVector::~VmaBlockVector()</div><div class="line"><a name="l06479"></a><span class="lineno"> 6479</span>&#160;{</div><div class="line"><a name="l06480"></a><span class="lineno"> 6480</span>&#160;    VMA_ASSERT(m_pDefragmentator == VMA_NULL);</div><div class="line"><a name="l06481"></a><span class="lineno"> 6481</span>&#160;</div><div class="line"><a name="l06482"></a><span class="lineno"> 6482</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_Blocks.size(); i--; )</div><div class="line"><a name="l06483"></a><span class="lineno"> 6483</span>&#160;    {</div><div class="line"><a name="l06484"></a><span class="lineno"> 6484</span>&#160;        m_Blocks[i]-&gt;Destroy(m_hAllocator);</div><div class="line"><a name="l06485"></a><span class="lineno"> 6485</span>&#160;        vma_delete(m_hAllocator, m_Blocks[i]);</div><div class="line"><a name="l06486"></a><span class="lineno"> 6486</span>&#160;    }</div><div class="line"><a name="l06487"></a><span class="lineno"> 6487</span>&#160;}</div><div class="line"><a name="l06488"></a><span class="lineno"> 6488</span>&#160;</div><div class="line"><a name="l06489"></a><span class="lineno"> 6489</span>&#160;VkResult VmaBlockVector::CreateMinBlocks()</div><div class="line"><a name="l06490"></a><span class="lineno"> 6490</span>&#160;{</div><div class="line"><a name="l06491"></a><span class="lineno"> 6491</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_MinBlockCount; ++i)</div><div class="line"><a name="l06492"></a><span class="lineno"> 6492</span>&#160;    {</div><div class="line"><a name="l06493"></a><span class="lineno"> 6493</span>&#160;        VkResult res = CreateBlock(m_PreferredBlockSize, VMA_NULL);</div><div class="line"><a name="l06494"></a><span class="lineno"> 6494</span>&#160;        <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l06495"></a><span class="lineno"> 6495</span>&#160;        {</div><div class="line"><a name="l06496"></a><span class="lineno"> 6496</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l06497"></a><span class="lineno"> 6497</span>&#160;        }</div><div class="line"><a name="l06498"></a><span class="lineno"> 6498</span>&#160;    }</div><div class="line"><a name="l06499"></a><span class="lineno"> 6499</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06500"></a><span class="lineno"> 6500</span>&#160;}</div><div class="line"><a name="l06501"></a><span class="lineno"> 6501</span>&#160;</div><div class="line"><a name="l06502"></a><span class="lineno"> 6502</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::GetPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pStats)</div><div class="line"><a name="l06503"></a><span class="lineno"> 6503</span>&#160;{</div><div class="line"><a name="l06504"></a><span class="lineno"> 6504</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a> = 0;</div><div class="line"><a name="l06505"></a><span class="lineno"> 6505</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> = 0;</div><div class="line"><a name="l06506"></a><span class="lineno"> 6506</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a> = 0;</div><div class="line"><a name="l06507"></a><span class="lineno"> 6507</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a> = 0;</div><div class="line"><a name="l06508"></a><span class="lineno"> 6508</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = 0;</div><div class="line"><a name="l06509"></a><span class="lineno"> 6509</span>&#160;</div><div class="line"><a name="l06510"></a><span class="lineno"> 6510</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06511"></a><span class="lineno"> 6511</span>&#160;</div><div class="line"><a name="l06512"></a><span class="lineno"> 6512</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l06513"></a><span class="lineno"> 6513</span>&#160;    {</div><div class="line"><a name="l06514"></a><span class="lineno"> 6514</span>&#160;        <span class="keyword">const</span> VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l06515"></a><span class="lineno"> 6515</span>&#160;        VMA_ASSERT(pBlock);</div><div class="line"><a name="l06516"></a><span class="lineno"> 6516</span>&#160;        VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l06517"></a><span class="lineno"> 6517</span>&#160;        pBlock-&gt;m_Metadata.AddPoolStats(*pStats);</div><div class="line"><a name="l06518"></a><span class="lineno"> 6518</span>&#160;    }</div><div class="line"><a name="l06519"></a><span class="lineno"> 6519</span>&#160;}</div><div class="line"><a name="l06520"></a><span class="lineno"> 6520</span>&#160;</div><div class="line"><a name="l06521"></a><span class="lineno"> 6521</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint32_t VMA_ALLOCATION_TRY_COUNT = 32;</div><div class="line"><a name="l06522"></a><span class="lineno"> 6522</span>&#160;</div><div class="line"><a name="l06523"></a><span class="lineno"> 6523</span>&#160;VkResult VmaBlockVector::Allocate(</div><div class="line"><a name="l06524"></a><span class="lineno"> 6524</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> hCurrentPool,</div><div class="line"><a name="l06525"></a><span class="lineno"> 6525</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l06526"></a><span class="lineno"> 6526</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l06527"></a><span class="lineno"> 6527</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l06528"></a><span class="lineno"> 6528</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l06529"></a><span class="lineno"> 6529</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l06530"></a><span class="lineno"> 6530</span>&#160;{</div><div class="line"><a name="l06531"></a><span class="lineno"> 6531</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> mapped = (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0;</div><div class="line"><a name="l06532"></a><span class="lineno"> 6532</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isUserDataString = (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0;</div><div class="line"><a name="l06533"></a><span class="lineno"> 6533</span>&#160;</div><div class="line"><a name="l06534"></a><span class="lineno"> 6534</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06535"></a><span class="lineno"> 6535</span>&#160;</div><div class="line"><a name="l06536"></a><span class="lineno"> 6536</span>&#160;    <span class="comment">// 1. Search existing allocations. Try to allocate without making other allocations lost.</span></div><div class="line"><a name="l06537"></a><span class="lineno"> 6537</span>&#160;    <span class="comment">// Forward order in m_Blocks - prefer blocks with smallest amount of free space.</span></div><div class="line"><a name="l06538"></a><span class="lineno"> 6538</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex )</div><div class="line"><a name="l06539"></a><span class="lineno"> 6539</span>&#160;    {</div><div class="line"><a name="l06540"></a><span class="lineno"> 6540</span>&#160;        VmaDeviceMemoryBlock* <span class="keyword">const</span> pCurrBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l06541"></a><span class="lineno"> 6541</span>&#160;        VMA_ASSERT(pCurrBlock);</div><div class="line"><a name="l06542"></a><span class="lineno"> 6542</span>&#160;        VmaAllocationRequest currRequest = {};</div><div class="line"><a name="l06543"></a><span class="lineno"> 6543</span>&#160;        <span class="keywordflow">if</span>(pCurrBlock-&gt;m_Metadata.CreateAllocationRequest(</div><div class="line"><a name="l06544"></a><span class="lineno"> 6544</span>&#160;            currentFrameIndex,</div><div class="line"><a name="l06545"></a><span class="lineno"> 6545</span>&#160;            m_FrameInUseCount,</div><div class="line"><a name="l06546"></a><span class="lineno"> 6546</span>&#160;            m_BufferImageGranularity,</div><div class="line"><a name="l06547"></a><span class="lineno"> 6547</span>&#160;            vkMemReq.size,</div><div class="line"><a name="l06548"></a><span class="lineno"> 6548</span>&#160;            vkMemReq.alignment,</div><div class="line"><a name="l06549"></a><span class="lineno"> 6549</span>&#160;            suballocType,</div><div class="line"><a name="l06550"></a><span class="lineno"> 6550</span>&#160;            <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l06551"></a><span class="lineno"> 6551</span>&#160;            &amp;currRequest))</div><div class="line"><a name="l06552"></a><span class="lineno"> 6552</span>&#160;        {</div><div class="line"><a name="l06553"></a><span class="lineno"> 6553</span>&#160;            <span class="comment">// Allocate from pCurrBlock.</span></div><div class="line"><a name="l06554"></a><span class="lineno"> 6554</span>&#160;            VMA_ASSERT(currRequest.itemsToMakeLostCount == 0);</div><div class="line"><a name="l06555"></a><span class="lineno"> 6555</span>&#160;</div><div class="line"><a name="l06556"></a><span class="lineno"> 6556</span>&#160;            <span class="keywordflow">if</span>(mapped)</div><div class="line"><a name="l06557"></a><span class="lineno"> 6557</span>&#160;            {</div><div class="line"><a name="l06558"></a><span class="lineno"> 6558</span>&#160;                VkResult res = pCurrBlock-&gt;Map(m_hAllocator, 1, VMA_NULL);</div><div class="line"><a name="l06559"></a><span class="lineno"> 6559</span>&#160;                <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l06560"></a><span class="lineno"> 6560</span>&#160;                {</div><div class="line"><a name="l06561"></a><span class="lineno"> 6561</span>&#160;                    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l06562"></a><span class="lineno"> 6562</span>&#160;                }</div><div class="line"><a name="l06563"></a><span class="lineno"> 6563</span>&#160;            }</div><div class="line"><a name="l06564"></a><span class="lineno"> 6564</span>&#160;            </div><div class="line"><a name="l06565"></a><span class="lineno"> 6565</span>&#160;            <span class="comment">// We no longer have an empty Allocation.</span></div><div class="line"><a name="l06566"></a><span class="lineno"> 6566</span>&#160;            <span class="keywordflow">if</span>(pCurrBlock-&gt;m_Metadata.IsEmpty())</div><div class="line"><a name="l06567"></a><span class="lineno"> 6567</span>&#160;            {</div><div class="line"><a name="l06568"></a><span class="lineno"> 6568</span>&#160;                m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l06569"></a><span class="lineno"> 6569</span>&#160;            }</div><div class="line"><a name="l06570"></a><span class="lineno"> 6570</span>&#160;            </div><div class="line"><a name="l06571"></a><span class="lineno"> 6571</span>&#160;            *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);</div><div class="line"><a name="l06572"></a><span class="lineno"> 6572</span>&#160;            pCurrBlock-&gt;m_Metadata.Alloc(currRequest, suballocType, vkMemReq.size, *pAllocation);</div><div class="line"><a name="l06573"></a><span class="lineno"> 6573</span>&#160;            (*pAllocation)-&gt;InitBlockAllocation(</div><div class="line"><a name="l06574"></a><span class="lineno"> 6574</span>&#160;                hCurrentPool,</div><div class="line"><a name="l06575"></a><span class="lineno"> 6575</span>&#160;                pCurrBlock,</div><div class="line"><a name="l06576"></a><span class="lineno"> 6576</span>&#160;                currRequest.offset,</div><div class="line"><a name="l06577"></a><span class="lineno"> 6577</span>&#160;                vkMemReq.alignment,</div><div class="line"><a name="l06578"></a><span class="lineno"> 6578</span>&#160;                vkMemReq.size,</div><div class="line"><a name="l06579"></a><span class="lineno"> 6579</span>&#160;                suballocType,</div><div class="line"><a name="l06580"></a><span class="lineno"> 6580</span>&#160;                mapped,</div><div class="line"><a name="l06581"></a><span class="lineno"> 6581</span>&#160;                (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a>) != 0);</div><div class="line"><a name="l06582"></a><span class="lineno"> 6582</span>&#160;            VMA_HEAVY_ASSERT(pCurrBlock-&gt;Validate());</div><div class="line"><a name="l06583"></a><span class="lineno"> 6583</span>&#160;            VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Returned from existing allocation #%u&quot;</span>, (uint32_t)blockIndex);</div><div class="line"><a name="l06584"></a><span class="lineno"> 6584</span>&#160;            (*pAllocation)-&gt;SetUserData(m_hAllocator, createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l06585"></a><span class="lineno"> 6585</span>&#160;            <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06586"></a><span class="lineno"> 6586</span>&#160;        }</div><div class="line"><a name="l06587"></a><span class="lineno"> 6587</span>&#160;    }</div><div class="line"><a name="l06588"></a><span class="lineno"> 6588</span>&#160;</div><div class="line"><a name="l06589"></a><span class="lineno"> 6589</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> canCreateNewBlock =</div><div class="line"><a name="l06590"></a><span class="lineno"> 6590</span>&#160;        ((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) == 0) &amp;&amp;</div><div class="line"><a name="l06591"></a><span class="lineno"> 6591</span>&#160;        (m_Blocks.size() &lt; m_MaxBlockCount);</div><div class="line"><a name="l06592"></a><span class="lineno"> 6592</span>&#160;</div><div class="line"><a name="l06593"></a><span class="lineno"> 6593</span>&#160;    <span class="comment">// 2. Try to create new block.</span></div><div class="line"><a name="l06594"></a><span class="lineno"> 6594</span>&#160;    <span class="keywordflow">if</span>(canCreateNewBlock)</div><div class="line"><a name="l06595"></a><span class="lineno"> 6595</span>&#160;    {</div><div class="line"><a name="l06596"></a><span class="lineno"> 6596</span>&#160;        <span class="comment">// Calculate optimal size for new block.</span></div><div class="line"><a name="l06597"></a><span class="lineno"> 6597</span>&#160;        VkDeviceSize newBlockSize = m_PreferredBlockSize;</div><div class="line"><a name="l06598"></a><span class="lineno"> 6598</span>&#160;        uint32_t newBlockSizeShift = 0;</div><div class="line"><a name="l06599"></a><span class="lineno"> 6599</span>&#160;        <span class="keyword">const</span> uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3;</div><div class="line"><a name="l06600"></a><span class="lineno"> 6600</span>&#160;</div><div class="line"><a name="l06601"></a><span class="lineno"> 6601</span>&#160;        <span class="comment">// Allocating blocks of other sizes is allowed only in default pools.</span></div><div class="line"><a name="l06602"></a><span class="lineno"> 6602</span>&#160;        <span class="comment">// In custom pools block size is fixed.</span></div><div class="line"><a name="l06603"></a><span class="lineno"> 6603</span>&#160;        <span class="keywordflow">if</span>(m_IsCustomPool == <span class="keyword">false</span>)</div><div class="line"><a name="l06604"></a><span class="lineno"> 6604</span>&#160;        {</div><div class="line"><a name="l06605"></a><span class="lineno"> 6605</span>&#160;            <span class="comment">// Allocate 1/8, 1/4, 1/2 as first blocks.</span></div><div class="line"><a name="l06606"></a><span class="lineno"> 6606</span>&#160;            <span class="keyword">const</span> VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize();</div><div class="line"><a name="l06607"></a><span class="lineno"> 6607</span>&#160;            <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; NEW_BLOCK_SIZE_SHIFT_MAX; ++i)</div><div class="line"><a name="l06608"></a><span class="lineno"> 6608</span>&#160;            {</div><div class="line"><a name="l06609"></a><span class="lineno"> 6609</span>&#160;                <span class="keyword">const</span> VkDeviceSize smallerNewBlockSize = newBlockSize / 2;</div><div class="line"><a name="l06610"></a><span class="lineno"> 6610</span>&#160;                <span class="keywordflow">if</span>(smallerNewBlockSize &gt; maxExistingBlockSize &amp;&amp; smallerNewBlockSize &gt;= vkMemReq.size * 2)</div><div class="line"><a name="l06611"></a><span class="lineno"> 6611</span>&#160;                {</div><div class="line"><a name="l06612"></a><span class="lineno"> 6612</span>&#160;                    newBlockSize = smallerNewBlockSize;</div><div class="line"><a name="l06613"></a><span class="lineno"> 6613</span>&#160;                    ++newBlockSizeShift;</div><div class="line"><a name="l06614"></a><span class="lineno"> 6614</span>&#160;                }</div><div class="line"><a name="l06615"></a><span class="lineno"> 6615</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l06616"></a><span class="lineno"> 6616</span>&#160;                {</div><div class="line"><a name="l06617"></a><span class="lineno"> 6617</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l06618"></a><span class="lineno"> 6618</span>&#160;                }</div><div class="line"><a name="l06619"></a><span class="lineno"> 6619</span>&#160;            }</div><div class="line"><a name="l06620"></a><span class="lineno"> 6620</span>&#160;        }</div><div class="line"><a name="l06621"></a><span class="lineno"> 6621</span>&#160;</div><div class="line"><a name="l06622"></a><span class="lineno"> 6622</span>&#160;        <span class="keywordtype">size_t</span> newBlockIndex = 0;</div><div class="line"><a name="l06623"></a><span class="lineno"> 6623</span>&#160;        VkResult res = CreateBlock(newBlockSize, &amp;newBlockIndex);</div><div class="line"><a name="l06624"></a><span class="lineno"> 6624</span>&#160;        <span class="comment">// Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.</span></div><div class="line"><a name="l06625"></a><span class="lineno"> 6625</span>&#160;        <span class="keywordflow">if</span>(m_IsCustomPool == <span class="keyword">false</span>)</div><div class="line"><a name="l06626"></a><span class="lineno"> 6626</span>&#160;        {</div><div class="line"><a name="l06627"></a><span class="lineno"> 6627</span>&#160;            <span class="keywordflow">while</span>(res &lt; 0 &amp;&amp; newBlockSizeShift &lt; NEW_BLOCK_SIZE_SHIFT_MAX)</div><div class="line"><a name="l06628"></a><span class="lineno"> 6628</span>&#160;            {</div><div class="line"><a name="l06629"></a><span class="lineno"> 6629</span>&#160;                <span class="keyword">const</span> VkDeviceSize smallerNewBlockSize = newBlockSize / 2;</div><div class="line"><a name="l06630"></a><span class="lineno"> 6630</span>&#160;                <span class="keywordflow">if</span>(smallerNewBlockSize &gt;= vkMemReq.size)</div><div class="line"><a name="l06631"></a><span class="lineno"> 6631</span>&#160;                {</div><div class="line"><a name="l06632"></a><span class="lineno"> 6632</span>&#160;                    newBlockSize = smallerNewBlockSize;</div><div class="line"><a name="l06633"></a><span class="lineno"> 6633</span>&#160;                    ++newBlockSizeShift;</div><div class="line"><a name="l06634"></a><span class="lineno"> 6634</span>&#160;                    res = CreateBlock(newBlockSize, &amp;newBlockIndex);</div><div class="line"><a name="l06635"></a><span class="lineno"> 6635</span>&#160;                }</div><div class="line"><a name="l06636"></a><span class="lineno"> 6636</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l06637"></a><span class="lineno"> 6637</span>&#160;                {</div><div class="line"><a name="l06638"></a><span class="lineno"> 6638</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l06639"></a><span class="lineno"> 6639</span>&#160;                }</div><div class="line"><a name="l06640"></a><span class="lineno"> 6640</span>&#160;            }</div><div class="line"><a name="l06641"></a><span class="lineno"> 6641</span>&#160;        }</div><div class="line"><a name="l06642"></a><span class="lineno"> 6642</span>&#160;</div><div class="line"><a name="l06643"></a><span class="lineno"> 6643</span>&#160;        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l06644"></a><span class="lineno"> 6644</span>&#160;        {</div><div class="line"><a name="l06645"></a><span class="lineno"> 6645</span>&#160;            VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[newBlockIndex];</div><div class="line"><a name="l06646"></a><span class="lineno"> 6646</span>&#160;            VMA_ASSERT(pBlock-&gt;m_Metadata.GetSize() &gt;= vkMemReq.size);</div><div class="line"><a name="l06647"></a><span class="lineno"> 6647</span>&#160;</div><div class="line"><a name="l06648"></a><span class="lineno"> 6648</span>&#160;            <span class="keywordflow">if</span>(mapped)</div><div class="line"><a name="l06649"></a><span class="lineno"> 6649</span>&#160;            {</div><div class="line"><a name="l06650"></a><span class="lineno"> 6650</span>&#160;                res = pBlock-&gt;Map(m_hAllocator, 1, VMA_NULL);</div><div class="line"><a name="l06651"></a><span class="lineno"> 6651</span>&#160;                <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l06652"></a><span class="lineno"> 6652</span>&#160;                {</div><div class="line"><a name="l06653"></a><span class="lineno"> 6653</span>&#160;                    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l06654"></a><span class="lineno"> 6654</span>&#160;                }</div><div class="line"><a name="l06655"></a><span class="lineno"> 6655</span>&#160;            }</div><div class="line"><a name="l06656"></a><span class="lineno"> 6656</span>&#160;</div><div class="line"><a name="l06657"></a><span class="lineno"> 6657</span>&#160;            <span class="comment">// Allocate from pBlock. Because it is empty, dstAllocRequest can be trivially filled.</span></div><div class="line"><a name="l06658"></a><span class="lineno"> 6658</span>&#160;            VmaAllocationRequest allocRequest;</div><div class="line"><a name="l06659"></a><span class="lineno"> 6659</span>&#160;            pBlock-&gt;m_Metadata.CreateFirstAllocationRequest(&amp;allocRequest);</div><div class="line"><a name="l06660"></a><span class="lineno"> 6660</span>&#160;            *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);</div><div class="line"><a name="l06661"></a><span class="lineno"> 6661</span>&#160;            pBlock-&gt;m_Metadata.Alloc(allocRequest, suballocType, vkMemReq.size, *pAllocation);</div><div class="line"><a name="l06662"></a><span class="lineno"> 6662</span>&#160;            (*pAllocation)-&gt;InitBlockAllocation(</div><div class="line"><a name="l06663"></a><span class="lineno"> 6663</span>&#160;                hCurrentPool,</div><div class="line"><a name="l06664"></a><span class="lineno"> 6664</span>&#160;                pBlock,</div><div class="line"><a name="l06665"></a><span class="lineno"> 6665</span>&#160;                allocRequest.offset,</div><div class="line"><a name="l06666"></a><span class="lineno"> 6666</span>&#160;                vkMemReq.alignment,</div><div class="line"><a name="l06667"></a><span class="lineno"> 6667</span>&#160;                vkMemReq.size,</div><div class="line"><a name="l06668"></a><span class="lineno"> 6668</span>&#160;                suballocType,</div><div class="line"><a name="l06669"></a><span class="lineno"> 6669</span>&#160;                mapped,</div><div class="line"><a name="l06670"></a><span class="lineno"> 6670</span>&#160;                (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a>) != 0);</div><div class="line"><a name="l06671"></a><span class="lineno"> 6671</span>&#160;            VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l06672"></a><span class="lineno"> 6672</span>&#160;            VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Created new allocation Size=%llu&quot;</span>, allocInfo.allocationSize);</div><div class="line"><a name="l06673"></a><span class="lineno"> 6673</span>&#160;            (*pAllocation)-&gt;SetUserData(m_hAllocator, createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l06674"></a><span class="lineno"> 6674</span>&#160;            <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06675"></a><span class="lineno"> 6675</span>&#160;        }</div><div class="line"><a name="l06676"></a><span class="lineno"> 6676</span>&#160;    }</div><div class="line"><a name="l06677"></a><span class="lineno"> 6677</span>&#160;</div><div class="line"><a name="l06678"></a><span class="lineno"> 6678</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> canMakeOtherLost = (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>) != 0;</div><div class="line"><a name="l06679"></a><span class="lineno"> 6679</span>&#160;</div><div class="line"><a name="l06680"></a><span class="lineno"> 6680</span>&#160;    <span class="comment">// 3. Try to allocate from existing blocks with making other allocations lost.</span></div><div class="line"><a name="l06681"></a><span class="lineno"> 6681</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost)</div><div class="line"><a name="l06682"></a><span class="lineno"> 6682</span>&#160;    {</div><div class="line"><a name="l06683"></a><span class="lineno"> 6683</span>&#160;        uint32_t tryIndex = 0;</div><div class="line"><a name="l06684"></a><span class="lineno"> 6684</span>&#160;        <span class="keywordflow">for</span>(; tryIndex &lt; VMA_ALLOCATION_TRY_COUNT; ++tryIndex)</div><div class="line"><a name="l06685"></a><span class="lineno"> 6685</span>&#160;        {</div><div class="line"><a name="l06686"></a><span class="lineno"> 6686</span>&#160;            VmaDeviceMemoryBlock* pBestRequestBlock = VMA_NULL;</div><div class="line"><a name="l06687"></a><span class="lineno"> 6687</span>&#160;            VmaAllocationRequest bestRequest = {};</div><div class="line"><a name="l06688"></a><span class="lineno"> 6688</span>&#160;            VkDeviceSize bestRequestCost = VK_WHOLE_SIZE;</div><div class="line"><a name="l06689"></a><span class="lineno"> 6689</span>&#160;</div><div class="line"><a name="l06690"></a><span class="lineno"> 6690</span>&#160;            <span class="comment">// 1. Search existing allocations.</span></div><div class="line"><a name="l06691"></a><span class="lineno"> 6691</span>&#160;            <span class="comment">// Forward order in m_Blocks - prefer blocks with smallest amount of free space.</span></div><div class="line"><a name="l06692"></a><span class="lineno"> 6692</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex )</div><div class="line"><a name="l06693"></a><span class="lineno"> 6693</span>&#160;            {</div><div class="line"><a name="l06694"></a><span class="lineno"> 6694</span>&#160;                VmaDeviceMemoryBlock* <span class="keyword">const</span> pCurrBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l06695"></a><span class="lineno"> 6695</span>&#160;                VMA_ASSERT(pCurrBlock);</div><div class="line"><a name="l06696"></a><span class="lineno"> 6696</span>&#160;                VmaAllocationRequest currRequest = {};</div><div class="line"><a name="l06697"></a><span class="lineno"> 6697</span>&#160;                <span class="keywordflow">if</span>(pCurrBlock-&gt;m_Metadata.CreateAllocationRequest(</div><div class="line"><a name="l06698"></a><span class="lineno"> 6698</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l06699"></a><span class="lineno"> 6699</span>&#160;                    m_FrameInUseCount,</div><div class="line"><a name="l06700"></a><span class="lineno"> 6700</span>&#160;                    m_BufferImageGranularity,</div><div class="line"><a name="l06701"></a><span class="lineno"> 6701</span>&#160;                    vkMemReq.size,</div><div class="line"><a name="l06702"></a><span class="lineno"> 6702</span>&#160;                    vkMemReq.alignment,</div><div class="line"><a name="l06703"></a><span class="lineno"> 6703</span>&#160;                    suballocType,</div><div class="line"><a name="l06704"></a><span class="lineno"> 6704</span>&#160;                    canMakeOtherLost,</div><div class="line"><a name="l06705"></a><span class="lineno"> 6705</span>&#160;                    &amp;currRequest))</div><div class="line"><a name="l06706"></a><span class="lineno"> 6706</span>&#160;                {</div><div class="line"><a name="l06707"></a><span class="lineno"> 6707</span>&#160;                    <span class="keyword">const</span> VkDeviceSize currRequestCost = currRequest.CalcCost();</div><div class="line"><a name="l06708"></a><span class="lineno"> 6708</span>&#160;                    <span class="keywordflow">if</span>(pBestRequestBlock == VMA_NULL ||</div><div class="line"><a name="l06709"></a><span class="lineno"> 6709</span>&#160;                        currRequestCost &lt; bestRequestCost)</div><div class="line"><a name="l06710"></a><span class="lineno"> 6710</span>&#160;                    {</div><div class="line"><a name="l06711"></a><span class="lineno"> 6711</span>&#160;                        pBestRequestBlock = pCurrBlock;</div><div class="line"><a name="l06712"></a><span class="lineno"> 6712</span>&#160;                        bestRequest = currRequest;</div><div class="line"><a name="l06713"></a><span class="lineno"> 6713</span>&#160;                        bestRequestCost = currRequestCost;</div><div class="line"><a name="l06714"></a><span class="lineno"> 6714</span>&#160;</div><div class="line"><a name="l06715"></a><span class="lineno"> 6715</span>&#160;                        <span class="keywordflow">if</span>(bestRequestCost == 0)</div><div class="line"><a name="l06716"></a><span class="lineno"> 6716</span>&#160;                        {</div><div class="line"><a name="l06717"></a><span class="lineno"> 6717</span>&#160;                            <span class="keywordflow">break</span>;</div><div class="line"><a name="l06718"></a><span class="lineno"> 6718</span>&#160;                        }</div><div class="line"><a name="l06719"></a><span class="lineno"> 6719</span>&#160;                    }</div><div class="line"><a name="l06720"></a><span class="lineno"> 6720</span>&#160;                }</div><div class="line"><a name="l06721"></a><span class="lineno"> 6721</span>&#160;            }</div><div class="line"><a name="l06722"></a><span class="lineno"> 6722</span>&#160;</div><div class="line"><a name="l06723"></a><span class="lineno"> 6723</span>&#160;            <span class="keywordflow">if</span>(pBestRequestBlock != VMA_NULL)</div><div class="line"><a name="l06724"></a><span class="lineno"> 6724</span>&#160;            {</div><div class="line"><a name="l06725"></a><span class="lineno"> 6725</span>&#160;                <span class="keywordflow">if</span>(mapped)</div><div class="line"><a name="l06726"></a><span class="lineno"> 6726</span>&#160;                {</div><div class="line"><a name="l06727"></a><span class="lineno"> 6727</span>&#160;                    VkResult res = pBestRequestBlock-&gt;Map(m_hAllocator, 1, VMA_NULL);</div><div class="line"><a name="l06728"></a><span class="lineno"> 6728</span>&#160;                    <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l06729"></a><span class="lineno"> 6729</span>&#160;                    {</div><div class="line"><a name="l06730"></a><span class="lineno"> 6730</span>&#160;                        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l06731"></a><span class="lineno"> 6731</span>&#160;                    }</div><div class="line"><a name="l06732"></a><span class="lineno"> 6732</span>&#160;                }</div><div class="line"><a name="l06733"></a><span class="lineno"> 6733</span>&#160;</div><div class="line"><a name="l06734"></a><span class="lineno"> 6734</span>&#160;                <span class="keywordflow">if</span>(pBestRequestBlock-&gt;m_Metadata.MakeRequestedAllocationsLost(</div><div class="line"><a name="l06735"></a><span class="lineno"> 6735</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l06736"></a><span class="lineno"> 6736</span>&#160;                    m_FrameInUseCount,</div><div class="line"><a name="l06737"></a><span class="lineno"> 6737</span>&#160;                    &amp;bestRequest))</div><div class="line"><a name="l06738"></a><span class="lineno"> 6738</span>&#160;                {</div><div class="line"><a name="l06739"></a><span class="lineno"> 6739</span>&#160;                    <span class="comment">// We no longer have an empty Allocation.</span></div><div class="line"><a name="l06740"></a><span class="lineno"> 6740</span>&#160;                    <span class="keywordflow">if</span>(pBestRequestBlock-&gt;m_Metadata.IsEmpty())</div><div class="line"><a name="l06741"></a><span class="lineno"> 6741</span>&#160;                    {</div><div class="line"><a name="l06742"></a><span class="lineno"> 6742</span>&#160;                        m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l06743"></a><span class="lineno"> 6743</span>&#160;                    }</div><div class="line"><a name="l06744"></a><span class="lineno"> 6744</span>&#160;                    <span class="comment">// Allocate from this pBlock.</span></div><div class="line"><a name="l06745"></a><span class="lineno"> 6745</span>&#160;                    *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);</div><div class="line"><a name="l06746"></a><span class="lineno"> 6746</span>&#160;                    pBestRequestBlock-&gt;m_Metadata.Alloc(bestRequest, suballocType, vkMemReq.size, *pAllocation);</div><div class="line"><a name="l06747"></a><span class="lineno"> 6747</span>&#160;                    (*pAllocation)-&gt;InitBlockAllocation(</div><div class="line"><a name="l06748"></a><span class="lineno"> 6748</span>&#160;                        hCurrentPool,</div><div class="line"><a name="l06749"></a><span class="lineno"> 6749</span>&#160;                        pBestRequestBlock,</div><div class="line"><a name="l06750"></a><span class="lineno"> 6750</span>&#160;                        bestRequest.offset,</div><div class="line"><a name="l06751"></a><span class="lineno"> 6751</span>&#160;                        vkMemReq.alignment,</div><div class="line"><a name="l06752"></a><span class="lineno"> 6752</span>&#160;                        vkMemReq.size,</div><div class="line"><a name="l06753"></a><span class="lineno"> 6753</span>&#160;                        suballocType,</div><div class="line"><a name="l06754"></a><span class="lineno"> 6754</span>&#160;                        mapped,</div><div class="line"><a name="l06755"></a><span class="lineno"> 6755</span>&#160;                        (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a>) != 0);</div><div class="line"><a name="l06756"></a><span class="lineno"> 6756</span>&#160;                    VMA_HEAVY_ASSERT(pBestRequestBlock-&gt;Validate());</div><div class="line"><a name="l06757"></a><span class="lineno"> 6757</span>&#160;                    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Returned from existing allocation #%u&quot;</span>, (uint32_t)blockIndex);</div><div class="line"><a name="l06758"></a><span class="lineno"> 6758</span>&#160;                    (*pAllocation)-&gt;SetUserData(m_hAllocator, createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l06759"></a><span class="lineno"> 6759</span>&#160;                    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06760"></a><span class="lineno"> 6760</span>&#160;                }</div><div class="line"><a name="l06761"></a><span class="lineno"> 6761</span>&#160;                <span class="comment">// else: Some allocations must have been touched while we are here. Next try.</span></div><div class="line"><a name="l06762"></a><span class="lineno"> 6762</span>&#160;            }</div><div class="line"><a name="l06763"></a><span class="lineno"> 6763</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l06764"></a><span class="lineno"> 6764</span>&#160;            {</div><div class="line"><a name="l06765"></a><span class="lineno"> 6765</span>&#160;                <span class="comment">// Could not find place in any of the blocks - break outer loop.</span></div><div class="line"><a name="l06766"></a><span class="lineno"> 6766</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l06767"></a><span class="lineno"> 6767</span>&#160;            }</div><div class="line"><a name="l06768"></a><span class="lineno"> 6768</span>&#160;        }</div><div class="line"><a name="l06769"></a><span class="lineno"> 6769</span>&#160;        <span class="comment">/* Maximum number of tries exceeded - a very unlike event when many other</span></div><div class="line"><a name="l06770"></a><span class="lineno"> 6770</span>&#160;<span class="comment">        threads are simultaneously touching allocations making it impossible to make</span></div><div class="line"><a name="l06771"></a><span class="lineno"> 6771</span>&#160;<span class="comment">        lost at the same time as we try to allocate. */</span></div><div class="line"><a name="l06772"></a><span class="lineno"> 6772</span>&#160;        <span class="keywordflow">if</span>(tryIndex == VMA_ALLOCATION_TRY_COUNT)</div><div class="line"><a name="l06773"></a><span class="lineno"> 6773</span>&#160;        {</div><div class="line"><a name="l06774"></a><span class="lineno"> 6774</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_TOO_MANY_OBJECTS;</div><div class="line"><a name="l06775"></a><span class="lineno"> 6775</span>&#160;        }</div><div class="line"><a name="l06776"></a><span class="lineno"> 6776</span>&#160;    }</div><div class="line"><a name="l06777"></a><span class="lineno"> 6777</span>&#160;</div><div class="line"><a name="l06778"></a><span class="lineno"> 6778</span>&#160;    <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l06779"></a><span class="lineno"> 6779</span>&#160;}</div><div class="line"><a name="l06780"></a><span class="lineno"> 6780</span>&#160;</div><div class="line"><a name="l06781"></a><span class="lineno"> 6781</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::Free(</div><div class="line"><a name="l06782"></a><span class="lineno"> 6782</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l06783"></a><span class="lineno"> 6783</span>&#160;{</div><div class="line"><a name="l06784"></a><span class="lineno"> 6784</span>&#160;    VmaDeviceMemoryBlock* pBlockToDelete = VMA_NULL;</div><div class="line"><a name="l06785"></a><span class="lineno"> 6785</span>&#160;</div><div class="line"><a name="l06786"></a><span class="lineno"> 6786</span>&#160;    <span class="comment">// Scope for lock.</span></div><div class="line"><a name="l06787"></a><span class="lineno"> 6787</span>&#160;    {</div><div class="line"><a name="l06788"></a><span class="lineno"> 6788</span>&#160;        VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06789"></a><span class="lineno"> 6789</span>&#160;</div><div class="line"><a name="l06790"></a><span class="lineno"> 6790</span>&#160;        VmaDeviceMemoryBlock* pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l06791"></a><span class="lineno"> 6791</span>&#160;</div><div class="line"><a name="l06792"></a><span class="lineno"> 6792</span>&#160;        <span class="keywordflow">if</span>(hAllocation-&gt;IsPersistentMap())</div><div class="line"><a name="l06793"></a><span class="lineno"> 6793</span>&#160;        {</div><div class="line"><a name="l06794"></a><span class="lineno"> 6794</span>&#160;            pBlock-&gt;Unmap(m_hAllocator, 1);</div><div class="line"><a name="l06795"></a><span class="lineno"> 6795</span>&#160;        }</div><div class="line"><a name="l06796"></a><span class="lineno"> 6796</span>&#160;</div><div class="line"><a name="l06797"></a><span class="lineno"> 6797</span>&#160;        pBlock-&gt;m_Metadata.Free(hAllocation);</div><div class="line"><a name="l06798"></a><span class="lineno"> 6798</span>&#160;        VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l06799"></a><span class="lineno"> 6799</span>&#160;</div><div class="line"><a name="l06800"></a><span class="lineno"> 6800</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;  Freed from MemoryTypeIndex=%u&quot;</span>, memTypeIndex);</div><div class="line"><a name="l06801"></a><span class="lineno"> 6801</span>&#160;</div><div class="line"><a name="l06802"></a><span class="lineno"> 6802</span>&#160;        <span class="comment">// pBlock became empty after this deallocation.</span></div><div class="line"><a name="l06803"></a><span class="lineno"> 6803</span>&#160;        <span class="keywordflow">if</span>(pBlock-&gt;m_Metadata.IsEmpty())</div><div class="line"><a name="l06804"></a><span class="lineno"> 6804</span>&#160;        {</div><div class="line"><a name="l06805"></a><span class="lineno"> 6805</span>&#160;            <span class="comment">// Already has empty Allocation. We don&#39;t want to have two, so delete this one.</span></div><div class="line"><a name="l06806"></a><span class="lineno"> 6806</span>&#160;            <span class="keywordflow">if</span>(m_HasEmptyBlock &amp;&amp; m_Blocks.size() &gt; m_MinBlockCount)</div><div class="line"><a name="l06807"></a><span class="lineno"> 6807</span>&#160;            {</div><div class="line"><a name="l06808"></a><span class="lineno"> 6808</span>&#160;                pBlockToDelete = pBlock;</div><div class="line"><a name="l06809"></a><span class="lineno"> 6809</span>&#160;                Remove(pBlock);</div><div class="line"><a name="l06810"></a><span class="lineno"> 6810</span>&#160;            }</div><div class="line"><a name="l06811"></a><span class="lineno"> 6811</span>&#160;            <span class="comment">// We now have first empty Allocation.</span></div><div class="line"><a name="l06812"></a><span class="lineno"> 6812</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l06813"></a><span class="lineno"> 6813</span>&#160;            {</div><div class="line"><a name="l06814"></a><span class="lineno"> 6814</span>&#160;                m_HasEmptyBlock = <span class="keyword">true</span>;</div><div class="line"><a name="l06815"></a><span class="lineno"> 6815</span>&#160;            }</div><div class="line"><a name="l06816"></a><span class="lineno"> 6816</span>&#160;        }</div><div class="line"><a name="l06817"></a><span class="lineno"> 6817</span>&#160;        <span class="comment">// pBlock didn&#39;t become empty, but we have another empty block - find and free that one.</span></div><div class="line"><a name="l06818"></a><span class="lineno"> 6818</span>&#160;        <span class="comment">// (This is optional, heuristics.)</span></div><div class="line"><a name="l06819"></a><span class="lineno"> 6819</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(m_HasEmptyBlock)</div><div class="line"><a name="l06820"></a><span class="lineno"> 6820</span>&#160;        {</div><div class="line"><a name="l06821"></a><span class="lineno"> 6821</span>&#160;            VmaDeviceMemoryBlock* pLastBlock = m_Blocks.back();</div><div class="line"><a name="l06822"></a><span class="lineno"> 6822</span>&#160;            <span class="keywordflow">if</span>(pLastBlock-&gt;m_Metadata.IsEmpty() &amp;&amp; m_Blocks.size() &gt; m_MinBlockCount)</div><div class="line"><a name="l06823"></a><span class="lineno"> 6823</span>&#160;            {</div><div class="line"><a name="l06824"></a><span class="lineno"> 6824</span>&#160;                pBlockToDelete = pLastBlock;</div><div class="line"><a name="l06825"></a><span class="lineno"> 6825</span>&#160;                m_Blocks.pop_back();</div><div class="line"><a name="l06826"></a><span class="lineno"> 6826</span>&#160;                m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l06827"></a><span class="lineno"> 6827</span>&#160;            }</div><div class="line"><a name="l06828"></a><span class="lineno"> 6828</span>&#160;        }</div><div class="line"><a name="l06829"></a><span class="lineno"> 6829</span>&#160;</div><div class="line"><a name="l06830"></a><span class="lineno"> 6830</span>&#160;        IncrementallySortBlocks();</div><div class="line"><a name="l06831"></a><span class="lineno"> 6831</span>&#160;    }</div><div class="line"><a name="l06832"></a><span class="lineno"> 6832</span>&#160;</div><div class="line"><a name="l06833"></a><span class="lineno"> 6833</span>&#160;    <span class="comment">// Destruction of a free Allocation. Deferred until this point, outside of mutex</span></div><div class="line"><a name="l06834"></a><span class="lineno"> 6834</span>&#160;    <span class="comment">// lock, for performance reason.</span></div><div class="line"><a name="l06835"></a><span class="lineno"> 6835</span>&#160;    <span class="keywordflow">if</span>(pBlockToDelete != VMA_NULL)</div><div class="line"><a name="l06836"></a><span class="lineno"> 6836</span>&#160;    {</div><div class="line"><a name="l06837"></a><span class="lineno"> 6837</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Deleted empty allocation&quot;</span>);</div><div class="line"><a name="l06838"></a><span class="lineno"> 6838</span>&#160;        pBlockToDelete-&gt;Destroy(m_hAllocator);</div><div class="line"><a name="l06839"></a><span class="lineno"> 6839</span>&#160;        vma_delete(m_hAllocator, pBlockToDelete);</div><div class="line"><a name="l06840"></a><span class="lineno"> 6840</span>&#160;    }</div><div class="line"><a name="l06841"></a><span class="lineno"> 6841</span>&#160;}</div><div class="line"><a name="l06842"></a><span class="lineno"> 6842</span>&#160;</div><div class="line"><a name="l06843"></a><span class="lineno"> 6843</span>&#160;<span class="keywordtype">size_t</span> VmaBlockVector::CalcMaxBlockSize()<span class="keyword"> const</span></div><div class="line"><a name="l06844"></a><span class="lineno"> 6844</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06845"></a><span class="lineno"> 6845</span>&#160;    <span class="keywordtype">size_t</span> result = 0;</div><div class="line"><a name="l06846"></a><span class="lineno"> 6846</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_Blocks.size(); i--; )</div><div class="line"><a name="l06847"></a><span class="lineno"> 6847</span>&#160;    {</div><div class="line"><a name="l06848"></a><span class="lineno"> 6848</span>&#160;        result = VMA_MAX((uint64_t)result, (uint64_t)m_Blocks[i]-&gt;m_Metadata.GetSize());</div><div class="line"><a name="l06849"></a><span class="lineno"> 6849</span>&#160;        <span class="keywordflow">if</span>(result &gt;= m_PreferredBlockSize)</div><div class="line"><a name="l06850"></a><span class="lineno"> 6850</span>&#160;        {</div><div class="line"><a name="l06851"></a><span class="lineno"> 6851</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l06852"></a><span class="lineno"> 6852</span>&#160;        }</div><div class="line"><a name="l06853"></a><span class="lineno"> 6853</span>&#160;    }</div><div class="line"><a name="l06854"></a><span class="lineno"> 6854</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l06855"></a><span class="lineno"> 6855</span>&#160;}</div><div class="line"><a name="l06856"></a><span class="lineno"> 6856</span>&#160;</div><div class="line"><a name="l06857"></a><span class="lineno"> 6857</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::Remove(VmaDeviceMemoryBlock* pBlock)</div><div class="line"><a name="l06858"></a><span class="lineno"> 6858</span>&#160;{</div><div class="line"><a name="l06859"></a><span class="lineno"> 6859</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l06860"></a><span class="lineno"> 6860</span>&#160;    {</div><div class="line"><a name="l06861"></a><span class="lineno"> 6861</span>&#160;        <span class="keywordflow">if</span>(m_Blocks[blockIndex] == pBlock)</div><div class="line"><a name="l06862"></a><span class="lineno"> 6862</span>&#160;        {</div><div class="line"><a name="l06863"></a><span class="lineno"> 6863</span>&#160;            VmaVectorRemove(m_Blocks, blockIndex);</div><div class="line"><a name="l06864"></a><span class="lineno"> 6864</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l06865"></a><span class="lineno"> 6865</span>&#160;        }</div><div class="line"><a name="l06866"></a><span class="lineno"> 6866</span>&#160;    }</div><div class="line"><a name="l06867"></a><span class="lineno"> 6867</span>&#160;    VMA_ASSERT(0);</div><div class="line"><a name="l06868"></a><span class="lineno"> 6868</span>&#160;}</div><div class="line"><a name="l06869"></a><span class="lineno"> 6869</span>&#160;</div><div class="line"><a name="l06870"></a><span class="lineno"> 6870</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::IncrementallySortBlocks()</div><div class="line"><a name="l06871"></a><span class="lineno"> 6871</span>&#160;{</div><div class="line"><a name="l06872"></a><span class="lineno"> 6872</span>&#160;    <span class="comment">// Bubble sort only until first swap.</span></div><div class="line"><a name="l06873"></a><span class="lineno"> 6873</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 1; i &lt; m_Blocks.size(); ++i)</div><div class="line"><a name="l06874"></a><span class="lineno"> 6874</span>&#160;    {</div><div class="line"><a name="l06875"></a><span class="lineno"> 6875</span>&#160;        <span class="keywordflow">if</span>(m_Blocks[i - 1]-&gt;m_Metadata.GetSumFreeSize() &gt; m_Blocks[i]-&gt;m_Metadata.GetSumFreeSize())</div><div class="line"><a name="l06876"></a><span class="lineno"> 6876</span>&#160;        {</div><div class="line"><a name="l06877"></a><span class="lineno"> 6877</span>&#160;            VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]);</div><div class="line"><a name="l06878"></a><span class="lineno"> 6878</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l06879"></a><span class="lineno"> 6879</span>&#160;        }</div><div class="line"><a name="l06880"></a><span class="lineno"> 6880</span>&#160;    }</div><div class="line"><a name="l06881"></a><span class="lineno"> 6881</span>&#160;}</div><div class="line"><a name="l06882"></a><span class="lineno"> 6882</span>&#160;</div><div class="line"><a name="l06883"></a><span class="lineno"> 6883</span>&#160;VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, <span class="keywordtype">size_t</span>* pNewBlockIndex)</div><div class="line"><a name="l06884"></a><span class="lineno"> 6884</span>&#160;{</div><div class="line"><a name="l06885"></a><span class="lineno"> 6885</span>&#160;    VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };</div><div class="line"><a name="l06886"></a><span class="lineno"> 6886</span>&#160;    allocInfo.memoryTypeIndex = m_MemoryTypeIndex;</div><div class="line"><a name="l06887"></a><span class="lineno"> 6887</span>&#160;    allocInfo.allocationSize = blockSize;</div><div class="line"><a name="l06888"></a><span class="lineno"> 6888</span>&#160;    VkDeviceMemory mem = VK_NULL_HANDLE;</div><div class="line"><a name="l06889"></a><span class="lineno"> 6889</span>&#160;    VkResult res = m_hAllocator-&gt;AllocateVulkanMemory(&amp;allocInfo, &amp;mem);</div><div class="line"><a name="l06890"></a><span class="lineno"> 6890</span>&#160;    <span class="keywordflow">if</span>(res &lt; 0)</div><div class="line"><a name="l06891"></a><span class="lineno"> 6891</span>&#160;    {</div><div class="line"><a name="l06892"></a><span class="lineno"> 6892</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l06893"></a><span class="lineno"> 6893</span>&#160;    }</div><div class="line"><a name="l06894"></a><span class="lineno"> 6894</span>&#160;</div><div class="line"><a name="l06895"></a><span class="lineno"> 6895</span>&#160;    <span class="comment">// New VkDeviceMemory successfully created.</span></div><div class="line"><a name="l06896"></a><span class="lineno"> 6896</span>&#160;</div><div class="line"><a name="l06897"></a><span class="lineno"> 6897</span>&#160;    <span class="comment">// Create new Allocation for it.</span></div><div class="line"><a name="l06898"></a><span class="lineno"> 6898</span>&#160;    VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = vma_new(m_hAllocator, VmaDeviceMemoryBlock)(m_hAllocator);</div><div class="line"><a name="l06899"></a><span class="lineno"> 6899</span>&#160;    pBlock-&gt;Init(</div><div class="line"><a name="l06900"></a><span class="lineno"> 6900</span>&#160;        m_MemoryTypeIndex,</div><div class="line"><a name="l06901"></a><span class="lineno"> 6901</span>&#160;        mem,</div><div class="line"><a name="l06902"></a><span class="lineno"> 6902</span>&#160;        allocInfo.allocationSize);</div><div class="line"><a name="l06903"></a><span class="lineno"> 6903</span>&#160;</div><div class="line"><a name="l06904"></a><span class="lineno"> 6904</span>&#160;    m_Blocks.push_back(pBlock);</div><div class="line"><a name="l06905"></a><span class="lineno"> 6905</span>&#160;    <span class="keywordflow">if</span>(pNewBlockIndex != VMA_NULL)</div><div class="line"><a name="l06906"></a><span class="lineno"> 6906</span>&#160;    {</div><div class="line"><a name="l06907"></a><span class="lineno"> 6907</span>&#160;        *pNewBlockIndex = m_Blocks.size() - 1;</div><div class="line"><a name="l06908"></a><span class="lineno"> 6908</span>&#160;    }</div><div class="line"><a name="l06909"></a><span class="lineno"> 6909</span>&#160;</div><div class="line"><a name="l06910"></a><span class="lineno"> 6910</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06911"></a><span class="lineno"> 6911</span>&#160;}</div><div class="line"><a name="l06912"></a><span class="lineno"> 6912</span>&#160;</div><div class="line"><a name="l06913"></a><span class="lineno"> 6913</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06914"></a><span class="lineno"> 6914</span>&#160;</div><div class="line"><a name="l06915"></a><span class="lineno"> 6915</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json)</div><div class="line"><a name="l06916"></a><span class="lineno"> 6916</span>&#160;{</div><div class="line"><a name="l06917"></a><span class="lineno"> 6917</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06918"></a><span class="lineno"> 6918</span>&#160;</div><div class="line"><a name="l06919"></a><span class="lineno"> 6919</span>&#160;    json.BeginObject();</div><div class="line"><a name="l06920"></a><span class="lineno"> 6920</span>&#160;</div><div class="line"><a name="l06921"></a><span class="lineno"> 6921</span>&#160;    <span class="keywordflow">if</span>(m_IsCustomPool)</div><div class="line"><a name="l06922"></a><span class="lineno"> 6922</span>&#160;    {</div><div class="line"><a name="l06923"></a><span class="lineno"> 6923</span>&#160;        json.WriteString(<span class="stringliteral">&quot;MemoryTypeIndex&quot;</span>);</div><div class="line"><a name="l06924"></a><span class="lineno"> 6924</span>&#160;        json.WriteNumber(m_MemoryTypeIndex);</div><div class="line"><a name="l06925"></a><span class="lineno"> 6925</span>&#160;</div><div class="line"><a name="l06926"></a><span class="lineno"> 6926</span>&#160;        json.WriteString(<span class="stringliteral">&quot;BlockSize&quot;</span>);</div><div class="line"><a name="l06927"></a><span class="lineno"> 6927</span>&#160;        json.WriteNumber(m_PreferredBlockSize);</div><div class="line"><a name="l06928"></a><span class="lineno"> 6928</span>&#160;</div><div class="line"><a name="l06929"></a><span class="lineno"> 6929</span>&#160;        json.WriteString(<span class="stringliteral">&quot;BlockCount&quot;</span>);</div><div class="line"><a name="l06930"></a><span class="lineno"> 6930</span>&#160;        json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l06931"></a><span class="lineno"> 6931</span>&#160;        <span class="keywordflow">if</span>(m_MinBlockCount &gt; 0)</div><div class="line"><a name="l06932"></a><span class="lineno"> 6932</span>&#160;        {</div><div class="line"><a name="l06933"></a><span class="lineno"> 6933</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Min&quot;</span>);</div><div class="line"><a name="l06934"></a><span class="lineno"> 6934</span>&#160;            json.WriteNumber((uint64_t)m_MinBlockCount);</div><div class="line"><a name="l06935"></a><span class="lineno"> 6935</span>&#160;        }</div><div class="line"><a name="l06936"></a><span class="lineno"> 6936</span>&#160;        <span class="keywordflow">if</span>(m_MaxBlockCount &lt; SIZE_MAX)</div><div class="line"><a name="l06937"></a><span class="lineno"> 6937</span>&#160;        {</div><div class="line"><a name="l06938"></a><span class="lineno"> 6938</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Max&quot;</span>);</div><div class="line"><a name="l06939"></a><span class="lineno"> 6939</span>&#160;            json.WriteNumber((uint64_t)m_MaxBlockCount);</div><div class="line"><a name="l06940"></a><span class="lineno"> 6940</span>&#160;        }</div><div class="line"><a name="l06941"></a><span class="lineno"> 6941</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Cur&quot;</span>);</div><div class="line"><a name="l06942"></a><span class="lineno"> 6942</span>&#160;        json.WriteNumber((uint64_t)m_Blocks.size());</div><div class="line"><a name="l06943"></a><span class="lineno"> 6943</span>&#160;        json.EndObject();</div><div class="line"><a name="l06944"></a><span class="lineno"> 6944</span>&#160;</div><div class="line"><a name="l06945"></a><span class="lineno"> 6945</span>&#160;        <span class="keywordflow">if</span>(m_FrameInUseCount &gt; 0)</div><div class="line"><a name="l06946"></a><span class="lineno"> 6946</span>&#160;        {</div><div class="line"><a name="l06947"></a><span class="lineno"> 6947</span>&#160;            json.WriteString(<span class="stringliteral">&quot;FrameInUseCount&quot;</span>);</div><div class="line"><a name="l06948"></a><span class="lineno"> 6948</span>&#160;            json.WriteNumber(m_FrameInUseCount);</div><div class="line"><a name="l06949"></a><span class="lineno"> 6949</span>&#160;        }</div><div class="line"><a name="l06950"></a><span class="lineno"> 6950</span>&#160;    }</div><div class="line"><a name="l06951"></a><span class="lineno"> 6951</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06952"></a><span class="lineno"> 6952</span>&#160;    {</div><div class="line"><a name="l06953"></a><span class="lineno"> 6953</span>&#160;        json.WriteString(<span class="stringliteral">&quot;PreferredBlockSize&quot;</span>);</div><div class="line"><a name="l06954"></a><span class="lineno"> 6954</span>&#160;        json.WriteNumber(m_PreferredBlockSize);</div><div class="line"><a name="l06955"></a><span class="lineno"> 6955</span>&#160;    }</div><div class="line"><a name="l06956"></a><span class="lineno"> 6956</span>&#160;</div><div class="line"><a name="l06957"></a><span class="lineno"> 6957</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Blocks&quot;</span>);</div><div class="line"><a name="l06958"></a><span class="lineno"> 6958</span>&#160;    json.BeginArray();</div><div class="line"><a name="l06959"></a><span class="lineno"> 6959</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_Blocks.size(); ++i)</div><div class="line"><a name="l06960"></a><span class="lineno"> 6960</span>&#160;    {</div><div class="line"><a name="l06961"></a><span class="lineno"> 6961</span>&#160;        m_Blocks[i]-&gt;m_Metadata.PrintDetailedMap(json);</div><div class="line"><a name="l06962"></a><span class="lineno"> 6962</span>&#160;    }</div><div class="line"><a name="l06963"></a><span class="lineno"> 6963</span>&#160;    json.EndArray();</div><div class="line"><a name="l06964"></a><span class="lineno"> 6964</span>&#160;</div><div class="line"><a name="l06965"></a><span class="lineno"> 6965</span>&#160;    json.EndObject();</div><div class="line"><a name="l06966"></a><span class="lineno"> 6966</span>&#160;}</div><div class="line"><a name="l06967"></a><span class="lineno"> 6967</span>&#160;</div><div class="line"><a name="l06968"></a><span class="lineno"> 6968</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06969"></a><span class="lineno"> 6969</span>&#160;</div><div class="line"><a name="l06970"></a><span class="lineno"> 6970</span>&#160;VmaDefragmentator* VmaBlockVector::EnsureDefragmentator(</div><div class="line"><a name="l06971"></a><span class="lineno"> 6971</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l06972"></a><span class="lineno"> 6972</span>&#160;    uint32_t currentFrameIndex)</div><div class="line"><a name="l06973"></a><span class="lineno"> 6973</span>&#160;{</div><div class="line"><a name="l06974"></a><span class="lineno"> 6974</span>&#160;    <span class="keywordflow">if</span>(m_pDefragmentator == VMA_NULL)</div><div class="line"><a name="l06975"></a><span class="lineno"> 6975</span>&#160;    {</div><div class="line"><a name="l06976"></a><span class="lineno"> 6976</span>&#160;        m_pDefragmentator = vma_new(m_hAllocator, VmaDefragmentator)(</div><div class="line"><a name="l06977"></a><span class="lineno"> 6977</span>&#160;            hAllocator,</div><div class="line"><a name="l06978"></a><span class="lineno"> 6978</span>&#160;            <span class="keyword">this</span>,</div><div class="line"><a name="l06979"></a><span class="lineno"> 6979</span>&#160;            currentFrameIndex);</div><div class="line"><a name="l06980"></a><span class="lineno"> 6980</span>&#160;    }</div><div class="line"><a name="l06981"></a><span class="lineno"> 6981</span>&#160;</div><div class="line"><a name="l06982"></a><span class="lineno"> 6982</span>&#160;    <span class="keywordflow">return</span> m_pDefragmentator;</div><div class="line"><a name="l06983"></a><span class="lineno"> 6983</span>&#160;}</div><div class="line"><a name="l06984"></a><span class="lineno"> 6984</span>&#160;</div><div class="line"><a name="l06985"></a><span class="lineno"> 6985</span>&#160;VkResult VmaBlockVector::Defragment(</div><div class="line"><a name="l06986"></a><span class="lineno"> 6986</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats,</div><div class="line"><a name="l06987"></a><span class="lineno"> 6987</span>&#160;    VkDeviceSize&amp; maxBytesToMove,</div><div class="line"><a name="l06988"></a><span class="lineno"> 6988</span>&#160;    uint32_t&amp; maxAllocationsToMove)</div><div class="line"><a name="l06989"></a><span class="lineno"> 6989</span>&#160;{</div><div class="line"><a name="l06990"></a><span class="lineno"> 6990</span>&#160;    <span class="keywordflow">if</span>(m_pDefragmentator == VMA_NULL)</div><div class="line"><a name="l06991"></a><span class="lineno"> 6991</span>&#160;    {</div><div class="line"><a name="l06992"></a><span class="lineno"> 6992</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06993"></a><span class="lineno"> 6993</span>&#160;    }</div><div class="line"><a name="l06994"></a><span class="lineno"> 6994</span>&#160;</div><div class="line"><a name="l06995"></a><span class="lineno"> 6995</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l06996"></a><span class="lineno"> 6996</span>&#160;</div><div class="line"><a name="l06997"></a><span class="lineno"> 6997</span>&#160;    <span class="comment">// Defragment.</span></div><div class="line"><a name="l06998"></a><span class="lineno"> 6998</span>&#160;    VkResult result = m_pDefragmentator-&gt;Defragment(maxBytesToMove, maxAllocationsToMove);</div><div class="line"><a name="l06999"></a><span class="lineno"> 6999</span>&#160;</div><div class="line"><a name="l07000"></a><span class="lineno"> 7000</span>&#160;    <span class="comment">// Accumulate statistics.</span></div><div class="line"><a name="l07001"></a><span class="lineno"> 7001</span>&#160;    <span class="keywordflow">if</span>(pDefragmentationStats != VMA_NULL)</div><div class="line"><a name="l07002"></a><span class="lineno"> 7002</span>&#160;    {</div><div class="line"><a name="l07003"></a><span class="lineno"> 7003</span>&#160;        <span class="keyword">const</span> VkDeviceSize <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a> = m_pDefragmentator-&gt;GetBytesMoved();</div><div class="line"><a name="l07004"></a><span class="lineno"> 7004</span>&#160;        <span class="keyword">const</span> uint32_t <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a> = m_pDefragmentator-&gt;GetAllocationsMoved();</div><div class="line"><a name="l07005"></a><span class="lineno"> 7005</span>&#160;        pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a> += <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a>;</div><div class="line"><a name="l07006"></a><span class="lineno"> 7006</span>&#160;        pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a> += <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a>;</div><div class="line"><a name="l07007"></a><span class="lineno"> 7007</span>&#160;        VMA_ASSERT(bytesMoved &lt;= maxBytesToMove);</div><div class="line"><a name="l07008"></a><span class="lineno"> 7008</span>&#160;        VMA_ASSERT(allocationsMoved &lt;= maxAllocationsToMove);</div><div class="line"><a name="l07009"></a><span class="lineno"> 7009</span>&#160;        maxBytesToMove -= <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a>;</div><div class="line"><a name="l07010"></a><span class="lineno"> 7010</span>&#160;        maxAllocationsToMove -= <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a>;</div><div class="line"><a name="l07011"></a><span class="lineno"> 7011</span>&#160;    }</div><div class="line"><a name="l07012"></a><span class="lineno"> 7012</span>&#160;    </div><div class="line"><a name="l07013"></a><span class="lineno"> 7013</span>&#160;    <span class="comment">// Free empty blocks.</span></div><div class="line"><a name="l07014"></a><span class="lineno"> 7014</span>&#160;    m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l07015"></a><span class="lineno"> 7015</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = m_Blocks.size(); blockIndex--; )</div><div class="line"><a name="l07016"></a><span class="lineno"> 7016</span>&#160;    {</div><div class="line"><a name="l07017"></a><span class="lineno"> 7017</span>&#160;        VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l07018"></a><span class="lineno"> 7018</span>&#160;        <span class="keywordflow">if</span>(pBlock-&gt;m_Metadata.IsEmpty())</div><div class="line"><a name="l07019"></a><span class="lineno"> 7019</span>&#160;        {</div><div class="line"><a name="l07020"></a><span class="lineno"> 7020</span>&#160;            <span class="keywordflow">if</span>(m_Blocks.size() &gt; m_MinBlockCount)</div><div class="line"><a name="l07021"></a><span class="lineno"> 7021</span>&#160;            {</div><div class="line"><a name="l07022"></a><span class="lineno"> 7022</span>&#160;                <span class="keywordflow">if</span>(pDefragmentationStats != VMA_NULL)</div><div class="line"><a name="l07023"></a><span class="lineno"> 7023</span>&#160;                {</div><div class="line"><a name="l07024"></a><span class="lineno"> 7024</span>&#160;                    ++pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b">deviceMemoryBlocksFreed</a>;</div><div class="line"><a name="l07025"></a><span class="lineno"> 7025</span>&#160;                    pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28">bytesFreed</a> += pBlock-&gt;m_Metadata.GetSize();</div><div class="line"><a name="l07026"></a><span class="lineno"> 7026</span>&#160;                }</div><div class="line"><a name="l07027"></a><span class="lineno"> 7027</span>&#160;</div><div class="line"><a name="l07028"></a><span class="lineno"> 7028</span>&#160;                VmaVectorRemove(m_Blocks, blockIndex);</div><div class="line"><a name="l07029"></a><span class="lineno"> 7029</span>&#160;                pBlock-&gt;Destroy(m_hAllocator);</div><div class="line"><a name="l07030"></a><span class="lineno"> 7030</span>&#160;                vma_delete(m_hAllocator, pBlock);</div><div class="line"><a name="l07031"></a><span class="lineno"> 7031</span>&#160;            }</div><div class="line"><a name="l07032"></a><span class="lineno"> 7032</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07033"></a><span class="lineno"> 7033</span>&#160;            {</div><div class="line"><a name="l07034"></a><span class="lineno"> 7034</span>&#160;                m_HasEmptyBlock = <span class="keyword">true</span>;</div><div class="line"><a name="l07035"></a><span class="lineno"> 7035</span>&#160;            }</div><div class="line"><a name="l07036"></a><span class="lineno"> 7036</span>&#160;        }</div><div class="line"><a name="l07037"></a><span class="lineno"> 7037</span>&#160;    }</div><div class="line"><a name="l07038"></a><span class="lineno"> 7038</span>&#160;</div><div class="line"><a name="l07039"></a><span class="lineno"> 7039</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l07040"></a><span class="lineno"> 7040</span>&#160;}</div><div class="line"><a name="l07041"></a><span class="lineno"> 7041</span>&#160;</div><div class="line"><a name="l07042"></a><span class="lineno"> 7042</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::DestroyDefragmentator()</div><div class="line"><a name="l07043"></a><span class="lineno"> 7043</span>&#160;{</div><div class="line"><a name="l07044"></a><span class="lineno"> 7044</span>&#160;    <span class="keywordflow">if</span>(m_pDefragmentator != VMA_NULL)</div><div class="line"><a name="l07045"></a><span class="lineno"> 7045</span>&#160;    {</div><div class="line"><a name="l07046"></a><span class="lineno"> 7046</span>&#160;        vma_delete(m_hAllocator, m_pDefragmentator);</div><div class="line"><a name="l07047"></a><span class="lineno"> 7047</span>&#160;        m_pDefragmentator = VMA_NULL;</div><div class="line"><a name="l07048"></a><span class="lineno"> 7048</span>&#160;    }</div><div class="line"><a name="l07049"></a><span class="lineno"> 7049</span>&#160;}</div><div class="line"><a name="l07050"></a><span class="lineno"> 7050</span>&#160;</div><div class="line"><a name="l07051"></a><span class="lineno"> 7051</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::MakePoolAllocationsLost(</div><div class="line"><a name="l07052"></a><span class="lineno"> 7052</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l07053"></a><span class="lineno"> 7053</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount)</div><div class="line"><a name="l07054"></a><span class="lineno"> 7054</span>&#160;{</div><div class="line"><a name="l07055"></a><span class="lineno"> 7055</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l07056"></a><span class="lineno"> 7056</span>&#160;    <span class="keywordtype">size_t</span> lostAllocationCount = 0;</div><div class="line"><a name="l07057"></a><span class="lineno"> 7057</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l07058"></a><span class="lineno"> 7058</span>&#160;    {</div><div class="line"><a name="l07059"></a><span class="lineno"> 7059</span>&#160;        VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l07060"></a><span class="lineno"> 7060</span>&#160;        VMA_ASSERT(pBlock);</div><div class="line"><a name="l07061"></a><span class="lineno"> 7061</span>&#160;        lostAllocationCount += pBlock-&gt;m_Metadata.MakeAllocationsLost(currentFrameIndex, m_FrameInUseCount);</div><div class="line"><a name="l07062"></a><span class="lineno"> 7062</span>&#160;    }</div><div class="line"><a name="l07063"></a><span class="lineno"> 7063</span>&#160;    <span class="keywordflow">if</span>(pLostAllocationCount != VMA_NULL)</div><div class="line"><a name="l07064"></a><span class="lineno"> 7064</span>&#160;    {</div><div class="line"><a name="l07065"></a><span class="lineno"> 7065</span>&#160;        *pLostAllocationCount = lostAllocationCount;</div><div class="line"><a name="l07066"></a><span class="lineno"> 7066</span>&#160;    }</div><div class="line"><a name="l07067"></a><span class="lineno"> 7067</span>&#160;}</div><div class="line"><a name="l07068"></a><span class="lineno"> 7068</span>&#160;</div><div class="line"><a name="l07069"></a><span class="lineno"> 7069</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::AddStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats)</div><div class="line"><a name="l07070"></a><span class="lineno"> 7070</span>&#160;{</div><div class="line"><a name="l07071"></a><span class="lineno"> 7071</span>&#160;    <span class="keyword">const</span> uint32_t memTypeIndex = m_MemoryTypeIndex;</div><div class="line"><a name="l07072"></a><span class="lineno"> 7072</span>&#160;    <span class="keyword">const</span> uint32_t memHeapIndex = m_hAllocator-&gt;MemoryTypeIndexToHeapIndex(memTypeIndex);</div><div class="line"><a name="l07073"></a><span class="lineno"> 7073</span>&#160;</div><div class="line"><a name="l07074"></a><span class="lineno"> 7074</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l07075"></a><span class="lineno"> 7075</span>&#160;</div><div class="line"><a name="l07076"></a><span class="lineno"> 7076</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l07077"></a><span class="lineno"> 7077</span>&#160;    {</div><div class="line"><a name="l07078"></a><span class="lineno"> 7078</span>&#160;        <span class="keyword">const</span> VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l07079"></a><span class="lineno"> 7079</span>&#160;        VMA_ASSERT(pBlock);</div><div class="line"><a name="l07080"></a><span class="lineno"> 7080</span>&#160;        VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l07081"></a><span class="lineno"> 7081</span>&#160;        <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> allocationStatInfo;</div><div class="line"><a name="l07082"></a><span class="lineno"> 7082</span>&#160;        pBlock-&gt;m_Metadata.CalcAllocationStatInfo(allocationStatInfo);</div><div class="line"><a name="l07083"></a><span class="lineno"> 7083</span>&#160;        VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>, allocationStatInfo);</div><div class="line"><a name="l07084"></a><span class="lineno"> 7084</span>&#160;        VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[memTypeIndex], allocationStatInfo);</div><div class="line"><a name="l07085"></a><span class="lineno"> 7085</span>&#160;        VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[memHeapIndex], allocationStatInfo);</div><div class="line"><a name="l07086"></a><span class="lineno"> 7086</span>&#160;    }</div><div class="line"><a name="l07087"></a><span class="lineno"> 7087</span>&#160;}</div><div class="line"><a name="l07088"></a><span class="lineno"> 7088</span>&#160;</div><div class="line"><a name="l07090"></a><span class="lineno"> 7090</span>&#160;<span class="comment">// VmaDefragmentator members definition</span></div><div class="line"><a name="l07091"></a><span class="lineno"> 7091</span>&#160;</div><div class="line"><a name="l07092"></a><span class="lineno"> 7092</span>&#160;VmaDefragmentator::VmaDefragmentator(</div><div class="line"><a name="l07093"></a><span class="lineno"> 7093</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l07094"></a><span class="lineno"> 7094</span>&#160;    VmaBlockVector* pBlockVector,</div><div class="line"><a name="l07095"></a><span class="lineno"> 7095</span>&#160;    uint32_t currentFrameIndex) :</div><div class="line"><a name="l07096"></a><span class="lineno"> 7096</span>&#160;    m_hAllocator(hAllocator),</div><div class="line"><a name="l07097"></a><span class="lineno"> 7097</span>&#160;    m_pBlockVector(pBlockVector),</div><div class="line"><a name="l07098"></a><span class="lineno"> 7098</span>&#160;    m_CurrentFrameIndex(currentFrameIndex),</div><div class="line"><a name="l07099"></a><span class="lineno"> 7099</span>&#160;    m_BytesMoved(0),</div><div class="line"><a name="l07100"></a><span class="lineno"> 7100</span>&#160;    m_AllocationsMoved(0),</div><div class="line"><a name="l07101"></a><span class="lineno"> 7101</span>&#160;    m_Allocations(VmaStlAllocator&lt;AllocationInfo&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l07102"></a><span class="lineno"> 7102</span>&#160;    m_Blocks(VmaStlAllocator&lt;BlockInfo*&gt;(hAllocator-&gt;GetAllocationCallbacks()))</div><div class="line"><a name="l07103"></a><span class="lineno"> 7103</span>&#160;{</div><div class="line"><a name="l07104"></a><span class="lineno"> 7104</span>&#160;}</div><div class="line"><a name="l07105"></a><span class="lineno"> 7105</span>&#160;</div><div class="line"><a name="l07106"></a><span class="lineno"> 7106</span>&#160;VmaDefragmentator::~VmaDefragmentator()</div><div class="line"><a name="l07107"></a><span class="lineno"> 7107</span>&#160;{</div><div class="line"><a name="l07108"></a><span class="lineno"> 7108</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_Blocks.size(); i--; )</div><div class="line"><a name="l07109"></a><span class="lineno"> 7109</span>&#160;    {</div><div class="line"><a name="l07110"></a><span class="lineno"> 7110</span>&#160;        vma_delete(m_hAllocator, m_Blocks[i]);</div><div class="line"><a name="l07111"></a><span class="lineno"> 7111</span>&#160;    }</div><div class="line"><a name="l07112"></a><span class="lineno"> 7112</span>&#160;}</div><div class="line"><a name="l07113"></a><span class="lineno"> 7113</span>&#160;</div><div class="line"><a name="l07114"></a><span class="lineno"> 7114</span>&#160;<span class="keywordtype">void</span> VmaDefragmentator::AddAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc, VkBool32* pChanged)</div><div class="line"><a name="l07115"></a><span class="lineno"> 7115</span>&#160;{</div><div class="line"><a name="l07116"></a><span class="lineno"> 7116</span>&#160;    AllocationInfo allocInfo;</div><div class="line"><a name="l07117"></a><span class="lineno"> 7117</span>&#160;    allocInfo.m_hAllocation = hAlloc;</div><div class="line"><a name="l07118"></a><span class="lineno"> 7118</span>&#160;    allocInfo.m_pChanged = pChanged;</div><div class="line"><a name="l07119"></a><span class="lineno"> 7119</span>&#160;    m_Allocations.push_back(allocInfo);</div><div class="line"><a name="l07120"></a><span class="lineno"> 7120</span>&#160;}</div><div class="line"><a name="l07121"></a><span class="lineno"> 7121</span>&#160;</div><div class="line"><a name="l07122"></a><span class="lineno"> 7122</span>&#160;VkResult VmaDefragmentator::BlockInfo::EnsureMapping(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppMappedData)</div><div class="line"><a name="l07123"></a><span class="lineno"> 7123</span>&#160;{</div><div class="line"><a name="l07124"></a><span class="lineno"> 7124</span>&#160;    <span class="comment">// It has already been mapped for defragmentation.</span></div><div class="line"><a name="l07125"></a><span class="lineno"> 7125</span>&#160;    <span class="keywordflow">if</span>(m_pMappedDataForDefragmentation)</div><div class="line"><a name="l07126"></a><span class="lineno"> 7126</span>&#160;    {</div><div class="line"><a name="l07127"></a><span class="lineno"> 7127</span>&#160;        *ppMappedData = m_pMappedDataForDefragmentation;</div><div class="line"><a name="l07128"></a><span class="lineno"> 7128</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07129"></a><span class="lineno"> 7129</span>&#160;    }</div><div class="line"><a name="l07130"></a><span class="lineno"> 7130</span>&#160;            </div><div class="line"><a name="l07131"></a><span class="lineno"> 7131</span>&#160;    <span class="comment">// It is originally mapped.</span></div><div class="line"><a name="l07132"></a><span class="lineno"> 7132</span>&#160;    <span class="keywordflow">if</span>(m_pBlock-&gt;GetMappedData())</div><div class="line"><a name="l07133"></a><span class="lineno"> 7133</span>&#160;    {</div><div class="line"><a name="l07134"></a><span class="lineno"> 7134</span>&#160;        *ppMappedData = m_pBlock-&gt;GetMappedData();</div><div class="line"><a name="l07135"></a><span class="lineno"> 7135</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07136"></a><span class="lineno"> 7136</span>&#160;    }</div><div class="line"><a name="l07137"></a><span class="lineno"> 7137</span>&#160;            </div><div class="line"><a name="l07138"></a><span class="lineno"> 7138</span>&#160;    <span class="comment">// Map on first usage.</span></div><div class="line"><a name="l07139"></a><span class="lineno"> 7139</span>&#160;    VkResult res = m_pBlock-&gt;Map(hAllocator, 1, &amp;m_pMappedDataForDefragmentation);</div><div class="line"><a name="l07140"></a><span class="lineno"> 7140</span>&#160;    *ppMappedData = m_pMappedDataForDefragmentation;</div><div class="line"><a name="l07141"></a><span class="lineno"> 7141</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07142"></a><span class="lineno"> 7142</span>&#160;}</div><div class="line"><a name="l07143"></a><span class="lineno"> 7143</span>&#160;</div><div class="line"><a name="l07144"></a><span class="lineno"> 7144</span>&#160;<span class="keywordtype">void</span> VmaDefragmentator::BlockInfo::Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l07145"></a><span class="lineno"> 7145</span>&#160;{</div><div class="line"><a name="l07146"></a><span class="lineno"> 7146</span>&#160;    <span class="keywordflow">if</span>(m_pMappedDataForDefragmentation != VMA_NULL)</div><div class="line"><a name="l07147"></a><span class="lineno"> 7147</span>&#160;    {</div><div class="line"><a name="l07148"></a><span class="lineno"> 7148</span>&#160;        m_pBlock-&gt;Unmap(hAllocator, 1);</div><div class="line"><a name="l07149"></a><span class="lineno"> 7149</span>&#160;    }</div><div class="line"><a name="l07150"></a><span class="lineno"> 7150</span>&#160;}</div><div class="line"><a name="l07151"></a><span class="lineno"> 7151</span>&#160;</div><div class="line"><a name="l07152"></a><span class="lineno"> 7152</span>&#160;VkResult VmaDefragmentator::DefragmentRound(</div><div class="line"><a name="l07153"></a><span class="lineno"> 7153</span>&#160;    VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l07154"></a><span class="lineno"> 7154</span>&#160;    uint32_t maxAllocationsToMove)</div><div class="line"><a name="l07155"></a><span class="lineno"> 7155</span>&#160;{</div><div class="line"><a name="l07156"></a><span class="lineno"> 7156</span>&#160;    <span class="keywordflow">if</span>(m_Blocks.empty())</div><div class="line"><a name="l07157"></a><span class="lineno"> 7157</span>&#160;    {</div><div class="line"><a name="l07158"></a><span class="lineno"> 7158</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07159"></a><span class="lineno"> 7159</span>&#160;    }</div><div class="line"><a name="l07160"></a><span class="lineno"> 7160</span>&#160;</div><div class="line"><a name="l07161"></a><span class="lineno"> 7161</span>&#160;    <span class="keywordtype">size_t</span> srcBlockIndex = m_Blocks.size() - 1;</div><div class="line"><a name="l07162"></a><span class="lineno"> 7162</span>&#160;    <span class="keywordtype">size_t</span> srcAllocIndex = SIZE_MAX;</div><div class="line"><a name="l07163"></a><span class="lineno"> 7163</span>&#160;    <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l07164"></a><span class="lineno"> 7164</span>&#160;    {</div><div class="line"><a name="l07165"></a><span class="lineno"> 7165</span>&#160;        <span class="comment">// 1. Find next allocation to move.</span></div><div class="line"><a name="l07166"></a><span class="lineno"> 7166</span>&#160;        <span class="comment">// 1.1. Start from last to first m_Blocks - they are sorted from most &quot;destination&quot; to most &quot;source&quot;.</span></div><div class="line"><a name="l07167"></a><span class="lineno"> 7167</span>&#160;        <span class="comment">// 1.2. Then start from last to first m_Allocations - they are sorted from largest to smallest.</span></div><div class="line"><a name="l07168"></a><span class="lineno"> 7168</span>&#160;        <span class="keywordflow">while</span>(srcAllocIndex &gt;= m_Blocks[srcBlockIndex]-&gt;m_Allocations.size())</div><div class="line"><a name="l07169"></a><span class="lineno"> 7169</span>&#160;        {</div><div class="line"><a name="l07170"></a><span class="lineno"> 7170</span>&#160;            <span class="keywordflow">if</span>(m_Blocks[srcBlockIndex]-&gt;m_Allocations.empty())</div><div class="line"><a name="l07171"></a><span class="lineno"> 7171</span>&#160;            {</div><div class="line"><a name="l07172"></a><span class="lineno"> 7172</span>&#160;                <span class="comment">// Finished: no more allocations to process.</span></div><div class="line"><a name="l07173"></a><span class="lineno"> 7173</span>&#160;                <span class="keywordflow">if</span>(srcBlockIndex == 0)</div><div class="line"><a name="l07174"></a><span class="lineno"> 7174</span>&#160;                {</div><div class="line"><a name="l07175"></a><span class="lineno"> 7175</span>&#160;                    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07176"></a><span class="lineno"> 7176</span>&#160;                }</div><div class="line"><a name="l07177"></a><span class="lineno"> 7177</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l07178"></a><span class="lineno"> 7178</span>&#160;                {</div><div class="line"><a name="l07179"></a><span class="lineno"> 7179</span>&#160;                    --srcBlockIndex;</div><div class="line"><a name="l07180"></a><span class="lineno"> 7180</span>&#160;                    srcAllocIndex = SIZE_MAX;</div><div class="line"><a name="l07181"></a><span class="lineno"> 7181</span>&#160;                }</div><div class="line"><a name="l07182"></a><span class="lineno"> 7182</span>&#160;            }</div><div class="line"><a name="l07183"></a><span class="lineno"> 7183</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07184"></a><span class="lineno"> 7184</span>&#160;            {</div><div class="line"><a name="l07185"></a><span class="lineno"> 7185</span>&#160;                srcAllocIndex = m_Blocks[srcBlockIndex]-&gt;m_Allocations.size() - 1;</div><div class="line"><a name="l07186"></a><span class="lineno"> 7186</span>&#160;            }</div><div class="line"><a name="l07187"></a><span class="lineno"> 7187</span>&#160;        }</div><div class="line"><a name="l07188"></a><span class="lineno"> 7188</span>&#160;        </div><div class="line"><a name="l07189"></a><span class="lineno"> 7189</span>&#160;        BlockInfo* pSrcBlockInfo = m_Blocks[srcBlockIndex];</div><div class="line"><a name="l07190"></a><span class="lineno"> 7190</span>&#160;        AllocationInfo&amp; allocInfo = pSrcBlockInfo-&gt;m_Allocations[srcAllocIndex];</div><div class="line"><a name="l07191"></a><span class="lineno"> 7191</span>&#160;</div><div class="line"><a name="l07192"></a><span class="lineno"> 7192</span>&#160;        <span class="keyword">const</span> VkDeviceSize size = allocInfo.m_hAllocation-&gt;GetSize();</div><div class="line"><a name="l07193"></a><span class="lineno"> 7193</span>&#160;        <span class="keyword">const</span> VkDeviceSize srcOffset = allocInfo.m_hAllocation-&gt;GetOffset();</div><div class="line"><a name="l07194"></a><span class="lineno"> 7194</span>&#160;        <span class="keyword">const</span> VkDeviceSize alignment = allocInfo.m_hAllocation-&gt;GetAlignment();</div><div class="line"><a name="l07195"></a><span class="lineno"> 7195</span>&#160;        <span class="keyword">const</span> VmaSuballocationType suballocType = allocInfo.m_hAllocation-&gt;GetSuballocationType();</div><div class="line"><a name="l07196"></a><span class="lineno"> 7196</span>&#160;</div><div class="line"><a name="l07197"></a><span class="lineno"> 7197</span>&#160;        <span class="comment">// 2. Try to find new place for this allocation in preceding or current block.</span></div><div class="line"><a name="l07198"></a><span class="lineno"> 7198</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> dstBlockIndex = 0; dstBlockIndex &lt;= srcBlockIndex; ++dstBlockIndex)</div><div class="line"><a name="l07199"></a><span class="lineno"> 7199</span>&#160;        {</div><div class="line"><a name="l07200"></a><span class="lineno"> 7200</span>&#160;            BlockInfo* pDstBlockInfo = m_Blocks[dstBlockIndex];</div><div class="line"><a name="l07201"></a><span class="lineno"> 7201</span>&#160;            VmaAllocationRequest dstAllocRequest;</div><div class="line"><a name="l07202"></a><span class="lineno"> 7202</span>&#160;            <span class="keywordflow">if</span>(pDstBlockInfo-&gt;m_pBlock-&gt;m_Metadata.CreateAllocationRequest(</div><div class="line"><a name="l07203"></a><span class="lineno"> 7203</span>&#160;                m_CurrentFrameIndex,</div><div class="line"><a name="l07204"></a><span class="lineno"> 7204</span>&#160;                m_pBlockVector-&gt;GetFrameInUseCount(),</div><div class="line"><a name="l07205"></a><span class="lineno"> 7205</span>&#160;                m_pBlockVector-&gt;GetBufferImageGranularity(),</div><div class="line"><a name="l07206"></a><span class="lineno"> 7206</span>&#160;                size,</div><div class="line"><a name="l07207"></a><span class="lineno"> 7207</span>&#160;                alignment,</div><div class="line"><a name="l07208"></a><span class="lineno"> 7208</span>&#160;                suballocType,</div><div class="line"><a name="l07209"></a><span class="lineno"> 7209</span>&#160;                <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l07210"></a><span class="lineno"> 7210</span>&#160;                &amp;dstAllocRequest) &amp;&amp;</div><div class="line"><a name="l07211"></a><span class="lineno"> 7211</span>&#160;            MoveMakesSense(</div><div class="line"><a name="l07212"></a><span class="lineno"> 7212</span>&#160;                dstBlockIndex, dstAllocRequest.offset, srcBlockIndex, srcOffset))</div><div class="line"><a name="l07213"></a><span class="lineno"> 7213</span>&#160;            {</div><div class="line"><a name="l07214"></a><span class="lineno"> 7214</span>&#160;                VMA_ASSERT(dstAllocRequest.itemsToMakeLostCount == 0);</div><div class="line"><a name="l07215"></a><span class="lineno"> 7215</span>&#160;</div><div class="line"><a name="l07216"></a><span class="lineno"> 7216</span>&#160;                <span class="comment">// Reached limit on number of allocations or bytes to move.</span></div><div class="line"><a name="l07217"></a><span class="lineno"> 7217</span>&#160;                <span class="keywordflow">if</span>((m_AllocationsMoved + 1 &gt; maxAllocationsToMove) ||</div><div class="line"><a name="l07218"></a><span class="lineno"> 7218</span>&#160;                    (m_BytesMoved + size &gt; maxBytesToMove))</div><div class="line"><a name="l07219"></a><span class="lineno"> 7219</span>&#160;                {</div><div class="line"><a name="l07220"></a><span class="lineno"> 7220</span>&#160;                    <span class="keywordflow">return</span> VK_INCOMPLETE;</div><div class="line"><a name="l07221"></a><span class="lineno"> 7221</span>&#160;                }</div><div class="line"><a name="l07222"></a><span class="lineno"> 7222</span>&#160;</div><div class="line"><a name="l07223"></a><span class="lineno"> 7223</span>&#160;                <span class="keywordtype">void</span>* pDstMappedData = VMA_NULL;</div><div class="line"><a name="l07224"></a><span class="lineno"> 7224</span>&#160;                VkResult res = pDstBlockInfo-&gt;EnsureMapping(m_hAllocator, &amp;pDstMappedData);</div><div class="line"><a name="l07225"></a><span class="lineno"> 7225</span>&#160;                <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l07226"></a><span class="lineno"> 7226</span>&#160;                {</div><div class="line"><a name="l07227"></a><span class="lineno"> 7227</span>&#160;                    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07228"></a><span class="lineno"> 7228</span>&#160;                }</div><div class="line"><a name="l07229"></a><span class="lineno"> 7229</span>&#160;</div><div class="line"><a name="l07230"></a><span class="lineno"> 7230</span>&#160;                <span class="keywordtype">void</span>* pSrcMappedData = VMA_NULL;</div><div class="line"><a name="l07231"></a><span class="lineno"> 7231</span>&#160;                res = pSrcBlockInfo-&gt;EnsureMapping(m_hAllocator, &amp;pSrcMappedData);</div><div class="line"><a name="l07232"></a><span class="lineno"> 7232</span>&#160;                <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l07233"></a><span class="lineno"> 7233</span>&#160;                {</div><div class="line"><a name="l07234"></a><span class="lineno"> 7234</span>&#160;                    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07235"></a><span class="lineno"> 7235</span>&#160;                }</div><div class="line"><a name="l07236"></a><span class="lineno"> 7236</span>&#160;                </div><div class="line"><a name="l07237"></a><span class="lineno"> 7237</span>&#160;                <span class="comment">// THE PLACE WHERE ACTUAL DATA COPY HAPPENS.</span></div><div class="line"><a name="l07238"></a><span class="lineno"> 7238</span>&#160;                memcpy(</div><div class="line"><a name="l07239"></a><span class="lineno"> 7239</span>&#160;                    reinterpret_cast&lt;char*&gt;(pDstMappedData) + dstAllocRequest.offset,</div><div class="line"><a name="l07240"></a><span class="lineno"> 7240</span>&#160;                    reinterpret_cast&lt;char*&gt;(pSrcMappedData) + srcOffset,</div><div class="line"><a name="l07241"></a><span class="lineno"> 7241</span>&#160;                    static_cast&lt;size_t&gt;(size));</div><div class="line"><a name="l07242"></a><span class="lineno"> 7242</span>&#160;                </div><div class="line"><a name="l07243"></a><span class="lineno"> 7243</span>&#160;                pDstBlockInfo-&gt;m_pBlock-&gt;m_Metadata.Alloc(dstAllocRequest, suballocType, size, allocInfo.m_hAllocation);</div><div class="line"><a name="l07244"></a><span class="lineno"> 7244</span>&#160;                pSrcBlockInfo-&gt;m_pBlock-&gt;m_Metadata.FreeAtOffset(srcOffset);</div><div class="line"><a name="l07245"></a><span class="lineno"> 7245</span>&#160;                </div><div class="line"><a name="l07246"></a><span class="lineno"> 7246</span>&#160;                allocInfo.m_hAllocation-&gt;ChangeBlockAllocation(m_hAllocator, pDstBlockInfo-&gt;m_pBlock, dstAllocRequest.offset);</div><div class="line"><a name="l07247"></a><span class="lineno"> 7247</span>&#160;</div><div class="line"><a name="l07248"></a><span class="lineno"> 7248</span>&#160;                <span class="keywordflow">if</span>(allocInfo.m_pChanged != VMA_NULL)</div><div class="line"><a name="l07249"></a><span class="lineno"> 7249</span>&#160;                {</div><div class="line"><a name="l07250"></a><span class="lineno"> 7250</span>&#160;                    *allocInfo.m_pChanged = VK_TRUE;</div><div class="line"><a name="l07251"></a><span class="lineno"> 7251</span>&#160;                }</div><div class="line"><a name="l07252"></a><span class="lineno"> 7252</span>&#160;</div><div class="line"><a name="l07253"></a><span class="lineno"> 7253</span>&#160;                ++m_AllocationsMoved;</div><div class="line"><a name="l07254"></a><span class="lineno"> 7254</span>&#160;                m_BytesMoved += size;</div><div class="line"><a name="l07255"></a><span class="lineno"> 7255</span>&#160;</div><div class="line"><a name="l07256"></a><span class="lineno"> 7256</span>&#160;                VmaVectorRemove(pSrcBlockInfo-&gt;m_Allocations, srcAllocIndex);</div><div class="line"><a name="l07257"></a><span class="lineno"> 7257</span>&#160;</div><div class="line"><a name="l07258"></a><span class="lineno"> 7258</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l07259"></a><span class="lineno"> 7259</span>&#160;            }</div><div class="line"><a name="l07260"></a><span class="lineno"> 7260</span>&#160;        }</div><div class="line"><a name="l07261"></a><span class="lineno"> 7261</span>&#160;</div><div class="line"><a name="l07262"></a><span class="lineno"> 7262</span>&#160;        <span class="comment">// If not processed, this allocInfo remains in pBlockInfo-&gt;m_Allocations for next round.</span></div><div class="line"><a name="l07263"></a><span class="lineno"> 7263</span>&#160;</div><div class="line"><a name="l07264"></a><span class="lineno"> 7264</span>&#160;        <span class="keywordflow">if</span>(srcAllocIndex &gt; 0)</div><div class="line"><a name="l07265"></a><span class="lineno"> 7265</span>&#160;        {</div><div class="line"><a name="l07266"></a><span class="lineno"> 7266</span>&#160;            --srcAllocIndex;</div><div class="line"><a name="l07267"></a><span class="lineno"> 7267</span>&#160;        }</div><div class="line"><a name="l07268"></a><span class="lineno"> 7268</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07269"></a><span class="lineno"> 7269</span>&#160;        {</div><div class="line"><a name="l07270"></a><span class="lineno"> 7270</span>&#160;            <span class="keywordflow">if</span>(srcBlockIndex &gt; 0)</div><div class="line"><a name="l07271"></a><span class="lineno"> 7271</span>&#160;            {</div><div class="line"><a name="l07272"></a><span class="lineno"> 7272</span>&#160;                --srcBlockIndex;</div><div class="line"><a name="l07273"></a><span class="lineno"> 7273</span>&#160;                srcAllocIndex = SIZE_MAX;</div><div class="line"><a name="l07274"></a><span class="lineno"> 7274</span>&#160;            }</div><div class="line"><a name="l07275"></a><span class="lineno"> 7275</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07276"></a><span class="lineno"> 7276</span>&#160;            {</div><div class="line"><a name="l07277"></a><span class="lineno"> 7277</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07278"></a><span class="lineno"> 7278</span>&#160;            }</div><div class="line"><a name="l07279"></a><span class="lineno"> 7279</span>&#160;        }</div><div class="line"><a name="l07280"></a><span class="lineno"> 7280</span>&#160;    }</div><div class="line"><a name="l07281"></a><span class="lineno"> 7281</span>&#160;}</div><div class="line"><a name="l07282"></a><span class="lineno"> 7282</span>&#160;</div><div class="line"><a name="l07283"></a><span class="lineno"> 7283</span>&#160;VkResult VmaDefragmentator::Defragment(</div><div class="line"><a name="l07284"></a><span class="lineno"> 7284</span>&#160;    VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l07285"></a><span class="lineno"> 7285</span>&#160;    uint32_t maxAllocationsToMove)</div><div class="line"><a name="l07286"></a><span class="lineno"> 7286</span>&#160;{</div><div class="line"><a name="l07287"></a><span class="lineno"> 7287</span>&#160;    <span class="keywordflow">if</span>(m_Allocations.empty())</div><div class="line"><a name="l07288"></a><span class="lineno"> 7288</span>&#160;    {</div><div class="line"><a name="l07289"></a><span class="lineno"> 7289</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07290"></a><span class="lineno"> 7290</span>&#160;    }</div><div class="line"><a name="l07291"></a><span class="lineno"> 7291</span>&#160;</div><div class="line"><a name="l07292"></a><span class="lineno"> 7292</span>&#160;    <span class="comment">// Create block info for each block.</span></div><div class="line"><a name="l07293"></a><span class="lineno"> 7293</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> blockCount = m_pBlockVector-&gt;m_Blocks.size();</div><div class="line"><a name="l07294"></a><span class="lineno"> 7294</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; blockCount; ++blockIndex)</div><div class="line"><a name="l07295"></a><span class="lineno"> 7295</span>&#160;    {</div><div class="line"><a name="l07296"></a><span class="lineno"> 7296</span>&#160;        BlockInfo* pBlockInfo = vma_new(m_hAllocator, BlockInfo)(m_hAllocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l07297"></a><span class="lineno"> 7297</span>&#160;        pBlockInfo-&gt;m_pBlock = m_pBlockVector-&gt;m_Blocks[blockIndex];</div><div class="line"><a name="l07298"></a><span class="lineno"> 7298</span>&#160;        m_Blocks.push_back(pBlockInfo);</div><div class="line"><a name="l07299"></a><span class="lineno"> 7299</span>&#160;    }</div><div class="line"><a name="l07300"></a><span class="lineno"> 7300</span>&#160;</div><div class="line"><a name="l07301"></a><span class="lineno"> 7301</span>&#160;    <span class="comment">// Sort them by m_pBlock pointer value.</span></div><div class="line"><a name="l07302"></a><span class="lineno"> 7302</span>&#160;    VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockPointerLess());</div><div class="line"><a name="l07303"></a><span class="lineno"> 7303</span>&#160;</div><div class="line"><a name="l07304"></a><span class="lineno"> 7304</span>&#160;    <span class="comment">// Move allocation infos from m_Allocations to appropriate m_Blocks[memTypeIndex].m_Allocations.</span></div><div class="line"><a name="l07305"></a><span class="lineno"> 7305</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0, allocCount = m_Allocations.size(); blockIndex &lt; allocCount; ++blockIndex)</div><div class="line"><a name="l07306"></a><span class="lineno"> 7306</span>&#160;    {</div><div class="line"><a name="l07307"></a><span class="lineno"> 7307</span>&#160;        AllocationInfo&amp; allocInfo = m_Allocations[blockIndex];</div><div class="line"><a name="l07308"></a><span class="lineno"> 7308</span>&#160;        <span class="comment">// Now as we are inside VmaBlockVector::m_Mutex, we can make final check if this allocation was not lost.</span></div><div class="line"><a name="l07309"></a><span class="lineno"> 7309</span>&#160;        <span class="keywordflow">if</span>(allocInfo.m_hAllocation-&gt;GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l07310"></a><span class="lineno"> 7310</span>&#160;        {</div><div class="line"><a name="l07311"></a><span class="lineno"> 7311</span>&#160;            VmaDeviceMemoryBlock* pBlock = allocInfo.m_hAllocation-&gt;GetBlock();</div><div class="line"><a name="l07312"></a><span class="lineno"> 7312</span>&#160;            BlockInfoVector::iterator it = VmaBinaryFindFirstNotLess(m_Blocks.begin(), m_Blocks.end(), pBlock, BlockPointerLess());</div><div class="line"><a name="l07313"></a><span class="lineno"> 7313</span>&#160;            <span class="keywordflow">if</span>(it != m_Blocks.end() &amp;&amp; (*it)-&gt;m_pBlock == pBlock)</div><div class="line"><a name="l07314"></a><span class="lineno"> 7314</span>&#160;            {</div><div class="line"><a name="l07315"></a><span class="lineno"> 7315</span>&#160;                (*it)-&gt;m_Allocations.push_back(allocInfo);</div><div class="line"><a name="l07316"></a><span class="lineno"> 7316</span>&#160;            }</div><div class="line"><a name="l07317"></a><span class="lineno"> 7317</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07318"></a><span class="lineno"> 7318</span>&#160;            {</div><div class="line"><a name="l07319"></a><span class="lineno"> 7319</span>&#160;                VMA_ASSERT(0);</div><div class="line"><a name="l07320"></a><span class="lineno"> 7320</span>&#160;            }</div><div class="line"><a name="l07321"></a><span class="lineno"> 7321</span>&#160;        }</div><div class="line"><a name="l07322"></a><span class="lineno"> 7322</span>&#160;    }</div><div class="line"><a name="l07323"></a><span class="lineno"> 7323</span>&#160;    m_Allocations.clear();</div><div class="line"><a name="l07324"></a><span class="lineno"> 7324</span>&#160;</div><div class="line"><a name="l07325"></a><span class="lineno"> 7325</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; blockCount; ++blockIndex)</div><div class="line"><a name="l07326"></a><span class="lineno"> 7326</span>&#160;    {</div><div class="line"><a name="l07327"></a><span class="lineno"> 7327</span>&#160;        BlockInfo* pBlockInfo = m_Blocks[blockIndex];</div><div class="line"><a name="l07328"></a><span class="lineno"> 7328</span>&#160;        pBlockInfo-&gt;CalcHasNonMovableAllocations();</div><div class="line"><a name="l07329"></a><span class="lineno"> 7329</span>&#160;        pBlockInfo-&gt;SortAllocationsBySizeDescecnding();</div><div class="line"><a name="l07330"></a><span class="lineno"> 7330</span>&#160;    }</div><div class="line"><a name="l07331"></a><span class="lineno"> 7331</span>&#160;</div><div class="line"><a name="l07332"></a><span class="lineno"> 7332</span>&#160;    <span class="comment">// Sort m_Blocks this time by the main criterium, from most &quot;destination&quot; to most &quot;source&quot; blocks.</span></div><div class="line"><a name="l07333"></a><span class="lineno"> 7333</span>&#160;    VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockInfoCompareMoveDestination());</div><div class="line"><a name="l07334"></a><span class="lineno"> 7334</span>&#160;</div><div class="line"><a name="l07335"></a><span class="lineno"> 7335</span>&#160;    <span class="comment">// Execute defragmentation rounds (the main part).</span></div><div class="line"><a name="l07336"></a><span class="lineno"> 7336</span>&#160;    VkResult result = VK_SUCCESS;</div><div class="line"><a name="l07337"></a><span class="lineno"> 7337</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> round = 0; (round &lt; 2) &amp;&amp; (result == VK_SUCCESS); ++round)</div><div class="line"><a name="l07338"></a><span class="lineno"> 7338</span>&#160;    {</div><div class="line"><a name="l07339"></a><span class="lineno"> 7339</span>&#160;        result = DefragmentRound(maxBytesToMove, maxAllocationsToMove);</div><div class="line"><a name="l07340"></a><span class="lineno"> 7340</span>&#160;    }</div><div class="line"><a name="l07341"></a><span class="lineno"> 7341</span>&#160;</div><div class="line"><a name="l07342"></a><span class="lineno"> 7342</span>&#160;    <span class="comment">// Unmap blocks that were mapped for defragmentation.</span></div><div class="line"><a name="l07343"></a><span class="lineno"> 7343</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; blockCount; ++blockIndex)</div><div class="line"><a name="l07344"></a><span class="lineno"> 7344</span>&#160;    {</div><div class="line"><a name="l07345"></a><span class="lineno"> 7345</span>&#160;        m_Blocks[blockIndex]-&gt;Unmap(m_hAllocator);</div><div class="line"><a name="l07346"></a><span class="lineno"> 7346</span>&#160;    }</div><div class="line"><a name="l07347"></a><span class="lineno"> 7347</span>&#160;</div><div class="line"><a name="l07348"></a><span class="lineno"> 7348</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l07349"></a><span class="lineno"> 7349</span>&#160;}</div><div class="line"><a name="l07350"></a><span class="lineno"> 7350</span>&#160;</div><div class="line"><a name="l07351"></a><span class="lineno"> 7351</span>&#160;<span class="keywordtype">bool</span> VmaDefragmentator::MoveMakesSense(</div><div class="line"><a name="l07352"></a><span class="lineno"> 7352</span>&#160;        <span class="keywordtype">size_t</span> dstBlockIndex, VkDeviceSize dstOffset,</div><div class="line"><a name="l07353"></a><span class="lineno"> 7353</span>&#160;        <span class="keywordtype">size_t</span> srcBlockIndex, VkDeviceSize srcOffset)</div><div class="line"><a name="l07354"></a><span class="lineno"> 7354</span>&#160;{</div><div class="line"><a name="l07355"></a><span class="lineno"> 7355</span>&#160;    <span class="keywordflow">if</span>(dstBlockIndex &lt; srcBlockIndex)</div><div class="line"><a name="l07356"></a><span class="lineno"> 7356</span>&#160;    {</div><div class="line"><a name="l07357"></a><span class="lineno"> 7357</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l07358"></a><span class="lineno"> 7358</span>&#160;    }</div><div class="line"><a name="l07359"></a><span class="lineno"> 7359</span>&#160;    <span class="keywordflow">if</span>(dstBlockIndex &gt; srcBlockIndex)</div><div class="line"><a name="l07360"></a><span class="lineno"> 7360</span>&#160;    {</div><div class="line"><a name="l07361"></a><span class="lineno"> 7361</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07362"></a><span class="lineno"> 7362</span>&#160;    }</div><div class="line"><a name="l07363"></a><span class="lineno"> 7363</span>&#160;    <span class="keywordflow">if</span>(dstOffset &lt; srcOffset)</div><div class="line"><a name="l07364"></a><span class="lineno"> 7364</span>&#160;    {</div><div class="line"><a name="l07365"></a><span class="lineno"> 7365</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l07366"></a><span class="lineno"> 7366</span>&#160;    }</div><div class="line"><a name="l07367"></a><span class="lineno"> 7367</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07368"></a><span class="lineno"> 7368</span>&#160;}</div><div class="line"><a name="l07369"></a><span class="lineno"> 7369</span>&#160;</div><div class="line"><a name="l07371"></a><span class="lineno"> 7371</span>&#160;<span class="comment">// VmaAllocator_T</span></div><div class="line"><a name="l07372"></a><span class="lineno"> 7372</span>&#160;</div><div class="line"><a name="l07373"></a><span class="lineno"> 7373</span>&#160;VmaAllocator_T::VmaAllocator_T(<span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo) :</div><div class="line"><a name="l07374"></a><span class="lineno"> 7374</span>&#160;    m_UseMutex((pCreateInfo-&gt;flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a>) == 0),</div><div class="line"><a name="l07375"></a><span class="lineno"> 7375</span>&#160;    m_UseKhrDedicatedAllocation((pCreateInfo-&gt;flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a>) != 0),</div><div class="line"><a name="l07376"></a><span class="lineno"> 7376</span>&#160;    m_hDevice(pCreateInfo-&gt;device),</div><div class="line"><a name="l07377"></a><span class="lineno"> 7377</span>&#160;    m_AllocationCallbacksSpecified(pCreateInfo-&gt;pAllocationCallbacks != VMA_NULL),</div><div class="line"><a name="l07378"></a><span class="lineno"> 7378</span>&#160;    m_AllocationCallbacks(pCreateInfo-&gt;pAllocationCallbacks ?</div><div class="line"><a name="l07379"></a><span class="lineno"> 7379</span>&#160;        *pCreateInfo-&gt;pAllocationCallbacks : VmaEmptyAllocationCallbacks),</div><div class="line"><a name="l07380"></a><span class="lineno"> 7380</span>&#160;    m_PreferredLargeHeapBlockSize(0),</div><div class="line"><a name="l07381"></a><span class="lineno"> 7381</span>&#160;    m_PhysicalDevice(pCreateInfo-&gt;physicalDevice),</div><div class="line"><a name="l07382"></a><span class="lineno"> 7382</span>&#160;    m_CurrentFrameIndex(0),</div><div class="line"><a name="l07383"></a><span class="lineno"> 7383</span>&#160;    m_Pools(VmaStlAllocator&lt;<a class="code" href="struct_vma_pool.html">VmaPool</a>&gt;(GetAllocationCallbacks()))</div><div class="line"><a name="l07384"></a><span class="lineno"> 7384</span>&#160;{</div><div class="line"><a name="l07385"></a><span class="lineno"> 7385</span>&#160;    VMA_ASSERT(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a> &amp;&amp; pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500">device</a>);    </div><div class="line"><a name="l07386"></a><span class="lineno"> 7386</span>&#160;</div><div class="line"><a name="l07387"></a><span class="lineno"> 7387</span>&#160;    memset(&amp;m_DeviceMemoryCallbacks, 0 ,<span class="keyword">sizeof</span>(m_DeviceMemoryCallbacks));</div><div class="line"><a name="l07388"></a><span class="lineno"> 7388</span>&#160;    memset(&amp;m_MemProps, 0, <span class="keyword">sizeof</span>(m_MemProps));</div><div class="line"><a name="l07389"></a><span class="lineno"> 7389</span>&#160;    memset(&amp;m_PhysicalDeviceProperties, 0, <span class="keyword">sizeof</span>(m_PhysicalDeviceProperties));</div><div class="line"><a name="l07390"></a><span class="lineno"> 7390</span>&#160;        </div><div class="line"><a name="l07391"></a><span class="lineno"> 7391</span>&#160;    memset(&amp;m_pBlockVectors, 0, <span class="keyword">sizeof</span>(m_pBlockVectors));</div><div class="line"><a name="l07392"></a><span class="lineno"> 7392</span>&#160;    memset(&amp;m_pDedicatedAllocations, 0, <span class="keyword">sizeof</span>(m_pDedicatedAllocations));</div><div class="line"><a name="l07393"></a><span class="lineno"> 7393</span>&#160;</div><div class="line"><a name="l07394"></a><span class="lineno"> 7394</span>&#160;    <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; VK_MAX_MEMORY_HEAPS; ++i)</div><div class="line"><a name="l07395"></a><span class="lineno"> 7395</span>&#160;    {</div><div class="line"><a name="l07396"></a><span class="lineno"> 7396</span>&#160;        m_HeapSizeLimit[i] = VK_WHOLE_SIZE;</div><div class="line"><a name="l07397"></a><span class="lineno"> 7397</span>&#160;    }</div><div class="line"><a name="l07398"></a><span class="lineno"> 7398</span>&#160;</div><div class="line"><a name="l07399"></a><span class="lineno"> 7399</span>&#160;    <span class="keywordflow">if</span>(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a> != VMA_NULL)</div><div class="line"><a name="l07400"></a><span class="lineno"> 7400</span>&#160;    {</div><div class="line"><a name="l07401"></a><span class="lineno"> 7401</span>&#160;        m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a> = pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a>-&gt;<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a>;</div><div class="line"><a name="l07402"></a><span class="lineno"> 7402</span>&#160;        m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a> = pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a>-&gt;<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a>;</div><div class="line"><a name="l07403"></a><span class="lineno"> 7403</span>&#160;    }</div><div class="line"><a name="l07404"></a><span class="lineno"> 7404</span>&#160;</div><div class="line"><a name="l07405"></a><span class="lineno"> 7405</span>&#160;    ImportVulkanFunctions(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a>);</div><div class="line"><a name="l07406"></a><span class="lineno"> 7406</span>&#160;</div><div class="line"><a name="l07407"></a><span class="lineno"> 7407</span>&#160;    (*m_VulkanFunctions.vkGetPhysicalDeviceProperties)(m_PhysicalDevice, &amp;m_PhysicalDeviceProperties);</div><div class="line"><a name="l07408"></a><span class="lineno"> 7408</span>&#160;    (*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &amp;m_MemProps);</div><div class="line"><a name="l07409"></a><span class="lineno"> 7409</span>&#160;</div><div class="line"><a name="l07410"></a><span class="lineno"> 7410</span>&#160;    m_PreferredLargeHeapBlockSize = (pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a> != 0) ?</div><div class="line"><a name="l07411"></a><span class="lineno"> 7411</span>&#160;        pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a> : static_cast&lt;VkDeviceSize&gt;(VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE);</div><div class="line"><a name="l07412"></a><span class="lineno"> 7412</span>&#160;</div><div class="line"><a name="l07413"></a><span class="lineno"> 7413</span>&#160;    <span class="keywordflow">if</span>(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a> != VMA_NULL)</div><div class="line"><a name="l07414"></a><span class="lineno"> 7414</span>&#160;    {</div><div class="line"><a name="l07415"></a><span class="lineno"> 7415</span>&#160;        <span class="keywordflow">for</span>(uint32_t heapIndex = 0; heapIndex &lt; GetMemoryHeapCount(); ++heapIndex)</div><div class="line"><a name="l07416"></a><span class="lineno"> 7416</span>&#160;        {</div><div class="line"><a name="l07417"></a><span class="lineno"> 7417</span>&#160;            <span class="keyword">const</span> VkDeviceSize limit = pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a>[heapIndex];</div><div class="line"><a name="l07418"></a><span class="lineno"> 7418</span>&#160;            <span class="keywordflow">if</span>(limit != VK_WHOLE_SIZE)</div><div class="line"><a name="l07419"></a><span class="lineno"> 7419</span>&#160;            {</div><div class="line"><a name="l07420"></a><span class="lineno"> 7420</span>&#160;                m_HeapSizeLimit[heapIndex] = limit;</div><div class="line"><a name="l07421"></a><span class="lineno"> 7421</span>&#160;                <span class="keywordflow">if</span>(limit &lt; m_MemProps.memoryHeaps[heapIndex].size)</div><div class="line"><a name="l07422"></a><span class="lineno"> 7422</span>&#160;                {</div><div class="line"><a name="l07423"></a><span class="lineno"> 7423</span>&#160;                    m_MemProps.memoryHeaps[heapIndex].size = limit;</div><div class="line"><a name="l07424"></a><span class="lineno"> 7424</span>&#160;                }</div><div class="line"><a name="l07425"></a><span class="lineno"> 7425</span>&#160;            }</div><div class="line"><a name="l07426"></a><span class="lineno"> 7426</span>&#160;        }</div><div class="line"><a name="l07427"></a><span class="lineno"> 7427</span>&#160;    }</div><div class="line"><a name="l07428"></a><span class="lineno"> 7428</span>&#160;</div><div class="line"><a name="l07429"></a><span class="lineno"> 7429</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l07430"></a><span class="lineno"> 7430</span>&#160;    {</div><div class="line"><a name="l07431"></a><span class="lineno"> 7431</span>&#160;        <span class="keyword">const</span> VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(memTypeIndex);</div><div class="line"><a name="l07432"></a><span class="lineno"> 7432</span>&#160;</div><div class="line"><a name="l07433"></a><span class="lineno"> 7433</span>&#160;        m_pBlockVectors[memTypeIndex] = vma_new(<span class="keyword">this</span>, VmaBlockVector)(</div><div class="line"><a name="l07434"></a><span class="lineno"> 7434</span>&#160;            <span class="keyword">this</span>,</div><div class="line"><a name="l07435"></a><span class="lineno"> 7435</span>&#160;            memTypeIndex,</div><div class="line"><a name="l07436"></a><span class="lineno"> 7436</span>&#160;            preferredBlockSize,</div><div class="line"><a name="l07437"></a><span class="lineno"> 7437</span>&#160;            0,</div><div class="line"><a name="l07438"></a><span class="lineno"> 7438</span>&#160;            SIZE_MAX,</div><div class="line"><a name="l07439"></a><span class="lineno"> 7439</span>&#160;            GetBufferImageGranularity(),</div><div class="line"><a name="l07440"></a><span class="lineno"> 7440</span>&#160;            pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">frameInUseCount</a>,</div><div class="line"><a name="l07441"></a><span class="lineno"> 7441</span>&#160;            <span class="keyword">false</span>); <span class="comment">// isCustomPool</span></div><div class="line"><a name="l07442"></a><span class="lineno"> 7442</span>&#160;        <span class="comment">// No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]-&gt;CreateMinBlocks here,</span></div><div class="line"><a name="l07443"></a><span class="lineno"> 7443</span>&#160;        <span class="comment">// becase minBlockCount is 0.</span></div><div class="line"><a name="l07444"></a><span class="lineno"> 7444</span>&#160;        m_pDedicatedAllocations[memTypeIndex] = vma_new(<span class="keyword">this</span>, AllocationVectorType)(VmaStlAllocator&lt;VmaAllocation&gt;(GetAllocationCallbacks()));</div><div class="line"><a name="l07445"></a><span class="lineno"> 7445</span>&#160;    }</div><div class="line"><a name="l07446"></a><span class="lineno"> 7446</span>&#160;}</div><div class="line"><a name="l07447"></a><span class="lineno"> 7447</span>&#160;</div><div class="line"><a name="l07448"></a><span class="lineno"> 7448</span>&#160;VmaAllocator_T::~VmaAllocator_T()</div><div class="line"><a name="l07449"></a><span class="lineno"> 7449</span>&#160;{</div><div class="line"><a name="l07450"></a><span class="lineno"> 7450</span>&#160;    VMA_ASSERT(m_Pools.empty());</div><div class="line"><a name="l07451"></a><span class="lineno"> 7451</span>&#160;</div><div class="line"><a name="l07452"></a><span class="lineno"> 7452</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = GetMemoryTypeCount(); i--; )</div><div class="line"><a name="l07453"></a><span class="lineno"> 7453</span>&#160;    {</div><div class="line"><a name="l07454"></a><span class="lineno"> 7454</span>&#160;        vma_delete(<span class="keyword">this</span>, m_pDedicatedAllocations[i]);</div><div class="line"><a name="l07455"></a><span class="lineno"> 7455</span>&#160;        vma_delete(<span class="keyword">this</span>, m_pBlockVectors[i]);</div><div class="line"><a name="l07456"></a><span class="lineno"> 7456</span>&#160;    }</div><div class="line"><a name="l07457"></a><span class="lineno"> 7457</span>&#160;}</div><div class="line"><a name="l07458"></a><span class="lineno"> 7458</span>&#160;</div><div class="line"><a name="l07459"></a><span class="lineno"> 7459</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::ImportVulkanFunctions(<span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>* pVulkanFunctions)</div><div class="line"><a name="l07460"></a><span class="lineno"> 7460</span>&#160;{</div><div class="line"><a name="l07461"></a><span class="lineno"> 7461</span>&#160;<span class="preprocessor">#if VMA_STATIC_VULKAN_FUNCTIONS == 1</span></div><div class="line"><a name="l07462"></a><span class="lineno"> 7462</span>&#160;    m_VulkanFunctions.vkGetPhysicalDeviceProperties = &amp;vkGetPhysicalDeviceProperties;</div><div class="line"><a name="l07463"></a><span class="lineno"> 7463</span>&#160;    m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties = &amp;vkGetPhysicalDeviceMemoryProperties;</div><div class="line"><a name="l07464"></a><span class="lineno"> 7464</span>&#160;    m_VulkanFunctions.vkAllocateMemory = &amp;vkAllocateMemory;</div><div class="line"><a name="l07465"></a><span class="lineno"> 7465</span>&#160;    m_VulkanFunctions.vkFreeMemory = &amp;vkFreeMemory;</div><div class="line"><a name="l07466"></a><span class="lineno"> 7466</span>&#160;    m_VulkanFunctions.vkMapMemory = &amp;vkMapMemory;</div><div class="line"><a name="l07467"></a><span class="lineno"> 7467</span>&#160;    m_VulkanFunctions.vkUnmapMemory = &amp;vkUnmapMemory;</div><div class="line"><a name="l07468"></a><span class="lineno"> 7468</span>&#160;    m_VulkanFunctions.vkBindBufferMemory = &amp;vkBindBufferMemory;</div><div class="line"><a name="l07469"></a><span class="lineno"> 7469</span>&#160;    m_VulkanFunctions.vkBindImageMemory = &amp;vkBindImageMemory;</div><div class="line"><a name="l07470"></a><span class="lineno"> 7470</span>&#160;    m_VulkanFunctions.vkGetBufferMemoryRequirements = &amp;vkGetBufferMemoryRequirements;</div><div class="line"><a name="l07471"></a><span class="lineno"> 7471</span>&#160;    m_VulkanFunctions.vkGetImageMemoryRequirements = &amp;vkGetImageMemoryRequirements;</div><div class="line"><a name="l07472"></a><span class="lineno"> 7472</span>&#160;    m_VulkanFunctions.vkCreateBuffer = &amp;vkCreateBuffer;</div><div class="line"><a name="l07473"></a><span class="lineno"> 7473</span>&#160;    m_VulkanFunctions.vkDestroyBuffer = &amp;vkDestroyBuffer;</div><div class="line"><a name="l07474"></a><span class="lineno"> 7474</span>&#160;    m_VulkanFunctions.vkCreateImage = &amp;vkCreateImage;</div><div class="line"><a name="l07475"></a><span class="lineno"> 7475</span>&#160;    m_VulkanFunctions.vkDestroyImage = &amp;vkDestroyImage;</div><div class="line"><a name="l07476"></a><span class="lineno"> 7476</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l07477"></a><span class="lineno"> 7477</span>&#160;    {</div><div class="line"><a name="l07478"></a><span class="lineno"> 7478</span>&#160;        m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR =</div><div class="line"><a name="l07479"></a><span class="lineno"> 7479</span>&#160;            (PFN_vkGetBufferMemoryRequirements2KHR)vkGetDeviceProcAddr(m_hDevice, <span class="stringliteral">&quot;vkGetBufferMemoryRequirements2KHR&quot;</span>);</div><div class="line"><a name="l07480"></a><span class="lineno"> 7480</span>&#160;        m_VulkanFunctions.vkGetImageMemoryRequirements2KHR =</div><div class="line"><a name="l07481"></a><span class="lineno"> 7481</span>&#160;            (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(m_hDevice, <span class="stringliteral">&quot;vkGetImageMemoryRequirements2KHR&quot;</span>);</div><div class="line"><a name="l07482"></a><span class="lineno"> 7482</span>&#160;    }</div><div class="line"><a name="l07483"></a><span class="lineno"> 7483</span>&#160;<span class="preprocessor">#endif // #if VMA_STATIC_VULKAN_FUNCTIONS == 1</span></div><div class="line"><a name="l07484"></a><span class="lineno"> 7484</span>&#160;</div><div class="line"><a name="l07485"></a><span class="lineno"> 7485</span>&#160;<span class="preprocessor">#define VMA_COPY_IF_NOT_NULL(funcName) \</span></div><div class="line"><a name="l07486"></a><span class="lineno"> 7486</span>&#160;<span class="preprocessor">    if(pVulkanFunctions-&gt;funcName != VMA_NULL) m_VulkanFunctions.funcName = pVulkanFunctions-&gt;funcName;</span></div><div class="line"><a name="l07487"></a><span class="lineno"> 7487</span>&#160;</div><div class="line"><a name="l07488"></a><span class="lineno"> 7488</span>&#160;    <span class="keywordflow">if</span>(pVulkanFunctions != VMA_NULL)</div><div class="line"><a name="l07489"></a><span class="lineno"> 7489</span>&#160;    {</div><div class="line"><a name="l07490"></a><span class="lineno"> 7490</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties);</div><div class="line"><a name="l07491"></a><span class="lineno"> 7491</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties);</div><div class="line"><a name="l07492"></a><span class="lineno"> 7492</span>&#160;        VMA_COPY_IF_NOT_NULL(vkAllocateMemory);</div><div class="line"><a name="l07493"></a><span class="lineno"> 7493</span>&#160;        VMA_COPY_IF_NOT_NULL(vkFreeMemory);</div><div class="line"><a name="l07494"></a><span class="lineno"> 7494</span>&#160;        VMA_COPY_IF_NOT_NULL(vkMapMemory);</div><div class="line"><a name="l07495"></a><span class="lineno"> 7495</span>&#160;        VMA_COPY_IF_NOT_NULL(vkUnmapMemory);</div><div class="line"><a name="l07496"></a><span class="lineno"> 7496</span>&#160;        VMA_COPY_IF_NOT_NULL(vkBindBufferMemory);</div><div class="line"><a name="l07497"></a><span class="lineno"> 7497</span>&#160;        VMA_COPY_IF_NOT_NULL(vkBindImageMemory);</div><div class="line"><a name="l07498"></a><span class="lineno"> 7498</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements);</div><div class="line"><a name="l07499"></a><span class="lineno"> 7499</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements);</div><div class="line"><a name="l07500"></a><span class="lineno"> 7500</span>&#160;        VMA_COPY_IF_NOT_NULL(vkCreateBuffer);</div><div class="line"><a name="l07501"></a><span class="lineno"> 7501</span>&#160;        VMA_COPY_IF_NOT_NULL(vkDestroyBuffer);</div><div class="line"><a name="l07502"></a><span class="lineno"> 7502</span>&#160;        VMA_COPY_IF_NOT_NULL(vkCreateImage);</div><div class="line"><a name="l07503"></a><span class="lineno"> 7503</span>&#160;        VMA_COPY_IF_NOT_NULL(vkDestroyImage);</div><div class="line"><a name="l07504"></a><span class="lineno"> 7504</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements2KHR);</div><div class="line"><a name="l07505"></a><span class="lineno"> 7505</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements2KHR);</div><div class="line"><a name="l07506"></a><span class="lineno"> 7506</span>&#160;    }</div><div class="line"><a name="l07507"></a><span class="lineno"> 7507</span>&#160;</div><div class="line"><a name="l07508"></a><span class="lineno"> 7508</span>&#160;<span class="preprocessor">#undef VMA_COPY_IF_NOT_NULL</span></div><div class="line"><a name="l07509"></a><span class="lineno"> 7509</span>&#160;</div><div class="line"><a name="l07510"></a><span class="lineno"> 7510</span>&#160;    <span class="comment">// If these asserts are hit, you must either #define VMA_STATIC_VULKAN_FUNCTIONS 1</span></div><div class="line"><a name="l07511"></a><span class="lineno"> 7511</span>&#160;    <span class="comment">// or pass valid pointers as VmaAllocatorCreateInfo::pVulkanFunctions.</span></div><div class="line"><a name="l07512"></a><span class="lineno"> 7512</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceProperties != VMA_NULL);</div><div class="line"><a name="l07513"></a><span class="lineno"> 7513</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties != VMA_NULL);</div><div class="line"><a name="l07514"></a><span class="lineno"> 7514</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkAllocateMemory != VMA_NULL);</div><div class="line"><a name="l07515"></a><span class="lineno"> 7515</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkFreeMemory != VMA_NULL);</div><div class="line"><a name="l07516"></a><span class="lineno"> 7516</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkMapMemory != VMA_NULL);</div><div class="line"><a name="l07517"></a><span class="lineno"> 7517</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkUnmapMemory != VMA_NULL);</div><div class="line"><a name="l07518"></a><span class="lineno"> 7518</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkBindBufferMemory != VMA_NULL);</div><div class="line"><a name="l07519"></a><span class="lineno"> 7519</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkBindImageMemory != VMA_NULL);</div><div class="line"><a name="l07520"></a><span class="lineno"> 7520</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements != VMA_NULL);</div><div class="line"><a name="l07521"></a><span class="lineno"> 7521</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements != VMA_NULL);</div><div class="line"><a name="l07522"></a><span class="lineno"> 7522</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkCreateBuffer != VMA_NULL);</div><div class="line"><a name="l07523"></a><span class="lineno"> 7523</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkDestroyBuffer != VMA_NULL);</div><div class="line"><a name="l07524"></a><span class="lineno"> 7524</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkCreateImage != VMA_NULL);</div><div class="line"><a name="l07525"></a><span class="lineno"> 7525</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkDestroyImage != VMA_NULL);</div><div class="line"><a name="l07526"></a><span class="lineno"> 7526</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l07527"></a><span class="lineno"> 7527</span>&#160;    {</div><div class="line"><a name="l07528"></a><span class="lineno"> 7528</span>&#160;        VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR != VMA_NULL);</div><div class="line"><a name="l07529"></a><span class="lineno"> 7529</span>&#160;        VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements2KHR != VMA_NULL);</div><div class="line"><a name="l07530"></a><span class="lineno"> 7530</span>&#160;    }</div><div class="line"><a name="l07531"></a><span class="lineno"> 7531</span>&#160;}</div><div class="line"><a name="l07532"></a><span class="lineno"> 7532</span>&#160;</div><div class="line"><a name="l07533"></a><span class="lineno"> 7533</span>&#160;VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)</div><div class="line"><a name="l07534"></a><span class="lineno"> 7534</span>&#160;{</div><div class="line"><a name="l07535"></a><span class="lineno"> 7535</span>&#160;    <span class="keyword">const</span> uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);</div><div class="line"><a name="l07536"></a><span class="lineno"> 7536</span>&#160;    <span class="keyword">const</span> VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size;</div><div class="line"><a name="l07537"></a><span class="lineno"> 7537</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isSmallHeap = heapSize &lt;= VMA_SMALL_HEAP_MAX_SIZE;</div><div class="line"><a name="l07538"></a><span class="lineno"> 7538</span>&#160;    <span class="keywordflow">return</span> isSmallHeap ? (heapSize / 8) : m_PreferredLargeHeapBlockSize;</div><div class="line"><a name="l07539"></a><span class="lineno"> 7539</span>&#160;}</div><div class="line"><a name="l07540"></a><span class="lineno"> 7540</span>&#160;</div><div class="line"><a name="l07541"></a><span class="lineno"> 7541</span>&#160;VkResult VmaAllocator_T::AllocateMemoryOfType(</div><div class="line"><a name="l07542"></a><span class="lineno"> 7542</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l07543"></a><span class="lineno"> 7543</span>&#160;    <span class="keywordtype">bool</span> dedicatedAllocation,</div><div class="line"><a name="l07544"></a><span class="lineno"> 7544</span>&#160;    VkBuffer dedicatedBuffer,</div><div class="line"><a name="l07545"></a><span class="lineno"> 7545</span>&#160;    VkImage dedicatedImage,</div><div class="line"><a name="l07546"></a><span class="lineno"> 7546</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l07547"></a><span class="lineno"> 7547</span>&#160;    uint32_t memTypeIndex,</div><div class="line"><a name="l07548"></a><span class="lineno"> 7548</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l07549"></a><span class="lineno"> 7549</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l07550"></a><span class="lineno"> 7550</span>&#160;{</div><div class="line"><a name="l07551"></a><span class="lineno"> 7551</span>&#160;    VMA_ASSERT(pAllocation != VMA_NULL);</div><div class="line"><a name="l07552"></a><span class="lineno"> 7552</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;  AllocateMemory: MemoryTypeIndex=%u, Size=%llu&quot;</span>, memTypeIndex, vkMemReq.size);</div><div class="line"><a name="l07553"></a><span class="lineno"> 7553</span>&#160;</div><div class="line"><a name="l07554"></a><span class="lineno"> 7554</span>&#160;    <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> finalCreateInfo = createInfo;</div><div class="line"><a name="l07555"></a><span class="lineno"> 7555</span>&#160;</div><div class="line"><a name="l07556"></a><span class="lineno"> 7556</span>&#160;    <span class="comment">// If memory type is not HOST_VISIBLE, disable MAPPED.</span></div><div class="line"><a name="l07557"></a><span class="lineno"> 7557</span>&#160;    <span class="keywordflow">if</span>((finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0 &amp;&amp;</div><div class="line"><a name="l07558"></a><span class="lineno"> 7558</span>&#160;        (m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)</div><div class="line"><a name="l07559"></a><span class="lineno"> 7559</span>&#160;    {</div><div class="line"><a name="l07560"></a><span class="lineno"> 7560</span>&#160;        finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp;= ~<a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><div class="line"><a name="l07561"></a><span class="lineno"> 7561</span>&#160;    }</div><div class="line"><a name="l07562"></a><span class="lineno"> 7562</span>&#160;</div><div class="line"><a name="l07563"></a><span class="lineno"> 7563</span>&#160;    VmaBlockVector* <span class="keyword">const</span> blockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l07564"></a><span class="lineno"> 7564</span>&#160;    VMA_ASSERT(blockVector);</div><div class="line"><a name="l07565"></a><span class="lineno"> 7565</span>&#160;</div><div class="line"><a name="l07566"></a><span class="lineno"> 7566</span>&#160;    <span class="keyword">const</span> VkDeviceSize preferredBlockSize = blockVector-&gt;GetPreferredBlockSize();</div><div class="line"><a name="l07567"></a><span class="lineno"> 7567</span>&#160;    <span class="keywordtype">bool</span> preferDedicatedMemory =</div><div class="line"><a name="l07568"></a><span class="lineno"> 7568</span>&#160;        VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ||</div><div class="line"><a name="l07569"></a><span class="lineno"> 7569</span>&#160;        dedicatedAllocation ||</div><div class="line"><a name="l07570"></a><span class="lineno"> 7570</span>&#160;        <span class="comment">// Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size.</span></div><div class="line"><a name="l07571"></a><span class="lineno"> 7571</span>&#160;        vkMemReq.size &gt; preferredBlockSize / 2;</div><div class="line"><a name="l07572"></a><span class="lineno"> 7572</span>&#160;</div><div class="line"><a name="l07573"></a><span class="lineno"> 7573</span>&#160;    <span class="keywordflow">if</span>(preferDedicatedMemory &amp;&amp;</div><div class="line"><a name="l07574"></a><span class="lineno"> 7574</span>&#160;        (finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) == 0 &amp;&amp;</div><div class="line"><a name="l07575"></a><span class="lineno"> 7575</span>&#160;        finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> == VK_NULL_HANDLE)</div><div class="line"><a name="l07576"></a><span class="lineno"> 7576</span>&#160;    {</div><div class="line"><a name="l07577"></a><span class="lineno"> 7577</span>&#160;        finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> |= <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>;</div><div class="line"><a name="l07578"></a><span class="lineno"> 7578</span>&#160;    }</div><div class="line"><a name="l07579"></a><span class="lineno"> 7579</span>&#160;</div><div class="line"><a name="l07580"></a><span class="lineno"> 7580</span>&#160;    <span class="keywordflow">if</span>((finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>) != 0)</div><div class="line"><a name="l07581"></a><span class="lineno"> 7581</span>&#160;    {</div><div class="line"><a name="l07582"></a><span class="lineno"> 7582</span>&#160;        <span class="keywordflow">if</span>((finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l07583"></a><span class="lineno"> 7583</span>&#160;        {</div><div class="line"><a name="l07584"></a><span class="lineno"> 7584</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07585"></a><span class="lineno"> 7585</span>&#160;        }</div><div class="line"><a name="l07586"></a><span class="lineno"> 7586</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07587"></a><span class="lineno"> 7587</span>&#160;        {</div><div class="line"><a name="l07588"></a><span class="lineno"> 7588</span>&#160;            <span class="keywordflow">return</span> AllocateDedicatedMemory(</div><div class="line"><a name="l07589"></a><span class="lineno"> 7589</span>&#160;                vkMemReq.size,</div><div class="line"><a name="l07590"></a><span class="lineno"> 7590</span>&#160;                suballocType,</div><div class="line"><a name="l07591"></a><span class="lineno"> 7591</span>&#160;                memTypeIndex,</div><div class="line"><a name="l07592"></a><span class="lineno"> 7592</span>&#160;                (finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0,</div><div class="line"><a name="l07593"></a><span class="lineno"> 7593</span>&#160;                (finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0,</div><div class="line"><a name="l07594"></a><span class="lineno"> 7594</span>&#160;                finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>,</div><div class="line"><a name="l07595"></a><span class="lineno"> 7595</span>&#160;                dedicatedBuffer,</div><div class="line"><a name="l07596"></a><span class="lineno"> 7596</span>&#160;                dedicatedImage,</div><div class="line"><a name="l07597"></a><span class="lineno"> 7597</span>&#160;                pAllocation);</div><div class="line"><a name="l07598"></a><span class="lineno"> 7598</span>&#160;        }</div><div class="line"><a name="l07599"></a><span class="lineno"> 7599</span>&#160;    }</div><div class="line"><a name="l07600"></a><span class="lineno"> 7600</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l07601"></a><span class="lineno"> 7601</span>&#160;    {</div><div class="line"><a name="l07602"></a><span class="lineno"> 7602</span>&#160;        VkResult res = blockVector-&gt;Allocate(</div><div class="line"><a name="l07603"></a><span class="lineno"> 7603</span>&#160;            VK_NULL_HANDLE, <span class="comment">// hCurrentPool</span></div><div class="line"><a name="l07604"></a><span class="lineno"> 7604</span>&#160;            m_CurrentFrameIndex.load(),</div><div class="line"><a name="l07605"></a><span class="lineno"> 7605</span>&#160;            vkMemReq,</div><div class="line"><a name="l07606"></a><span class="lineno"> 7606</span>&#160;            finalCreateInfo,</div><div class="line"><a name="l07607"></a><span class="lineno"> 7607</span>&#160;            suballocType,</div><div class="line"><a name="l07608"></a><span class="lineno"> 7608</span>&#160;            pAllocation);</div><div class="line"><a name="l07609"></a><span class="lineno"> 7609</span>&#160;        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l07610"></a><span class="lineno"> 7610</span>&#160;        {</div><div class="line"><a name="l07611"></a><span class="lineno"> 7611</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07612"></a><span class="lineno"> 7612</span>&#160;        }</div><div class="line"><a name="l07613"></a><span class="lineno"> 7613</span>&#160;</div><div class="line"><a name="l07614"></a><span class="lineno"> 7614</span>&#160;        <span class="comment">// 5. Try dedicated memory.</span></div><div class="line"><a name="l07615"></a><span class="lineno"> 7615</span>&#160;        <span class="keywordflow">if</span>((finalCreateInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l07616"></a><span class="lineno"> 7616</span>&#160;        {</div><div class="line"><a name="l07617"></a><span class="lineno"> 7617</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07618"></a><span class="lineno"> 7618</span>&#160;        }</div><div class="line"><a name="l07619"></a><span class="lineno"> 7619</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07620"></a><span class="lineno"> 7620</span>&#160;        {</div><div class="line"><a name="l07621"></a><span class="lineno"> 7621</span>&#160;            res = AllocateDedicatedMemory(</div><div class="line"><a name="l07622"></a><span class="lineno"> 7622</span>&#160;                vkMemReq.size,</div><div class="line"><a name="l07623"></a><span class="lineno"> 7623</span>&#160;                suballocType,</div><div class="line"><a name="l07624"></a><span class="lineno"> 7624</span>&#160;                memTypeIndex,</div><div class="line"><a name="l07625"></a><span class="lineno"> 7625</span>&#160;                (finalCreateInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0,</div><div class="line"><a name="l07626"></a><span class="lineno"> 7626</span>&#160;                (finalCreateInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0,</div><div class="line"><a name="l07627"></a><span class="lineno"> 7627</span>&#160;                finalCreateInfo.pUserData,</div><div class="line"><a name="l07628"></a><span class="lineno"> 7628</span>&#160;                dedicatedBuffer,</div><div class="line"><a name="l07629"></a><span class="lineno"> 7629</span>&#160;                dedicatedImage,</div><div class="line"><a name="l07630"></a><span class="lineno"> 7630</span>&#160;                pAllocation);</div><div class="line"><a name="l07631"></a><span class="lineno"> 7631</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l07632"></a><span class="lineno"> 7632</span>&#160;            {</div><div class="line"><a name="l07633"></a><span class="lineno"> 7633</span>&#160;                <span class="comment">// Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here.</span></div><div class="line"><a name="l07634"></a><span class="lineno"> 7634</span>&#160;                VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Allocated as DedicatedMemory&quot;</span>);</div><div class="line"><a name="l07635"></a><span class="lineno"> 7635</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07636"></a><span class="lineno"> 7636</span>&#160;            }</div><div class="line"><a name="l07637"></a><span class="lineno"> 7637</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07638"></a><span class="lineno"> 7638</span>&#160;            {</div><div class="line"><a name="l07639"></a><span class="lineno"> 7639</span>&#160;                <span class="comment">// Everything failed: Return error code.</span></div><div class="line"><a name="l07640"></a><span class="lineno"> 7640</span>&#160;                VMA_DEBUG_LOG(<span class="stringliteral">&quot;    vkAllocateMemory FAILED&quot;</span>);</div><div class="line"><a name="l07641"></a><span class="lineno"> 7641</span>&#160;                <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07642"></a><span class="lineno"> 7642</span>&#160;            }</div><div class="line"><a name="l07643"></a><span class="lineno"> 7643</span>&#160;        }</div><div class="line"><a name="l07644"></a><span class="lineno"> 7644</span>&#160;    }</div><div class="line"><a name="l07645"></a><span class="lineno"> 7645</span>&#160;}</div><div class="line"><a name="l07646"></a><span class="lineno"> 7646</span>&#160;</div><div class="line"><a name="l07647"></a><span class="lineno"> 7647</span>&#160;VkResult VmaAllocator_T::AllocateDedicatedMemory(</div><div class="line"><a name="l07648"></a><span class="lineno"> 7648</span>&#160;    VkDeviceSize size,</div><div class="line"><a name="l07649"></a><span class="lineno"> 7649</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l07650"></a><span class="lineno"> 7650</span>&#160;    uint32_t memTypeIndex,</div><div class="line"><a name="l07651"></a><span class="lineno"> 7651</span>&#160;    <span class="keywordtype">bool</span> map,</div><div class="line"><a name="l07652"></a><span class="lineno"> 7652</span>&#160;    <span class="keywordtype">bool</span> isUserDataString,</div><div class="line"><a name="l07653"></a><span class="lineno"> 7653</span>&#160;    <span class="keywordtype">void</span>* pUserData,</div><div class="line"><a name="l07654"></a><span class="lineno"> 7654</span>&#160;    VkBuffer dedicatedBuffer,</div><div class="line"><a name="l07655"></a><span class="lineno"> 7655</span>&#160;    VkImage dedicatedImage,</div><div class="line"><a name="l07656"></a><span class="lineno"> 7656</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l07657"></a><span class="lineno"> 7657</span>&#160;{</div><div class="line"><a name="l07658"></a><span class="lineno"> 7658</span>&#160;    VMA_ASSERT(pAllocation);</div><div class="line"><a name="l07659"></a><span class="lineno"> 7659</span>&#160;</div><div class="line"><a name="l07660"></a><span class="lineno"> 7660</span>&#160;    VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };</div><div class="line"><a name="l07661"></a><span class="lineno"> 7661</span>&#160;    allocInfo.memoryTypeIndex = memTypeIndex;</div><div class="line"><a name="l07662"></a><span class="lineno"> 7662</span>&#160;    allocInfo.allocationSize = size;</div><div class="line"><a name="l07663"></a><span class="lineno"> 7663</span>&#160;</div><div class="line"><a name="l07664"></a><span class="lineno"> 7664</span>&#160;    VkMemoryDedicatedAllocateInfoKHR dedicatedAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR };</div><div class="line"><a name="l07665"></a><span class="lineno"> 7665</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l07666"></a><span class="lineno"> 7666</span>&#160;    {</div><div class="line"><a name="l07667"></a><span class="lineno"> 7667</span>&#160;        <span class="keywordflow">if</span>(dedicatedBuffer != VK_NULL_HANDLE)</div><div class="line"><a name="l07668"></a><span class="lineno"> 7668</span>&#160;        {</div><div class="line"><a name="l07669"></a><span class="lineno"> 7669</span>&#160;            VMA_ASSERT(dedicatedImage == VK_NULL_HANDLE);</div><div class="line"><a name="l07670"></a><span class="lineno"> 7670</span>&#160;            dedicatedAllocInfo.buffer = dedicatedBuffer;</div><div class="line"><a name="l07671"></a><span class="lineno"> 7671</span>&#160;            allocInfo.pNext = &amp;dedicatedAllocInfo;</div><div class="line"><a name="l07672"></a><span class="lineno"> 7672</span>&#160;        }</div><div class="line"><a name="l07673"></a><span class="lineno"> 7673</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(dedicatedImage != VK_NULL_HANDLE)</div><div class="line"><a name="l07674"></a><span class="lineno"> 7674</span>&#160;        {</div><div class="line"><a name="l07675"></a><span class="lineno"> 7675</span>&#160;            dedicatedAllocInfo.image = dedicatedImage;</div><div class="line"><a name="l07676"></a><span class="lineno"> 7676</span>&#160;            allocInfo.pNext = &amp;dedicatedAllocInfo;</div><div class="line"><a name="l07677"></a><span class="lineno"> 7677</span>&#160;        }</div><div class="line"><a name="l07678"></a><span class="lineno"> 7678</span>&#160;    }</div><div class="line"><a name="l07679"></a><span class="lineno"> 7679</span>&#160;</div><div class="line"><a name="l07680"></a><span class="lineno"> 7680</span>&#160;    <span class="comment">// Allocate VkDeviceMemory.</span></div><div class="line"><a name="l07681"></a><span class="lineno"> 7681</span>&#160;    VkDeviceMemory hMemory = VK_NULL_HANDLE;</div><div class="line"><a name="l07682"></a><span class="lineno"> 7682</span>&#160;    VkResult res = AllocateVulkanMemory(&amp;allocInfo, &amp;hMemory);</div><div class="line"><a name="l07683"></a><span class="lineno"> 7683</span>&#160;    <span class="keywordflow">if</span>(res &lt; 0)</div><div class="line"><a name="l07684"></a><span class="lineno"> 7684</span>&#160;    {</div><div class="line"><a name="l07685"></a><span class="lineno"> 7685</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;    vkAllocateMemory FAILED&quot;</span>);</div><div class="line"><a name="l07686"></a><span class="lineno"> 7686</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07687"></a><span class="lineno"> 7687</span>&#160;    }</div><div class="line"><a name="l07688"></a><span class="lineno"> 7688</span>&#160;</div><div class="line"><a name="l07689"></a><span class="lineno"> 7689</span>&#160;    <span class="keywordtype">void</span>* pMappedData = VMA_NULL;</div><div class="line"><a name="l07690"></a><span class="lineno"> 7690</span>&#160;    <span class="keywordflow">if</span>(map)</div><div class="line"><a name="l07691"></a><span class="lineno"> 7691</span>&#160;    {</div><div class="line"><a name="l07692"></a><span class="lineno"> 7692</span>&#160;        res = (*m_VulkanFunctions.vkMapMemory)(</div><div class="line"><a name="l07693"></a><span class="lineno"> 7693</span>&#160;            m_hDevice,</div><div class="line"><a name="l07694"></a><span class="lineno"> 7694</span>&#160;            hMemory,</div><div class="line"><a name="l07695"></a><span class="lineno"> 7695</span>&#160;            0,</div><div class="line"><a name="l07696"></a><span class="lineno"> 7696</span>&#160;            VK_WHOLE_SIZE,</div><div class="line"><a name="l07697"></a><span class="lineno"> 7697</span>&#160;            0,</div><div class="line"><a name="l07698"></a><span class="lineno"> 7698</span>&#160;            &amp;pMappedData);</div><div class="line"><a name="l07699"></a><span class="lineno"> 7699</span>&#160;        <span class="keywordflow">if</span>(res &lt; 0)</div><div class="line"><a name="l07700"></a><span class="lineno"> 7700</span>&#160;        {</div><div class="line"><a name="l07701"></a><span class="lineno"> 7701</span>&#160;            VMA_DEBUG_LOG(<span class="stringliteral">&quot;    vkMapMemory FAILED&quot;</span>);</div><div class="line"><a name="l07702"></a><span class="lineno"> 7702</span>&#160;            FreeVulkanMemory(memTypeIndex, size, hMemory);</div><div class="line"><a name="l07703"></a><span class="lineno"> 7703</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07704"></a><span class="lineno"> 7704</span>&#160;        }</div><div class="line"><a name="l07705"></a><span class="lineno"> 7705</span>&#160;    }</div><div class="line"><a name="l07706"></a><span class="lineno"> 7706</span>&#160;</div><div class="line"><a name="l07707"></a><span class="lineno"> 7707</span>&#160;    *pAllocation = vma_new(<span class="keyword">this</span>, VmaAllocation_T)(m_CurrentFrameIndex.load(), isUserDataString);</div><div class="line"><a name="l07708"></a><span class="lineno"> 7708</span>&#160;    (*pAllocation)-&gt;InitDedicatedAllocation(memTypeIndex, hMemory, suballocType, pMappedData, size);</div><div class="line"><a name="l07709"></a><span class="lineno"> 7709</span>&#160;    (*pAllocation)-&gt;SetUserData(<span class="keyword">this</span>, pUserData);</div><div class="line"><a name="l07710"></a><span class="lineno"> 7710</span>&#160;</div><div class="line"><a name="l07711"></a><span class="lineno"> 7711</span>&#160;    <span class="comment">// Register it in m_pDedicatedAllocations.</span></div><div class="line"><a name="l07712"></a><span class="lineno"> 7712</span>&#160;    {</div><div class="line"><a name="l07713"></a><span class="lineno"> 7713</span>&#160;        VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l07714"></a><span class="lineno"> 7714</span>&#160;        AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l07715"></a><span class="lineno"> 7715</span>&#160;        VMA_ASSERT(pDedicatedAllocations);</div><div class="line"><a name="l07716"></a><span class="lineno"> 7716</span>&#160;        VmaVectorInsertSorted&lt;VmaPointerLess&gt;(*pDedicatedAllocations, *pAllocation);</div><div class="line"><a name="l07717"></a><span class="lineno"> 7717</span>&#160;    }</div><div class="line"><a name="l07718"></a><span class="lineno"> 7718</span>&#160;</div><div class="line"><a name="l07719"></a><span class="lineno"> 7719</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Allocated DedicatedMemory MemoryTypeIndex=#%u&quot;</span>, memTypeIndex);</div><div class="line"><a name="l07720"></a><span class="lineno"> 7720</span>&#160;</div><div class="line"><a name="l07721"></a><span class="lineno"> 7721</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l07722"></a><span class="lineno"> 7722</span>&#160;}</div><div class="line"><a name="l07723"></a><span class="lineno"> 7723</span>&#160;</div><div class="line"><a name="l07724"></a><span class="lineno"> 7724</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetBufferMemoryRequirements(</div><div class="line"><a name="l07725"></a><span class="lineno"> 7725</span>&#160;    VkBuffer hBuffer,</div><div class="line"><a name="l07726"></a><span class="lineno"> 7726</span>&#160;    VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l07727"></a><span class="lineno"> 7727</span>&#160;    <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l07728"></a><span class="lineno"> 7728</span>&#160;    <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation)<span class="keyword"> const</span></div><div class="line"><a name="l07729"></a><span class="lineno"> 7729</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07730"></a><span class="lineno"> 7730</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l07731"></a><span class="lineno"> 7731</span>&#160;    {</div><div class="line"><a name="l07732"></a><span class="lineno"> 7732</span>&#160;        VkBufferMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR };</div><div class="line"><a name="l07733"></a><span class="lineno"> 7733</span>&#160;        memReqInfo.buffer = hBuffer;</div><div class="line"><a name="l07734"></a><span class="lineno"> 7734</span>&#160;</div><div class="line"><a name="l07735"></a><span class="lineno"> 7735</span>&#160;        VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };</div><div class="line"><a name="l07736"></a><span class="lineno"> 7736</span>&#160;</div><div class="line"><a name="l07737"></a><span class="lineno"> 7737</span>&#160;        VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };</div><div class="line"><a name="l07738"></a><span class="lineno"> 7738</span>&#160;        memReq2.pNext = &amp;memDedicatedReq;</div><div class="line"><a name="l07739"></a><span class="lineno"> 7739</span>&#160;</div><div class="line"><a name="l07740"></a><span class="lineno"> 7740</span>&#160;        (*m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR)(m_hDevice, &amp;memReqInfo, &amp;memReq2);</div><div class="line"><a name="l07741"></a><span class="lineno"> 7741</span>&#160;</div><div class="line"><a name="l07742"></a><span class="lineno"> 7742</span>&#160;        memReq = memReq2.memoryRequirements;</div><div class="line"><a name="l07743"></a><span class="lineno"> 7743</span>&#160;        requiresDedicatedAllocation = (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE);</div><div class="line"><a name="l07744"></a><span class="lineno"> 7744</span>&#160;        prefersDedicatedAllocation  = (memDedicatedReq.prefersDedicatedAllocation  != VK_FALSE);</div><div class="line"><a name="l07745"></a><span class="lineno"> 7745</span>&#160;    }</div><div class="line"><a name="l07746"></a><span class="lineno"> 7746</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l07747"></a><span class="lineno"> 7747</span>&#160;    {</div><div class="line"><a name="l07748"></a><span class="lineno"> 7748</span>&#160;        (*m_VulkanFunctions.vkGetBufferMemoryRequirements)(m_hDevice, hBuffer, &amp;memReq);</div><div class="line"><a name="l07749"></a><span class="lineno"> 7749</span>&#160;        requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l07750"></a><span class="lineno"> 7750</span>&#160;        prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l07751"></a><span class="lineno"> 7751</span>&#160;    }</div><div class="line"><a name="l07752"></a><span class="lineno"> 7752</span>&#160;}</div><div class="line"><a name="l07753"></a><span class="lineno"> 7753</span>&#160;</div><div class="line"><a name="l07754"></a><span class="lineno"> 7754</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetImageMemoryRequirements(</div><div class="line"><a name="l07755"></a><span class="lineno"> 7755</span>&#160;    VkImage hImage,</div><div class="line"><a name="l07756"></a><span class="lineno"> 7756</span>&#160;    VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l07757"></a><span class="lineno"> 7757</span>&#160;    <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l07758"></a><span class="lineno"> 7758</span>&#160;    <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation)<span class="keyword"> const</span></div><div class="line"><a name="l07759"></a><span class="lineno"> 7759</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07760"></a><span class="lineno"> 7760</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l07761"></a><span class="lineno"> 7761</span>&#160;    {</div><div class="line"><a name="l07762"></a><span class="lineno"> 7762</span>&#160;        VkImageMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR };</div><div class="line"><a name="l07763"></a><span class="lineno"> 7763</span>&#160;        memReqInfo.image = hImage;</div><div class="line"><a name="l07764"></a><span class="lineno"> 7764</span>&#160;</div><div class="line"><a name="l07765"></a><span class="lineno"> 7765</span>&#160;        VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };</div><div class="line"><a name="l07766"></a><span class="lineno"> 7766</span>&#160;</div><div class="line"><a name="l07767"></a><span class="lineno"> 7767</span>&#160;        VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };</div><div class="line"><a name="l07768"></a><span class="lineno"> 7768</span>&#160;        memReq2.pNext = &amp;memDedicatedReq;</div><div class="line"><a name="l07769"></a><span class="lineno"> 7769</span>&#160;</div><div class="line"><a name="l07770"></a><span class="lineno"> 7770</span>&#160;        (*m_VulkanFunctions.vkGetImageMemoryRequirements2KHR)(m_hDevice, &amp;memReqInfo, &amp;memReq2);</div><div class="line"><a name="l07771"></a><span class="lineno"> 7771</span>&#160;</div><div class="line"><a name="l07772"></a><span class="lineno"> 7772</span>&#160;        memReq = memReq2.memoryRequirements;</div><div class="line"><a name="l07773"></a><span class="lineno"> 7773</span>&#160;        requiresDedicatedAllocation = (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE);</div><div class="line"><a name="l07774"></a><span class="lineno"> 7774</span>&#160;        prefersDedicatedAllocation  = (memDedicatedReq.prefersDedicatedAllocation  != VK_FALSE);</div><div class="line"><a name="l07775"></a><span class="lineno"> 7775</span>&#160;    }</div><div class="line"><a name="l07776"></a><span class="lineno"> 7776</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l07777"></a><span class="lineno"> 7777</span>&#160;    {</div><div class="line"><a name="l07778"></a><span class="lineno"> 7778</span>&#160;        (*m_VulkanFunctions.vkGetImageMemoryRequirements)(m_hDevice, hImage, &amp;memReq);</div><div class="line"><a name="l07779"></a><span class="lineno"> 7779</span>&#160;        requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l07780"></a><span class="lineno"> 7780</span>&#160;        prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l07781"></a><span class="lineno"> 7781</span>&#160;    }</div><div class="line"><a name="l07782"></a><span class="lineno"> 7782</span>&#160;}</div><div class="line"><a name="l07783"></a><span class="lineno"> 7783</span>&#160;</div><div class="line"><a name="l07784"></a><span class="lineno"> 7784</span>&#160;VkResult VmaAllocator_T::AllocateMemory(</div><div class="line"><a name="l07785"></a><span class="lineno"> 7785</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l07786"></a><span class="lineno"> 7786</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l07787"></a><span class="lineno"> 7787</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l07788"></a><span class="lineno"> 7788</span>&#160;    VkBuffer dedicatedBuffer,</div><div class="line"><a name="l07789"></a><span class="lineno"> 7789</span>&#160;    VkImage dedicatedImage,</div><div class="line"><a name="l07790"></a><span class="lineno"> 7790</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l07791"></a><span class="lineno"> 7791</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l07792"></a><span class="lineno"> 7792</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l07793"></a><span class="lineno"> 7793</span>&#160;{</div><div class="line"><a name="l07794"></a><span class="lineno"> 7794</span>&#160;    <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>) != 0 &amp;&amp;</div><div class="line"><a name="l07795"></a><span class="lineno"> 7795</span>&#160;        (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l07796"></a><span class="lineno"> 7796</span>&#160;    {</div><div class="line"><a name="l07797"></a><span class="lineno"> 7797</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT together with VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT makes no sense.&quot;</span>);</div><div class="line"><a name="l07798"></a><span class="lineno"> 7798</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07799"></a><span class="lineno"> 7799</span>&#160;    }</div><div class="line"><a name="l07800"></a><span class="lineno"> 7800</span>&#160;    <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0 &amp;&amp;</div><div class="line"><a name="l07801"></a><span class="lineno"> 7801</span>&#160;        (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a>) != 0)</div><div class="line"><a name="l07802"></a><span class="lineno"> 7802</span>&#160;    {</div><div class="line"><a name="l07803"></a><span class="lineno"> 7803</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Specifying VMA_ALLOCATION_CREATE_MAPPED_BIT together with VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT is invalid.&quot;</span>);</div><div class="line"><a name="l07804"></a><span class="lineno"> 7804</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07805"></a><span class="lineno"> 7805</span>&#160;    }</div><div class="line"><a name="l07806"></a><span class="lineno"> 7806</span>&#160;    <span class="keywordflow">if</span>(requiresDedicatedAllocation)</div><div class="line"><a name="l07807"></a><span class="lineno"> 7807</span>&#160;    {</div><div class="line"><a name="l07808"></a><span class="lineno"> 7808</span>&#160;        <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l07809"></a><span class="lineno"> 7809</span>&#160;        {</div><div class="line"><a name="l07810"></a><span class="lineno"> 7810</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT specified while dedicated allocation is required.&quot;</span>);</div><div class="line"><a name="l07811"></a><span class="lineno"> 7811</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07812"></a><span class="lineno"> 7812</span>&#160;        }</div><div class="line"><a name="l07813"></a><span class="lineno"> 7813</span>&#160;        <span class="keywordflow">if</span>(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> != VK_NULL_HANDLE)</div><div class="line"><a name="l07814"></a><span class="lineno"> 7814</span>&#160;        {</div><div class="line"><a name="l07815"></a><span class="lineno"> 7815</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Pool specified while dedicated allocation is required.&quot;</span>);</div><div class="line"><a name="l07816"></a><span class="lineno"> 7816</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07817"></a><span class="lineno"> 7817</span>&#160;        }</div><div class="line"><a name="l07818"></a><span class="lineno"> 7818</span>&#160;    }</div><div class="line"><a name="l07819"></a><span class="lineno"> 7819</span>&#160;    <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> != VK_NULL_HANDLE) &amp;&amp;</div><div class="line"><a name="l07820"></a><span class="lineno"> 7820</span>&#160;        ((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; (<a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>)) != 0))</div><div class="line"><a name="l07821"></a><span class="lineno"> 7821</span>&#160;    {</div><div class="line"><a name="l07822"></a><span class="lineno"> 7822</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT when pool != null is invalid.&quot;</span>);</div><div class="line"><a name="l07823"></a><span class="lineno"> 7823</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07824"></a><span class="lineno"> 7824</span>&#160;    }</div><div class="line"><a name="l07825"></a><span class="lineno"> 7825</span>&#160;</div><div class="line"><a name="l07826"></a><span class="lineno"> 7826</span>&#160;    <span class="keywordflow">if</span>(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> != VK_NULL_HANDLE)</div><div class="line"><a name="l07827"></a><span class="lineno"> 7827</span>&#160;    {</div><div class="line"><a name="l07828"></a><span class="lineno"> 7828</span>&#160;        <span class="keywordflow">return</span> createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>-&gt;m_BlockVector.Allocate(</div><div class="line"><a name="l07829"></a><span class="lineno"> 7829</span>&#160;            createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>,</div><div class="line"><a name="l07830"></a><span class="lineno"> 7830</span>&#160;            m_CurrentFrameIndex.load(),</div><div class="line"><a name="l07831"></a><span class="lineno"> 7831</span>&#160;            vkMemReq,</div><div class="line"><a name="l07832"></a><span class="lineno"> 7832</span>&#160;            createInfo,</div><div class="line"><a name="l07833"></a><span class="lineno"> 7833</span>&#160;            suballocType,</div><div class="line"><a name="l07834"></a><span class="lineno"> 7834</span>&#160;            pAllocation);</div><div class="line"><a name="l07835"></a><span class="lineno"> 7835</span>&#160;    }</div><div class="line"><a name="l07836"></a><span class="lineno"> 7836</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l07837"></a><span class="lineno"> 7837</span>&#160;    {</div><div class="line"><a name="l07838"></a><span class="lineno"> 7838</span>&#160;        <span class="comment">// Bit mask of memory Vulkan types acceptable for this allocation.</span></div><div class="line"><a name="l07839"></a><span class="lineno"> 7839</span>&#160;        uint32_t memoryTypeBits = vkMemReq.memoryTypeBits;</div><div class="line"><a name="l07840"></a><span class="lineno"> 7840</span>&#160;        uint32_t memTypeIndex = UINT32_MAX;</div><div class="line"><a name="l07841"></a><span class="lineno"> 7841</span>&#160;        VkResult res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(<span class="keyword">this</span>, memoryTypeBits, &amp;createInfo, &amp;memTypeIndex);</div><div class="line"><a name="l07842"></a><span class="lineno"> 7842</span>&#160;        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l07843"></a><span class="lineno"> 7843</span>&#160;        {</div><div class="line"><a name="l07844"></a><span class="lineno"> 7844</span>&#160;            res = AllocateMemoryOfType(</div><div class="line"><a name="l07845"></a><span class="lineno"> 7845</span>&#160;                vkMemReq,</div><div class="line"><a name="l07846"></a><span class="lineno"> 7846</span>&#160;                requiresDedicatedAllocation || prefersDedicatedAllocation,</div><div class="line"><a name="l07847"></a><span class="lineno"> 7847</span>&#160;                dedicatedBuffer,</div><div class="line"><a name="l07848"></a><span class="lineno"> 7848</span>&#160;                dedicatedImage,</div><div class="line"><a name="l07849"></a><span class="lineno"> 7849</span>&#160;                createInfo,</div><div class="line"><a name="l07850"></a><span class="lineno"> 7850</span>&#160;                memTypeIndex,</div><div class="line"><a name="l07851"></a><span class="lineno"> 7851</span>&#160;                suballocType,</div><div class="line"><a name="l07852"></a><span class="lineno"> 7852</span>&#160;                pAllocation);</div><div class="line"><a name="l07853"></a><span class="lineno"> 7853</span>&#160;            <span class="comment">// Succeeded on first try.</span></div><div class="line"><a name="l07854"></a><span class="lineno"> 7854</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l07855"></a><span class="lineno"> 7855</span>&#160;            {</div><div class="line"><a name="l07856"></a><span class="lineno"> 7856</span>&#160;                <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07857"></a><span class="lineno"> 7857</span>&#160;            }</div><div class="line"><a name="l07858"></a><span class="lineno"> 7858</span>&#160;            <span class="comment">// Allocation from this memory type failed. Try other compatible memory types.</span></div><div class="line"><a name="l07859"></a><span class="lineno"> 7859</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07860"></a><span class="lineno"> 7860</span>&#160;            {</div><div class="line"><a name="l07861"></a><span class="lineno"> 7861</span>&#160;                <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l07862"></a><span class="lineno"> 7862</span>&#160;                {</div><div class="line"><a name="l07863"></a><span class="lineno"> 7863</span>&#160;                    <span class="comment">// Remove old memTypeIndex from list of possibilities.</span></div><div class="line"><a name="l07864"></a><span class="lineno"> 7864</span>&#160;                    memoryTypeBits &amp;= ~(1u &lt;&lt; memTypeIndex);</div><div class="line"><a name="l07865"></a><span class="lineno"> 7865</span>&#160;                    <span class="comment">// Find alternative memTypeIndex.</span></div><div class="line"><a name="l07866"></a><span class="lineno"> 7866</span>&#160;                    res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(<span class="keyword">this</span>, memoryTypeBits, &amp;createInfo, &amp;memTypeIndex);</div><div class="line"><a name="l07867"></a><span class="lineno"> 7867</span>&#160;                    <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l07868"></a><span class="lineno"> 7868</span>&#160;                    {</div><div class="line"><a name="l07869"></a><span class="lineno"> 7869</span>&#160;                        res = AllocateMemoryOfType(</div><div class="line"><a name="l07870"></a><span class="lineno"> 7870</span>&#160;                            vkMemReq,</div><div class="line"><a name="l07871"></a><span class="lineno"> 7871</span>&#160;                            requiresDedicatedAllocation || prefersDedicatedAllocation,</div><div class="line"><a name="l07872"></a><span class="lineno"> 7872</span>&#160;                            dedicatedBuffer,</div><div class="line"><a name="l07873"></a><span class="lineno"> 7873</span>&#160;                            dedicatedImage,</div><div class="line"><a name="l07874"></a><span class="lineno"> 7874</span>&#160;                            createInfo,</div><div class="line"><a name="l07875"></a><span class="lineno"> 7875</span>&#160;                            memTypeIndex,</div><div class="line"><a name="l07876"></a><span class="lineno"> 7876</span>&#160;                            suballocType,</div><div class="line"><a name="l07877"></a><span class="lineno"> 7877</span>&#160;                            pAllocation);</div><div class="line"><a name="l07878"></a><span class="lineno"> 7878</span>&#160;                        <span class="comment">// Allocation from this alternative memory type succeeded.</span></div><div class="line"><a name="l07879"></a><span class="lineno"> 7879</span>&#160;                        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l07880"></a><span class="lineno"> 7880</span>&#160;                        {</div><div class="line"><a name="l07881"></a><span class="lineno"> 7881</span>&#160;                            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07882"></a><span class="lineno"> 7882</span>&#160;                        }</div><div class="line"><a name="l07883"></a><span class="lineno"> 7883</span>&#160;                        <span class="comment">// else: Allocation from this memory type failed. Try next one - next loop iteration.</span></div><div class="line"><a name="l07884"></a><span class="lineno"> 7884</span>&#160;                    }</div><div class="line"><a name="l07885"></a><span class="lineno"> 7885</span>&#160;                    <span class="comment">// No other matching memory type index could be found.</span></div><div class="line"><a name="l07886"></a><span class="lineno"> 7886</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l07887"></a><span class="lineno"> 7887</span>&#160;                    {</div><div class="line"><a name="l07888"></a><span class="lineno"> 7888</span>&#160;                        <span class="comment">// Not returning res, which is VK_ERROR_FEATURE_NOT_PRESENT, because we already failed to allocate once.</span></div><div class="line"><a name="l07889"></a><span class="lineno"> 7889</span>&#160;                        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l07890"></a><span class="lineno"> 7890</span>&#160;                    }</div><div class="line"><a name="l07891"></a><span class="lineno"> 7891</span>&#160;                }</div><div class="line"><a name="l07892"></a><span class="lineno"> 7892</span>&#160;            }</div><div class="line"><a name="l07893"></a><span class="lineno"> 7893</span>&#160;        }</div><div class="line"><a name="l07894"></a><span class="lineno"> 7894</span>&#160;        <span class="comment">// Can&#39;t find any single memory type maching requirements. res is VK_ERROR_FEATURE_NOT_PRESENT.</span></div><div class="line"><a name="l07895"></a><span class="lineno"> 7895</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07896"></a><span class="lineno"> 7896</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l07897"></a><span class="lineno"> 7897</span>&#160;    }</div><div class="line"><a name="l07898"></a><span class="lineno"> 7898</span>&#160;}</div><div class="line"><a name="l07899"></a><span class="lineno"> 7899</span>&#160;</div><div class="line"><a name="l07900"></a><span class="lineno"> 7900</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FreeMemory(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l07901"></a><span class="lineno"> 7901</span>&#160;{</div><div class="line"><a name="l07902"></a><span class="lineno"> 7902</span>&#160;    VMA_ASSERT(allocation);</div><div class="line"><a name="l07903"></a><span class="lineno"> 7903</span>&#160;</div><div class="line"><a name="l07904"></a><span class="lineno"> 7904</span>&#160;    <span class="keywordflow">if</span>(allocation-&gt;CanBecomeLost() == <span class="keyword">false</span> ||</div><div class="line"><a name="l07905"></a><span class="lineno"> 7905</span>&#160;        allocation-&gt;GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l07906"></a><span class="lineno"> 7906</span>&#160;    {</div><div class="line"><a name="l07907"></a><span class="lineno"> 7907</span>&#160;        <span class="keywordflow">switch</span>(allocation-&gt;GetType())</div><div class="line"><a name="l07908"></a><span class="lineno"> 7908</span>&#160;        {</div><div class="line"><a name="l07909"></a><span class="lineno"> 7909</span>&#160;        <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l07910"></a><span class="lineno"> 7910</span>&#160;            {</div><div class="line"><a name="l07911"></a><span class="lineno"> 7911</span>&#160;                VmaBlockVector* pBlockVector = VMA_NULL;</div><div class="line"><a name="l07912"></a><span class="lineno"> 7912</span>&#160;                <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool = allocation-&gt;GetPool();</div><div class="line"><a name="l07913"></a><span class="lineno"> 7913</span>&#160;                <span class="keywordflow">if</span>(hPool != VK_NULL_HANDLE)</div><div class="line"><a name="l07914"></a><span class="lineno"> 7914</span>&#160;                {</div><div class="line"><a name="l07915"></a><span class="lineno"> 7915</span>&#160;                    pBlockVector = &amp;hPool-&gt;m_BlockVector;</div><div class="line"><a name="l07916"></a><span class="lineno"> 7916</span>&#160;                }</div><div class="line"><a name="l07917"></a><span class="lineno"> 7917</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l07918"></a><span class="lineno"> 7918</span>&#160;                {</div><div class="line"><a name="l07919"></a><span class="lineno"> 7919</span>&#160;                    <span class="keyword">const</span> uint32_t memTypeIndex = allocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l07920"></a><span class="lineno"> 7920</span>&#160;                    pBlockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l07921"></a><span class="lineno"> 7921</span>&#160;                }</div><div class="line"><a name="l07922"></a><span class="lineno"> 7922</span>&#160;                pBlockVector-&gt;Free(allocation);</div><div class="line"><a name="l07923"></a><span class="lineno"> 7923</span>&#160;            }</div><div class="line"><a name="l07924"></a><span class="lineno"> 7924</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l07925"></a><span class="lineno"> 7925</span>&#160;        <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l07926"></a><span class="lineno"> 7926</span>&#160;            FreeDedicatedMemory(allocation);</div><div class="line"><a name="l07927"></a><span class="lineno"> 7927</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l07928"></a><span class="lineno"> 7928</span>&#160;        <span class="keywordflow">default</span>:</div><div class="line"><a name="l07929"></a><span class="lineno"> 7929</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l07930"></a><span class="lineno"> 7930</span>&#160;        }</div><div class="line"><a name="l07931"></a><span class="lineno"> 7931</span>&#160;    }</div><div class="line"><a name="l07932"></a><span class="lineno"> 7932</span>&#160;</div><div class="line"><a name="l07933"></a><span class="lineno"> 7933</span>&#160;    allocation-&gt;SetUserData(<span class="keyword">this</span>, VMA_NULL);</div><div class="line"><a name="l07934"></a><span class="lineno"> 7934</span>&#160;    vma_delete(<span class="keyword">this</span>, allocation);</div><div class="line"><a name="l07935"></a><span class="lineno"> 7935</span>&#160;}</div><div class="line"><a name="l07936"></a><span class="lineno"> 7936</span>&#160;</div><div class="line"><a name="l07937"></a><span class="lineno"> 7937</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::CalculateStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats)</div><div class="line"><a name="l07938"></a><span class="lineno"> 7938</span>&#160;{</div><div class="line"><a name="l07939"></a><span class="lineno"> 7939</span>&#160;    <span class="comment">// Initialize.</span></div><div class="line"><a name="l07940"></a><span class="lineno"> 7940</span>&#160;    InitStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>);</div><div class="line"><a name="l07941"></a><span class="lineno"> 7941</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; VK_MAX_MEMORY_TYPES; ++i)</div><div class="line"><a name="l07942"></a><span class="lineno"> 7942</span>&#160;        InitStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[i]);</div><div class="line"><a name="l07943"></a><span class="lineno"> 7943</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; VK_MAX_MEMORY_HEAPS; ++i)</div><div class="line"><a name="l07944"></a><span class="lineno"> 7944</span>&#160;        InitStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[i]);</div><div class="line"><a name="l07945"></a><span class="lineno"> 7945</span>&#160;    </div><div class="line"><a name="l07946"></a><span class="lineno"> 7946</span>&#160;    <span class="comment">// Process default pools.</span></div><div class="line"><a name="l07947"></a><span class="lineno"> 7947</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l07948"></a><span class="lineno"> 7948</span>&#160;    {</div><div class="line"><a name="l07949"></a><span class="lineno"> 7949</span>&#160;        VmaBlockVector* <span class="keyword">const</span> pBlockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l07950"></a><span class="lineno"> 7950</span>&#160;        VMA_ASSERT(pBlockVector);</div><div class="line"><a name="l07951"></a><span class="lineno"> 7951</span>&#160;        pBlockVector-&gt;AddStats(pStats);</div><div class="line"><a name="l07952"></a><span class="lineno"> 7952</span>&#160;    }</div><div class="line"><a name="l07953"></a><span class="lineno"> 7953</span>&#160;</div><div class="line"><a name="l07954"></a><span class="lineno"> 7954</span>&#160;    <span class="comment">// Process custom pools.</span></div><div class="line"><a name="l07955"></a><span class="lineno"> 7955</span>&#160;    {</div><div class="line"><a name="l07956"></a><span class="lineno"> 7956</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l07957"></a><span class="lineno"> 7957</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = 0, poolCount = m_Pools.size(); poolIndex &lt; poolCount; ++poolIndex)</div><div class="line"><a name="l07958"></a><span class="lineno"> 7958</span>&#160;        {</div><div class="line"><a name="l07959"></a><span class="lineno"> 7959</span>&#160;            m_Pools[poolIndex]-&gt;GetBlockVector().AddStats(pStats);</div><div class="line"><a name="l07960"></a><span class="lineno"> 7960</span>&#160;        }</div><div class="line"><a name="l07961"></a><span class="lineno"> 7961</span>&#160;    }</div><div class="line"><a name="l07962"></a><span class="lineno"> 7962</span>&#160;</div><div class="line"><a name="l07963"></a><span class="lineno"> 7963</span>&#160;    <span class="comment">// Process dedicated allocations.</span></div><div class="line"><a name="l07964"></a><span class="lineno"> 7964</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l07965"></a><span class="lineno"> 7965</span>&#160;    {</div><div class="line"><a name="l07966"></a><span class="lineno"> 7966</span>&#160;        <span class="keyword">const</span> uint32_t memHeapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);</div><div class="line"><a name="l07967"></a><span class="lineno"> 7967</span>&#160;        VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l07968"></a><span class="lineno"> 7968</span>&#160;        AllocationVectorType* <span class="keyword">const</span> pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l07969"></a><span class="lineno"> 7969</span>&#160;        VMA_ASSERT(pDedicatedAllocVector);</div><div class="line"><a name="l07970"></a><span class="lineno"> 7970</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> allocIndex = 0, allocCount = pDedicatedAllocVector-&gt;size(); allocIndex &lt; allocCount; ++allocIndex)</div><div class="line"><a name="l07971"></a><span class="lineno"> 7971</span>&#160;        {</div><div class="line"><a name="l07972"></a><span class="lineno"> 7972</span>&#160;            <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> allocationStatInfo;</div><div class="line"><a name="l07973"></a><span class="lineno"> 7973</span>&#160;            (*pDedicatedAllocVector)[allocIndex]-&gt;DedicatedAllocCalcStatsInfo(allocationStatInfo);</div><div class="line"><a name="l07974"></a><span class="lineno"> 7974</span>&#160;            VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>, allocationStatInfo);</div><div class="line"><a name="l07975"></a><span class="lineno"> 7975</span>&#160;            VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[memTypeIndex], allocationStatInfo);</div><div class="line"><a name="l07976"></a><span class="lineno"> 7976</span>&#160;            VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[memHeapIndex], allocationStatInfo);</div><div class="line"><a name="l07977"></a><span class="lineno"> 7977</span>&#160;        }</div><div class="line"><a name="l07978"></a><span class="lineno"> 7978</span>&#160;    }</div><div class="line"><a name="l07979"></a><span class="lineno"> 7979</span>&#160;</div><div class="line"><a name="l07980"></a><span class="lineno"> 7980</span>&#160;    <span class="comment">// Postprocess.</span></div><div class="line"><a name="l07981"></a><span class="lineno"> 7981</span>&#160;    VmaPostprocessCalcStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>);</div><div class="line"><a name="l07982"></a><span class="lineno"> 7982</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; GetMemoryTypeCount(); ++i)</div><div class="line"><a name="l07983"></a><span class="lineno"> 7983</span>&#160;        VmaPostprocessCalcStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[i]);</div><div class="line"><a name="l07984"></a><span class="lineno"> 7984</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; GetMemoryHeapCount(); ++i)</div><div class="line"><a name="l07985"></a><span class="lineno"> 7985</span>&#160;        VmaPostprocessCalcStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[i]);</div><div class="line"><a name="l07986"></a><span class="lineno"> 7986</span>&#160;}</div><div class="line"><a name="l07987"></a><span class="lineno"> 7987</span>&#160;</div><div class="line"><a name="l07988"></a><span class="lineno"> 7988</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint32_t VMA_VENDOR_ID_AMD = 4098;</div><div class="line"><a name="l07989"></a><span class="lineno"> 7989</span>&#160;</div><div class="line"><a name="l07990"></a><span class="lineno"> 7990</span>&#160;VkResult VmaAllocator_T::Defragment(</div><div class="line"><a name="l07991"></a><span class="lineno"> 7991</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l07992"></a><span class="lineno"> 7992</span>&#160;    <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l07993"></a><span class="lineno"> 7993</span>&#160;    VkBool32* pAllocationsChanged,</div><div class="line"><a name="l07994"></a><span class="lineno"> 7994</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>* pDefragmentationInfo,</div><div class="line"><a name="l07995"></a><span class="lineno"> 7995</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats)</div><div class="line"><a name="l07996"></a><span class="lineno"> 7996</span>&#160;{</div><div class="line"><a name="l07997"></a><span class="lineno"> 7997</span>&#160;    <span class="keywordflow">if</span>(pAllocationsChanged != VMA_NULL)</div><div class="line"><a name="l07998"></a><span class="lineno"> 7998</span>&#160;    {</div><div class="line"><a name="l07999"></a><span class="lineno"> 7999</span>&#160;        memset(pAllocationsChanged, 0, <span class="keyword">sizeof</span>(*pAllocationsChanged));</div><div class="line"><a name="l08000"></a><span class="lineno"> 8000</span>&#160;    }</div><div class="line"><a name="l08001"></a><span class="lineno"> 8001</span>&#160;    <span class="keywordflow">if</span>(pDefragmentationStats != VMA_NULL)</div><div class="line"><a name="l08002"></a><span class="lineno"> 8002</span>&#160;    {</div><div class="line"><a name="l08003"></a><span class="lineno"> 8003</span>&#160;        memset(pDefragmentationStats, 0, <span class="keyword">sizeof</span>(*pDefragmentationStats));</div><div class="line"><a name="l08004"></a><span class="lineno"> 8004</span>&#160;    }</div><div class="line"><a name="l08005"></a><span class="lineno"> 8005</span>&#160;</div><div class="line"><a name="l08006"></a><span class="lineno"> 8006</span>&#160;    <span class="keyword">const</span> uint32_t currentFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l08007"></a><span class="lineno"> 8007</span>&#160;</div><div class="line"><a name="l08008"></a><span class="lineno"> 8008</span>&#160;    VmaMutexLock poolsLock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l08009"></a><span class="lineno"> 8009</span>&#160;</div><div class="line"><a name="l08010"></a><span class="lineno"> 8010</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> poolCount = m_Pools.size();</div><div class="line"><a name="l08011"></a><span class="lineno"> 8011</span>&#160;</div><div class="line"><a name="l08012"></a><span class="lineno"> 8012</span>&#160;    <span class="comment">// Dispatch pAllocations among defragmentators. Create them in BlockVectors when necessary.</span></div><div class="line"><a name="l08013"></a><span class="lineno"> 8013</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> allocIndex = 0; allocIndex &lt; allocationCount; ++allocIndex)</div><div class="line"><a name="l08014"></a><span class="lineno"> 8014</span>&#160;    {</div><div class="line"><a name="l08015"></a><span class="lineno"> 8015</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc = pAllocations[allocIndex];</div><div class="line"><a name="l08016"></a><span class="lineno"> 8016</span>&#160;        VMA_ASSERT(hAlloc);</div><div class="line"><a name="l08017"></a><span class="lineno"> 8017</span>&#160;        <span class="keyword">const</span> uint32_t memTypeIndex = hAlloc-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l08018"></a><span class="lineno"> 8018</span>&#160;        <span class="comment">// DedicatedAlloc cannot be defragmented.</span></div><div class="line"><a name="l08019"></a><span class="lineno"> 8019</span>&#160;        <span class="keywordflow">if</span>((hAlloc-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK) &amp;&amp;</div><div class="line"><a name="l08020"></a><span class="lineno"> 8020</span>&#160;            <span class="comment">// Only HOST_VISIBLE memory types can be defragmented.</span></div><div class="line"><a name="l08021"></a><span class="lineno"> 8021</span>&#160;            ((m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) &amp;&amp;</div><div class="line"><a name="l08022"></a><span class="lineno"> 8022</span>&#160;            <span class="comment">// Lost allocation cannot be defragmented.</span></div><div class="line"><a name="l08023"></a><span class="lineno"> 8023</span>&#160;            (hAlloc-&gt;GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST))</div><div class="line"><a name="l08024"></a><span class="lineno"> 8024</span>&#160;        {</div><div class="line"><a name="l08025"></a><span class="lineno"> 8025</span>&#160;            VmaBlockVector* pAllocBlockVector = VMA_NULL;</div><div class="line"><a name="l08026"></a><span class="lineno"> 8026</span>&#160;</div><div class="line"><a name="l08027"></a><span class="lineno"> 8027</span>&#160;            <span class="keyword">const</span> <a class="code" href="struct_vma_pool.html">VmaPool</a> hAllocPool = hAlloc-&gt;GetPool();</div><div class="line"><a name="l08028"></a><span class="lineno"> 8028</span>&#160;            <span class="comment">// This allocation belongs to custom pool.</span></div><div class="line"><a name="l08029"></a><span class="lineno"> 8029</span>&#160;            <span class="keywordflow">if</span>(hAllocPool != VK_NULL_HANDLE)</div><div class="line"><a name="l08030"></a><span class="lineno"> 8030</span>&#160;            {</div><div class="line"><a name="l08031"></a><span class="lineno"> 8031</span>&#160;                pAllocBlockVector = &amp;hAllocPool-&gt;GetBlockVector();</div><div class="line"><a name="l08032"></a><span class="lineno"> 8032</span>&#160;            }</div><div class="line"><a name="l08033"></a><span class="lineno"> 8033</span>&#160;            <span class="comment">// This allocation belongs to general pool.</span></div><div class="line"><a name="l08034"></a><span class="lineno"> 8034</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l08035"></a><span class="lineno"> 8035</span>&#160;            {</div><div class="line"><a name="l08036"></a><span class="lineno"> 8036</span>&#160;                pAllocBlockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l08037"></a><span class="lineno"> 8037</span>&#160;            }</div><div class="line"><a name="l08038"></a><span class="lineno"> 8038</span>&#160;</div><div class="line"><a name="l08039"></a><span class="lineno"> 8039</span>&#160;            VmaDefragmentator* <span class="keyword">const</span> pDefragmentator = pAllocBlockVector-&gt;EnsureDefragmentator(<span class="keyword">this</span>, currentFrameIndex);</div><div class="line"><a name="l08040"></a><span class="lineno"> 8040</span>&#160;</div><div class="line"><a name="l08041"></a><span class="lineno"> 8041</span>&#160;            VkBool32* <span class="keyword">const</span> pChanged = (pAllocationsChanged != VMA_NULL) ?</div><div class="line"><a name="l08042"></a><span class="lineno"> 8042</span>&#160;                &amp;pAllocationsChanged[allocIndex] : VMA_NULL;</div><div class="line"><a name="l08043"></a><span class="lineno"> 8043</span>&#160;            pDefragmentator-&gt;AddAllocation(hAlloc, pChanged);</div><div class="line"><a name="l08044"></a><span class="lineno"> 8044</span>&#160;        }</div><div class="line"><a name="l08045"></a><span class="lineno"> 8045</span>&#160;    }</div><div class="line"><a name="l08046"></a><span class="lineno"> 8046</span>&#160;</div><div class="line"><a name="l08047"></a><span class="lineno"> 8047</span>&#160;    VkResult result = VK_SUCCESS;</div><div class="line"><a name="l08048"></a><span class="lineno"> 8048</span>&#160;</div><div class="line"><a name="l08049"></a><span class="lineno"> 8049</span>&#160;    <span class="comment">// ======== Main processing.</span></div><div class="line"><a name="l08050"></a><span class="lineno"> 8050</span>&#160;</div><div class="line"><a name="l08051"></a><span class="lineno"> 8051</span>&#160;    VkDeviceSize maxBytesToMove = SIZE_MAX;</div><div class="line"><a name="l08052"></a><span class="lineno"> 8052</span>&#160;    uint32_t maxAllocationsToMove = UINT32_MAX;</div><div class="line"><a name="l08053"></a><span class="lineno"> 8053</span>&#160;    <span class="keywordflow">if</span>(pDefragmentationInfo != VMA_NULL)</div><div class="line"><a name="l08054"></a><span class="lineno"> 8054</span>&#160;    {</div><div class="line"><a name="l08055"></a><span class="lineno"> 8055</span>&#160;        maxBytesToMove = pDefragmentationInfo-&gt;<a class="code" href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d">maxBytesToMove</a>;</div><div class="line"><a name="l08056"></a><span class="lineno"> 8056</span>&#160;        maxAllocationsToMove = pDefragmentationInfo-&gt;<a class="code" href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc">maxAllocationsToMove</a>;</div><div class="line"><a name="l08057"></a><span class="lineno"> 8057</span>&#160;    }</div><div class="line"><a name="l08058"></a><span class="lineno"> 8058</span>&#160;</div><div class="line"><a name="l08059"></a><span class="lineno"> 8059</span>&#160;    <span class="comment">// Process standard memory.</span></div><div class="line"><a name="l08060"></a><span class="lineno"> 8060</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0;</div><div class="line"><a name="l08061"></a><span class="lineno"> 8061</span>&#160;        (memTypeIndex &lt; GetMemoryTypeCount()) &amp;&amp; (result == VK_SUCCESS);</div><div class="line"><a name="l08062"></a><span class="lineno"> 8062</span>&#160;        ++memTypeIndex)</div><div class="line"><a name="l08063"></a><span class="lineno"> 8063</span>&#160;    {</div><div class="line"><a name="l08064"></a><span class="lineno"> 8064</span>&#160;        <span class="comment">// Only HOST_VISIBLE memory types can be defragmented.</span></div><div class="line"><a name="l08065"></a><span class="lineno"> 8065</span>&#160;        <span class="keywordflow">if</span>((m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)</div><div class="line"><a name="l08066"></a><span class="lineno"> 8066</span>&#160;        {</div><div class="line"><a name="l08067"></a><span class="lineno"> 8067</span>&#160;            result = m_pBlockVectors[memTypeIndex]-&gt;Defragment(</div><div class="line"><a name="l08068"></a><span class="lineno"> 8068</span>&#160;                pDefragmentationStats,</div><div class="line"><a name="l08069"></a><span class="lineno"> 8069</span>&#160;                maxBytesToMove,</div><div class="line"><a name="l08070"></a><span class="lineno"> 8070</span>&#160;                maxAllocationsToMove);</div><div class="line"><a name="l08071"></a><span class="lineno"> 8071</span>&#160;        }</div><div class="line"><a name="l08072"></a><span class="lineno"> 8072</span>&#160;    }</div><div class="line"><a name="l08073"></a><span class="lineno"> 8073</span>&#160;</div><div class="line"><a name="l08074"></a><span class="lineno"> 8074</span>&#160;    <span class="comment">// Process custom pools.</span></div><div class="line"><a name="l08075"></a><span class="lineno"> 8075</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = 0; (poolIndex &lt; poolCount) &amp;&amp; (result == VK_SUCCESS); ++poolIndex)</div><div class="line"><a name="l08076"></a><span class="lineno"> 8076</span>&#160;    {</div><div class="line"><a name="l08077"></a><span class="lineno"> 8077</span>&#160;        result = m_Pools[poolIndex]-&gt;GetBlockVector().Defragment(</div><div class="line"><a name="l08078"></a><span class="lineno"> 8078</span>&#160;            pDefragmentationStats,</div><div class="line"><a name="l08079"></a><span class="lineno"> 8079</span>&#160;            maxBytesToMove,</div><div class="line"><a name="l08080"></a><span class="lineno"> 8080</span>&#160;            maxAllocationsToMove);</div><div class="line"><a name="l08081"></a><span class="lineno"> 8081</span>&#160;    }</div><div class="line"><a name="l08082"></a><span class="lineno"> 8082</span>&#160;</div><div class="line"><a name="l08083"></a><span class="lineno"> 8083</span>&#160;    <span class="comment">// ========  Destroy defragmentators.</span></div><div class="line"><a name="l08084"></a><span class="lineno"> 8084</span>&#160;</div><div class="line"><a name="l08085"></a><span class="lineno"> 8085</span>&#160;    <span class="comment">// Process custom pools.</span></div><div class="line"><a name="l08086"></a><span class="lineno"> 8086</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = poolCount; poolIndex--; )</div><div class="line"><a name="l08087"></a><span class="lineno"> 8087</span>&#160;    {</div><div class="line"><a name="l08088"></a><span class="lineno"> 8088</span>&#160;        m_Pools[poolIndex]-&gt;GetBlockVector().DestroyDefragmentator();</div><div class="line"><a name="l08089"></a><span class="lineno"> 8089</span>&#160;    }</div><div class="line"><a name="l08090"></a><span class="lineno"> 8090</span>&#160;</div><div class="line"><a name="l08091"></a><span class="lineno"> 8091</span>&#160;    <span class="comment">// Process standard memory.</span></div><div class="line"><a name="l08092"></a><span class="lineno"> 8092</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; )</div><div class="line"><a name="l08093"></a><span class="lineno"> 8093</span>&#160;    {</div><div class="line"><a name="l08094"></a><span class="lineno"> 8094</span>&#160;        <span class="keywordflow">if</span>((m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)</div><div class="line"><a name="l08095"></a><span class="lineno"> 8095</span>&#160;        {</div><div class="line"><a name="l08096"></a><span class="lineno"> 8096</span>&#160;            m_pBlockVectors[memTypeIndex]-&gt;DestroyDefragmentator();</div><div class="line"><a name="l08097"></a><span class="lineno"> 8097</span>&#160;        }</div><div class="line"><a name="l08098"></a><span class="lineno"> 8098</span>&#160;    }</div><div class="line"><a name="l08099"></a><span class="lineno"> 8099</span>&#160;</div><div class="line"><a name="l08100"></a><span class="lineno"> 8100</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l08101"></a><span class="lineno"> 8101</span>&#160;}</div><div class="line"><a name="l08102"></a><span class="lineno"> 8102</span>&#160;</div><div class="line"><a name="l08103"></a><span class="lineno"> 8103</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetAllocationInfo(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l08104"></a><span class="lineno"> 8104</span>&#160;{</div><div class="line"><a name="l08105"></a><span class="lineno"> 8105</span>&#160;    <span class="keywordflow">if</span>(hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l08106"></a><span class="lineno"> 8106</span>&#160;    {</div><div class="line"><a name="l08107"></a><span class="lineno"> 8107</span>&#160;        <span class="comment">/*</span></div><div class="line"><a name="l08108"></a><span class="lineno"> 8108</span>&#160;<span class="comment">        Warning: This is a carefully designed algorithm.</span></div><div class="line"><a name="l08109"></a><span class="lineno"> 8109</span>&#160;<span class="comment">        Do not modify unless you really know what you&#39;re doing :)</span></div><div class="line"><a name="l08110"></a><span class="lineno"> 8110</span>&#160;<span class="comment">        */</span></div><div class="line"><a name="l08111"></a><span class="lineno"> 8111</span>&#160;        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l08112"></a><span class="lineno"> 8112</span>&#160;        uint32_t localLastUseFrameIndex = hAllocation-&gt;GetLastUseFrameIndex();</div><div class="line"><a name="l08113"></a><span class="lineno"> 8113</span>&#160;        <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l08114"></a><span class="lineno"> 8114</span>&#160;        {</div><div class="line"><a name="l08115"></a><span class="lineno"> 8115</span>&#160;            <span class="keywordflow">if</span>(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l08116"></a><span class="lineno"> 8116</span>&#160;            {</div><div class="line"><a name="l08117"></a><span class="lineno"> 8117</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a> = UINT32_MAX;</div><div class="line"><a name="l08118"></a><span class="lineno"> 8118</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a> = VK_NULL_HANDLE;</div><div class="line"><a name="l08119"></a><span class="lineno"> 8119</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a> = 0;</div><div class="line"><a name="l08120"></a><span class="lineno"> 8120</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a> = hAllocation-&gt;GetSize();</div><div class="line"><a name="l08121"></a><span class="lineno"> 8121</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a> = VMA_NULL;</div><div class="line"><a name="l08122"></a><span class="lineno"> 8122</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> = hAllocation-&gt;GetUserData();</div><div class="line"><a name="l08123"></a><span class="lineno"> 8123</span>&#160;                <span class="keywordflow">return</span>;</div><div class="line"><a name="l08124"></a><span class="lineno"> 8124</span>&#160;            }</div><div class="line"><a name="l08125"></a><span class="lineno"> 8125</span>&#160;            <span class="keywordflow">else</span> <span class="keywordflow">if</span>(localLastUseFrameIndex == localCurrFrameIndex)</div><div class="line"><a name="l08126"></a><span class="lineno"> 8126</span>&#160;            {</div><div class="line"><a name="l08127"></a><span class="lineno"> 8127</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a> = hAllocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l08128"></a><span class="lineno"> 8128</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a> = hAllocation-&gt;GetMemory();</div><div class="line"><a name="l08129"></a><span class="lineno"> 8129</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a> = hAllocation-&gt;GetOffset();</div><div class="line"><a name="l08130"></a><span class="lineno"> 8130</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a> = hAllocation-&gt;GetSize();</div><div class="line"><a name="l08131"></a><span class="lineno"> 8131</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a> = VMA_NULL;</div><div class="line"><a name="l08132"></a><span class="lineno"> 8132</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> = hAllocation-&gt;GetUserData();</div><div class="line"><a name="l08133"></a><span class="lineno"> 8133</span>&#160;                <span class="keywordflow">return</span>;</div><div class="line"><a name="l08134"></a><span class="lineno"> 8134</span>&#160;            }</div><div class="line"><a name="l08135"></a><span class="lineno"> 8135</span>&#160;            <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l08136"></a><span class="lineno"> 8136</span>&#160;            {</div><div class="line"><a name="l08137"></a><span class="lineno"> 8137</span>&#160;                <span class="keywordflow">if</span>(hAllocation-&gt;CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))</div><div class="line"><a name="l08138"></a><span class="lineno"> 8138</span>&#160;                {</div><div class="line"><a name="l08139"></a><span class="lineno"> 8139</span>&#160;                    localLastUseFrameIndex = localCurrFrameIndex;</div><div class="line"><a name="l08140"></a><span class="lineno"> 8140</span>&#160;                }</div><div class="line"><a name="l08141"></a><span class="lineno"> 8141</span>&#160;            }</div><div class="line"><a name="l08142"></a><span class="lineno"> 8142</span>&#160;        }</div><div class="line"><a name="l08143"></a><span class="lineno"> 8143</span>&#160;    }</div><div class="line"><a name="l08144"></a><span class="lineno"> 8144</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l08145"></a><span class="lineno"> 8145</span>&#160;    {</div><div class="line"><a name="l08146"></a><span class="lineno"> 8146</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a> = hAllocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l08147"></a><span class="lineno"> 8147</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a> = hAllocation-&gt;GetMemory();</div><div class="line"><a name="l08148"></a><span class="lineno"> 8148</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a> = hAllocation-&gt;GetOffset();</div><div class="line"><a name="l08149"></a><span class="lineno"> 8149</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a> = hAllocation-&gt;GetSize();</div><div class="line"><a name="l08150"></a><span class="lineno"> 8150</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a> = hAllocation-&gt;GetMappedData();</div><div class="line"><a name="l08151"></a><span class="lineno"> 8151</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> = hAllocation-&gt;GetUserData();</div><div class="line"><a name="l08152"></a><span class="lineno"> 8152</span>&#160;    }</div><div class="line"><a name="l08153"></a><span class="lineno"> 8153</span>&#160;}</div><div class="line"><a name="l08154"></a><span class="lineno"> 8154</span>&#160;</div><div class="line"><a name="l08155"></a><span class="lineno"> 8155</span>&#160;<span class="keywordtype">bool</span> VmaAllocator_T::TouchAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l08156"></a><span class="lineno"> 8156</span>&#160;{</div><div class="line"><a name="l08157"></a><span class="lineno"> 8157</span>&#160;    <span class="comment">// This is a stripped-down version of VmaAllocator_T::GetAllocationInfo.</span></div><div class="line"><a name="l08158"></a><span class="lineno"> 8158</span>&#160;    <span class="keywordflow">if</span>(hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l08159"></a><span class="lineno"> 8159</span>&#160;    {</div><div class="line"><a name="l08160"></a><span class="lineno"> 8160</span>&#160;        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l08161"></a><span class="lineno"> 8161</span>&#160;        uint32_t localLastUseFrameIndex = hAllocation-&gt;GetLastUseFrameIndex();</div><div class="line"><a name="l08162"></a><span class="lineno"> 8162</span>&#160;        <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l08163"></a><span class="lineno"> 8163</span>&#160;        {</div><div class="line"><a name="l08164"></a><span class="lineno"> 8164</span>&#160;            <span class="keywordflow">if</span>(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l08165"></a><span class="lineno"> 8165</span>&#160;            {</div><div class="line"><a name="l08166"></a><span class="lineno"> 8166</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08167"></a><span class="lineno"> 8167</span>&#160;            }</div><div class="line"><a name="l08168"></a><span class="lineno"> 8168</span>&#160;            <span class="keywordflow">else</span> <span class="keywordflow">if</span>(localLastUseFrameIndex == localCurrFrameIndex)</div><div class="line"><a name="l08169"></a><span class="lineno"> 8169</span>&#160;            {</div><div class="line"><a name="l08170"></a><span class="lineno"> 8170</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l08171"></a><span class="lineno"> 8171</span>&#160;            }</div><div class="line"><a name="l08172"></a><span class="lineno"> 8172</span>&#160;            <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l08173"></a><span class="lineno"> 8173</span>&#160;            {</div><div class="line"><a name="l08174"></a><span class="lineno"> 8174</span>&#160;                <span class="keywordflow">if</span>(hAllocation-&gt;CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))</div><div class="line"><a name="l08175"></a><span class="lineno"> 8175</span>&#160;                {</div><div class="line"><a name="l08176"></a><span class="lineno"> 8176</span>&#160;                    localLastUseFrameIndex = localCurrFrameIndex;</div><div class="line"><a name="l08177"></a><span class="lineno"> 8177</span>&#160;                }</div><div class="line"><a name="l08178"></a><span class="lineno"> 8178</span>&#160;            }</div><div class="line"><a name="l08179"></a><span class="lineno"> 8179</span>&#160;        }</div><div class="line"><a name="l08180"></a><span class="lineno"> 8180</span>&#160;    }</div><div class="line"><a name="l08181"></a><span class="lineno"> 8181</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l08182"></a><span class="lineno"> 8182</span>&#160;    {</div><div class="line"><a name="l08183"></a><span class="lineno"> 8183</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l08184"></a><span class="lineno"> 8184</span>&#160;    }</div><div class="line"><a name="l08185"></a><span class="lineno"> 8185</span>&#160;}</div><div class="line"><a name="l08186"></a><span class="lineno"> 8186</span>&#160;</div><div class="line"><a name="l08187"></a><span class="lineno"> 8187</span>&#160;VkResult VmaAllocator_T::CreatePool(<span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo, <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool)</div><div class="line"><a name="l08188"></a><span class="lineno"> 8188</span>&#160;{</div><div class="line"><a name="l08189"></a><span class="lineno"> 8189</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;  CreatePool: MemoryTypeIndex=%u&quot;</span>, pCreateInfo-&gt;<a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a>);</div><div class="line"><a name="l08190"></a><span class="lineno"> 8190</span>&#160;</div><div class="line"><a name="l08191"></a><span class="lineno"> 8191</span>&#160;    <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> newCreateInfo = *pCreateInfo;</div><div class="line"><a name="l08192"></a><span class="lineno"> 8192</span>&#160;</div><div class="line"><a name="l08193"></a><span class="lineno"> 8193</span>&#160;    <span class="keywordflow">if</span>(newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a> == 0)</div><div class="line"><a name="l08194"></a><span class="lineno"> 8194</span>&#160;    {</div><div class="line"><a name="l08195"></a><span class="lineno"> 8195</span>&#160;        newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a> = SIZE_MAX;</div><div class="line"><a name="l08196"></a><span class="lineno"> 8196</span>&#160;    }</div><div class="line"><a name="l08197"></a><span class="lineno"> 8197</span>&#160;    <span class="keywordflow">if</span>(newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">blockSize</a> == 0)</div><div class="line"><a name="l08198"></a><span class="lineno"> 8198</span>&#160;    {</div><div class="line"><a name="l08199"></a><span class="lineno"> 8199</span>&#160;        newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">blockSize</a> = CalcPreferredBlockSize(newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a>);</div><div class="line"><a name="l08200"></a><span class="lineno"> 8200</span>&#160;    }</div><div class="line"><a name="l08201"></a><span class="lineno"> 8201</span>&#160;</div><div class="line"><a name="l08202"></a><span class="lineno"> 8202</span>&#160;    *pPool = vma_new(<span class="keyword">this</span>, VmaPool_T)(<span class="keyword">this</span>, newCreateInfo);</div><div class="line"><a name="l08203"></a><span class="lineno"> 8203</span>&#160;</div><div class="line"><a name="l08204"></a><span class="lineno"> 8204</span>&#160;    VkResult res = (*pPool)-&gt;m_BlockVector.CreateMinBlocks();</div><div class="line"><a name="l08205"></a><span class="lineno"> 8205</span>&#160;    <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l08206"></a><span class="lineno"> 8206</span>&#160;    {</div><div class="line"><a name="l08207"></a><span class="lineno"> 8207</span>&#160;        vma_delete(<span class="keyword">this</span>, *pPool);</div><div class="line"><a name="l08208"></a><span class="lineno"> 8208</span>&#160;        *pPool = VMA_NULL;</div><div class="line"><a name="l08209"></a><span class="lineno"> 8209</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l08210"></a><span class="lineno"> 8210</span>&#160;    }</div><div class="line"><a name="l08211"></a><span class="lineno"> 8211</span>&#160;</div><div class="line"><a name="l08212"></a><span class="lineno"> 8212</span>&#160;    <span class="comment">// Add to m_Pools.</span></div><div class="line"><a name="l08213"></a><span class="lineno"> 8213</span>&#160;    {</div><div class="line"><a name="l08214"></a><span class="lineno"> 8214</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l08215"></a><span class="lineno"> 8215</span>&#160;        VmaVectorInsertSorted&lt;VmaPointerLess&gt;(m_Pools, *pPool);</div><div class="line"><a name="l08216"></a><span class="lineno"> 8216</span>&#160;    }</div><div class="line"><a name="l08217"></a><span class="lineno"> 8217</span>&#160;</div><div class="line"><a name="l08218"></a><span class="lineno"> 8218</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l08219"></a><span class="lineno"> 8219</span>&#160;}</div><div class="line"><a name="l08220"></a><span class="lineno"> 8220</span>&#160;</div><div class="line"><a name="l08221"></a><span class="lineno"> 8221</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::DestroyPool(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l08222"></a><span class="lineno"> 8222</span>&#160;{</div><div class="line"><a name="l08223"></a><span class="lineno"> 8223</span>&#160;    <span class="comment">// Remove from m_Pools.</span></div><div class="line"><a name="l08224"></a><span class="lineno"> 8224</span>&#160;    {</div><div class="line"><a name="l08225"></a><span class="lineno"> 8225</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l08226"></a><span class="lineno"> 8226</span>&#160;        <span class="keywordtype">bool</span> success = VmaVectorRemoveSorted&lt;VmaPointerLess&gt;(m_Pools, pool);</div><div class="line"><a name="l08227"></a><span class="lineno"> 8227</span>&#160;        VMA_ASSERT(success &amp;&amp; <span class="stringliteral">&quot;Pool not found in Allocator.&quot;</span>);</div><div class="line"><a name="l08228"></a><span class="lineno"> 8228</span>&#160;    }</div><div class="line"><a name="l08229"></a><span class="lineno"> 8229</span>&#160;</div><div class="line"><a name="l08230"></a><span class="lineno"> 8230</span>&#160;    vma_delete(<span class="keyword">this</span>, pool);</div><div class="line"><a name="l08231"></a><span class="lineno"> 8231</span>&#160;}</div><div class="line"><a name="l08232"></a><span class="lineno"> 8232</span>&#160;</div><div class="line"><a name="l08233"></a><span class="lineno"> 8233</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetPoolStats(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool, <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats)</div><div class="line"><a name="l08234"></a><span class="lineno"> 8234</span>&#160;{</div><div class="line"><a name="l08235"></a><span class="lineno"> 8235</span>&#160;    pool-&gt;m_BlockVector.GetPoolStats(pPoolStats);</div><div class="line"><a name="l08236"></a><span class="lineno"> 8236</span>&#160;}</div><div class="line"><a name="l08237"></a><span class="lineno"> 8237</span>&#160;</div><div class="line"><a name="l08238"></a><span class="lineno"> 8238</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::SetCurrentFrameIndex(uint32_t frameIndex)</div><div class="line"><a name="l08239"></a><span class="lineno"> 8239</span>&#160;{</div><div class="line"><a name="l08240"></a><span class="lineno"> 8240</span>&#160;    m_CurrentFrameIndex.store(frameIndex);</div><div class="line"><a name="l08241"></a><span class="lineno"> 8241</span>&#160;}</div><div class="line"><a name="l08242"></a><span class="lineno"> 8242</span>&#160;</div><div class="line"><a name="l08243"></a><span class="lineno"> 8243</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::MakePoolAllocationsLost(</div><div class="line"><a name="l08244"></a><span class="lineno"> 8244</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool,</div><div class="line"><a name="l08245"></a><span class="lineno"> 8245</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount)</div><div class="line"><a name="l08246"></a><span class="lineno"> 8246</span>&#160;{</div><div class="line"><a name="l08247"></a><span class="lineno"> 8247</span>&#160;    hPool-&gt;m_BlockVector.MakePoolAllocationsLost(</div><div class="line"><a name="l08248"></a><span class="lineno"> 8248</span>&#160;        m_CurrentFrameIndex.load(),</div><div class="line"><a name="l08249"></a><span class="lineno"> 8249</span>&#160;        pLostAllocationCount);</div><div class="line"><a name="l08250"></a><span class="lineno"> 8250</span>&#160;}</div><div class="line"><a name="l08251"></a><span class="lineno"> 8251</span>&#160;</div><div class="line"><a name="l08252"></a><span class="lineno"> 8252</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::CreateLostAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l08253"></a><span class="lineno"> 8253</span>&#160;{</div><div class="line"><a name="l08254"></a><span class="lineno"> 8254</span>&#160;    *pAllocation = vma_new(<span class="keyword">this</span>, VmaAllocation_T)(VMA_FRAME_INDEX_LOST, <span class="keyword">false</span>);</div><div class="line"><a name="l08255"></a><span class="lineno"> 8255</span>&#160;    (*pAllocation)-&gt;InitLost();</div><div class="line"><a name="l08256"></a><span class="lineno"> 8256</span>&#160;}</div><div class="line"><a name="l08257"></a><span class="lineno"> 8257</span>&#160;</div><div class="line"><a name="l08258"></a><span class="lineno"> 8258</span>&#160;VkResult VmaAllocator_T::AllocateVulkanMemory(<span class="keyword">const</span> VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory)</div><div class="line"><a name="l08259"></a><span class="lineno"> 8259</span>&#160;{</div><div class="line"><a name="l08260"></a><span class="lineno"> 8260</span>&#160;    <span class="keyword">const</span> uint32_t heapIndex = MemoryTypeIndexToHeapIndex(pAllocateInfo-&gt;memoryTypeIndex);</div><div class="line"><a name="l08261"></a><span class="lineno"> 8261</span>&#160;</div><div class="line"><a name="l08262"></a><span class="lineno"> 8262</span>&#160;    VkResult res;</div><div class="line"><a name="l08263"></a><span class="lineno"> 8263</span>&#160;    <span class="keywordflow">if</span>(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE)</div><div class="line"><a name="l08264"></a><span class="lineno"> 8264</span>&#160;    {</div><div class="line"><a name="l08265"></a><span class="lineno"> 8265</span>&#160;        VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex);</div><div class="line"><a name="l08266"></a><span class="lineno"> 8266</span>&#160;        <span class="keywordflow">if</span>(m_HeapSizeLimit[heapIndex] &gt;= pAllocateInfo-&gt;allocationSize)</div><div class="line"><a name="l08267"></a><span class="lineno"> 8267</span>&#160;        {</div><div class="line"><a name="l08268"></a><span class="lineno"> 8268</span>&#160;            res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory);</div><div class="line"><a name="l08269"></a><span class="lineno"> 8269</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l08270"></a><span class="lineno"> 8270</span>&#160;            {</div><div class="line"><a name="l08271"></a><span class="lineno"> 8271</span>&#160;                m_HeapSizeLimit[heapIndex] -= pAllocateInfo-&gt;allocationSize;</div><div class="line"><a name="l08272"></a><span class="lineno"> 8272</span>&#160;            }</div><div class="line"><a name="l08273"></a><span class="lineno"> 8273</span>&#160;        }</div><div class="line"><a name="l08274"></a><span class="lineno"> 8274</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l08275"></a><span class="lineno"> 8275</span>&#160;        {</div><div class="line"><a name="l08276"></a><span class="lineno"> 8276</span>&#160;            res = VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l08277"></a><span class="lineno"> 8277</span>&#160;        }</div><div class="line"><a name="l08278"></a><span class="lineno"> 8278</span>&#160;    }</div><div class="line"><a name="l08279"></a><span class="lineno"> 8279</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l08280"></a><span class="lineno"> 8280</span>&#160;    {</div><div class="line"><a name="l08281"></a><span class="lineno"> 8281</span>&#160;        res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory);</div><div class="line"><a name="l08282"></a><span class="lineno"> 8282</span>&#160;    }</div><div class="line"><a name="l08283"></a><span class="lineno"> 8283</span>&#160;</div><div class="line"><a name="l08284"></a><span class="lineno"> 8284</span>&#160;    <span class="keywordflow">if</span>(res == VK_SUCCESS &amp;&amp; m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a> != VMA_NULL)</div><div class="line"><a name="l08285"></a><span class="lineno"> 8285</span>&#160;    {</div><div class="line"><a name="l08286"></a><span class="lineno"> 8286</span>&#160;        (*m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a>)(<span class="keyword">this</span>, pAllocateInfo-&gt;memoryTypeIndex, *pMemory, pAllocateInfo-&gt;allocationSize);</div><div class="line"><a name="l08287"></a><span class="lineno"> 8287</span>&#160;    }</div><div class="line"><a name="l08288"></a><span class="lineno"> 8288</span>&#160;</div><div class="line"><a name="l08289"></a><span class="lineno"> 8289</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l08290"></a><span class="lineno"> 8290</span>&#160;}</div><div class="line"><a name="l08291"></a><span class="lineno"> 8291</span>&#160;</div><div class="line"><a name="l08292"></a><span class="lineno"> 8292</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory)</div><div class="line"><a name="l08293"></a><span class="lineno"> 8293</span>&#160;{</div><div class="line"><a name="l08294"></a><span class="lineno"> 8294</span>&#160;    <span class="keywordflow">if</span>(m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a> != VMA_NULL)</div><div class="line"><a name="l08295"></a><span class="lineno"> 8295</span>&#160;    {</div><div class="line"><a name="l08296"></a><span class="lineno"> 8296</span>&#160;        (*m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a>)(<span class="keyword">this</span>, memoryType, hMemory, size);</div><div class="line"><a name="l08297"></a><span class="lineno"> 8297</span>&#160;    }</div><div class="line"><a name="l08298"></a><span class="lineno"> 8298</span>&#160;</div><div class="line"><a name="l08299"></a><span class="lineno"> 8299</span>&#160;    (*m_VulkanFunctions.vkFreeMemory)(m_hDevice, hMemory, GetAllocationCallbacks());</div><div class="line"><a name="l08300"></a><span class="lineno"> 8300</span>&#160;</div><div class="line"><a name="l08301"></a><span class="lineno"> 8301</span>&#160;    <span class="keyword">const</span> uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memoryType);</div><div class="line"><a name="l08302"></a><span class="lineno"> 8302</span>&#160;    <span class="keywordflow">if</span>(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE)</div><div class="line"><a name="l08303"></a><span class="lineno"> 8303</span>&#160;    {</div><div class="line"><a name="l08304"></a><span class="lineno"> 8304</span>&#160;        VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex);</div><div class="line"><a name="l08305"></a><span class="lineno"> 8305</span>&#160;        m_HeapSizeLimit[heapIndex] += size;</div><div class="line"><a name="l08306"></a><span class="lineno"> 8306</span>&#160;    }</div><div class="line"><a name="l08307"></a><span class="lineno"> 8307</span>&#160;}</div><div class="line"><a name="l08308"></a><span class="lineno"> 8308</span>&#160;</div><div class="line"><a name="l08309"></a><span class="lineno"> 8309</span>&#160;VkResult VmaAllocator_T::Map(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l08310"></a><span class="lineno"> 8310</span>&#160;{</div><div class="line"><a name="l08311"></a><span class="lineno"> 8311</span>&#160;    <span class="keywordflow">if</span>(hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l08312"></a><span class="lineno"> 8312</span>&#160;    {</div><div class="line"><a name="l08313"></a><span class="lineno"> 8313</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_MEMORY_MAP_FAILED;</div><div class="line"><a name="l08314"></a><span class="lineno"> 8314</span>&#160;    }</div><div class="line"><a name="l08315"></a><span class="lineno"> 8315</span>&#160;</div><div class="line"><a name="l08316"></a><span class="lineno"> 8316</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l08317"></a><span class="lineno"> 8317</span>&#160;    {</div><div class="line"><a name="l08318"></a><span class="lineno"> 8318</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l08319"></a><span class="lineno"> 8319</span>&#160;        {</div><div class="line"><a name="l08320"></a><span class="lineno"> 8320</span>&#160;            VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l08321"></a><span class="lineno"> 8321</span>&#160;            <span class="keywordtype">char</span> *pBytes = VMA_NULL;</div><div class="line"><a name="l08322"></a><span class="lineno"> 8322</span>&#160;            VkResult res = pBlock-&gt;Map(<span class="keyword">this</span>, 1, (<span class="keywordtype">void</span>**)&amp;pBytes);</div><div class="line"><a name="l08323"></a><span class="lineno"> 8323</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l08324"></a><span class="lineno"> 8324</span>&#160;            {</div><div class="line"><a name="l08325"></a><span class="lineno"> 8325</span>&#160;                *ppData = pBytes + (ptrdiff_t)hAllocation-&gt;GetOffset();</div><div class="line"><a name="l08326"></a><span class="lineno"> 8326</span>&#160;                hAllocation-&gt;BlockAllocMap();</div><div class="line"><a name="l08327"></a><span class="lineno"> 8327</span>&#160;            }</div><div class="line"><a name="l08328"></a><span class="lineno"> 8328</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l08329"></a><span class="lineno"> 8329</span>&#160;        }</div><div class="line"><a name="l08330"></a><span class="lineno"> 8330</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l08331"></a><span class="lineno"> 8331</span>&#160;        <span class="keywordflow">return</span> hAllocation-&gt;DedicatedAllocMap(<span class="keyword">this</span>, ppData);</div><div class="line"><a name="l08332"></a><span class="lineno"> 8332</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l08333"></a><span class="lineno"> 8333</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l08334"></a><span class="lineno"> 8334</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_MEMORY_MAP_FAILED;</div><div class="line"><a name="l08335"></a><span class="lineno"> 8335</span>&#160;    }</div><div class="line"><a name="l08336"></a><span class="lineno"> 8336</span>&#160;}</div><div class="line"><a name="l08337"></a><span class="lineno"> 8337</span>&#160;</div><div class="line"><a name="l08338"></a><span class="lineno"> 8338</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::Unmap(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l08339"></a><span class="lineno"> 8339</span>&#160;{</div><div class="line"><a name="l08340"></a><span class="lineno"> 8340</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l08341"></a><span class="lineno"> 8341</span>&#160;    {</div><div class="line"><a name="l08342"></a><span class="lineno"> 8342</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l08343"></a><span class="lineno"> 8343</span>&#160;        {</div><div class="line"><a name="l08344"></a><span class="lineno"> 8344</span>&#160;            VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l08345"></a><span class="lineno"> 8345</span>&#160;            hAllocation-&gt;BlockAllocUnmap();</div><div class="line"><a name="l08346"></a><span class="lineno"> 8346</span>&#160;            pBlock-&gt;Unmap(<span class="keyword">this</span>, 1);</div><div class="line"><a name="l08347"></a><span class="lineno"> 8347</span>&#160;        }</div><div class="line"><a name="l08348"></a><span class="lineno"> 8348</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08349"></a><span class="lineno"> 8349</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l08350"></a><span class="lineno"> 8350</span>&#160;        hAllocation-&gt;DedicatedAllocUnmap(<span class="keyword">this</span>);</div><div class="line"><a name="l08351"></a><span class="lineno"> 8351</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08352"></a><span class="lineno"> 8352</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l08353"></a><span class="lineno"> 8353</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l08354"></a><span class="lineno"> 8354</span>&#160;    }</div><div class="line"><a name="l08355"></a><span class="lineno"> 8355</span>&#160;}</div><div class="line"><a name="l08356"></a><span class="lineno"> 8356</span>&#160;</div><div class="line"><a name="l08357"></a><span class="lineno"> 8357</span>&#160;VkResult VmaAllocator_T::BindBufferMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkBuffer hBuffer)</div><div class="line"><a name="l08358"></a><span class="lineno"> 8358</span>&#160;{</div><div class="line"><a name="l08359"></a><span class="lineno"> 8359</span>&#160;    VkResult res = VK_SUCCESS;</div><div class="line"><a name="l08360"></a><span class="lineno"> 8360</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l08361"></a><span class="lineno"> 8361</span>&#160;    {</div><div class="line"><a name="l08362"></a><span class="lineno"> 8362</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l08363"></a><span class="lineno"> 8363</span>&#160;        res = GetVulkanFunctions().vkBindBufferMemory(</div><div class="line"><a name="l08364"></a><span class="lineno"> 8364</span>&#160;            m_hDevice,</div><div class="line"><a name="l08365"></a><span class="lineno"> 8365</span>&#160;            hBuffer,</div><div class="line"><a name="l08366"></a><span class="lineno"> 8366</span>&#160;            hAllocation-&gt;GetMemory(),</div><div class="line"><a name="l08367"></a><span class="lineno"> 8367</span>&#160;            0); <span class="comment">//memoryOffset</span></div><div class="line"><a name="l08368"></a><span class="lineno"> 8368</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08369"></a><span class="lineno"> 8369</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l08370"></a><span class="lineno"> 8370</span>&#160;    {</div><div class="line"><a name="l08371"></a><span class="lineno"> 8371</span>&#160;        VmaDeviceMemoryBlock* pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l08372"></a><span class="lineno"> 8372</span>&#160;        VMA_ASSERT(pBlock &amp;&amp; <span class="stringliteral">&quot;Binding buffer to allocation that doesn&#39;t belong to any block. Is the allocation lost?&quot;</span>);</div><div class="line"><a name="l08373"></a><span class="lineno"> 8373</span>&#160;        res = pBlock-&gt;BindBufferMemory(<span class="keyword">this</span>, hAllocation, hBuffer);</div><div class="line"><a name="l08374"></a><span class="lineno"> 8374</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08375"></a><span class="lineno"> 8375</span>&#160;    }</div><div class="line"><a name="l08376"></a><span class="lineno"> 8376</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l08377"></a><span class="lineno"> 8377</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l08378"></a><span class="lineno"> 8378</span>&#160;    }</div><div class="line"><a name="l08379"></a><span class="lineno"> 8379</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l08380"></a><span class="lineno"> 8380</span>&#160;}</div><div class="line"><a name="l08381"></a><span class="lineno"> 8381</span>&#160;</div><div class="line"><a name="l08382"></a><span class="lineno"> 8382</span>&#160;VkResult VmaAllocator_T::BindImageMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkImage hImage)</div><div class="line"><a name="l08383"></a><span class="lineno"> 8383</span>&#160;{</div><div class="line"><a name="l08384"></a><span class="lineno"> 8384</span>&#160;    VkResult res = VK_SUCCESS;</div><div class="line"><a name="l08385"></a><span class="lineno"> 8385</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l08386"></a><span class="lineno"> 8386</span>&#160;    {</div><div class="line"><a name="l08387"></a><span class="lineno"> 8387</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l08388"></a><span class="lineno"> 8388</span>&#160;        res = GetVulkanFunctions().vkBindImageMemory(</div><div class="line"><a name="l08389"></a><span class="lineno"> 8389</span>&#160;            m_hDevice,</div><div class="line"><a name="l08390"></a><span class="lineno"> 8390</span>&#160;            hImage,</div><div class="line"><a name="l08391"></a><span class="lineno"> 8391</span>&#160;            hAllocation-&gt;GetMemory(),</div><div class="line"><a name="l08392"></a><span class="lineno"> 8392</span>&#160;            0); <span class="comment">//memoryOffset</span></div><div class="line"><a name="l08393"></a><span class="lineno"> 8393</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08394"></a><span class="lineno"> 8394</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l08395"></a><span class="lineno"> 8395</span>&#160;    {</div><div class="line"><a name="l08396"></a><span class="lineno"> 8396</span>&#160;        VmaDeviceMemoryBlock* pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l08397"></a><span class="lineno"> 8397</span>&#160;        VMA_ASSERT(pBlock &amp;&amp; <span class="stringliteral">&quot;Binding image to allocation that doesn&#39;t belong to any block. Is the allocation lost?&quot;</span>);</div><div class="line"><a name="l08398"></a><span class="lineno"> 8398</span>&#160;        res = pBlock-&gt;BindImageMemory(<span class="keyword">this</span>, hAllocation, hImage);</div><div class="line"><a name="l08399"></a><span class="lineno"> 8399</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08400"></a><span class="lineno"> 8400</span>&#160;    }</div><div class="line"><a name="l08401"></a><span class="lineno"> 8401</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l08402"></a><span class="lineno"> 8402</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l08403"></a><span class="lineno"> 8403</span>&#160;    }</div><div class="line"><a name="l08404"></a><span class="lineno"> 8404</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l08405"></a><span class="lineno"> 8405</span>&#160;}</div><div class="line"><a name="l08406"></a><span class="lineno"> 8406</span>&#160;</div><div class="line"><a name="l08407"></a><span class="lineno"> 8407</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FreeDedicatedMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l08408"></a><span class="lineno"> 8408</span>&#160;{</div><div class="line"><a name="l08409"></a><span class="lineno"> 8409</span>&#160;    VMA_ASSERT(allocation &amp;&amp; allocation-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l08410"></a><span class="lineno"> 8410</span>&#160;</div><div class="line"><a name="l08411"></a><span class="lineno"> 8411</span>&#160;    <span class="keyword">const</span> uint32_t memTypeIndex = allocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l08412"></a><span class="lineno"> 8412</span>&#160;    {</div><div class="line"><a name="l08413"></a><span class="lineno"> 8413</span>&#160;        VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l08414"></a><span class="lineno"> 8414</span>&#160;        AllocationVectorType* <span class="keyword">const</span> pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l08415"></a><span class="lineno"> 8415</span>&#160;        VMA_ASSERT(pDedicatedAllocations);</div><div class="line"><a name="l08416"></a><span class="lineno"> 8416</span>&#160;        <span class="keywordtype">bool</span> success = VmaVectorRemoveSorted&lt;VmaPointerLess&gt;(*pDedicatedAllocations, allocation);</div><div class="line"><a name="l08417"></a><span class="lineno"> 8417</span>&#160;        VMA_ASSERT(success);</div><div class="line"><a name="l08418"></a><span class="lineno"> 8418</span>&#160;    }</div><div class="line"><a name="l08419"></a><span class="lineno"> 8419</span>&#160;</div><div class="line"><a name="l08420"></a><span class="lineno"> 8420</span>&#160;    VkDeviceMemory hMemory = allocation-&gt;GetMemory();</div><div class="line"><a name="l08421"></a><span class="lineno"> 8421</span>&#160;    </div><div class="line"><a name="l08422"></a><span class="lineno"> 8422</span>&#160;    <span class="keywordflow">if</span>(allocation-&gt;GetMappedData() != VMA_NULL)</div><div class="line"><a name="l08423"></a><span class="lineno"> 8423</span>&#160;    {</div><div class="line"><a name="l08424"></a><span class="lineno"> 8424</span>&#160;        (*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory);</div><div class="line"><a name="l08425"></a><span class="lineno"> 8425</span>&#160;    }</div><div class="line"><a name="l08426"></a><span class="lineno"> 8426</span>&#160;    </div><div class="line"><a name="l08427"></a><span class="lineno"> 8427</span>&#160;    FreeVulkanMemory(memTypeIndex, allocation-&gt;GetSize(), hMemory);</div><div class="line"><a name="l08428"></a><span class="lineno"> 8428</span>&#160;</div><div class="line"><a name="l08429"></a><span class="lineno"> 8429</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Freed DedicatedMemory MemoryTypeIndex=%u&quot;</span>, memTypeIndex);</div><div class="line"><a name="l08430"></a><span class="lineno"> 8430</span>&#160;}</div><div class="line"><a name="l08431"></a><span class="lineno"> 8431</span>&#160;</div><div class="line"><a name="l08432"></a><span class="lineno"> 8432</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l08433"></a><span class="lineno"> 8433</span>&#160;</div><div class="line"><a name="l08434"></a><span class="lineno"> 8434</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::PrintDetailedMap(VmaJsonWriter&amp; json)</div><div class="line"><a name="l08435"></a><span class="lineno"> 8435</span>&#160;{</div><div class="line"><a name="l08436"></a><span class="lineno"> 8436</span>&#160;    <span class="keywordtype">bool</span> dedicatedAllocationsStarted = <span class="keyword">false</span>;</div><div class="line"><a name="l08437"></a><span class="lineno"> 8437</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l08438"></a><span class="lineno"> 8438</span>&#160;    {</div><div class="line"><a name="l08439"></a><span class="lineno"> 8439</span>&#160;        VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l08440"></a><span class="lineno"> 8440</span>&#160;        AllocationVectorType* <span class="keyword">const</span> pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l08441"></a><span class="lineno"> 8441</span>&#160;        VMA_ASSERT(pDedicatedAllocVector);</div><div class="line"><a name="l08442"></a><span class="lineno"> 8442</span>&#160;        <span class="keywordflow">if</span>(pDedicatedAllocVector-&gt;empty() == <span class="keyword">false</span>)</div><div class="line"><a name="l08443"></a><span class="lineno"> 8443</span>&#160;        {</div><div class="line"><a name="l08444"></a><span class="lineno"> 8444</span>&#160;            <span class="keywordflow">if</span>(dedicatedAllocationsStarted == <span class="keyword">false</span>)</div><div class="line"><a name="l08445"></a><span class="lineno"> 8445</span>&#160;            {</div><div class="line"><a name="l08446"></a><span class="lineno"> 8446</span>&#160;                dedicatedAllocationsStarted = <span class="keyword">true</span>;</div><div class="line"><a name="l08447"></a><span class="lineno"> 8447</span>&#160;                json.WriteString(<span class="stringliteral">&quot;DedicatedAllocations&quot;</span>);</div><div class="line"><a name="l08448"></a><span class="lineno"> 8448</span>&#160;                json.BeginObject();</div><div class="line"><a name="l08449"></a><span class="lineno"> 8449</span>&#160;            }</div><div class="line"><a name="l08450"></a><span class="lineno"> 8450</span>&#160;</div><div class="line"><a name="l08451"></a><span class="lineno"> 8451</span>&#160;            json.BeginString(<span class="stringliteral">&quot;Type &quot;</span>);</div><div class="line"><a name="l08452"></a><span class="lineno"> 8452</span>&#160;            json.ContinueString(memTypeIndex);</div><div class="line"><a name="l08453"></a><span class="lineno"> 8453</span>&#160;            json.EndString();</div><div class="line"><a name="l08454"></a><span class="lineno"> 8454</span>&#160;                </div><div class="line"><a name="l08455"></a><span class="lineno"> 8455</span>&#160;            json.BeginArray();</div><div class="line"><a name="l08456"></a><span class="lineno"> 8456</span>&#160;</div><div class="line"><a name="l08457"></a><span class="lineno"> 8457</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; pDedicatedAllocVector-&gt;size(); ++i)</div><div class="line"><a name="l08458"></a><span class="lineno"> 8458</span>&#160;            {</div><div class="line"><a name="l08459"></a><span class="lineno"> 8459</span>&#160;                <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc = (*pDedicatedAllocVector)[i];</div><div class="line"><a name="l08460"></a><span class="lineno"> 8460</span>&#160;                json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l08461"></a><span class="lineno"> 8461</span>&#160;                    </div><div class="line"><a name="l08462"></a><span class="lineno"> 8462</span>&#160;                json.WriteString(<span class="stringliteral">&quot;Type&quot;</span>);</div><div class="line"><a name="l08463"></a><span class="lineno"> 8463</span>&#160;                json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[hAlloc-&gt;GetSuballocationType()]);</div><div class="line"><a name="l08464"></a><span class="lineno"> 8464</span>&#160;</div><div class="line"><a name="l08465"></a><span class="lineno"> 8465</span>&#160;                json.WriteString(<span class="stringliteral">&quot;Size&quot;</span>);</div><div class="line"><a name="l08466"></a><span class="lineno"> 8466</span>&#160;                json.WriteNumber(hAlloc-&gt;GetSize());</div><div class="line"><a name="l08467"></a><span class="lineno"> 8467</span>&#160;</div><div class="line"><a name="l08468"></a><span class="lineno"> 8468</span>&#160;                <span class="keyword">const</span> <span class="keywordtype">void</span>* pUserData = hAlloc-&gt;GetUserData();</div><div class="line"><a name="l08469"></a><span class="lineno"> 8469</span>&#160;                <span class="keywordflow">if</span>(pUserData != VMA_NULL)</div><div class="line"><a name="l08470"></a><span class="lineno"> 8470</span>&#160;                {</div><div class="line"><a name="l08471"></a><span class="lineno"> 8471</span>&#160;                    json.WriteString(<span class="stringliteral">&quot;UserData&quot;</span>);</div><div class="line"><a name="l08472"></a><span class="lineno"> 8472</span>&#160;                    <span class="keywordflow">if</span>(hAlloc-&gt;IsUserDataString())</div><div class="line"><a name="l08473"></a><span class="lineno"> 8473</span>&#160;                    {</div><div class="line"><a name="l08474"></a><span class="lineno"> 8474</span>&#160;                        json.WriteString((<span class="keyword">const</span> <span class="keywordtype">char</span>*)pUserData);</div><div class="line"><a name="l08475"></a><span class="lineno"> 8475</span>&#160;                    }</div><div class="line"><a name="l08476"></a><span class="lineno"> 8476</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l08477"></a><span class="lineno"> 8477</span>&#160;                    {</div><div class="line"><a name="l08478"></a><span class="lineno"> 8478</span>&#160;                        json.BeginString();</div><div class="line"><a name="l08479"></a><span class="lineno"> 8479</span>&#160;                        json.ContinueString_Pointer(pUserData);</div><div class="line"><a name="l08480"></a><span class="lineno"> 8480</span>&#160;                        json.EndString();</div><div class="line"><a name="l08481"></a><span class="lineno"> 8481</span>&#160;                    }</div><div class="line"><a name="l08482"></a><span class="lineno"> 8482</span>&#160;                }</div><div class="line"><a name="l08483"></a><span class="lineno"> 8483</span>&#160;</div><div class="line"><a name="l08484"></a><span class="lineno"> 8484</span>&#160;                json.EndObject();</div><div class="line"><a name="l08485"></a><span class="lineno"> 8485</span>&#160;            }</div><div class="line"><a name="l08486"></a><span class="lineno"> 8486</span>&#160;</div><div class="line"><a name="l08487"></a><span class="lineno"> 8487</span>&#160;            json.EndArray();</div><div class="line"><a name="l08488"></a><span class="lineno"> 8488</span>&#160;        }</div><div class="line"><a name="l08489"></a><span class="lineno"> 8489</span>&#160;    }</div><div class="line"><a name="l08490"></a><span class="lineno"> 8490</span>&#160;    <span class="keywordflow">if</span>(dedicatedAllocationsStarted)</div><div class="line"><a name="l08491"></a><span class="lineno"> 8491</span>&#160;    {</div><div class="line"><a name="l08492"></a><span class="lineno"> 8492</span>&#160;        json.EndObject();</div><div class="line"><a name="l08493"></a><span class="lineno"> 8493</span>&#160;    }</div><div class="line"><a name="l08494"></a><span class="lineno"> 8494</span>&#160;</div><div class="line"><a name="l08495"></a><span class="lineno"> 8495</span>&#160;    {</div><div class="line"><a name="l08496"></a><span class="lineno"> 8496</span>&#160;        <span class="keywordtype">bool</span> allocationsStarted = <span class="keyword">false</span>;</div><div class="line"><a name="l08497"></a><span class="lineno"> 8497</span>&#160;        <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l08498"></a><span class="lineno"> 8498</span>&#160;        {</div><div class="line"><a name="l08499"></a><span class="lineno"> 8499</span>&#160;            <span class="keywordflow">if</span>(m_pBlockVectors[memTypeIndex]-&gt;IsEmpty() == <span class="keyword">false</span>)</div><div class="line"><a name="l08500"></a><span class="lineno"> 8500</span>&#160;            {</div><div class="line"><a name="l08501"></a><span class="lineno"> 8501</span>&#160;                <span class="keywordflow">if</span>(allocationsStarted == <span class="keyword">false</span>)</div><div class="line"><a name="l08502"></a><span class="lineno"> 8502</span>&#160;                {</div><div class="line"><a name="l08503"></a><span class="lineno"> 8503</span>&#160;                    allocationsStarted = <span class="keyword">true</span>;</div><div class="line"><a name="l08504"></a><span class="lineno"> 8504</span>&#160;                    json.WriteString(<span class="stringliteral">&quot;DefaultPools&quot;</span>);</div><div class="line"><a name="l08505"></a><span class="lineno"> 8505</span>&#160;                    json.BeginObject();</div><div class="line"><a name="l08506"></a><span class="lineno"> 8506</span>&#160;                }</div><div class="line"><a name="l08507"></a><span class="lineno"> 8507</span>&#160;</div><div class="line"><a name="l08508"></a><span class="lineno"> 8508</span>&#160;                json.BeginString(<span class="stringliteral">&quot;Type &quot;</span>);</div><div class="line"><a name="l08509"></a><span class="lineno"> 8509</span>&#160;                json.ContinueString(memTypeIndex);</div><div class="line"><a name="l08510"></a><span class="lineno"> 8510</span>&#160;                json.EndString();</div><div class="line"><a name="l08511"></a><span class="lineno"> 8511</span>&#160;</div><div class="line"><a name="l08512"></a><span class="lineno"> 8512</span>&#160;                m_pBlockVectors[memTypeIndex]-&gt;PrintDetailedMap(json);</div><div class="line"><a name="l08513"></a><span class="lineno"> 8513</span>&#160;            }</div><div class="line"><a name="l08514"></a><span class="lineno"> 8514</span>&#160;        }</div><div class="line"><a name="l08515"></a><span class="lineno"> 8515</span>&#160;        <span class="keywordflow">if</span>(allocationsStarted)</div><div class="line"><a name="l08516"></a><span class="lineno"> 8516</span>&#160;        {</div><div class="line"><a name="l08517"></a><span class="lineno"> 8517</span>&#160;            json.EndObject();</div><div class="line"><a name="l08518"></a><span class="lineno"> 8518</span>&#160;        }</div><div class="line"><a name="l08519"></a><span class="lineno"> 8519</span>&#160;    }</div><div class="line"><a name="l08520"></a><span class="lineno"> 8520</span>&#160;</div><div class="line"><a name="l08521"></a><span class="lineno"> 8521</span>&#160;    {</div><div class="line"><a name="l08522"></a><span class="lineno"> 8522</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l08523"></a><span class="lineno"> 8523</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> poolCount = m_Pools.size();</div><div class="line"><a name="l08524"></a><span class="lineno"> 8524</span>&#160;        <span class="keywordflow">if</span>(poolCount &gt; 0)</div><div class="line"><a name="l08525"></a><span class="lineno"> 8525</span>&#160;        {</div><div class="line"><a name="l08526"></a><span class="lineno"> 8526</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Pools&quot;</span>);</div><div class="line"><a name="l08527"></a><span class="lineno"> 8527</span>&#160;            json.BeginArray();</div><div class="line"><a name="l08528"></a><span class="lineno"> 8528</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = 0; poolIndex &lt; poolCount; ++poolIndex)</div><div class="line"><a name="l08529"></a><span class="lineno"> 8529</span>&#160;            {</div><div class="line"><a name="l08530"></a><span class="lineno"> 8530</span>&#160;                m_Pools[poolIndex]-&gt;m_BlockVector.PrintDetailedMap(json);</div><div class="line"><a name="l08531"></a><span class="lineno"> 8531</span>&#160;            }</div><div class="line"><a name="l08532"></a><span class="lineno"> 8532</span>&#160;            json.EndArray();</div><div class="line"><a name="l08533"></a><span class="lineno"> 8533</span>&#160;        }</div><div class="line"><a name="l08534"></a><span class="lineno"> 8534</span>&#160;    }</div><div class="line"><a name="l08535"></a><span class="lineno"> 8535</span>&#160;}</div><div class="line"><a name="l08536"></a><span class="lineno"> 8536</span>&#160;</div><div class="line"><a name="l08537"></a><span class="lineno"> 8537</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l08538"></a><span class="lineno"> 8538</span>&#160;</div><div class="line"><a name="l08539"></a><span class="lineno"> 8539</span>&#160;<span class="keyword">static</span> VkResult AllocateMemoryForImage(</div><div class="line"><a name="l08540"></a><span class="lineno"> 8540</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08541"></a><span class="lineno"> 8541</span>&#160;    VkImage image,</div><div class="line"><a name="l08542"></a><span class="lineno"> 8542</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l08543"></a><span class="lineno"> 8543</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l08544"></a><span class="lineno"> 8544</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l08545"></a><span class="lineno"> 8545</span>&#160;{</div><div class="line"><a name="l08546"></a><span class="lineno"> 8546</span>&#160;    VMA_ASSERT(allocator &amp;&amp; (image != VK_NULL_HANDLE) &amp;&amp; pAllocationCreateInfo &amp;&amp; pAllocation);</div><div class="line"><a name="l08547"></a><span class="lineno"> 8547</span>&#160;    </div><div class="line"><a name="l08548"></a><span class="lineno"> 8548</span>&#160;    VkMemoryRequirements vkMemReq = {};</div><div class="line"><a name="l08549"></a><span class="lineno"> 8549</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l08550"></a><span class="lineno"> 8550</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l08551"></a><span class="lineno"> 8551</span>&#160;    allocator-&gt;GetImageMemoryRequirements(image, vkMemReq,</div><div class="line"><a name="l08552"></a><span class="lineno"> 8552</span>&#160;        requiresDedicatedAllocation, prefersDedicatedAllocation);</div><div class="line"><a name="l08553"></a><span class="lineno"> 8553</span>&#160;</div><div class="line"><a name="l08554"></a><span class="lineno"> 8554</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;AllocateMemory(</div><div class="line"><a name="l08555"></a><span class="lineno"> 8555</span>&#160;        vkMemReq,</div><div class="line"><a name="l08556"></a><span class="lineno"> 8556</span>&#160;        requiresDedicatedAllocation,</div><div class="line"><a name="l08557"></a><span class="lineno"> 8557</span>&#160;        prefersDedicatedAllocation,</div><div class="line"><a name="l08558"></a><span class="lineno"> 8558</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l08559"></a><span class="lineno"> 8559</span>&#160;        image, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l08560"></a><span class="lineno"> 8560</span>&#160;        *pAllocationCreateInfo,</div><div class="line"><a name="l08561"></a><span class="lineno"> 8561</span>&#160;        suballocType,</div><div class="line"><a name="l08562"></a><span class="lineno"> 8562</span>&#160;        pAllocation);</div><div class="line"><a name="l08563"></a><span class="lineno"> 8563</span>&#160;}</div><div class="line"><a name="l08564"></a><span class="lineno"> 8564</span>&#160;</div><div class="line"><a name="l08566"></a><span class="lineno"> 8566</span>&#160;<span class="comment">// Public interface</span></div><div class="line"><a name="l08567"></a><span class="lineno"> 8567</span>&#160;</div><div class="line"><a name="l08568"></a><span class="lineno"> 8568</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a>(</div><div class="line"><a name="l08569"></a><span class="lineno"> 8569</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l08570"></a><span class="lineno"> 8570</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>* pAllocator)</div><div class="line"><a name="l08571"></a><span class="lineno"> 8571</span>&#160;{</div><div class="line"><a name="l08572"></a><span class="lineno"> 8572</span>&#160;    VMA_ASSERT(pCreateInfo &amp;&amp; pAllocator);</div><div class="line"><a name="l08573"></a><span class="lineno"> 8573</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreateAllocator&quot;</span>);</div><div class="line"><a name="l08574"></a><span class="lineno"> 8574</span>&#160;    *pAllocator = vma_new(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">pAllocationCallbacks</a>, VmaAllocator_T)(pCreateInfo);</div><div class="line"><a name="l08575"></a><span class="lineno"> 8575</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l08576"></a><span class="lineno"> 8576</span>&#160;}</div><div class="line"><a name="l08577"></a><span class="lineno"> 8577</span>&#160;</div><div class="line"><a name="l08578"></a><span class="lineno"> 8578</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa8d164061c88f22fb1fd3c8f3534bc1d">vmaDestroyAllocator</a>(</div><div class="line"><a name="l08579"></a><span class="lineno"> 8579</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator)</div><div class="line"><a name="l08580"></a><span class="lineno"> 8580</span>&#160;{</div><div class="line"><a name="l08581"></a><span class="lineno"> 8581</span>&#160;    <span class="keywordflow">if</span>(allocator != VK_NULL_HANDLE)</div><div class="line"><a name="l08582"></a><span class="lineno"> 8582</span>&#160;    {</div><div class="line"><a name="l08583"></a><span class="lineno"> 8583</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyAllocator&quot;</span>);</div><div class="line"><a name="l08584"></a><span class="lineno"> 8584</span>&#160;        VkAllocationCallbacks allocationCallbacks = allocator-&gt;m_AllocationCallbacks;</div><div class="line"><a name="l08585"></a><span class="lineno"> 8585</span>&#160;        vma_delete(&amp;allocationCallbacks, allocator);</div><div class="line"><a name="l08586"></a><span class="lineno"> 8586</span>&#160;    }</div><div class="line"><a name="l08587"></a><span class="lineno"> 8587</span>&#160;}</div><div class="line"><a name="l08588"></a><span class="lineno"> 8588</span>&#160;</div><div class="line"><a name="l08589"></a><span class="lineno"> 8589</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aecabf7b6e91ea87d0316fa0a9e014fe0">vmaGetPhysicalDeviceProperties</a>(</div><div class="line"><a name="l08590"></a><span class="lineno"> 8590</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08591"></a><span class="lineno"> 8591</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)</div><div class="line"><a name="l08592"></a><span class="lineno"> 8592</span>&#160;{</div><div class="line"><a name="l08593"></a><span class="lineno"> 8593</span>&#160;    VMA_ASSERT(allocator &amp;&amp; ppPhysicalDeviceProperties);</div><div class="line"><a name="l08594"></a><span class="lineno"> 8594</span>&#160;    *ppPhysicalDeviceProperties = &amp;allocator-&gt;m_PhysicalDeviceProperties;</div><div class="line"><a name="l08595"></a><span class="lineno"> 8595</span>&#160;}</div><div class="line"><a name="l08596"></a><span class="lineno"> 8596</span>&#160;</div><div class="line"><a name="l08597"></a><span class="lineno"> 8597</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ab88db292a17974f911182543fda52d19">vmaGetMemoryProperties</a>(</div><div class="line"><a name="l08598"></a><span class="lineno"> 8598</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08599"></a><span class="lineno"> 8599</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties)</div><div class="line"><a name="l08600"></a><span class="lineno"> 8600</span>&#160;{</div><div class="line"><a name="l08601"></a><span class="lineno"> 8601</span>&#160;    VMA_ASSERT(allocator &amp;&amp; ppPhysicalDeviceMemoryProperties);</div><div class="line"><a name="l08602"></a><span class="lineno"> 8602</span>&#160;    *ppPhysicalDeviceMemoryProperties = &amp;allocator-&gt;m_MemProps;</div><div class="line"><a name="l08603"></a><span class="lineno"> 8603</span>&#160;}</div><div class="line"><a name="l08604"></a><span class="lineno"> 8604</span>&#160;</div><div class="line"><a name="l08605"></a><span class="lineno"> 8605</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(</div><div class="line"><a name="l08606"></a><span class="lineno"> 8606</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08607"></a><span class="lineno"> 8607</span>&#160;    uint32_t memoryTypeIndex,</div><div class="line"><a name="l08608"></a><span class="lineno"> 8608</span>&#160;    VkMemoryPropertyFlags* pFlags)</div><div class="line"><a name="l08609"></a><span class="lineno"> 8609</span>&#160;{</div><div class="line"><a name="l08610"></a><span class="lineno"> 8610</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pFlags);</div><div class="line"><a name="l08611"></a><span class="lineno"> 8611</span>&#160;    VMA_ASSERT(memoryTypeIndex &lt; allocator-&gt;GetMemoryTypeCount());</div><div class="line"><a name="l08612"></a><span class="lineno"> 8612</span>&#160;    *pFlags = allocator-&gt;m_MemProps.memoryTypes[memoryTypeIndex].propertyFlags;</div><div class="line"><a name="l08613"></a><span class="lineno"> 8613</span>&#160;}</div><div class="line"><a name="l08614"></a><span class="lineno"> 8614</span>&#160;</div><div class="line"><a name="l08615"></a><span class="lineno"> 8615</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236">vmaSetCurrentFrameIndex</a>(</div><div class="line"><a name="l08616"></a><span class="lineno"> 8616</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08617"></a><span class="lineno"> 8617</span>&#160;    uint32_t frameIndex)</div><div class="line"><a name="l08618"></a><span class="lineno"> 8618</span>&#160;{</div><div class="line"><a name="l08619"></a><span class="lineno"> 8619</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l08620"></a><span class="lineno"> 8620</span>&#160;    VMA_ASSERT(frameIndex != VMA_FRAME_INDEX_LOST);</div><div class="line"><a name="l08621"></a><span class="lineno"> 8621</span>&#160;</div><div class="line"><a name="l08622"></a><span class="lineno"> 8622</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08623"></a><span class="lineno"> 8623</span>&#160;</div><div class="line"><a name="l08624"></a><span class="lineno"> 8624</span>&#160;    allocator-&gt;SetCurrentFrameIndex(frameIndex);</div><div class="line"><a name="l08625"></a><span class="lineno"> 8625</span>&#160;}</div><div class="line"><a name="l08626"></a><span class="lineno"> 8626</span>&#160;</div><div class="line"><a name="l08627"></a><span class="lineno"> 8627</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3">vmaCalculateStats</a>(</div><div class="line"><a name="l08628"></a><span class="lineno"> 8628</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08629"></a><span class="lineno"> 8629</span>&#160;    <a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats)</div><div class="line"><a name="l08630"></a><span class="lineno"> 8630</span>&#160;{</div><div class="line"><a name="l08631"></a><span class="lineno"> 8631</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pStats);</div><div class="line"><a name="l08632"></a><span class="lineno"> 8632</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08633"></a><span class="lineno"> 8633</span>&#160;    allocator-&gt;CalculateStats(pStats);</div><div class="line"><a name="l08634"></a><span class="lineno"> 8634</span>&#160;}</div><div class="line"><a name="l08635"></a><span class="lineno"> 8635</span>&#160;</div><div class="line"><a name="l08636"></a><span class="lineno"> 8636</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l08637"></a><span class="lineno"> 8637</span>&#160;</div><div class="line"><a name="l08638"></a><span class="lineno"> 8638</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0">vmaBuildStatsString</a>(</div><div class="line"><a name="l08639"></a><span class="lineno"> 8639</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08640"></a><span class="lineno"> 8640</span>&#160;    <span class="keywordtype">char</span>** ppStatsString,</div><div class="line"><a name="l08641"></a><span class="lineno"> 8641</span>&#160;    VkBool32 detailedMap)</div><div class="line"><a name="l08642"></a><span class="lineno"> 8642</span>&#160;{</div><div class="line"><a name="l08643"></a><span class="lineno"> 8643</span>&#160;    VMA_ASSERT(allocator &amp;&amp; ppStatsString);</div><div class="line"><a name="l08644"></a><span class="lineno"> 8644</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08645"></a><span class="lineno"> 8645</span>&#160;</div><div class="line"><a name="l08646"></a><span class="lineno"> 8646</span>&#160;    VmaStringBuilder sb(allocator);</div><div class="line"><a name="l08647"></a><span class="lineno"> 8647</span>&#160;    {</div><div class="line"><a name="l08648"></a><span class="lineno"> 8648</span>&#160;        VmaJsonWriter json(allocator-&gt;GetAllocationCallbacks(), sb);</div><div class="line"><a name="l08649"></a><span class="lineno"> 8649</span>&#160;        json.BeginObject();</div><div class="line"><a name="l08650"></a><span class="lineno"> 8650</span>&#160;</div><div class="line"><a name="l08651"></a><span class="lineno"> 8651</span>&#160;        <a class="code" href="struct_vma_stats.html">VmaStats</a> stats;</div><div class="line"><a name="l08652"></a><span class="lineno"> 8652</span>&#160;        allocator-&gt;CalculateStats(&amp;stats);</div><div class="line"><a name="l08653"></a><span class="lineno"> 8653</span>&#160;</div><div class="line"><a name="l08654"></a><span class="lineno"> 8654</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Total&quot;</span>);</div><div class="line"><a name="l08655"></a><span class="lineno"> 8655</span>&#160;        VmaPrintStatInfo(json, stats.<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>);</div><div class="line"><a name="l08656"></a><span class="lineno"> 8656</span>&#160;    </div><div class="line"><a name="l08657"></a><span class="lineno"> 8657</span>&#160;        <span class="keywordflow">for</span>(uint32_t heapIndex = 0; heapIndex &lt; allocator-&gt;GetMemoryHeapCount(); ++heapIndex)</div><div class="line"><a name="l08658"></a><span class="lineno"> 8658</span>&#160;        {</div><div class="line"><a name="l08659"></a><span class="lineno"> 8659</span>&#160;            json.BeginString(<span class="stringliteral">&quot;Heap &quot;</span>);</div><div class="line"><a name="l08660"></a><span class="lineno"> 8660</span>&#160;            json.ContinueString(heapIndex);</div><div class="line"><a name="l08661"></a><span class="lineno"> 8661</span>&#160;            json.EndString();</div><div class="line"><a name="l08662"></a><span class="lineno"> 8662</span>&#160;            json.BeginObject();</div><div class="line"><a name="l08663"></a><span class="lineno"> 8663</span>&#160;</div><div class="line"><a name="l08664"></a><span class="lineno"> 8664</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Size&quot;</span>);</div><div class="line"><a name="l08665"></a><span class="lineno"> 8665</span>&#160;            json.WriteNumber(allocator-&gt;m_MemProps.memoryHeaps[heapIndex].size);</div><div class="line"><a name="l08666"></a><span class="lineno"> 8666</span>&#160;</div><div class="line"><a name="l08667"></a><span class="lineno"> 8667</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Flags&quot;</span>);</div><div class="line"><a name="l08668"></a><span class="lineno"> 8668</span>&#160;            json.BeginArray(<span class="keyword">true</span>);</div><div class="line"><a name="l08669"></a><span class="lineno"> 8669</span>&#160;            <span class="keywordflow">if</span>((allocator-&gt;m_MemProps.memoryHeaps[heapIndex].flags &amp; VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)</div><div class="line"><a name="l08670"></a><span class="lineno"> 8670</span>&#160;            {</div><div class="line"><a name="l08671"></a><span class="lineno"> 8671</span>&#160;                json.WriteString(<span class="stringliteral">&quot;DEVICE_LOCAL&quot;</span>);</div><div class="line"><a name="l08672"></a><span class="lineno"> 8672</span>&#160;            }</div><div class="line"><a name="l08673"></a><span class="lineno"> 8673</span>&#160;            json.EndArray();</div><div class="line"><a name="l08674"></a><span class="lineno"> 8674</span>&#160;</div><div class="line"><a name="l08675"></a><span class="lineno"> 8675</span>&#160;            <span class="keywordflow">if</span>(stats.<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[heapIndex].<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> &gt; 0)</div><div class="line"><a name="l08676"></a><span class="lineno"> 8676</span>&#160;            {</div><div class="line"><a name="l08677"></a><span class="lineno"> 8677</span>&#160;                json.WriteString(<span class="stringliteral">&quot;Stats&quot;</span>);</div><div class="line"><a name="l08678"></a><span class="lineno"> 8678</span>&#160;                VmaPrintStatInfo(json, stats.<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[heapIndex]);</div><div class="line"><a name="l08679"></a><span class="lineno"> 8679</span>&#160;            }</div><div class="line"><a name="l08680"></a><span class="lineno"> 8680</span>&#160;</div><div class="line"><a name="l08681"></a><span class="lineno"> 8681</span>&#160;            <span class="keywordflow">for</span>(uint32_t typeIndex = 0; typeIndex &lt; allocator-&gt;GetMemoryTypeCount(); ++typeIndex)</div><div class="line"><a name="l08682"></a><span class="lineno"> 8682</span>&#160;            {</div><div class="line"><a name="l08683"></a><span class="lineno"> 8683</span>&#160;                <span class="keywordflow">if</span>(allocator-&gt;MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex)</div><div class="line"><a name="l08684"></a><span class="lineno"> 8684</span>&#160;                {</div><div class="line"><a name="l08685"></a><span class="lineno"> 8685</span>&#160;                    json.BeginString(<span class="stringliteral">&quot;Type &quot;</span>);</div><div class="line"><a name="l08686"></a><span class="lineno"> 8686</span>&#160;                    json.ContinueString(typeIndex);</div><div class="line"><a name="l08687"></a><span class="lineno"> 8687</span>&#160;                    json.EndString();</div><div class="line"><a name="l08688"></a><span class="lineno"> 8688</span>&#160;</div><div class="line"><a name="l08689"></a><span class="lineno"> 8689</span>&#160;                    json.BeginObject();</div><div class="line"><a name="l08690"></a><span class="lineno"> 8690</span>&#160;</div><div class="line"><a name="l08691"></a><span class="lineno"> 8691</span>&#160;                    json.WriteString(<span class="stringliteral">&quot;Flags&quot;</span>);</div><div class="line"><a name="l08692"></a><span class="lineno"> 8692</span>&#160;                    json.BeginArray(<span class="keyword">true</span>);</div><div class="line"><a name="l08693"></a><span class="lineno"> 8693</span>&#160;                    VkMemoryPropertyFlags flags = allocator-&gt;m_MemProps.memoryTypes[typeIndex].propertyFlags;</div><div class="line"><a name="l08694"></a><span class="lineno"> 8694</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)</div><div class="line"><a name="l08695"></a><span class="lineno"> 8695</span>&#160;                    {</div><div class="line"><a name="l08696"></a><span class="lineno"> 8696</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;DEVICE_LOCAL&quot;</span>);</div><div class="line"><a name="l08697"></a><span class="lineno"> 8697</span>&#160;                    }</div><div class="line"><a name="l08698"></a><span class="lineno"> 8698</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)</div><div class="line"><a name="l08699"></a><span class="lineno"> 8699</span>&#160;                    {</div><div class="line"><a name="l08700"></a><span class="lineno"> 8700</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;HOST_VISIBLE&quot;</span>);</div><div class="line"><a name="l08701"></a><span class="lineno"> 8701</span>&#160;                    }</div><div class="line"><a name="l08702"></a><span class="lineno"> 8702</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)</div><div class="line"><a name="l08703"></a><span class="lineno"> 8703</span>&#160;                    {</div><div class="line"><a name="l08704"></a><span class="lineno"> 8704</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;HOST_COHERENT&quot;</span>);</div><div class="line"><a name="l08705"></a><span class="lineno"> 8705</span>&#160;                    }</div><div class="line"><a name="l08706"></a><span class="lineno"> 8706</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)</div><div class="line"><a name="l08707"></a><span class="lineno"> 8707</span>&#160;                    {</div><div class="line"><a name="l08708"></a><span class="lineno"> 8708</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;HOST_CACHED&quot;</span>);</div><div class="line"><a name="l08709"></a><span class="lineno"> 8709</span>&#160;                    }</div><div class="line"><a name="l08710"></a><span class="lineno"> 8710</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)</div><div class="line"><a name="l08711"></a><span class="lineno"> 8711</span>&#160;                    {</div><div class="line"><a name="l08712"></a><span class="lineno"> 8712</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;LAZILY_ALLOCATED&quot;</span>);</div><div class="line"><a name="l08713"></a><span class="lineno"> 8713</span>&#160;                    }</div><div class="line"><a name="l08714"></a><span class="lineno"> 8714</span>&#160;                    json.EndArray();</div><div class="line"><a name="l08715"></a><span class="lineno"> 8715</span>&#160;</div><div class="line"><a name="l08716"></a><span class="lineno"> 8716</span>&#160;                    <span class="keywordflow">if</span>(stats.<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[typeIndex].<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> &gt; 0)</div><div class="line"><a name="l08717"></a><span class="lineno"> 8717</span>&#160;                    {</div><div class="line"><a name="l08718"></a><span class="lineno"> 8718</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;Stats&quot;</span>);</div><div class="line"><a name="l08719"></a><span class="lineno"> 8719</span>&#160;                        VmaPrintStatInfo(json, stats.<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[typeIndex]);</div><div class="line"><a name="l08720"></a><span class="lineno"> 8720</span>&#160;                    }</div><div class="line"><a name="l08721"></a><span class="lineno"> 8721</span>&#160;</div><div class="line"><a name="l08722"></a><span class="lineno"> 8722</span>&#160;                    json.EndObject();</div><div class="line"><a name="l08723"></a><span class="lineno"> 8723</span>&#160;                }</div><div class="line"><a name="l08724"></a><span class="lineno"> 8724</span>&#160;            }</div><div class="line"><a name="l08725"></a><span class="lineno"> 8725</span>&#160;</div><div class="line"><a name="l08726"></a><span class="lineno"> 8726</span>&#160;            json.EndObject();</div><div class="line"><a name="l08727"></a><span class="lineno"> 8727</span>&#160;        }</div><div class="line"><a name="l08728"></a><span class="lineno"> 8728</span>&#160;        <span class="keywordflow">if</span>(detailedMap == VK_TRUE)</div><div class="line"><a name="l08729"></a><span class="lineno"> 8729</span>&#160;        {</div><div class="line"><a name="l08730"></a><span class="lineno"> 8730</span>&#160;            allocator-&gt;PrintDetailedMap(json);</div><div class="line"><a name="l08731"></a><span class="lineno"> 8731</span>&#160;        }</div><div class="line"><a name="l08732"></a><span class="lineno"> 8732</span>&#160;</div><div class="line"><a name="l08733"></a><span class="lineno"> 8733</span>&#160;        json.EndObject();</div><div class="line"><a name="l08734"></a><span class="lineno"> 8734</span>&#160;    }</div><div class="line"><a name="l08735"></a><span class="lineno"> 8735</span>&#160;</div><div class="line"><a name="l08736"></a><span class="lineno"> 8736</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> len = sb.GetLength();</div><div class="line"><a name="l08737"></a><span class="lineno"> 8737</span>&#160;    <span class="keywordtype">char</span>* <span class="keyword">const</span> pChars = vma_new_array(allocator, <span class="keywordtype">char</span>, len + 1);</div><div class="line"><a name="l08738"></a><span class="lineno"> 8738</span>&#160;    <span class="keywordflow">if</span>(len &gt; 0)</div><div class="line"><a name="l08739"></a><span class="lineno"> 8739</span>&#160;    {</div><div class="line"><a name="l08740"></a><span class="lineno"> 8740</span>&#160;        memcpy(pChars, sb.GetData(), len);</div><div class="line"><a name="l08741"></a><span class="lineno"> 8741</span>&#160;    }</div><div class="line"><a name="l08742"></a><span class="lineno"> 8742</span>&#160;    pChars[len] = <span class="charliteral">&#39;\0&#39;</span>;</div><div class="line"><a name="l08743"></a><span class="lineno"> 8743</span>&#160;    *ppStatsString = pChars;</div><div class="line"><a name="l08744"></a><span class="lineno"> 8744</span>&#160;}</div><div class="line"><a name="l08745"></a><span class="lineno"> 8745</span>&#160;</div><div class="line"><a name="l08746"></a><span class="lineno"> 8746</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vmaFreeStatsString</a>(</div><div class="line"><a name="l08747"></a><span class="lineno"> 8747</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08748"></a><span class="lineno"> 8748</span>&#160;    <span class="keywordtype">char</span>* pStatsString)</div><div class="line"><a name="l08749"></a><span class="lineno"> 8749</span>&#160;{</div><div class="line"><a name="l08750"></a><span class="lineno"> 8750</span>&#160;    <span class="keywordflow">if</span>(pStatsString != VMA_NULL)</div><div class="line"><a name="l08751"></a><span class="lineno"> 8751</span>&#160;    {</div><div class="line"><a name="l08752"></a><span class="lineno"> 8752</span>&#160;        VMA_ASSERT(allocator);</div><div class="line"><a name="l08753"></a><span class="lineno"> 8753</span>&#160;        <span class="keywordtype">size_t</span> len = strlen(pStatsString);</div><div class="line"><a name="l08754"></a><span class="lineno"> 8754</span>&#160;        vma_delete_array(allocator, pStatsString, len + 1);</div><div class="line"><a name="l08755"></a><span class="lineno"> 8755</span>&#160;    }</div><div class="line"><a name="l08756"></a><span class="lineno"> 8756</span>&#160;}</div><div class="line"><a name="l08757"></a><span class="lineno"> 8757</span>&#160;</div><div class="line"><a name="l08758"></a><span class="lineno"> 8758</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l08759"></a><span class="lineno"> 8759</span>&#160;</div><div class="line"><a name="l08760"></a><span class="lineno"> 8760</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l08761"></a><span class="lineno"> 8761</span>&#160;<span class="comment">This function is not protected by any mutex because it just reads immutable data.</span></div><div class="line"><a name="l08762"></a><span class="lineno"> 8762</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l08763"></a><span class="lineno"> 8763</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l08764"></a><span class="lineno"> 8764</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08765"></a><span class="lineno"> 8765</span>&#160;    uint32_t memoryTypeBits,</div><div class="line"><a name="l08766"></a><span class="lineno"> 8766</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l08767"></a><span class="lineno"> 8767</span>&#160;    uint32_t* pMemoryTypeIndex)</div><div class="line"><a name="l08768"></a><span class="lineno"> 8768</span>&#160;{</div><div class="line"><a name="l08769"></a><span class="lineno"> 8769</span>&#160;    VMA_ASSERT(allocator != VK_NULL_HANDLE);</div><div class="line"><a name="l08770"></a><span class="lineno"> 8770</span>&#160;    VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);</div><div class="line"><a name="l08771"></a><span class="lineno"> 8771</span>&#160;    VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);</div><div class="line"><a name="l08772"></a><span class="lineno"> 8772</span>&#160;</div><div class="line"><a name="l08773"></a><span class="lineno"> 8773</span>&#160;    <span class="keywordflow">if</span>(pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a> != 0)</div><div class="line"><a name="l08774"></a><span class="lineno"> 8774</span>&#160;    {</div><div class="line"><a name="l08775"></a><span class="lineno"> 8775</span>&#160;        memoryTypeBits &amp;= pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>;</div><div class="line"><a name="l08776"></a><span class="lineno"> 8776</span>&#160;    }</div><div class="line"><a name="l08777"></a><span class="lineno"> 8777</span>&#160;    </div><div class="line"><a name="l08778"></a><span class="lineno"> 8778</span>&#160;    uint32_t requiredFlags = pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>;</div><div class="line"><a name="l08779"></a><span class="lineno"> 8779</span>&#160;    uint32_t preferredFlags = pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>;</div><div class="line"><a name="l08780"></a><span class="lineno"> 8780</span>&#160;</div><div class="line"><a name="l08781"></a><span class="lineno"> 8781</span>&#160;    <span class="comment">// Convert usage to requiredFlags and preferredFlags.</span></div><div class="line"><a name="l08782"></a><span class="lineno"> 8782</span>&#160;    <span class="keywordflow">switch</span>(pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>)</div><div class="line"><a name="l08783"></a><span class="lineno"> 8783</span>&#160;    {</div><div class="line"><a name="l08784"></a><span class="lineno"> 8784</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a>:</div><div class="line"><a name="l08785"></a><span class="lineno"> 8785</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08786"></a><span class="lineno"> 8786</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>:</div><div class="line"><a name="l08787"></a><span class="lineno"> 8787</span>&#160;        preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;</div><div class="line"><a name="l08788"></a><span class="lineno"> 8788</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08789"></a><span class="lineno"> 8789</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a>:</div><div class="line"><a name="l08790"></a><span class="lineno"> 8790</span>&#160;        requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;</div><div class="line"><a name="l08791"></a><span class="lineno"> 8791</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08792"></a><span class="lineno"> 8792</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a>:</div><div class="line"><a name="l08793"></a><span class="lineno"> 8793</span>&#160;        requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;</div><div class="line"><a name="l08794"></a><span class="lineno"> 8794</span>&#160;        preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;</div><div class="line"><a name="l08795"></a><span class="lineno"> 8795</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08796"></a><span class="lineno"> 8796</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a>:</div><div class="line"><a name="l08797"></a><span class="lineno"> 8797</span>&#160;        requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;</div><div class="line"><a name="l08798"></a><span class="lineno"> 8798</span>&#160;        preferredFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;</div><div class="line"><a name="l08799"></a><span class="lineno"> 8799</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08800"></a><span class="lineno"> 8800</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l08801"></a><span class="lineno"> 8801</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08802"></a><span class="lineno"> 8802</span>&#160;    }</div><div class="line"><a name="l08803"></a><span class="lineno"> 8803</span>&#160;</div><div class="line"><a name="l08804"></a><span class="lineno"> 8804</span>&#160;    *pMemoryTypeIndex = UINT32_MAX;</div><div class="line"><a name="l08805"></a><span class="lineno"> 8805</span>&#160;    uint32_t minCost = UINT32_MAX;</div><div class="line"><a name="l08806"></a><span class="lineno"> 8806</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0, memTypeBit = 1;</div><div class="line"><a name="l08807"></a><span class="lineno"> 8807</span>&#160;        memTypeIndex &lt; allocator-&gt;GetMemoryTypeCount();</div><div class="line"><a name="l08808"></a><span class="lineno"> 8808</span>&#160;        ++memTypeIndex, memTypeBit &lt;&lt;= 1)</div><div class="line"><a name="l08809"></a><span class="lineno"> 8809</span>&#160;    {</div><div class="line"><a name="l08810"></a><span class="lineno"> 8810</span>&#160;        <span class="comment">// This memory type is acceptable according to memoryTypeBits bitmask.</span></div><div class="line"><a name="l08811"></a><span class="lineno"> 8811</span>&#160;        <span class="keywordflow">if</span>((memTypeBit &amp; memoryTypeBits) != 0)</div><div class="line"><a name="l08812"></a><span class="lineno"> 8812</span>&#160;        {</div><div class="line"><a name="l08813"></a><span class="lineno"> 8813</span>&#160;            <span class="keyword">const</span> VkMemoryPropertyFlags currFlags =</div><div class="line"><a name="l08814"></a><span class="lineno"> 8814</span>&#160;                allocator-&gt;m_MemProps.memoryTypes[memTypeIndex].propertyFlags;</div><div class="line"><a name="l08815"></a><span class="lineno"> 8815</span>&#160;            <span class="comment">// This memory type contains requiredFlags.</span></div><div class="line"><a name="l08816"></a><span class="lineno"> 8816</span>&#160;            <span class="keywordflow">if</span>((requiredFlags &amp; ~currFlags) == 0)</div><div class="line"><a name="l08817"></a><span class="lineno"> 8817</span>&#160;            {</div><div class="line"><a name="l08818"></a><span class="lineno"> 8818</span>&#160;                <span class="comment">// Calculate cost as number of bits from preferredFlags not present in this memory type.</span></div><div class="line"><a name="l08819"></a><span class="lineno"> 8819</span>&#160;                uint32_t currCost = VmaCountBitsSet(preferredFlags &amp; ~currFlags);</div><div class="line"><a name="l08820"></a><span class="lineno"> 8820</span>&#160;                <span class="comment">// Remember memory type with lowest cost.</span></div><div class="line"><a name="l08821"></a><span class="lineno"> 8821</span>&#160;                <span class="keywordflow">if</span>(currCost &lt; minCost)</div><div class="line"><a name="l08822"></a><span class="lineno"> 8822</span>&#160;                {</div><div class="line"><a name="l08823"></a><span class="lineno"> 8823</span>&#160;                    *pMemoryTypeIndex = memTypeIndex;</div><div class="line"><a name="l08824"></a><span class="lineno"> 8824</span>&#160;                    <span class="keywordflow">if</span>(currCost == 0)</div><div class="line"><a name="l08825"></a><span class="lineno"> 8825</span>&#160;                    {</div><div class="line"><a name="l08826"></a><span class="lineno"> 8826</span>&#160;                        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l08827"></a><span class="lineno"> 8827</span>&#160;                    }</div><div class="line"><a name="l08828"></a><span class="lineno"> 8828</span>&#160;                    minCost = currCost;</div><div class="line"><a name="l08829"></a><span class="lineno"> 8829</span>&#160;                }</div><div class="line"><a name="l08830"></a><span class="lineno"> 8830</span>&#160;            }</div><div class="line"><a name="l08831"></a><span class="lineno"> 8831</span>&#160;        }</div><div class="line"><a name="l08832"></a><span class="lineno"> 8832</span>&#160;    }</div><div class="line"><a name="l08833"></a><span class="lineno"> 8833</span>&#160;    <span class="keywordflow">return</span> (*pMemoryTypeIndex != UINT32_MAX) ? VK_SUCCESS : VK_ERROR_FEATURE_NOT_PRESENT;</div><div class="line"><a name="l08834"></a><span class="lineno"> 8834</span>&#160;}</div><div class="line"><a name="l08835"></a><span class="lineno"> 8835</span>&#160;</div><div class="line"><a name="l08836"></a><span class="lineno"> 8836</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(</div><div class="line"><a name="l08837"></a><span class="lineno"> 8837</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08838"></a><span class="lineno"> 8838</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l08839"></a><span class="lineno"> 8839</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l08840"></a><span class="lineno"> 8840</span>&#160;    uint32_t* pMemoryTypeIndex)</div><div class="line"><a name="l08841"></a><span class="lineno"> 8841</span>&#160;{</div><div class="line"><a name="l08842"></a><span class="lineno"> 8842</span>&#160;    VMA_ASSERT(allocator != VK_NULL_HANDLE);</div><div class="line"><a name="l08843"></a><span class="lineno"> 8843</span>&#160;    VMA_ASSERT(pBufferCreateInfo != VMA_NULL);</div><div class="line"><a name="l08844"></a><span class="lineno"> 8844</span>&#160;    VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);</div><div class="line"><a name="l08845"></a><span class="lineno"> 8845</span>&#160;    VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);</div><div class="line"><a name="l08846"></a><span class="lineno"> 8846</span>&#160;</div><div class="line"><a name="l08847"></a><span class="lineno"> 8847</span>&#160;    <span class="keyword">const</span> VkDevice hDev = allocator-&gt;m_hDevice;</div><div class="line"><a name="l08848"></a><span class="lineno"> 8848</span>&#160;    VkBuffer hBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l08849"></a><span class="lineno"> 8849</span>&#160;    VkResult res = allocator-&gt;GetVulkanFunctions().vkCreateBuffer(</div><div class="line"><a name="l08850"></a><span class="lineno"> 8850</span>&#160;        hDev, pBufferCreateInfo, allocator-&gt;GetAllocationCallbacks(), &amp;hBuffer);</div><div class="line"><a name="l08851"></a><span class="lineno"> 8851</span>&#160;    <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l08852"></a><span class="lineno"> 8852</span>&#160;    {</div><div class="line"><a name="l08853"></a><span class="lineno"> 8853</span>&#160;        VkMemoryRequirements memReq = {};</div><div class="line"><a name="l08854"></a><span class="lineno"> 8854</span>&#160;        allocator-&gt;GetVulkanFunctions().vkGetBufferMemoryRequirements(</div><div class="line"><a name="l08855"></a><span class="lineno"> 8855</span>&#160;            hDev, hBuffer, &amp;memReq);</div><div class="line"><a name="l08856"></a><span class="lineno"> 8856</span>&#160;</div><div class="line"><a name="l08857"></a><span class="lineno"> 8857</span>&#160;        res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l08858"></a><span class="lineno"> 8858</span>&#160;            allocator,</div><div class="line"><a name="l08859"></a><span class="lineno"> 8859</span>&#160;            memReq.memoryTypeBits,</div><div class="line"><a name="l08860"></a><span class="lineno"> 8860</span>&#160;            pAllocationCreateInfo,</div><div class="line"><a name="l08861"></a><span class="lineno"> 8861</span>&#160;            pMemoryTypeIndex);</div><div class="line"><a name="l08862"></a><span class="lineno"> 8862</span>&#160;</div><div class="line"><a name="l08863"></a><span class="lineno"> 8863</span>&#160;        allocator-&gt;GetVulkanFunctions().vkDestroyBuffer(</div><div class="line"><a name="l08864"></a><span class="lineno"> 8864</span>&#160;            hDev, hBuffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l08865"></a><span class="lineno"> 8865</span>&#160;    }</div><div class="line"><a name="l08866"></a><span class="lineno"> 8866</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l08867"></a><span class="lineno"> 8867</span>&#160;}</div><div class="line"><a name="l08868"></a><span class="lineno"> 8868</span>&#160;</div><div class="line"><a name="l08869"></a><span class="lineno"> 8869</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472">vmaFindMemoryTypeIndexForImageInfo</a>(</div><div class="line"><a name="l08870"></a><span class="lineno"> 8870</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08871"></a><span class="lineno"> 8871</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l08872"></a><span class="lineno"> 8872</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l08873"></a><span class="lineno"> 8873</span>&#160;    uint32_t* pMemoryTypeIndex)</div><div class="line"><a name="l08874"></a><span class="lineno"> 8874</span>&#160;{</div><div class="line"><a name="l08875"></a><span class="lineno"> 8875</span>&#160;    VMA_ASSERT(allocator != VK_NULL_HANDLE);</div><div class="line"><a name="l08876"></a><span class="lineno"> 8876</span>&#160;    VMA_ASSERT(pImageCreateInfo != VMA_NULL);</div><div class="line"><a name="l08877"></a><span class="lineno"> 8877</span>&#160;    VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);</div><div class="line"><a name="l08878"></a><span class="lineno"> 8878</span>&#160;    VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);</div><div class="line"><a name="l08879"></a><span class="lineno"> 8879</span>&#160;</div><div class="line"><a name="l08880"></a><span class="lineno"> 8880</span>&#160;    <span class="keyword">const</span> VkDevice hDev = allocator-&gt;m_hDevice;</div><div class="line"><a name="l08881"></a><span class="lineno"> 8881</span>&#160;    VkImage hImage = VK_NULL_HANDLE;</div><div class="line"><a name="l08882"></a><span class="lineno"> 8882</span>&#160;    VkResult res = allocator-&gt;GetVulkanFunctions().vkCreateImage(</div><div class="line"><a name="l08883"></a><span class="lineno"> 8883</span>&#160;        hDev, pImageCreateInfo, allocator-&gt;GetAllocationCallbacks(), &amp;hImage);</div><div class="line"><a name="l08884"></a><span class="lineno"> 8884</span>&#160;    <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l08885"></a><span class="lineno"> 8885</span>&#160;    {</div><div class="line"><a name="l08886"></a><span class="lineno"> 8886</span>&#160;        VkMemoryRequirements memReq = {};</div><div class="line"><a name="l08887"></a><span class="lineno"> 8887</span>&#160;        allocator-&gt;GetVulkanFunctions().vkGetImageMemoryRequirements(</div><div class="line"><a name="l08888"></a><span class="lineno"> 8888</span>&#160;            hDev, hImage, &amp;memReq);</div><div class="line"><a name="l08889"></a><span class="lineno"> 8889</span>&#160;</div><div class="line"><a name="l08890"></a><span class="lineno"> 8890</span>&#160;        res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l08891"></a><span class="lineno"> 8891</span>&#160;            allocator,</div><div class="line"><a name="l08892"></a><span class="lineno"> 8892</span>&#160;            memReq.memoryTypeBits,</div><div class="line"><a name="l08893"></a><span class="lineno"> 8893</span>&#160;            pAllocationCreateInfo,</div><div class="line"><a name="l08894"></a><span class="lineno"> 8894</span>&#160;            pMemoryTypeIndex);</div><div class="line"><a name="l08895"></a><span class="lineno"> 8895</span>&#160;</div><div class="line"><a name="l08896"></a><span class="lineno"> 8896</span>&#160;        allocator-&gt;GetVulkanFunctions().vkDestroyImage(</div><div class="line"><a name="l08897"></a><span class="lineno"> 8897</span>&#160;            hDev, hImage, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l08898"></a><span class="lineno"> 8898</span>&#160;    }</div><div class="line"><a name="l08899"></a><span class="lineno"> 8899</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l08900"></a><span class="lineno"> 8900</span>&#160;}</div><div class="line"><a name="l08901"></a><span class="lineno"> 8901</span>&#160;</div><div class="line"><a name="l08902"></a><span class="lineno"> 8902</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(</div><div class="line"><a name="l08903"></a><span class="lineno"> 8903</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08904"></a><span class="lineno"> 8904</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l08905"></a><span class="lineno"> 8905</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool)</div><div class="line"><a name="l08906"></a><span class="lineno"> 8906</span>&#160;{</div><div class="line"><a name="l08907"></a><span class="lineno"> 8907</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pCreateInfo &amp;&amp; pPool);</div><div class="line"><a name="l08908"></a><span class="lineno"> 8908</span>&#160;</div><div class="line"><a name="l08909"></a><span class="lineno"> 8909</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreatePool&quot;</span>);</div><div class="line"><a name="l08910"></a><span class="lineno"> 8910</span>&#160;</div><div class="line"><a name="l08911"></a><span class="lineno"> 8911</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08912"></a><span class="lineno"> 8912</span>&#160;</div><div class="line"><a name="l08913"></a><span class="lineno"> 8913</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;CreatePool(pCreateInfo, pPool);</div><div class="line"><a name="l08914"></a><span class="lineno"> 8914</span>&#160;}</div><div class="line"><a name="l08915"></a><span class="lineno"> 8915</span>&#160;</div><div class="line"><a name="l08916"></a><span class="lineno"> 8916</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a>(</div><div class="line"><a name="l08917"></a><span class="lineno"> 8917</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08918"></a><span class="lineno"> 8918</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l08919"></a><span class="lineno"> 8919</span>&#160;{</div><div class="line"><a name="l08920"></a><span class="lineno"> 8920</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l08921"></a><span class="lineno"> 8921</span>&#160;</div><div class="line"><a name="l08922"></a><span class="lineno"> 8922</span>&#160;    <span class="keywordflow">if</span>(pool == VK_NULL_HANDLE)</div><div class="line"><a name="l08923"></a><span class="lineno"> 8923</span>&#160;    {</div><div class="line"><a name="l08924"></a><span class="lineno"> 8924</span>&#160;        <span class="keywordflow">return</span>;</div><div class="line"><a name="l08925"></a><span class="lineno"> 8925</span>&#160;    }</div><div class="line"><a name="l08926"></a><span class="lineno"> 8926</span>&#160;</div><div class="line"><a name="l08927"></a><span class="lineno"> 8927</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyPool&quot;</span>);</div><div class="line"><a name="l08928"></a><span class="lineno"> 8928</span>&#160;</div><div class="line"><a name="l08929"></a><span class="lineno"> 8929</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08930"></a><span class="lineno"> 8930</span>&#160;</div><div class="line"><a name="l08931"></a><span class="lineno"> 8931</span>&#160;    allocator-&gt;DestroyPool(pool);</div><div class="line"><a name="l08932"></a><span class="lineno"> 8932</span>&#160;}</div><div class="line"><a name="l08933"></a><span class="lineno"> 8933</span>&#160;</div><div class="line"><a name="l08934"></a><span class="lineno"> 8934</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153">vmaGetPoolStats</a>(</div><div class="line"><a name="l08935"></a><span class="lineno"> 8935</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08936"></a><span class="lineno"> 8936</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l08937"></a><span class="lineno"> 8937</span>&#160;    <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats)</div><div class="line"><a name="l08938"></a><span class="lineno"> 8938</span>&#160;{</div><div class="line"><a name="l08939"></a><span class="lineno"> 8939</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pool &amp;&amp; pPoolStats);</div><div class="line"><a name="l08940"></a><span class="lineno"> 8940</span>&#160;</div><div class="line"><a name="l08941"></a><span class="lineno"> 8941</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08942"></a><span class="lineno"> 8942</span>&#160;</div><div class="line"><a name="l08943"></a><span class="lineno"> 8943</span>&#160;    allocator-&gt;GetPoolStats(pool, pPoolStats);</div><div class="line"><a name="l08944"></a><span class="lineno"> 8944</span>&#160;}</div><div class="line"><a name="l08945"></a><span class="lineno"> 8945</span>&#160;</div><div class="line"><a name="l08946"></a><span class="lineno"> 8946</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vmaMakePoolAllocationsLost</a>(</div><div class="line"><a name="l08947"></a><span class="lineno"> 8947</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08948"></a><span class="lineno"> 8948</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l08949"></a><span class="lineno"> 8949</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount)</div><div class="line"><a name="l08950"></a><span class="lineno"> 8950</span>&#160;{</div><div class="line"><a name="l08951"></a><span class="lineno"> 8951</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pool);</div><div class="line"><a name="l08952"></a><span class="lineno"> 8952</span>&#160;</div><div class="line"><a name="l08953"></a><span class="lineno"> 8953</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08954"></a><span class="lineno"> 8954</span>&#160;</div><div class="line"><a name="l08955"></a><span class="lineno"> 8955</span>&#160;    allocator-&gt;MakePoolAllocationsLost(pool, pLostAllocationCount);</div><div class="line"><a name="l08956"></a><span class="lineno"> 8956</span>&#160;}</div><div class="line"><a name="l08957"></a><span class="lineno"> 8957</span>&#160;</div><div class="line"><a name="l08958"></a><span class="lineno"> 8958</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a>(</div><div class="line"><a name="l08959"></a><span class="lineno"> 8959</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08960"></a><span class="lineno"> 8960</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements* pVkMemoryRequirements,</div><div class="line"><a name="l08961"></a><span class="lineno"> 8961</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l08962"></a><span class="lineno"> 8962</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l08963"></a><span class="lineno"> 8963</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l08964"></a><span class="lineno"> 8964</span>&#160;{</div><div class="line"><a name="l08965"></a><span class="lineno"> 8965</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pVkMemoryRequirements &amp;&amp; pCreateInfo &amp;&amp; pAllocation);</div><div class="line"><a name="l08966"></a><span class="lineno"> 8966</span>&#160;</div><div class="line"><a name="l08967"></a><span class="lineno"> 8967</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaAllocateMemory&quot;</span>);</div><div class="line"><a name="l08968"></a><span class="lineno"> 8968</span>&#160;</div><div class="line"><a name="l08969"></a><span class="lineno"> 8969</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l08970"></a><span class="lineno"> 8970</span>&#160;</div><div class="line"><a name="l08971"></a><span class="lineno"> 8971</span>&#160;    VkResult result = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l08972"></a><span class="lineno"> 8972</span>&#160;        *pVkMemoryRequirements,</div><div class="line"><a name="l08973"></a><span class="lineno"> 8973</span>&#160;        <span class="keyword">false</span>, <span class="comment">// requiresDedicatedAllocation</span></div><div class="line"><a name="l08974"></a><span class="lineno"> 8974</span>&#160;        <span class="keyword">false</span>, <span class="comment">// prefersDedicatedAllocation</span></div><div class="line"><a name="l08975"></a><span class="lineno"> 8975</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l08976"></a><span class="lineno"> 8976</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l08977"></a><span class="lineno"> 8977</span>&#160;        *pCreateInfo,</div><div class="line"><a name="l08978"></a><span class="lineno"> 8978</span>&#160;        VMA_SUBALLOCATION_TYPE_UNKNOWN,</div><div class="line"><a name="l08979"></a><span class="lineno"> 8979</span>&#160;        pAllocation);</div><div class="line"><a name="l08980"></a><span class="lineno"> 8980</span>&#160;</div><div class="line"><a name="l08981"></a><span class="lineno"> 8981</span>&#160;    <span class="keywordflow">if</span>(pAllocationInfo &amp;&amp; result == VK_SUCCESS)</div><div class="line"><a name="l08982"></a><span class="lineno"> 8982</span>&#160;    {</div><div class="line"><a name="l08983"></a><span class="lineno"> 8983</span>&#160;        allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l08984"></a><span class="lineno"> 8984</span>&#160;    }</div><div class="line"><a name="l08985"></a><span class="lineno"> 8985</span>&#160;</div><div class="line"><a name="l08986"></a><span class="lineno"> 8986</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l08987"></a><span class="lineno"> 8987</span>&#160;}</div><div class="line"><a name="l08988"></a><span class="lineno"> 8988</span>&#160;</div><div class="line"><a name="l08989"></a><span class="lineno"> 8989</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer</a>(</div><div class="line"><a name="l08990"></a><span class="lineno"> 8990</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l08991"></a><span class="lineno"> 8991</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l08992"></a><span class="lineno"> 8992</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l08993"></a><span class="lineno"> 8993</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l08994"></a><span class="lineno"> 8994</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l08995"></a><span class="lineno"> 8995</span>&#160;{</div><div class="line"><a name="l08996"></a><span class="lineno"> 8996</span>&#160;    VMA_ASSERT(allocator &amp;&amp; buffer != VK_NULL_HANDLE &amp;&amp; pCreateInfo &amp;&amp; pAllocation);</div><div class="line"><a name="l08997"></a><span class="lineno"> 8997</span>&#160;</div><div class="line"><a name="l08998"></a><span class="lineno"> 8998</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaAllocateMemoryForBuffer&quot;</span>);</div><div class="line"><a name="l08999"></a><span class="lineno"> 8999</span>&#160;</div><div class="line"><a name="l09000"></a><span class="lineno"> 9000</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09001"></a><span class="lineno"> 9001</span>&#160;</div><div class="line"><a name="l09002"></a><span class="lineno"> 9002</span>&#160;    VkMemoryRequirements vkMemReq = {};</div><div class="line"><a name="l09003"></a><span class="lineno"> 9003</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l09004"></a><span class="lineno"> 9004</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l09005"></a><span class="lineno"> 9005</span>&#160;    allocator-&gt;GetBufferMemoryRequirements(buffer, vkMemReq,</div><div class="line"><a name="l09006"></a><span class="lineno"> 9006</span>&#160;        requiresDedicatedAllocation,</div><div class="line"><a name="l09007"></a><span class="lineno"> 9007</span>&#160;        prefersDedicatedAllocation);</div><div class="line"><a name="l09008"></a><span class="lineno"> 9008</span>&#160;</div><div class="line"><a name="l09009"></a><span class="lineno"> 9009</span>&#160;    VkResult result = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l09010"></a><span class="lineno"> 9010</span>&#160;        vkMemReq,</div><div class="line"><a name="l09011"></a><span class="lineno"> 9011</span>&#160;        requiresDedicatedAllocation,</div><div class="line"><a name="l09012"></a><span class="lineno"> 9012</span>&#160;        prefersDedicatedAllocation,</div><div class="line"><a name="l09013"></a><span class="lineno"> 9013</span>&#160;        buffer, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l09014"></a><span class="lineno"> 9014</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l09015"></a><span class="lineno"> 9015</span>&#160;        *pCreateInfo,</div><div class="line"><a name="l09016"></a><span class="lineno"> 9016</span>&#160;        VMA_SUBALLOCATION_TYPE_BUFFER,</div><div class="line"><a name="l09017"></a><span class="lineno"> 9017</span>&#160;        pAllocation);</div><div class="line"><a name="l09018"></a><span class="lineno"> 9018</span>&#160;</div><div class="line"><a name="l09019"></a><span class="lineno"> 9019</span>&#160;    <span class="keywordflow">if</span>(pAllocationInfo &amp;&amp; result == VK_SUCCESS)</div><div class="line"><a name="l09020"></a><span class="lineno"> 9020</span>&#160;    {</div><div class="line"><a name="l09021"></a><span class="lineno"> 9021</span>&#160;        allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l09022"></a><span class="lineno"> 9022</span>&#160;    }</div><div class="line"><a name="l09023"></a><span class="lineno"> 9023</span>&#160;</div><div class="line"><a name="l09024"></a><span class="lineno"> 9024</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l09025"></a><span class="lineno"> 9025</span>&#160;}</div><div class="line"><a name="l09026"></a><span class="lineno"> 9026</span>&#160;</div><div class="line"><a name="l09027"></a><span class="lineno"> 9027</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vmaAllocateMemoryForImage</a>(</div><div class="line"><a name="l09028"></a><span class="lineno"> 9028</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09029"></a><span class="lineno"> 9029</span>&#160;    VkImage image,</div><div class="line"><a name="l09030"></a><span class="lineno"> 9030</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l09031"></a><span class="lineno"> 9031</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l09032"></a><span class="lineno"> 9032</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l09033"></a><span class="lineno"> 9033</span>&#160;{</div><div class="line"><a name="l09034"></a><span class="lineno"> 9034</span>&#160;    VMA_ASSERT(allocator &amp;&amp; image != VK_NULL_HANDLE &amp;&amp; pCreateInfo &amp;&amp; pAllocation);</div><div class="line"><a name="l09035"></a><span class="lineno"> 9035</span>&#160;</div><div class="line"><a name="l09036"></a><span class="lineno"> 9036</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaAllocateMemoryForImage&quot;</span>);</div><div class="line"><a name="l09037"></a><span class="lineno"> 9037</span>&#160;</div><div class="line"><a name="l09038"></a><span class="lineno"> 9038</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09039"></a><span class="lineno"> 9039</span>&#160;</div><div class="line"><a name="l09040"></a><span class="lineno"> 9040</span>&#160;    VkResult result = AllocateMemoryForImage(</div><div class="line"><a name="l09041"></a><span class="lineno"> 9041</span>&#160;        allocator,</div><div class="line"><a name="l09042"></a><span class="lineno"> 9042</span>&#160;        image,</div><div class="line"><a name="l09043"></a><span class="lineno"> 9043</span>&#160;        pCreateInfo,</div><div class="line"><a name="l09044"></a><span class="lineno"> 9044</span>&#160;        VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,</div><div class="line"><a name="l09045"></a><span class="lineno"> 9045</span>&#160;        pAllocation);</div><div class="line"><a name="l09046"></a><span class="lineno"> 9046</span>&#160;</div><div class="line"><a name="l09047"></a><span class="lineno"> 9047</span>&#160;    <span class="keywordflow">if</span>(pAllocationInfo &amp;&amp; result == VK_SUCCESS)</div><div class="line"><a name="l09048"></a><span class="lineno"> 9048</span>&#160;    {</div><div class="line"><a name="l09049"></a><span class="lineno"> 9049</span>&#160;        allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l09050"></a><span class="lineno"> 9050</span>&#160;    }</div><div class="line"><a name="l09051"></a><span class="lineno"> 9051</span>&#160;</div><div class="line"><a name="l09052"></a><span class="lineno"> 9052</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l09053"></a><span class="lineno"> 9053</span>&#160;}</div><div class="line"><a name="l09054"></a><span class="lineno"> 9054</span>&#160;</div><div class="line"><a name="l09055"></a><span class="lineno"> 9055</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vmaFreeMemory</a>(</div><div class="line"><a name="l09056"></a><span class="lineno"> 9056</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09057"></a><span class="lineno"> 9057</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l09058"></a><span class="lineno"> 9058</span>&#160;{</div><div class="line"><a name="l09059"></a><span class="lineno"> 9059</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l09060"></a><span class="lineno"> 9060</span>&#160;</div><div class="line"><a name="l09061"></a><span class="lineno"> 9061</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaFreeMemory&quot;</span>);</div><div class="line"><a name="l09062"></a><span class="lineno"> 9062</span>&#160;</div><div class="line"><a name="l09063"></a><span class="lineno"> 9063</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09064"></a><span class="lineno"> 9064</span>&#160;</div><div class="line"><a name="l09065"></a><span class="lineno"> 9065</span>&#160;    allocator-&gt;FreeMemory(allocation);</div><div class="line"><a name="l09066"></a><span class="lineno"> 9066</span>&#160;}</div><div class="line"><a name="l09067"></a><span class="lineno"> 9067</span>&#160;</div><div class="line"><a name="l09068"></a><span class="lineno"> 9068</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(</div><div class="line"><a name="l09069"></a><span class="lineno"> 9069</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09070"></a><span class="lineno"> 9070</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l09071"></a><span class="lineno"> 9071</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l09072"></a><span class="lineno"> 9072</span>&#160;{</div><div class="line"><a name="l09073"></a><span class="lineno"> 9073</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; pAllocationInfo);</div><div class="line"><a name="l09074"></a><span class="lineno"> 9074</span>&#160;</div><div class="line"><a name="l09075"></a><span class="lineno"> 9075</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09076"></a><span class="lineno"> 9076</span>&#160;</div><div class="line"><a name="l09077"></a><span class="lineno"> 9077</span>&#160;    allocator-&gt;GetAllocationInfo(allocation, pAllocationInfo);</div><div class="line"><a name="l09078"></a><span class="lineno"> 9078</span>&#160;}</div><div class="line"><a name="l09079"></a><span class="lineno"> 9079</span>&#160;</div><div class="line"><a name="l09080"></a><span class="lineno"> 9080</span>&#160;VkBool32 <a class="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(</div><div class="line"><a name="l09081"></a><span class="lineno"> 9081</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09082"></a><span class="lineno"> 9082</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l09083"></a><span class="lineno"> 9083</span>&#160;{</div><div class="line"><a name="l09084"></a><span class="lineno"> 9084</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l09085"></a><span class="lineno"> 9085</span>&#160;</div><div class="line"><a name="l09086"></a><span class="lineno"> 9086</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09087"></a><span class="lineno"> 9087</span>&#160;</div><div class="line"><a name="l09088"></a><span class="lineno"> 9088</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;TouchAllocation(allocation);</div><div class="line"><a name="l09089"></a><span class="lineno"> 9089</span>&#160;}</div><div class="line"><a name="l09090"></a><span class="lineno"> 9090</span>&#160;</div><div class="line"><a name="l09091"></a><span class="lineno"> 9091</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f">vmaSetAllocationUserData</a>(</div><div class="line"><a name="l09092"></a><span class="lineno"> 9092</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09093"></a><span class="lineno"> 9093</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l09094"></a><span class="lineno"> 9094</span>&#160;    <span class="keywordtype">void</span>* pUserData)</div><div class="line"><a name="l09095"></a><span class="lineno"> 9095</span>&#160;{</div><div class="line"><a name="l09096"></a><span class="lineno"> 9096</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l09097"></a><span class="lineno"> 9097</span>&#160;</div><div class="line"><a name="l09098"></a><span class="lineno"> 9098</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09099"></a><span class="lineno"> 9099</span>&#160;</div><div class="line"><a name="l09100"></a><span class="lineno"> 9100</span>&#160;    allocation-&gt;SetUserData(allocator, pUserData);</div><div class="line"><a name="l09101"></a><span class="lineno"> 9101</span>&#160;}</div><div class="line"><a name="l09102"></a><span class="lineno"> 9102</span>&#160;</div><div class="line"><a name="l09103"></a><span class="lineno"> 9103</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae5c9657d9e94756269145b01c05d16f1">vmaCreateLostAllocation</a>(</div><div class="line"><a name="l09104"></a><span class="lineno"> 9104</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09105"></a><span class="lineno"> 9105</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l09106"></a><span class="lineno"> 9106</span>&#160;{</div><div class="line"><a name="l09107"></a><span class="lineno"> 9107</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pAllocation);</div><div class="line"><a name="l09108"></a><span class="lineno"> 9108</span>&#160;</div><div class="line"><a name="l09109"></a><span class="lineno"> 9109</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK;</div><div class="line"><a name="l09110"></a><span class="lineno"> 9110</span>&#160;</div><div class="line"><a name="l09111"></a><span class="lineno"> 9111</span>&#160;    allocator-&gt;CreateLostAllocation(pAllocation);</div><div class="line"><a name="l09112"></a><span class="lineno"> 9112</span>&#160;}</div><div class="line"><a name="l09113"></a><span class="lineno"> 9113</span>&#160;</div><div class="line"><a name="l09114"></a><span class="lineno"> 9114</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(</div><div class="line"><a name="l09115"></a><span class="lineno"> 9115</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09116"></a><span class="lineno"> 9116</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l09117"></a><span class="lineno"> 9117</span>&#160;    <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l09118"></a><span class="lineno"> 9118</span>&#160;{</div><div class="line"><a name="l09119"></a><span class="lineno"> 9119</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; ppData);</div><div class="line"><a name="l09120"></a><span class="lineno"> 9120</span>&#160;</div><div class="line"><a name="l09121"></a><span class="lineno"> 9121</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09122"></a><span class="lineno"> 9122</span>&#160;</div><div class="line"><a name="l09123"></a><span class="lineno"> 9123</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;Map(allocation, ppData);</div><div class="line"><a name="l09124"></a><span class="lineno"> 9124</span>&#160;}</div><div class="line"><a name="l09125"></a><span class="lineno"> 9125</span>&#160;</div><div class="line"><a name="l09126"></a><span class="lineno"> 9126</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(</div><div class="line"><a name="l09127"></a><span class="lineno"> 9127</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09128"></a><span class="lineno"> 9128</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l09129"></a><span class="lineno"> 9129</span>&#160;{</div><div class="line"><a name="l09130"></a><span class="lineno"> 9130</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l09131"></a><span class="lineno"> 9131</span>&#160;</div><div class="line"><a name="l09132"></a><span class="lineno"> 9132</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09133"></a><span class="lineno"> 9133</span>&#160;</div><div class="line"><a name="l09134"></a><span class="lineno"> 9134</span>&#160;    allocator-&gt;Unmap(allocation);</div><div class="line"><a name="l09135"></a><span class="lineno"> 9135</span>&#160;}</div><div class="line"><a name="l09136"></a><span class="lineno"> 9136</span>&#160;</div><div class="line"><a name="l09137"></a><span class="lineno"> 9137</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a>(</div><div class="line"><a name="l09138"></a><span class="lineno"> 9138</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09139"></a><span class="lineno"> 9139</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l09140"></a><span class="lineno"> 9140</span>&#160;    <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l09141"></a><span class="lineno"> 9141</span>&#160;    VkBool32* pAllocationsChanged,</div><div class="line"><a name="l09142"></a><span class="lineno"> 9142</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *pDefragmentationInfo,</div><div class="line"><a name="l09143"></a><span class="lineno"> 9143</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats)</div><div class="line"><a name="l09144"></a><span class="lineno"> 9144</span>&#160;{</div><div class="line"><a name="l09145"></a><span class="lineno"> 9145</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pAllocations);</div><div class="line"><a name="l09146"></a><span class="lineno"> 9146</span>&#160;</div><div class="line"><a name="l09147"></a><span class="lineno"> 9147</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDefragment&quot;</span>);</div><div class="line"><a name="l09148"></a><span class="lineno"> 9148</span>&#160;</div><div class="line"><a name="l09149"></a><span class="lineno"> 9149</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09150"></a><span class="lineno"> 9150</span>&#160;</div><div class="line"><a name="l09151"></a><span class="lineno"> 9151</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;Defragment(pAllocations, allocationCount, pAllocationsChanged, pDefragmentationInfo, pDefragmentationStats);</div><div class="line"><a name="l09152"></a><span class="lineno"> 9152</span>&#160;}</div><div class="line"><a name="l09153"></a><span class="lineno"> 9153</span>&#160;</div><div class="line"><a name="l09154"></a><span class="lineno"> 9154</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vmaBindBufferMemory</a>(</div><div class="line"><a name="l09155"></a><span class="lineno"> 9155</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09156"></a><span class="lineno"> 9156</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l09157"></a><span class="lineno"> 9157</span>&#160;    VkBuffer buffer)</div><div class="line"><a name="l09158"></a><span class="lineno"> 9158</span>&#160;{</div><div class="line"><a name="l09159"></a><span class="lineno"> 9159</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; buffer);</div><div class="line"><a name="l09160"></a><span class="lineno"> 9160</span>&#160;</div><div class="line"><a name="l09161"></a><span class="lineno"> 9161</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaBindBufferMemory&quot;</span>);</div><div class="line"><a name="l09162"></a><span class="lineno"> 9162</span>&#160;</div><div class="line"><a name="l09163"></a><span class="lineno"> 9163</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09164"></a><span class="lineno"> 9164</span>&#160;</div><div class="line"><a name="l09165"></a><span class="lineno"> 9165</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;BindBufferMemory(allocation, buffer);</div><div class="line"><a name="l09166"></a><span class="lineno"> 9166</span>&#160;}</div><div class="line"><a name="l09167"></a><span class="lineno"> 9167</span>&#160;</div><div class="line"><a name="l09168"></a><span class="lineno"> 9168</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vmaBindImageMemory</a>(</div><div class="line"><a name="l09169"></a><span class="lineno"> 9169</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09170"></a><span class="lineno"> 9170</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l09171"></a><span class="lineno"> 9171</span>&#160;    VkImage image)</div><div class="line"><a name="l09172"></a><span class="lineno"> 9172</span>&#160;{</div><div class="line"><a name="l09173"></a><span class="lineno"> 9173</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; image);</div><div class="line"><a name="l09174"></a><span class="lineno"> 9174</span>&#160;</div><div class="line"><a name="l09175"></a><span class="lineno"> 9175</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaBindImageMemory&quot;</span>);</div><div class="line"><a name="l09176"></a><span class="lineno"> 9176</span>&#160;</div><div class="line"><a name="l09177"></a><span class="lineno"> 9177</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09178"></a><span class="lineno"> 9178</span>&#160;</div><div class="line"><a name="l09179"></a><span class="lineno"> 9179</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;BindImageMemory(allocation, image);</div><div class="line"><a name="l09180"></a><span class="lineno"> 9180</span>&#160;}</div><div class="line"><a name="l09181"></a><span class="lineno"> 9181</span>&#160;</div><div class="line"><a name="l09182"></a><span class="lineno"> 9182</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(</div><div class="line"><a name="l09183"></a><span class="lineno"> 9183</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09184"></a><span class="lineno"> 9184</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l09185"></a><span class="lineno"> 9185</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l09186"></a><span class="lineno"> 9186</span>&#160;    VkBuffer* pBuffer,</div><div class="line"><a name="l09187"></a><span class="lineno"> 9187</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l09188"></a><span class="lineno"> 9188</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l09189"></a><span class="lineno"> 9189</span>&#160;{</div><div class="line"><a name="l09190"></a><span class="lineno"> 9190</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pBufferCreateInfo &amp;&amp; pAllocationCreateInfo &amp;&amp; pBuffer &amp;&amp; pAllocation);</div><div class="line"><a name="l09191"></a><span class="lineno"> 9191</span>&#160;    </div><div class="line"><a name="l09192"></a><span class="lineno"> 9192</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreateBuffer&quot;</span>);</div><div class="line"><a name="l09193"></a><span class="lineno"> 9193</span>&#160;    </div><div class="line"><a name="l09194"></a><span class="lineno"> 9194</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09195"></a><span class="lineno"> 9195</span>&#160;</div><div class="line"><a name="l09196"></a><span class="lineno"> 9196</span>&#160;    *pBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l09197"></a><span class="lineno"> 9197</span>&#160;    *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l09198"></a><span class="lineno"> 9198</span>&#160;</div><div class="line"><a name="l09199"></a><span class="lineno"> 9199</span>&#160;    <span class="comment">// 1. Create VkBuffer.</span></div><div class="line"><a name="l09200"></a><span class="lineno"> 9200</span>&#160;    VkResult res = (*allocator-&gt;GetVulkanFunctions().vkCreateBuffer)(</div><div class="line"><a name="l09201"></a><span class="lineno"> 9201</span>&#160;        allocator-&gt;m_hDevice,</div><div class="line"><a name="l09202"></a><span class="lineno"> 9202</span>&#160;        pBufferCreateInfo,</div><div class="line"><a name="l09203"></a><span class="lineno"> 9203</span>&#160;        allocator-&gt;GetAllocationCallbacks(),</div><div class="line"><a name="l09204"></a><span class="lineno"> 9204</span>&#160;        pBuffer);</div><div class="line"><a name="l09205"></a><span class="lineno"> 9205</span>&#160;    <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l09206"></a><span class="lineno"> 9206</span>&#160;    {</div><div class="line"><a name="l09207"></a><span class="lineno"> 9207</span>&#160;        <span class="comment">// 2. vkGetBufferMemoryRequirements.</span></div><div class="line"><a name="l09208"></a><span class="lineno"> 9208</span>&#160;        VkMemoryRequirements vkMemReq = {};</div><div class="line"><a name="l09209"></a><span class="lineno"> 9209</span>&#160;        <span class="keywordtype">bool</span> requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l09210"></a><span class="lineno"> 9210</span>&#160;        <span class="keywordtype">bool</span> prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l09211"></a><span class="lineno"> 9211</span>&#160;        allocator-&gt;GetBufferMemoryRequirements(*pBuffer, vkMemReq,</div><div class="line"><a name="l09212"></a><span class="lineno"> 9212</span>&#160;            requiresDedicatedAllocation, prefersDedicatedAllocation);</div><div class="line"><a name="l09213"></a><span class="lineno"> 9213</span>&#160;</div><div class="line"><a name="l09214"></a><span class="lineno"> 9214</span>&#160;         <span class="comment">// Make sure alignment requirements for specific buffer usages reported</span></div><div class="line"><a name="l09215"></a><span class="lineno"> 9215</span>&#160;         <span class="comment">// in Physical Device Properties are included in alignment reported by memory requirements.</span></div><div class="line"><a name="l09216"></a><span class="lineno"> 9216</span>&#160;        <span class="keywordflow">if</span>((pBufferCreateInfo-&gt;usage &amp; VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) != 0)</div><div class="line"><a name="l09217"></a><span class="lineno"> 9217</span>&#160;        {</div><div class="line"><a name="l09218"></a><span class="lineno"> 9218</span>&#160;           VMA_ASSERT(vkMemReq.alignment %</div><div class="line"><a name="l09219"></a><span class="lineno"> 9219</span>&#160;              allocator-&gt;m_PhysicalDeviceProperties.limits.minTexelBufferOffsetAlignment == 0);</div><div class="line"><a name="l09220"></a><span class="lineno"> 9220</span>&#160;        }</div><div class="line"><a name="l09221"></a><span class="lineno"> 9221</span>&#160;        <span class="keywordflow">if</span>((pBufferCreateInfo-&gt;usage &amp; VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) != 0)</div><div class="line"><a name="l09222"></a><span class="lineno"> 9222</span>&#160;        {</div><div class="line"><a name="l09223"></a><span class="lineno"> 9223</span>&#160;           VMA_ASSERT(vkMemReq.alignment %</div><div class="line"><a name="l09224"></a><span class="lineno"> 9224</span>&#160;              allocator-&gt;m_PhysicalDeviceProperties.limits.minUniformBufferOffsetAlignment == 0);</div><div class="line"><a name="l09225"></a><span class="lineno"> 9225</span>&#160;        }</div><div class="line"><a name="l09226"></a><span class="lineno"> 9226</span>&#160;        <span class="keywordflow">if</span>((pBufferCreateInfo-&gt;usage &amp; VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0)</div><div class="line"><a name="l09227"></a><span class="lineno"> 9227</span>&#160;        {</div><div class="line"><a name="l09228"></a><span class="lineno"> 9228</span>&#160;           VMA_ASSERT(vkMemReq.alignment %</div><div class="line"><a name="l09229"></a><span class="lineno"> 9229</span>&#160;              allocator-&gt;m_PhysicalDeviceProperties.limits.minStorageBufferOffsetAlignment == 0);</div><div class="line"><a name="l09230"></a><span class="lineno"> 9230</span>&#160;        }</div><div class="line"><a name="l09231"></a><span class="lineno"> 9231</span>&#160;</div><div class="line"><a name="l09232"></a><span class="lineno"> 9232</span>&#160;        <span class="comment">// 3. Allocate memory using allocator.</span></div><div class="line"><a name="l09233"></a><span class="lineno"> 9233</span>&#160;        res = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l09234"></a><span class="lineno"> 9234</span>&#160;            vkMemReq,</div><div class="line"><a name="l09235"></a><span class="lineno"> 9235</span>&#160;            requiresDedicatedAllocation,</div><div class="line"><a name="l09236"></a><span class="lineno"> 9236</span>&#160;            prefersDedicatedAllocation,</div><div class="line"><a name="l09237"></a><span class="lineno"> 9237</span>&#160;            *pBuffer, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l09238"></a><span class="lineno"> 9238</span>&#160;            VK_NULL_HANDLE, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l09239"></a><span class="lineno"> 9239</span>&#160;            *pAllocationCreateInfo,</div><div class="line"><a name="l09240"></a><span class="lineno"> 9240</span>&#160;            VMA_SUBALLOCATION_TYPE_BUFFER,</div><div class="line"><a name="l09241"></a><span class="lineno"> 9241</span>&#160;            pAllocation);</div><div class="line"><a name="l09242"></a><span class="lineno"> 9242</span>&#160;        <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l09243"></a><span class="lineno"> 9243</span>&#160;        {</div><div class="line"><a name="l09244"></a><span class="lineno"> 9244</span>&#160;            <span class="comment">// 3. Bind buffer with memory.</span></div><div class="line"><a name="l09245"></a><span class="lineno"> 9245</span>&#160;            res = allocator-&gt;BindBufferMemory(*pAllocation, *pBuffer);</div><div class="line"><a name="l09246"></a><span class="lineno"> 9246</span>&#160;            <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l09247"></a><span class="lineno"> 9247</span>&#160;            {</div><div class="line"><a name="l09248"></a><span class="lineno"> 9248</span>&#160;                <span class="comment">// All steps succeeded.</span></div><div class="line"><a name="l09249"></a><span class="lineno"> 9249</span>&#160;                <span class="keywordflow">if</span>(pAllocationInfo != VMA_NULL)</div><div class="line"><a name="l09250"></a><span class="lineno"> 9250</span>&#160;                {</div><div class="line"><a name="l09251"></a><span class="lineno"> 9251</span>&#160;                    allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l09252"></a><span class="lineno"> 9252</span>&#160;                }</div><div class="line"><a name="l09253"></a><span class="lineno"> 9253</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09254"></a><span class="lineno"> 9254</span>&#160;            }</div><div class="line"><a name="l09255"></a><span class="lineno"> 9255</span>&#160;            allocator-&gt;FreeMemory(*pAllocation);</div><div class="line"><a name="l09256"></a><span class="lineno"> 9256</span>&#160;            *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l09257"></a><span class="lineno"> 9257</span>&#160;            (*allocator-&gt;GetVulkanFunctions().vkDestroyBuffer)(allocator-&gt;m_hDevice, *pBuffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l09258"></a><span class="lineno"> 9258</span>&#160;            *pBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l09259"></a><span class="lineno"> 9259</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09260"></a><span class="lineno"> 9260</span>&#160;        }</div><div class="line"><a name="l09261"></a><span class="lineno"> 9261</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyBuffer)(allocator-&gt;m_hDevice, *pBuffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l09262"></a><span class="lineno"> 9262</span>&#160;        *pBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l09263"></a><span class="lineno"> 9263</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09264"></a><span class="lineno"> 9264</span>&#160;    }</div><div class="line"><a name="l09265"></a><span class="lineno"> 9265</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09266"></a><span class="lineno"> 9266</span>&#160;}</div><div class="line"><a name="l09267"></a><span class="lineno"> 9267</span>&#160;</div><div class="line"><a name="l09268"></a><span class="lineno"> 9268</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(</div><div class="line"><a name="l09269"></a><span class="lineno"> 9269</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09270"></a><span class="lineno"> 9270</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l09271"></a><span class="lineno"> 9271</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l09272"></a><span class="lineno"> 9272</span>&#160;{</div><div class="line"><a name="l09273"></a><span class="lineno"> 9273</span>&#160;    <span class="keywordflow">if</span>(buffer != VK_NULL_HANDLE)</div><div class="line"><a name="l09274"></a><span class="lineno"> 9274</span>&#160;    {</div><div class="line"><a name="l09275"></a><span class="lineno"> 9275</span>&#160;        VMA_ASSERT(allocator);</div><div class="line"><a name="l09276"></a><span class="lineno"> 9276</span>&#160;</div><div class="line"><a name="l09277"></a><span class="lineno"> 9277</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyBuffer&quot;</span>);</div><div class="line"><a name="l09278"></a><span class="lineno"> 9278</span>&#160;</div><div class="line"><a name="l09279"></a><span class="lineno"> 9279</span>&#160;        VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09280"></a><span class="lineno"> 9280</span>&#160;</div><div class="line"><a name="l09281"></a><span class="lineno"> 9281</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyBuffer)(allocator-&gt;m_hDevice, buffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l09282"></a><span class="lineno"> 9282</span>&#160;        </div><div class="line"><a name="l09283"></a><span class="lineno"> 9283</span>&#160;        allocator-&gt;FreeMemory(allocation);</div><div class="line"><a name="l09284"></a><span class="lineno"> 9284</span>&#160;    }</div><div class="line"><a name="l09285"></a><span class="lineno"> 9285</span>&#160;}</div><div class="line"><a name="l09286"></a><span class="lineno"> 9286</span>&#160;</div><div class="line"><a name="l09287"></a><span class="lineno"> 9287</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73">vmaCreateImage</a>(</div><div class="line"><a name="l09288"></a><span class="lineno"> 9288</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09289"></a><span class="lineno"> 9289</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l09290"></a><span class="lineno"> 9290</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l09291"></a><span class="lineno"> 9291</span>&#160;    VkImage* pImage,</div><div class="line"><a name="l09292"></a><span class="lineno"> 9292</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l09293"></a><span class="lineno"> 9293</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l09294"></a><span class="lineno"> 9294</span>&#160;{</div><div class="line"><a name="l09295"></a><span class="lineno"> 9295</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pImageCreateInfo &amp;&amp; pAllocationCreateInfo &amp;&amp; pImage &amp;&amp; pAllocation);</div><div class="line"><a name="l09296"></a><span class="lineno"> 9296</span>&#160;</div><div class="line"><a name="l09297"></a><span class="lineno"> 9297</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreateImage&quot;</span>);</div><div class="line"><a name="l09298"></a><span class="lineno"> 9298</span>&#160;</div><div class="line"><a name="l09299"></a><span class="lineno"> 9299</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09300"></a><span class="lineno"> 9300</span>&#160;</div><div class="line"><a name="l09301"></a><span class="lineno"> 9301</span>&#160;    *pImage = VK_NULL_HANDLE;</div><div class="line"><a name="l09302"></a><span class="lineno"> 9302</span>&#160;    *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l09303"></a><span class="lineno"> 9303</span>&#160;</div><div class="line"><a name="l09304"></a><span class="lineno"> 9304</span>&#160;    <span class="comment">// 1. Create VkImage.</span></div><div class="line"><a name="l09305"></a><span class="lineno"> 9305</span>&#160;    VkResult res = (*allocator-&gt;GetVulkanFunctions().vkCreateImage)(</div><div class="line"><a name="l09306"></a><span class="lineno"> 9306</span>&#160;        allocator-&gt;m_hDevice,</div><div class="line"><a name="l09307"></a><span class="lineno"> 9307</span>&#160;        pImageCreateInfo,</div><div class="line"><a name="l09308"></a><span class="lineno"> 9308</span>&#160;        allocator-&gt;GetAllocationCallbacks(),</div><div class="line"><a name="l09309"></a><span class="lineno"> 9309</span>&#160;        pImage);</div><div class="line"><a name="l09310"></a><span class="lineno"> 9310</span>&#160;    <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l09311"></a><span class="lineno"> 9311</span>&#160;    {</div><div class="line"><a name="l09312"></a><span class="lineno"> 9312</span>&#160;        VmaSuballocationType suballocType = pImageCreateInfo-&gt;tiling == VK_IMAGE_TILING_OPTIMAL ?</div><div class="line"><a name="l09313"></a><span class="lineno"> 9313</span>&#160;            VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :</div><div class="line"><a name="l09314"></a><span class="lineno"> 9314</span>&#160;            VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR;</div><div class="line"><a name="l09315"></a><span class="lineno"> 9315</span>&#160;        </div><div class="line"><a name="l09316"></a><span class="lineno"> 9316</span>&#160;        <span class="comment">// 2. Allocate memory using allocator.</span></div><div class="line"><a name="l09317"></a><span class="lineno"> 9317</span>&#160;        res = AllocateMemoryForImage(allocator, *pImage, pAllocationCreateInfo, suballocType, pAllocation);</div><div class="line"><a name="l09318"></a><span class="lineno"> 9318</span>&#160;        <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l09319"></a><span class="lineno"> 9319</span>&#160;        {</div><div class="line"><a name="l09320"></a><span class="lineno"> 9320</span>&#160;            <span class="comment">// 3. Bind image with memory.</span></div><div class="line"><a name="l09321"></a><span class="lineno"> 9321</span>&#160;            res = allocator-&gt;BindImageMemory(*pAllocation, *pImage);</div><div class="line"><a name="l09322"></a><span class="lineno"> 9322</span>&#160;            <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l09323"></a><span class="lineno"> 9323</span>&#160;            {</div><div class="line"><a name="l09324"></a><span class="lineno"> 9324</span>&#160;                <span class="comment">// All steps succeeded.</span></div><div class="line"><a name="l09325"></a><span class="lineno"> 9325</span>&#160;                <span class="keywordflow">if</span>(pAllocationInfo != VMA_NULL)</div><div class="line"><a name="l09326"></a><span class="lineno"> 9326</span>&#160;                {</div><div class="line"><a name="l09327"></a><span class="lineno"> 9327</span>&#160;                    allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l09328"></a><span class="lineno"> 9328</span>&#160;                }</div><div class="line"><a name="l09329"></a><span class="lineno"> 9329</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09330"></a><span class="lineno"> 9330</span>&#160;            }</div><div class="line"><a name="l09331"></a><span class="lineno"> 9331</span>&#160;            allocator-&gt;FreeMemory(*pAllocation);</div><div class="line"><a name="l09332"></a><span class="lineno"> 9332</span>&#160;            *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l09333"></a><span class="lineno"> 9333</span>&#160;            (*allocator-&gt;GetVulkanFunctions().vkDestroyImage)(allocator-&gt;m_hDevice, *pImage, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l09334"></a><span class="lineno"> 9334</span>&#160;            *pImage = VK_NULL_HANDLE;</div><div class="line"><a name="l09335"></a><span class="lineno"> 9335</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09336"></a><span class="lineno"> 9336</span>&#160;        }</div><div class="line"><a name="l09337"></a><span class="lineno"> 9337</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyImage)(allocator-&gt;m_hDevice, *pImage, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l09338"></a><span class="lineno"> 9338</span>&#160;        *pImage = VK_NULL_HANDLE;</div><div class="line"><a name="l09339"></a><span class="lineno"> 9339</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09340"></a><span class="lineno"> 9340</span>&#160;    }</div><div class="line"><a name="l09341"></a><span class="lineno"> 9341</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09342"></a><span class="lineno"> 9342</span>&#160;}</div><div class="line"><a name="l09343"></a><span class="lineno"> 9343</span>&#160;</div><div class="line"><a name="l09344"></a><span class="lineno"> 9344</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae50d2cb3b4a3bfd4dd40987234e50e7e">vmaDestroyImage</a>(</div><div class="line"><a name="l09345"></a><span class="lineno"> 9345</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l09346"></a><span class="lineno"> 9346</span>&#160;    VkImage image,</div><div class="line"><a name="l09347"></a><span class="lineno"> 9347</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l09348"></a><span class="lineno"> 9348</span>&#160;{</div><div class="line"><a name="l09349"></a><span class="lineno"> 9349</span>&#160;    <span class="keywordflow">if</span>(image != VK_NULL_HANDLE)</div><div class="line"><a name="l09350"></a><span class="lineno"> 9350</span>&#160;    {</div><div class="line"><a name="l09351"></a><span class="lineno"> 9351</span>&#160;        VMA_ASSERT(allocator);</div><div class="line"><a name="l09352"></a><span class="lineno"> 9352</span>&#160;</div><div class="line"><a name="l09353"></a><span class="lineno"> 9353</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyImage&quot;</span>);</div><div class="line"><a name="l09354"></a><span class="lineno"> 9354</span>&#160;</div><div class="line"><a name="l09355"></a><span class="lineno"> 9355</span>&#160;        VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l09356"></a><span class="lineno"> 9356</span>&#160;</div><div class="line"><a name="l09357"></a><span class="lineno"> 9357</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyImage)(allocator-&gt;m_hDevice, image, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l09358"></a><span class="lineno"> 9358</span>&#160;</div><div class="line"><a name="l09359"></a><span class="lineno"> 9359</span>&#160;        allocator-&gt;FreeMemory(allocation);</div><div class="line"><a name="l09360"></a><span class="lineno"> 9360</span>&#160;    }</div><div class="line"><a name="l09361"></a><span class="lineno"> 9361</span>&#160;}</div><div class="line"><a name="l09362"></a><span class="lineno"> 9362</span>&#160;</div><div class="line"><a name="l09363"></a><span class="lineno"> 9363</span>&#160;<span class="preprocessor">#endif // #ifdef VMA_IMPLEMENTATION</span></div><div class="ttc" id="struct_vma_vulkan_functions_html_a77b7a74082823e865dd6546623468f96"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">VmaVulkanFunctions::vkGetPhysicalDeviceProperties</a></div><div class="ttdeci">PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1153</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a></div><div class="ttdoc">Set this flag if the allocation should have its own memory block. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1415</div></div>
+<a href="vk__mem__alloc_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment">// Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved.</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment">// Permission is hereby granted, free of charge, to any person obtaining a copy</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment">// of this software and associated documentation files (the &quot;Software&quot;), to deal</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment">// in the Software without restriction, including without limitation the rights</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment">// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment">// copies of the Software, and to permit persons to whom the Software is</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment">// furnished to do so, subject to the following conditions:</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment">// The above copyright notice and this permission notice shall be included in</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment">// all copies or substantial portions of the Software.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment">// THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment">// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;<span class="comment">// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE</span></div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="comment">// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="comment">// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;<span class="comment">// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN</span></div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="comment">// THE SOFTWARE.</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="preprocessor">#ifndef AMD_VULKAN_MEMORY_ALLOCATOR_H</span></div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="preprocessor">#define AMD_VULKAN_MEMORY_ALLOCATOR_H</span></div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;<span class="preprocessor">#ifdef __cplusplus</span></div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="keyword">extern</span> <span class="stringliteral">&quot;C&quot;</span> {</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;</div><div class="line"><a name="l01359"></a><span class="lineno"> 1359</span>&#160;<span class="preprocessor">#include &lt;vulkan/vulkan.h&gt;</span></div><div class="line"><a name="l01360"></a><span class="lineno"> 1360</span>&#160;</div><div class="line"><a name="l01361"></a><span class="lineno"> 1361</span>&#160;<span class="preprocessor">#if !defined(VMA_DEDICATED_ALLOCATION)</span></div><div class="line"><a name="l01362"></a><span class="lineno"> 1362</span>&#160;<span class="preprocessor">    #if VK_KHR_get_memory_requirements2 &amp;&amp; VK_KHR_dedicated_allocation</span></div><div class="line"><a name="l01363"></a><span class="lineno"> 1363</span>&#160;<span class="preprocessor">        #define VMA_DEDICATED_ALLOCATION 1</span></div><div class="line"><a name="l01364"></a><span class="lineno"> 1364</span>&#160;<span class="preprocessor">    #else</span></div><div class="line"><a name="l01365"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4"> 1365</a></span>&#160;<span class="preprocessor">        #define VMA_DEDICATED_ALLOCATION 0</span></div><div class="line"><a name="l01366"></a><span class="lineno"> 1366</span>&#160;<span class="preprocessor">    #endif</span></div><div class="line"><a name="l01367"></a><span class="lineno"> 1367</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l01368"></a><span class="lineno"> 1368</span>&#160;</div><div class="line"><a name="l01378"></a><span class="lineno"> 1378</span>&#160;VK_DEFINE_HANDLE(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a>)</div><div class="line"><a name="l01379"></a><span class="lineno"> 1379</span>&#160;</div><div class="line"><a name="l01380"></a><span class="lineno"> 1380</span>&#160;<span class="keyword">typedef</span> void (VKAPI_PTR *<a class="code" href="vk__mem__alloc_8h.html#ab6a6477cda1ce775b30bde96d766203b">PFN_vmaAllocateDeviceMemoryFunction</a>)(</div><div class="line"><a name="l01382"></a><span class="lineno"> 1382</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>      allocator,</div><div class="line"><a name="l01383"></a><span class="lineno"> 1383</span>&#160;    uint32_t          memoryType,</div><div class="line"><a name="l01384"></a><span class="lineno"> 1384</span>&#160;    VkDeviceMemory    memory,</div><div class="line"><a name="l01385"></a><span class="lineno"> 1385</span>&#160;    VkDeviceSize      size);</div><div class="line"><a name="l01387"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49"> 1387</a></span>&#160;<span class="keyword">typedef</span> void (VKAPI_PTR *<a class="code" href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49">PFN_vmaFreeDeviceMemoryFunction</a>)(</div><div class="line"><a name="l01388"></a><span class="lineno"> 1388</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>      allocator,</div><div class="line"><a name="l01389"></a><span class="lineno"> 1389</span>&#160;    uint32_t          memoryType,</div><div class="line"><a name="l01390"></a><span class="lineno"> 1390</span>&#160;    VkDeviceMemory    memory,</div><div class="line"><a name="l01391"></a><span class="lineno"> 1391</span>&#160;    VkDeviceSize      size);</div><div class="line"><a name="l01392"></a><span class="lineno"> 1392</span>&#160;</div><div class="line"><a name="l01400"></a><span class="lineno"><a class="line" href="struct_vma_device_memory_callbacks.html"> 1400</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a> {</div><div class="line"><a name="l01402"></a><span class="lineno"><a class="line" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb"> 1402</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ab6a6477cda1ce775b30bde96d766203b">PFN_vmaAllocateDeviceMemoryFunction</a> <a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a>;</div><div class="line"><a name="l01404"></a><span class="lineno"><a class="line" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c"> 1404</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49">PFN_vmaFreeDeviceMemoryFunction</a> <a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a>;</div><div class="line"><a name="l01405"></a><span class="lineno"> 1405</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a5e2eb68d727cfd4df25702b027b7aa31">VmaDeviceMemoryCallbacks</a>;</div><div class="line"><a name="l01406"></a><span class="lineno"> 1406</span>&#160;</div><div class="line"><a name="l01408"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c"> 1408</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">enum</span> <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a> {</div><div class="line"><a name="l01413"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d"> 1413</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a> = 0x00000001,</div><div class="line"><a name="l01435"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878"> 1435</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a> = 0x00000002,</div><div class="line"><a name="l01436"></a><span class="lineno"> 1436</span>&#160;</div><div class="line"><a name="l01437"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c"> 1437</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c">VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01438"></a><span class="lineno"> 1438</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a>;</div><div class="line"><a name="l01439"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#acfe6863e160722c2c1bbcf7573fddc4d"> 1439</a></span>&#160;<span class="keyword">typedef</span> VkFlags <a class="code" href="vk__mem__alloc_8h.html#acfe6863e160722c2c1bbcf7573fddc4d">VmaAllocatorCreateFlags</a>;</div><div class="line"><a name="l01440"></a><span class="lineno"> 1440</span>&#160;</div><div class="line"><a name="l01445"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html"> 1445</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a> {</div><div class="line"><a name="l01446"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96"> 1446</a></span>&#160;    PFN_vkGetPhysicalDeviceProperties <a class="code" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">vkGetPhysicalDeviceProperties</a>;</div><div class="line"><a name="l01447"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830"> 1447</a></span>&#160;    PFN_vkGetPhysicalDeviceMemoryProperties <a class="code" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">vkGetPhysicalDeviceMemoryProperties</a>;</div><div class="line"><a name="l01448"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a2943bf99dfd784a0e8f599d987e22e6c"> 1448</a></span>&#160;    PFN_vkAllocateMemory <a class="code" href="struct_vma_vulkan_functions.html#a2943bf99dfd784a0e8f599d987e22e6c">vkAllocateMemory</a>;</div><div class="line"><a name="l01449"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4"> 1449</a></span>&#160;    PFN_vkFreeMemory <a class="code" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">vkFreeMemory</a>;</div><div class="line"><a name="l01450"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49"> 1450</a></span>&#160;    PFN_vkMapMemory <a class="code" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">vkMapMemory</a>;</div><div class="line"><a name="l01451"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9"> 1451</a></span>&#160;    PFN_vkUnmapMemory <a class="code" href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9">vkUnmapMemory</a>;</div><div class="line"><a name="l01452"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9"> 1452</a></span>&#160;    PFN_vkFlushMappedMemoryRanges <a class="code" href="struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9">vkFlushMappedMemoryRanges</a>;</div><div class="line"><a name="l01453"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1"> 1453</a></span>&#160;    PFN_vkInvalidateMappedMemoryRanges <a class="code" href="struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1">vkInvalidateMappedMemoryRanges</a>;</div><div class="line"><a name="l01454"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2"> 1454</a></span>&#160;    PFN_vkBindBufferMemory <a class="code" href="struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2">vkBindBufferMemory</a>;</div><div class="line"><a name="l01455"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637"> 1455</a></span>&#160;    PFN_vkBindImageMemory <a class="code" href="struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637">vkBindImageMemory</a>;</div><div class="line"><a name="l01456"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143"> 1456</a></span>&#160;    PFN_vkGetBufferMemoryRequirements <a class="code" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">vkGetBufferMemoryRequirements</a>;</div><div class="line"><a name="l01457"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4"> 1457</a></span>&#160;    PFN_vkGetImageMemoryRequirements <a class="code" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">vkGetImageMemoryRequirements</a>;</div><div class="line"><a name="l01458"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#ae8084315a25006271a2edfc3a447519f"> 1458</a></span>&#160;    PFN_vkCreateBuffer <a class="code" href="struct_vma_vulkan_functions.html#ae8084315a25006271a2edfc3a447519f">vkCreateBuffer</a>;</div><div class="line"><a name="l01459"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45"> 1459</a></span>&#160;    PFN_vkDestroyBuffer <a class="code" href="struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45">vkDestroyBuffer</a>;</div><div class="line"><a name="l01460"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325"> 1460</a></span>&#160;    PFN_vkCreateImage <a class="code" href="struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325">vkCreateImage</a>;</div><div class="line"><a name="l01461"></a><span class="lineno"><a class="line" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa"> 1461</a></span>&#160;    PFN_vkDestroyImage <a class="code" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">vkDestroyImage</a>;</div><div class="line"><a name="l01462"></a><span class="lineno"> 1462</span>&#160;<span class="preprocessor">#if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l01463"></a><span class="lineno"> 1463</span>&#160;    PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;</div><div class="line"><a name="l01464"></a><span class="lineno"> 1464</span>&#160;    PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;</div><div class="line"><a name="l01465"></a><span class="lineno"> 1465</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l01466"></a><span class="lineno"> 1466</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a97064a1a271b0061ebfc3a079862d0c5">VmaVulkanFunctions</a>;</div><div class="line"><a name="l01467"></a><span class="lineno"> 1467</span>&#160;</div><div class="line"><a name="l01469"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2"> 1469</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">enum</span> <a class="code" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a> {</div><div class="line"><a name="l01475"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7"> 1475</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7">VMA_RECORD_FLUSH_AFTER_CALL_BIT</a> = 0x00000001,</div><div class="line"><a name="l01476"></a><span class="lineno"> 1476</span>&#160;    </div><div class="line"><a name="l01477"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e"> 1477</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e">VMA_RECORD_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01478"></a><span class="lineno"> 1478</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a>;</div><div class="line"><a name="l01479"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828"> 1479</a></span>&#160;<span class="keyword">typedef</span> VkFlags <a class="code" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">VmaRecordFlags</a>;</div><div class="line"><a name="l01480"></a><span class="lineno"> 1480</span>&#160;</div><div class="line"><a name="l01481"></a><span class="lineno"> 1481</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l01482"></a><span class="lineno"> 1482</span>&#160;<span class="comment">Define this macro to 0/1 to disable/enable support for recording functionality,</span></div><div class="line"><a name="l01483"></a><span class="lineno"> 1483</span>&#160;<span class="comment">available through VmaAllocatorCreateInfo::pRecordSettings.</span></div><div class="line"><a name="l01484"></a><span class="lineno"> 1484</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l01485"></a><span class="lineno"> 1485</span>&#160;<span class="preprocessor">#ifndef VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l01486"></a><span class="lineno"> 1486</span>&#160;<span class="preprocessor">    #ifdef _WIN32</span></div><div class="line"><a name="l01487"></a><span class="lineno"> 1487</span>&#160;<span class="preprocessor">        #define VMA_RECORDING_ENABLED 1</span></div><div class="line"><a name="l01488"></a><span class="lineno"> 1488</span>&#160;<span class="preprocessor">    #else</span></div><div class="line"><a name="l01489"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c"> 1489</a></span>&#160;<span class="preprocessor">        #define VMA_RECORDING_ENABLED 0</span></div><div class="line"><a name="l01490"></a><span class="lineno"> 1490</span>&#160;<span class="preprocessor">    #endif</span></div><div class="line"><a name="l01491"></a><span class="lineno"> 1491</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l01492"></a><span class="lineno"> 1492</span>&#160;</div><div class="line"><a name="l01494"></a><span class="lineno"><a class="line" href="struct_vma_record_settings.html"> 1494</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_record_settings.html">VmaRecordSettings</a></div><div class="line"><a name="l01495"></a><span class="lineno"> 1495</span>&#160;{</div><div class="line"><a name="l01497"></a><span class="lineno"><a class="line" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a"> 1497</a></span>&#160;    VmaRecordFlags <a class="code" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a">flags</a>;</div><div class="line"><a name="l01505"></a><span class="lineno"><a class="line" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d"> 1505</a></span>&#160;    <span class="keyword">const</span> <span class="keywordtype">char</span>* <a class="code" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">pFilePath</a>;</div><div class="line"><a name="l01506"></a><span class="lineno"> 1506</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a0ab61e87ff6365f1d59915eadc37a9f0">VmaRecordSettings</a>;</div><div class="line"><a name="l01507"></a><span class="lineno"> 1507</span>&#160;</div><div class="line"><a name="l01509"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html"> 1509</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></div><div class="line"><a name="l01510"></a><span class="lineno"> 1510</span>&#160;{</div><div class="line"><a name="l01512"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346"> 1512</a></span>&#160;    VmaAllocatorCreateFlags <a class="code" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">flags</a>;</div><div class="line"><a name="l01514"></a><span class="lineno"> 1514</span>&#160;</div><div class="line"><a name="l01515"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156"> 1515</a></span>&#160;    VkPhysicalDevice <a class="code" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a>;</div><div class="line"><a name="l01517"></a><span class="lineno"> 1517</span>&#160;</div><div class="line"><a name="l01518"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500"> 1518</a></span>&#160;    VkDevice <a class="code" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500">device</a>;</div><div class="line"><a name="l01520"></a><span class="lineno"> 1520</span>&#160;</div><div class="line"><a name="l01521"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a"> 1521</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a>;</div><div class="line"><a name="l01523"></a><span class="lineno"> 1523</span>&#160;</div><div class="line"><a name="l01524"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d"> 1524</a></span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* <a class="code" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">pAllocationCallbacks</a>;</div><div class="line"><a name="l01526"></a><span class="lineno"> 1526</span>&#160;</div><div class="line"><a name="l01527"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e"> 1527</a></span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a>* <a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a>;</div><div class="line"><a name="l01541"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7"> 1541</a></span>&#160;    uint32_t <a class="code" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">frameInUseCount</a>;</div><div class="line"><a name="l01565"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b"> 1565</a></span>&#160;    <span class="keyword">const</span> VkDeviceSize* <a class="code" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a>;</div><div class="line"><a name="l01577"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd"> 1577</a></span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>* <a class="code" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a>;</div><div class="line"><a name="l01584"></a><span class="lineno"><a class="line" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee"> 1584</a></span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_record_settings.html">VmaRecordSettings</a>* <a class="code" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">pRecordSettings</a>;</div><div class="line"><a name="l01585"></a><span class="lineno"> 1585</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ae0f6d1d733dded220d28134da46b4283">VmaAllocatorCreateInfo</a>;</div><div class="line"><a name="l01586"></a><span class="lineno"> 1586</span>&#160;</div><div class="line"><a name="l01588"></a><span class="lineno"> 1588</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a>(</div><div class="line"><a name="l01589"></a><span class="lineno"> 1589</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l01590"></a><span class="lineno"> 1590</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>* pAllocator);</div><div class="line"><a name="l01591"></a><span class="lineno"> 1591</span>&#160;</div><div class="line"><a name="l01593"></a><span class="lineno"> 1593</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa8d164061c88f22fb1fd3c8f3534bc1d">vmaDestroyAllocator</a>(</div><div class="line"><a name="l01594"></a><span class="lineno"> 1594</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator);</div><div class="line"><a name="l01595"></a><span class="lineno"> 1595</span>&#160;</div><div class="line"><a name="l01600"></a><span class="lineno"> 1600</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aecabf7b6e91ea87d0316fa0a9e014fe0">vmaGetPhysicalDeviceProperties</a>(</div><div class="line"><a name="l01601"></a><span class="lineno"> 1601</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01602"></a><span class="lineno"> 1602</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceProperties** ppPhysicalDeviceProperties);</div><div class="line"><a name="l01603"></a><span class="lineno"> 1603</span>&#160;</div><div class="line"><a name="l01608"></a><span class="lineno"> 1608</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ab88db292a17974f911182543fda52d19">vmaGetMemoryProperties</a>(</div><div class="line"><a name="l01609"></a><span class="lineno"> 1609</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01610"></a><span class="lineno"> 1610</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties);</div><div class="line"><a name="l01611"></a><span class="lineno"> 1611</span>&#160;</div><div class="line"><a name="l01618"></a><span class="lineno"> 1618</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(</div><div class="line"><a name="l01619"></a><span class="lineno"> 1619</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01620"></a><span class="lineno"> 1620</span>&#160;    uint32_t memoryTypeIndex,</div><div class="line"><a name="l01621"></a><span class="lineno"> 1621</span>&#160;    VkMemoryPropertyFlags* pFlags);</div><div class="line"><a name="l01622"></a><span class="lineno"> 1622</span>&#160;</div><div class="line"><a name="l01631"></a><span class="lineno"> 1631</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236">vmaSetCurrentFrameIndex</a>(</div><div class="line"><a name="l01632"></a><span class="lineno"> 1632</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01633"></a><span class="lineno"> 1633</span>&#160;    uint32_t frameIndex);</div><div class="line"><a name="l01634"></a><span class="lineno"> 1634</span>&#160;</div><div class="line"><a name="l01637"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html"> 1637</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a></div><div class="line"><a name="l01638"></a><span class="lineno"> 1638</span>&#160;{</div><div class="line"><a name="l01640"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4"> 1640</a></span>&#160;    uint32_t <a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a>;</div><div class="line"><a name="l01642"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff"> 1642</a></span>&#160;    uint32_t <a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>;</div><div class="line"><a name="l01644"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9"> 1644</a></span>&#160;    uint32_t <a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l01646"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a"> 1646</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>;</div><div class="line"><a name="l01648"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669"> 1648</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>;</div><div class="line"><a name="l01649"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea"> 1649</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, allocationSizeAvg, allocationSizeMax;</div><div class="line"><a name="l01650"></a><span class="lineno"><a class="line" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4"> 1650</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSizeAvg, unusedRangeSizeMax;</div><div class="line"><a name="l01651"></a><span class="lineno"> 1651</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a810b009a788ee8aac72a25b42ffbe31c">VmaStatInfo</a>;</div><div class="line"><a name="l01652"></a><span class="lineno"> 1652</span>&#160;</div><div class="line"><a name="l01654"></a><span class="lineno"><a class="line" href="struct_vma_stats.html"> 1654</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_stats.html">VmaStats</a></div><div class="line"><a name="l01655"></a><span class="lineno"> 1655</span>&#160;{</div><div class="line"><a name="l01656"></a><span class="lineno"><a class="line" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331"> 1656</a></span>&#160;    <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> memoryType[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l01657"></a><span class="lineno"><a class="line" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0"> 1657</a></span>&#160;    <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> memoryHeap[VK_MAX_MEMORY_HEAPS];</div><div class="line"><a name="l01658"></a><span class="lineno"><a class="line" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9"> 1658</a></span>&#160;    <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> <a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>;</div><div class="line"><a name="l01659"></a><span class="lineno"> 1659</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a732be855fb4a7c248e6853d928a729af">VmaStats</a>;</div><div class="line"><a name="l01660"></a><span class="lineno"> 1660</span>&#160;</div><div class="line"><a name="l01662"></a><span class="lineno"> 1662</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3">vmaCalculateStats</a>(</div><div class="line"><a name="l01663"></a><span class="lineno"> 1663</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01664"></a><span class="lineno"> 1664</span>&#160;    <a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats);</div><div class="line"><a name="l01665"></a><span class="lineno"> 1665</span>&#160;</div><div class="line"><a name="l01666"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1"> 1666</a></span>&#160;<span class="preprocessor">#define VMA_STATS_STRING_ENABLED 1</span></div><div class="line"><a name="l01667"></a><span class="lineno"> 1667</span>&#160;</div><div class="line"><a name="l01668"></a><span class="lineno"> 1668</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l01669"></a><span class="lineno"> 1669</span>&#160;</div><div class="line"><a name="l01671"></a><span class="lineno"> 1671</span>&#160;</div><div class="line"><a name="l01673"></a><span class="lineno"> 1673</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0">vmaBuildStatsString</a>(</div><div class="line"><a name="l01674"></a><span class="lineno"> 1674</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01675"></a><span class="lineno"> 1675</span>&#160;    <span class="keywordtype">char</span>** ppStatsString,</div><div class="line"><a name="l01676"></a><span class="lineno"> 1676</span>&#160;    VkBool32 detailedMap);</div><div class="line"><a name="l01677"></a><span class="lineno"> 1677</span>&#160;</div><div class="line"><a name="l01678"></a><span class="lineno"> 1678</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vmaFreeStatsString</a>(</div><div class="line"><a name="l01679"></a><span class="lineno"> 1679</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01680"></a><span class="lineno"> 1680</span>&#160;    <span class="keywordtype">char</span>* pStatsString);</div><div class="line"><a name="l01681"></a><span class="lineno"> 1681</span>&#160;</div><div class="line"><a name="l01682"></a><span class="lineno"> 1682</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l01683"></a><span class="lineno"> 1683</span>&#160;</div><div class="line"><a name="l01692"></a><span class="lineno"> 1692</span>&#160;VK_DEFINE_HANDLE(<a class="code" href="struct_vma_pool.html">VmaPool</a>)</div><div class="line"><a name="l01693"></a><span class="lineno"> 1693</span>&#160;</div><div class="line"><a name="l01694"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc"> 1694</a></span>&#160;typedef enum <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a></div><div class="line"><a name="l01695"></a><span class="lineno"> 1695</span>&#160;{</div><div class="line"><a name="l01699"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd"> 1699</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a> = 0,</div><div class="line"><a name="l01716"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7"> 1716</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a> = 1,</div><div class="line"><a name="l01726"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"> 1726</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a> = 2,</div><div class="line"><a name="l01733"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67"> 1733</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a> = 3,</div><div class="line"><a name="l01742"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27"> 1742</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a> = 4,</div><div class="line"><a name="l01743"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e"> 1743</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e">VMA_MEMORY_USAGE_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01744"></a><span class="lineno"> 1744</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a>;</div><div class="line"><a name="l01745"></a><span class="lineno"> 1745</span>&#160;</div><div class="line"><a name="l01747"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597"> 1747</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">enum</span> <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a> {</div><div class="line"><a name="l01759"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f"> 1759</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> = 0x00000001,</div><div class="line"><a name="l01760"></a><span class="lineno"> 1760</span>&#160;</div><div class="line"><a name="l01770"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff"> 1770</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a> = 0x00000002,</div><div class="line"><a name="l01783"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f"> 1783</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> = 0x00000004,</div><div class="line"><a name="l01796"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2"> 1796</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> = 0x00000008,</div><div class="line"><a name="l01803"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e"> 1803</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> = 0x00000010,</div><div class="line"><a name="l01809"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520"> 1809</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a> = 0x00000020,</div><div class="line"><a name="l01814"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df"> 1814</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a> = 0x00000040,</div><div class="line"><a name="l01815"></a><span class="lineno"> 1815</span>&#160;</div><div class="line"><a name="l01816"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882"> 1816</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01817"></a><span class="lineno"> 1817</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a>;</div><div class="line"><a name="l01818"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817"> 1818</a></span>&#160;<span class="keyword">typedef</span> VkFlags <a class="code" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a>;</div><div class="line"><a name="l01819"></a><span class="lineno"> 1819</span>&#160;</div><div class="line"><a name="l01820"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html"> 1820</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></div><div class="line"><a name="l01821"></a><span class="lineno"> 1821</span>&#160;{</div><div class="line"><a name="l01823"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b"> 1823</a></span>&#160;    VmaAllocationCreateFlags <a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>;</div><div class="line"><a name="l01829"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910"> 1829</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a> <a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>;</div><div class="line"><a name="l01834"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90"> 1834</a></span>&#160;    VkMemoryPropertyFlags <a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>;</div><div class="line"><a name="l01839"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d"> 1839</a></span>&#160;    VkMemoryPropertyFlags <a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>;</div><div class="line"><a name="l01847"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055"> 1847</a></span>&#160;    uint32_t <a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>;</div><div class="line"><a name="l01853"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150"> 1853</a></span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> <a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>;</div><div class="line"><a name="l01860"></a><span class="lineno"><a class="line" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19"> 1860</a></span>&#160;    <span class="keywordtype">void</span>* <a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>;</div><div class="line"><a name="l01861"></a><span class="lineno"> 1861</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a86c44f9950b40d50088ed93a17870a7a">VmaAllocationCreateInfo</a>;</div><div class="line"><a name="l01862"></a><span class="lineno"> 1862</span>&#160;</div><div class="line"><a name="l01879"></a><span class="lineno"> 1879</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l01880"></a><span class="lineno"> 1880</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01881"></a><span class="lineno"> 1881</span>&#160;    uint32_t memoryTypeBits,</div><div class="line"><a name="l01882"></a><span class="lineno"> 1882</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l01883"></a><span class="lineno"> 1883</span>&#160;    uint32_t* pMemoryTypeIndex);</div><div class="line"><a name="l01884"></a><span class="lineno"> 1884</span>&#160;</div><div class="line"><a name="l01897"></a><span class="lineno"> 1897</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(</div><div class="line"><a name="l01898"></a><span class="lineno"> 1898</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01899"></a><span class="lineno"> 1899</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l01900"></a><span class="lineno"> 1900</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l01901"></a><span class="lineno"> 1901</span>&#160;    uint32_t* pMemoryTypeIndex);</div><div class="line"><a name="l01902"></a><span class="lineno"> 1902</span>&#160;</div><div class="line"><a name="l01915"></a><span class="lineno"> 1915</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472">vmaFindMemoryTypeIndexForImageInfo</a>(</div><div class="line"><a name="l01916"></a><span class="lineno"> 1916</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l01917"></a><span class="lineno"> 1917</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l01918"></a><span class="lineno"> 1918</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l01919"></a><span class="lineno"> 1919</span>&#160;    uint32_t* pMemoryTypeIndex);</div><div class="line"><a name="l01920"></a><span class="lineno"> 1920</span>&#160;</div><div class="line"><a name="l01922"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7"> 1922</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">enum</span> <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a> {</div><div class="line"><a name="l01940"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2"> 1940</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a> = 0x00000002,</div><div class="line"><a name="l01941"></a><span class="lineno"> 1941</span>&#160;</div><div class="line"><a name="l01955"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726"> 1955</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a> = 0x00000004,</div><div class="line"><a name="l01956"></a><span class="lineno"> 1956</span>&#160;</div><div class="line"><a name="l01957"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec"> 1957</a></span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec">VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF</div><div class="line"><a name="l01958"></a><span class="lineno"> 1958</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a>;</div><div class="line"><a name="l01959"></a><span class="lineno"><a class="line" href="vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a"> 1959</a></span>&#160;<span class="keyword">typedef</span> VkFlags <a class="code" href="vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a">VmaPoolCreateFlags</a>;</div><div class="line"><a name="l01960"></a><span class="lineno"> 1960</span>&#160;</div><div class="line"><a name="l01963"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html"> 1963</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> {</div><div class="line"><a name="l01966"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319"> 1966</a></span>&#160;    uint32_t <a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a>;</div><div class="line"><a name="l01969"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446"> 1969</a></span>&#160;    VmaPoolCreateFlags <a class="code" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">flags</a>;</div><div class="line"><a name="l01978"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676"> 1978</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">blockSize</a>;</div><div class="line"><a name="l01983"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae"> 1983</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae">minBlockCount</a>;</div><div class="line"><a name="l01991"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c"> 1991</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a>;</div><div class="line"><a name="l02005"></a><span class="lineno"><a class="line" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa"> 2005</a></span>&#160;    uint32_t <a class="code" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa">frameInUseCount</a>;</div><div class="line"><a name="l02006"></a><span class="lineno"> 2006</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a211706e9348dcee25a843ed4ea69bce7">VmaPoolCreateInfo</a>;</div><div class="line"><a name="l02007"></a><span class="lineno"> 2007</span>&#160;</div><div class="line"><a name="l02010"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html"> 2010</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a> {</div><div class="line"><a name="l02013"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c"> 2013</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a>;</div><div class="line"><a name="l02016"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8"> 2016</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a>;</div><div class="line"><a name="l02019"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb"> 2019</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a>;</div><div class="line"><a name="l02022"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4"> 2022</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l02029"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b"> 2029</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>;</div><div class="line"><a name="l02032"></a><span class="lineno"><a class="line" href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7"> 2032</a></span>&#160;    <span class="keywordtype">size_t</span> <a class="code" href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7">blockCount</a>;</div><div class="line"><a name="l02033"></a><span class="lineno"> 2033</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34">VmaPoolStats</a>;</div><div class="line"><a name="l02034"></a><span class="lineno"> 2034</span>&#160;</div><div class="line"><a name="l02041"></a><span class="lineno"> 2041</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(</div><div class="line"><a name="l02042"></a><span class="lineno"> 2042</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02043"></a><span class="lineno"> 2043</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l02044"></a><span class="lineno"> 2044</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool);</div><div class="line"><a name="l02045"></a><span class="lineno"> 2045</span>&#160;</div><div class="line"><a name="l02048"></a><span class="lineno"> 2048</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a>(</div><div class="line"><a name="l02049"></a><span class="lineno"> 2049</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02050"></a><span class="lineno"> 2050</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l02051"></a><span class="lineno"> 2051</span>&#160;</div><div class="line"><a name="l02058"></a><span class="lineno"> 2058</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153">vmaGetPoolStats</a>(</div><div class="line"><a name="l02059"></a><span class="lineno"> 2059</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02060"></a><span class="lineno"> 2060</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l02061"></a><span class="lineno"> 2061</span>&#160;    <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats);</div><div class="line"><a name="l02062"></a><span class="lineno"> 2062</span>&#160;</div><div class="line"><a name="l02069"></a><span class="lineno"> 2069</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vmaMakePoolAllocationsLost</a>(</div><div class="line"><a name="l02070"></a><span class="lineno"> 2070</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02071"></a><span class="lineno"> 2071</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l02072"></a><span class="lineno"> 2072</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount);</div><div class="line"><a name="l02073"></a><span class="lineno"> 2073</span>&#160;</div><div class="line"><a name="l02088"></a><span class="lineno"> 2088</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89">vmaCheckPoolCorruption</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l02089"></a><span class="lineno"> 2089</span>&#160;</div><div class="line"><a name="l02114"></a><span class="lineno"> 2114</span>&#160;VK_DEFINE_HANDLE(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a>)</div><div class="line"><a name="l02115"></a><span class="lineno"> 2115</span>&#160;</div><div class="line"><a name="l02116"></a><span class="lineno"> 2116</span>&#160;</div><div class="line"><a name="l02118"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html"> 2118</a></span>&#160;typedef struct <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> {</div><div class="line"><a name="l02123"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5"> 2123</a></span>&#160;    uint32_t <a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>;</div><div class="line"><a name="l02132"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67"> 2132</a></span>&#160;    VkDeviceMemory <a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><div class="line"><a name="l02137"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268"> 2137</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><div class="line"><a name="l02142"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f"> 2142</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><div class="line"><a name="l02151"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2"> 2151</a></span>&#160;    <span class="keywordtype">void</span>* <a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>;</div><div class="line"><a name="l02156"></a><span class="lineno"><a class="line" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13"> 2156</a></span>&#160;    <span class="keywordtype">void</span>* <a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a>;</div><div class="line"><a name="l02157"></a><span class="lineno"> 2157</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#a795e6ff02a21d5486c0565f403dd9255">VmaAllocationInfo</a>;</div><div class="line"><a name="l02158"></a><span class="lineno"> 2158</span>&#160;</div><div class="line"><a name="l02169"></a><span class="lineno"> 2169</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a>(</div><div class="line"><a name="l02170"></a><span class="lineno"> 2170</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02171"></a><span class="lineno"> 2171</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements* pVkMemoryRequirements,</div><div class="line"><a name="l02172"></a><span class="lineno"> 2172</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l02173"></a><span class="lineno"> 2173</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l02174"></a><span class="lineno"> 2174</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02175"></a><span class="lineno"> 2175</span>&#160;</div><div class="line"><a name="l02182"></a><span class="lineno"> 2182</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer</a>(</div><div class="line"><a name="l02183"></a><span class="lineno"> 2183</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02184"></a><span class="lineno"> 2184</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l02185"></a><span class="lineno"> 2185</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l02186"></a><span class="lineno"> 2186</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l02187"></a><span class="lineno"> 2187</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02188"></a><span class="lineno"> 2188</span>&#160;</div><div class="line"><a name="l02190"></a><span class="lineno"> 2190</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vmaAllocateMemoryForImage</a>(</div><div class="line"><a name="l02191"></a><span class="lineno"> 2191</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02192"></a><span class="lineno"> 2192</span>&#160;    VkImage image,</div><div class="line"><a name="l02193"></a><span class="lineno"> 2193</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l02194"></a><span class="lineno"> 2194</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l02195"></a><span class="lineno"> 2195</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02196"></a><span class="lineno"> 2196</span>&#160;</div><div class="line"><a name="l02198"></a><span class="lineno"> 2198</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vmaFreeMemory</a>(</div><div class="line"><a name="l02199"></a><span class="lineno"> 2199</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02200"></a><span class="lineno"> 2200</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l02201"></a><span class="lineno"> 2201</span>&#160;</div><div class="line"><a name="l02218"></a><span class="lineno"> 2218</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(</div><div class="line"><a name="l02219"></a><span class="lineno"> 2219</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02220"></a><span class="lineno"> 2220</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l02221"></a><span class="lineno"> 2221</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02222"></a><span class="lineno"> 2222</span>&#160;</div><div class="line"><a name="l02237"></a><span class="lineno"> 2237</span>&#160;VkBool32 <a class="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(</div><div class="line"><a name="l02238"></a><span class="lineno"> 2238</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02239"></a><span class="lineno"> 2239</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l02240"></a><span class="lineno"> 2240</span>&#160;</div><div class="line"><a name="l02254"></a><span class="lineno"> 2254</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f">vmaSetAllocationUserData</a>(</div><div class="line"><a name="l02255"></a><span class="lineno"> 2255</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02256"></a><span class="lineno"> 2256</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l02257"></a><span class="lineno"> 2257</span>&#160;    <span class="keywordtype">void</span>* pUserData);</div><div class="line"><a name="l02258"></a><span class="lineno"> 2258</span>&#160;</div><div class="line"><a name="l02269"></a><span class="lineno"> 2269</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae5c9657d9e94756269145b01c05d16f1">vmaCreateLostAllocation</a>(</div><div class="line"><a name="l02270"></a><span class="lineno"> 2270</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02271"></a><span class="lineno"> 2271</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l02272"></a><span class="lineno"> 2272</span>&#160;</div><div class="line"><a name="l02307"></a><span class="lineno"> 2307</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(</div><div class="line"><a name="l02308"></a><span class="lineno"> 2308</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02309"></a><span class="lineno"> 2309</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l02310"></a><span class="lineno"> 2310</span>&#160;    <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l02311"></a><span class="lineno"> 2311</span>&#160;</div><div class="line"><a name="l02316"></a><span class="lineno"> 2316</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(</div><div class="line"><a name="l02317"></a><span class="lineno"> 2317</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02318"></a><span class="lineno"> 2318</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l02319"></a><span class="lineno"> 2319</span>&#160;</div><div class="line"><a name="l02332"></a><span class="lineno"> 2332</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de">vmaFlushAllocation</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size);</div><div class="line"><a name="l02333"></a><span class="lineno"> 2333</span>&#160;</div><div class="line"><a name="l02346"></a><span class="lineno"> 2346</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006">vmaInvalidateAllocation</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size);</div><div class="line"><a name="l02347"></a><span class="lineno"> 2347</span>&#160;</div><div class="line"><a name="l02364"></a><span class="lineno"> 2364</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98">vmaCheckCorruption</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, uint32_t memoryTypeBits);</div><div class="line"><a name="l02365"></a><span class="lineno"> 2365</span>&#160;</div><div class="line"><a name="l02367"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_info.html"> 2367</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> {</div><div class="line"><a name="l02372"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d"> 2372</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d">maxBytesToMove</a>;</div><div class="line"><a name="l02377"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc"> 2377</a></span>&#160;    uint32_t <a class="code" href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc">maxAllocationsToMove</a>;</div><div class="line"><a name="l02378"></a><span class="lineno"> 2378</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ae67f8573a0cf20f16f0a1eecbca566a0">VmaDefragmentationInfo</a>;</div><div class="line"><a name="l02379"></a><span class="lineno"> 2379</span>&#160;</div><div class="line"><a name="l02381"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html"> 2381</a></span>&#160;<span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a> {</div><div class="line"><a name="l02383"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d"> 2383</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a>;</div><div class="line"><a name="l02385"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28"> 2385</a></span>&#160;    VkDeviceSize <a class="code" href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28">bytesFreed</a>;</div><div class="line"><a name="l02387"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9"> 2387</a></span>&#160;    uint32_t <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a>;</div><div class="line"><a name="l02389"></a><span class="lineno"><a class="line" href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b"> 2389</a></span>&#160;    uint32_t <a class="code" href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b">deviceMemoryBlocksFreed</a>;</div><div class="line"><a name="l02390"></a><span class="lineno"> 2390</span>&#160;} <a class="code" href="vk__mem__alloc_8h.html#ab0f9b06441c840fee560de4a2967f8c9">VmaDefragmentationStats</a>;</div><div class="line"><a name="l02391"></a><span class="lineno"> 2391</span>&#160;</div><div class="line"><a name="l02478"></a><span class="lineno"> 2478</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a>(</div><div class="line"><a name="l02479"></a><span class="lineno"> 2479</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02480"></a><span class="lineno"> 2480</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l02481"></a><span class="lineno"> 2481</span>&#160;    <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l02482"></a><span class="lineno"> 2482</span>&#160;    VkBool32* pAllocationsChanged,</div><div class="line"><a name="l02483"></a><span class="lineno"> 2483</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *pDefragmentationInfo,</div><div class="line"><a name="l02484"></a><span class="lineno"> 2484</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats);</div><div class="line"><a name="l02485"></a><span class="lineno"> 2485</span>&#160;</div><div class="line"><a name="l02498"></a><span class="lineno"> 2498</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vmaBindBufferMemory</a>(</div><div class="line"><a name="l02499"></a><span class="lineno"> 2499</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02500"></a><span class="lineno"> 2500</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l02501"></a><span class="lineno"> 2501</span>&#160;    VkBuffer buffer);</div><div class="line"><a name="l02502"></a><span class="lineno"> 2502</span>&#160;</div><div class="line"><a name="l02515"></a><span class="lineno"> 2515</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vmaBindImageMemory</a>(</div><div class="line"><a name="l02516"></a><span class="lineno"> 2516</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02517"></a><span class="lineno"> 2517</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l02518"></a><span class="lineno"> 2518</span>&#160;    VkImage image);</div><div class="line"><a name="l02519"></a><span class="lineno"> 2519</span>&#160;</div><div class="line"><a name="l02546"></a><span class="lineno"> 2546</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(</div><div class="line"><a name="l02547"></a><span class="lineno"> 2547</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02548"></a><span class="lineno"> 2548</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l02549"></a><span class="lineno"> 2549</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l02550"></a><span class="lineno"> 2550</span>&#160;    VkBuffer* pBuffer,</div><div class="line"><a name="l02551"></a><span class="lineno"> 2551</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l02552"></a><span class="lineno"> 2552</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02553"></a><span class="lineno"> 2553</span>&#160;</div><div class="line"><a name="l02565"></a><span class="lineno"> 2565</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(</div><div class="line"><a name="l02566"></a><span class="lineno"> 2566</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02567"></a><span class="lineno"> 2567</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l02568"></a><span class="lineno"> 2568</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l02569"></a><span class="lineno"> 2569</span>&#160;</div><div class="line"><a name="l02571"></a><span class="lineno"> 2571</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73">vmaCreateImage</a>(</div><div class="line"><a name="l02572"></a><span class="lineno"> 2572</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02573"></a><span class="lineno"> 2573</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l02574"></a><span class="lineno"> 2574</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l02575"></a><span class="lineno"> 2575</span>&#160;    VkImage* pImage,</div><div class="line"><a name="l02576"></a><span class="lineno"> 2576</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l02577"></a><span class="lineno"> 2577</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l02578"></a><span class="lineno"> 2578</span>&#160;</div><div class="line"><a name="l02590"></a><span class="lineno"> 2590</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae50d2cb3b4a3bfd4dd40987234e50e7e">vmaDestroyImage</a>(</div><div class="line"><a name="l02591"></a><span class="lineno"> 2591</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l02592"></a><span class="lineno"> 2592</span>&#160;    VkImage image,</div><div class="line"><a name="l02593"></a><span class="lineno"> 2593</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l02594"></a><span class="lineno"> 2594</span>&#160;</div><div class="line"><a name="l02595"></a><span class="lineno"> 2595</span>&#160;<span class="preprocessor">#ifdef __cplusplus</span></div><div class="line"><a name="l02596"></a><span class="lineno"> 2596</span>&#160;}</div><div class="line"><a name="l02597"></a><span class="lineno"> 2597</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02598"></a><span class="lineno"> 2598</span>&#160;</div><div class="line"><a name="l02599"></a><span class="lineno"> 2599</span>&#160;<span class="preprocessor">#endif // AMD_VULKAN_MEMORY_ALLOCATOR_H</span></div><div class="line"><a name="l02600"></a><span class="lineno"> 2600</span>&#160;</div><div class="line"><a name="l02601"></a><span class="lineno"> 2601</span>&#160;<span class="comment">// For Visual Studio IntelliSense.</span></div><div class="line"><a name="l02602"></a><span class="lineno"> 2602</span>&#160;<span class="preprocessor">#if defined(__cplusplus) &amp;&amp; defined(__INTELLISENSE__)</span></div><div class="line"><a name="l02603"></a><span class="lineno"> 2603</span>&#160;<span class="preprocessor">#define VMA_IMPLEMENTATION</span></div><div class="line"><a name="l02604"></a><span class="lineno"> 2604</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02605"></a><span class="lineno"> 2605</span>&#160;</div><div class="line"><a name="l02606"></a><span class="lineno"> 2606</span>&#160;<span class="preprocessor">#ifdef VMA_IMPLEMENTATION</span></div><div class="line"><a name="l02607"></a><span class="lineno"> 2607</span>&#160;<span class="preprocessor">#undef VMA_IMPLEMENTATION</span></div><div class="line"><a name="l02608"></a><span class="lineno"> 2608</span>&#160;</div><div class="line"><a name="l02609"></a><span class="lineno"> 2609</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l02610"></a><span class="lineno"> 2610</span>&#160;<span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><a name="l02611"></a><span class="lineno"> 2611</span>&#160;<span class="preprocessor">#include &lt;cstring&gt;</span></div><div class="line"><a name="l02612"></a><span class="lineno"> 2612</span>&#160;</div><div class="line"><a name="l02613"></a><span class="lineno"> 2613</span>&#160;<span class="comment">/*******************************************************************************</span></div><div class="line"><a name="l02614"></a><span class="lineno"> 2614</span>&#160;<span class="comment">CONFIGURATION SECTION</span></div><div class="line"><a name="l02615"></a><span class="lineno"> 2615</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02616"></a><span class="lineno"> 2616</span>&#160;<span class="comment">Define some of these macros before each #include of this header or change them</span></div><div class="line"><a name="l02617"></a><span class="lineno"> 2617</span>&#160;<span class="comment">here if you need other then default behavior depending on your environment.</span></div><div class="line"><a name="l02618"></a><span class="lineno"> 2618</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02619"></a><span class="lineno"> 2619</span>&#160;</div><div class="line"><a name="l02620"></a><span class="lineno"> 2620</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02621"></a><span class="lineno"> 2621</span>&#160;<span class="comment">Define this macro to 1 to make the library fetch pointers to Vulkan functions</span></div><div class="line"><a name="l02622"></a><span class="lineno"> 2622</span>&#160;<span class="comment">internally, like:</span></div><div class="line"><a name="l02623"></a><span class="lineno"> 2623</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02624"></a><span class="lineno"> 2624</span>&#160;<span class="comment">    vulkanFunctions.vkAllocateMemory = &amp;vkAllocateMemory;</span></div><div class="line"><a name="l02625"></a><span class="lineno"> 2625</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02626"></a><span class="lineno"> 2626</span>&#160;<span class="comment">Define to 0 if you are going to provide you own pointers to Vulkan functions via</span></div><div class="line"><a name="l02627"></a><span class="lineno"> 2627</span>&#160;<span class="comment">VmaAllocatorCreateInfo::pVulkanFunctions.</span></div><div class="line"><a name="l02628"></a><span class="lineno"> 2628</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02629"></a><span class="lineno"> 2629</span>&#160;<span class="preprocessor">#if !defined(VMA_STATIC_VULKAN_FUNCTIONS) &amp;&amp; !defined(VK_NO_PROTOTYPES)</span></div><div class="line"><a name="l02630"></a><span class="lineno"> 2630</span>&#160;<span class="preprocessor">#define VMA_STATIC_VULKAN_FUNCTIONS 1</span></div><div class="line"><a name="l02631"></a><span class="lineno"> 2631</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02632"></a><span class="lineno"> 2632</span>&#160;</div><div class="line"><a name="l02633"></a><span class="lineno"> 2633</span>&#160;<span class="comment">// Define this macro to 1 to make the library use STL containers instead of its own implementation.</span></div><div class="line"><a name="l02634"></a><span class="lineno"> 2634</span>&#160;<span class="comment">//#define VMA_USE_STL_CONTAINERS 1</span></div><div class="line"><a name="l02635"></a><span class="lineno"> 2635</span>&#160;</div><div class="line"><a name="l02636"></a><span class="lineno"> 2636</span>&#160;<span class="comment">/* Set this macro to 1 to make the library including and using STL containers:</span></div><div class="line"><a name="l02637"></a><span class="lineno"> 2637</span>&#160;<span class="comment">std::pair, std::vector, std::list, std::unordered_map.</span></div><div class="line"><a name="l02638"></a><span class="lineno"> 2638</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02639"></a><span class="lineno"> 2639</span>&#160;<span class="comment">Set it to 0 or undefined to make the library using its own implementation of</span></div><div class="line"><a name="l02640"></a><span class="lineno"> 2640</span>&#160;<span class="comment">the containers.</span></div><div class="line"><a name="l02641"></a><span class="lineno"> 2641</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02642"></a><span class="lineno"> 2642</span>&#160;<span class="preprocessor">#if VMA_USE_STL_CONTAINERS</span></div><div class="line"><a name="l02643"></a><span class="lineno"> 2643</span>&#160;<span class="preprocessor">   #define VMA_USE_STL_VECTOR 1</span></div><div class="line"><a name="l02644"></a><span class="lineno"> 2644</span>&#160;<span class="preprocessor">   #define VMA_USE_STL_UNORDERED_MAP 1</span></div><div class="line"><a name="l02645"></a><span class="lineno"> 2645</span>&#160;<span class="preprocessor">   #define VMA_USE_STL_LIST 1</span></div><div class="line"><a name="l02646"></a><span class="lineno"> 2646</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02647"></a><span class="lineno"> 2647</span>&#160;</div><div class="line"><a name="l02648"></a><span class="lineno"> 2648</span>&#160;<span class="preprocessor">#if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l02649"></a><span class="lineno"> 2649</span>&#160;<span class="preprocessor">   #include &lt;vector&gt;</span></div><div class="line"><a name="l02650"></a><span class="lineno"> 2650</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02651"></a><span class="lineno"> 2651</span>&#160;</div><div class="line"><a name="l02652"></a><span class="lineno"> 2652</span>&#160;<span class="preprocessor">#if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l02653"></a><span class="lineno"> 2653</span>&#160;<span class="preprocessor">   #include &lt;unordered_map&gt;</span></div><div class="line"><a name="l02654"></a><span class="lineno"> 2654</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02655"></a><span class="lineno"> 2655</span>&#160;</div><div class="line"><a name="l02656"></a><span class="lineno"> 2656</span>&#160;<span class="preprocessor">#if VMA_USE_STL_LIST</span></div><div class="line"><a name="l02657"></a><span class="lineno"> 2657</span>&#160;<span class="preprocessor">   #include &lt;list&gt;</span></div><div class="line"><a name="l02658"></a><span class="lineno"> 2658</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02659"></a><span class="lineno"> 2659</span>&#160;</div><div class="line"><a name="l02660"></a><span class="lineno"> 2660</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02661"></a><span class="lineno"> 2661</span>&#160;<span class="comment">Following headers are used in this CONFIGURATION section only, so feel free to</span></div><div class="line"><a name="l02662"></a><span class="lineno"> 2662</span>&#160;<span class="comment">remove them if not needed.</span></div><div class="line"><a name="l02663"></a><span class="lineno"> 2663</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02664"></a><span class="lineno"> 2664</span>&#160;<span class="preprocessor">#include &lt;cassert&gt;</span> <span class="comment">// for assert</span></div><div class="line"><a name="l02665"></a><span class="lineno"> 2665</span>&#160;<span class="preprocessor">#include &lt;algorithm&gt;</span> <span class="comment">// for min, max</span></div><div class="line"><a name="l02666"></a><span class="lineno"> 2666</span>&#160;<span class="preprocessor">#include &lt;mutex&gt;</span> <span class="comment">// for std::mutex</span></div><div class="line"><a name="l02667"></a><span class="lineno"> 2667</span>&#160;<span class="preprocessor">#include &lt;atomic&gt;</span> <span class="comment">// for std::atomic</span></div><div class="line"><a name="l02668"></a><span class="lineno"> 2668</span>&#160;</div><div class="line"><a name="l02669"></a><span class="lineno"> 2669</span>&#160;<span class="preprocessor">#ifndef VMA_NULL</span></div><div class="line"><a name="l02670"></a><span class="lineno"> 2670</span>&#160;   <span class="comment">// Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.</span></div><div class="line"><a name="l02671"></a><span class="lineno"> 2671</span>&#160;<span class="preprocessor">   #define VMA_NULL   nullptr</span></div><div class="line"><a name="l02672"></a><span class="lineno"> 2672</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02673"></a><span class="lineno"> 2673</span>&#160;</div><div class="line"><a name="l02674"></a><span class="lineno"> 2674</span>&#160;<span class="preprocessor">#if defined(__APPLE__) || defined(__ANDROID__)</span></div><div class="line"><a name="l02675"></a><span class="lineno"> 2675</span>&#160;<span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><a name="l02676"></a><span class="lineno"> 2676</span>&#160;<span class="keywordtype">void</span> *aligned_alloc(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size)</div><div class="line"><a name="l02677"></a><span class="lineno"> 2677</span>&#160;{</div><div class="line"><a name="l02678"></a><span class="lineno"> 2678</span>&#160;    <span class="comment">// alignment must be &gt;= sizeof(void*)</span></div><div class="line"><a name="l02679"></a><span class="lineno"> 2679</span>&#160;    <span class="keywordflow">if</span>(alignment &lt; <span class="keyword">sizeof</span>(<span class="keywordtype">void</span>*))</div><div class="line"><a name="l02680"></a><span class="lineno"> 2680</span>&#160;    {</div><div class="line"><a name="l02681"></a><span class="lineno"> 2681</span>&#160;        alignment = <span class="keyword">sizeof</span>(<span class="keywordtype">void</span>*);</div><div class="line"><a name="l02682"></a><span class="lineno"> 2682</span>&#160;    }</div><div class="line"><a name="l02683"></a><span class="lineno"> 2683</span>&#160;</div><div class="line"><a name="l02684"></a><span class="lineno"> 2684</span>&#160;    <span class="keywordtype">void</span> *pointer;</div><div class="line"><a name="l02685"></a><span class="lineno"> 2685</span>&#160;    <span class="keywordflow">if</span>(posix_memalign(&amp;pointer, alignment, size) == 0)</div><div class="line"><a name="l02686"></a><span class="lineno"> 2686</span>&#160;        <span class="keywordflow">return</span> pointer;</div><div class="line"><a name="l02687"></a><span class="lineno"> 2687</span>&#160;    <span class="keywordflow">return</span> VMA_NULL;</div><div class="line"><a name="l02688"></a><span class="lineno"> 2688</span>&#160;}</div><div class="line"><a name="l02689"></a><span class="lineno"> 2689</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02690"></a><span class="lineno"> 2690</span>&#160;</div><div class="line"><a name="l02691"></a><span class="lineno"> 2691</span>&#160;<span class="comment">// If your compiler is not compatible with C++11 and definition of</span></div><div class="line"><a name="l02692"></a><span class="lineno"> 2692</span>&#160;<span class="comment">// aligned_alloc() function is missing, uncommeting following line may help:</span></div><div class="line"><a name="l02693"></a><span class="lineno"> 2693</span>&#160;</div><div class="line"><a name="l02694"></a><span class="lineno"> 2694</span>&#160;<span class="comment">//#include &lt;malloc.h&gt;</span></div><div class="line"><a name="l02695"></a><span class="lineno"> 2695</span>&#160;</div><div class="line"><a name="l02696"></a><span class="lineno"> 2696</span>&#160;<span class="comment">// Normal assert to check for programmer&#39;s errors, especially in Debug configuration.</span></div><div class="line"><a name="l02697"></a><span class="lineno"> 2697</span>&#160;<span class="preprocessor">#ifndef VMA_ASSERT</span></div><div class="line"><a name="l02698"></a><span class="lineno"> 2698</span>&#160;<span class="preprocessor">   #ifdef _DEBUG</span></div><div class="line"><a name="l02699"></a><span class="lineno"> 2699</span>&#160;<span class="preprocessor">       #define VMA_ASSERT(expr)         assert(expr)</span></div><div class="line"><a name="l02700"></a><span class="lineno"> 2700</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02701"></a><span class="lineno"> 2701</span>&#160;<span class="preprocessor">       #define VMA_ASSERT(expr)</span></div><div class="line"><a name="l02702"></a><span class="lineno"> 2702</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02703"></a><span class="lineno"> 2703</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02704"></a><span class="lineno"> 2704</span>&#160;</div><div class="line"><a name="l02705"></a><span class="lineno"> 2705</span>&#160;<span class="comment">// Assert that will be called very often, like inside data structures e.g. operator[].</span></div><div class="line"><a name="l02706"></a><span class="lineno"> 2706</span>&#160;<span class="comment">// Making it non-empty can make program slow.</span></div><div class="line"><a name="l02707"></a><span class="lineno"> 2707</span>&#160;<span class="preprocessor">#ifndef VMA_HEAVY_ASSERT</span></div><div class="line"><a name="l02708"></a><span class="lineno"> 2708</span>&#160;<span class="preprocessor">   #ifdef _DEBUG</span></div><div class="line"><a name="l02709"></a><span class="lineno"> 2709</span>&#160;<span class="preprocessor">       #define VMA_HEAVY_ASSERT(expr)   //VMA_ASSERT(expr)</span></div><div class="line"><a name="l02710"></a><span class="lineno"> 2710</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02711"></a><span class="lineno"> 2711</span>&#160;<span class="preprocessor">       #define VMA_HEAVY_ASSERT(expr)</span></div><div class="line"><a name="l02712"></a><span class="lineno"> 2712</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02713"></a><span class="lineno"> 2713</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02714"></a><span class="lineno"> 2714</span>&#160;</div><div class="line"><a name="l02715"></a><span class="lineno"> 2715</span>&#160;<span class="preprocessor">#ifndef VMA_ALIGN_OF</span></div><div class="line"><a name="l02716"></a><span class="lineno"> 2716</span>&#160;<span class="preprocessor">   #define VMA_ALIGN_OF(type)       (__alignof(type))</span></div><div class="line"><a name="l02717"></a><span class="lineno"> 2717</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02718"></a><span class="lineno"> 2718</span>&#160;</div><div class="line"><a name="l02719"></a><span class="lineno"> 2719</span>&#160;<span class="preprocessor">#ifndef VMA_SYSTEM_ALIGNED_MALLOC</span></div><div class="line"><a name="l02720"></a><span class="lineno"> 2720</span>&#160;<span class="preprocessor">   #if defined(_WIN32)</span></div><div class="line"><a name="l02721"></a><span class="lineno"> 2721</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment)   (_aligned_malloc((size), (alignment)))</span></div><div class="line"><a name="l02722"></a><span class="lineno"> 2722</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02723"></a><span class="lineno"> 2723</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment)   (aligned_alloc((alignment), (size) ))</span></div><div class="line"><a name="l02724"></a><span class="lineno"> 2724</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02725"></a><span class="lineno"> 2725</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02726"></a><span class="lineno"> 2726</span>&#160;</div><div class="line"><a name="l02727"></a><span class="lineno"> 2727</span>&#160;<span class="preprocessor">#ifndef VMA_SYSTEM_FREE</span></div><div class="line"><a name="l02728"></a><span class="lineno"> 2728</span>&#160;<span class="preprocessor">   #if defined(_WIN32)</span></div><div class="line"><a name="l02729"></a><span class="lineno"> 2729</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_FREE(ptr)   _aligned_free(ptr)</span></div><div class="line"><a name="l02730"></a><span class="lineno"> 2730</span>&#160;<span class="preprocessor">   #else</span></div><div class="line"><a name="l02731"></a><span class="lineno"> 2731</span>&#160;<span class="preprocessor">       #define VMA_SYSTEM_FREE(ptr)   free(ptr)</span></div><div class="line"><a name="l02732"></a><span class="lineno"> 2732</span>&#160;<span class="preprocessor">   #endif</span></div><div class="line"><a name="l02733"></a><span class="lineno"> 2733</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02734"></a><span class="lineno"> 2734</span>&#160;</div><div class="line"><a name="l02735"></a><span class="lineno"> 2735</span>&#160;<span class="preprocessor">#ifndef VMA_MIN</span></div><div class="line"><a name="l02736"></a><span class="lineno"> 2736</span>&#160;<span class="preprocessor">   #define VMA_MIN(v1, v2)    (std::min((v1), (v2)))</span></div><div class="line"><a name="l02737"></a><span class="lineno"> 2737</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02738"></a><span class="lineno"> 2738</span>&#160;</div><div class="line"><a name="l02739"></a><span class="lineno"> 2739</span>&#160;<span class="preprocessor">#ifndef VMA_MAX</span></div><div class="line"><a name="l02740"></a><span class="lineno"> 2740</span>&#160;<span class="preprocessor">   #define VMA_MAX(v1, v2)    (std::max((v1), (v2)))</span></div><div class="line"><a name="l02741"></a><span class="lineno"> 2741</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02742"></a><span class="lineno"> 2742</span>&#160;</div><div class="line"><a name="l02743"></a><span class="lineno"> 2743</span>&#160;<span class="preprocessor">#ifndef VMA_SWAP</span></div><div class="line"><a name="l02744"></a><span class="lineno"> 2744</span>&#160;<span class="preprocessor">   #define VMA_SWAP(v1, v2)   std::swap((v1), (v2))</span></div><div class="line"><a name="l02745"></a><span class="lineno"> 2745</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02746"></a><span class="lineno"> 2746</span>&#160;</div><div class="line"><a name="l02747"></a><span class="lineno"> 2747</span>&#160;<span class="preprocessor">#ifndef VMA_SORT</span></div><div class="line"><a name="l02748"></a><span class="lineno"> 2748</span>&#160;<span class="preprocessor">   #define VMA_SORT(beg, end, cmp)  std::sort(beg, end, cmp)</span></div><div class="line"><a name="l02749"></a><span class="lineno"> 2749</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02750"></a><span class="lineno"> 2750</span>&#160;</div><div class="line"><a name="l02751"></a><span class="lineno"> 2751</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_LOG</span></div><div class="line"><a name="l02752"></a><span class="lineno"> 2752</span>&#160;<span class="preprocessor">   #define VMA_DEBUG_LOG(format, ...)</span></div><div class="line"><a name="l02753"></a><span class="lineno"> 2753</span>&#160;   <span class="comment">/*</span></div><div class="line"><a name="l02754"></a><span class="lineno"> 2754</span>&#160;<span class="comment">   #define VMA_DEBUG_LOG(format, ...) do { \</span></div><div class="line"><a name="l02755"></a><span class="lineno"> 2755</span>&#160;<span class="comment">       printf(format, __VA_ARGS__); \</span></div><div class="line"><a name="l02756"></a><span class="lineno"> 2756</span>&#160;<span class="comment">       printf(&quot;\n&quot;); \</span></div><div class="line"><a name="l02757"></a><span class="lineno"> 2757</span>&#160;<span class="comment">   } while(false)</span></div><div class="line"><a name="l02758"></a><span class="lineno"> 2758</span>&#160;<span class="comment">   */</span></div><div class="line"><a name="l02759"></a><span class="lineno"> 2759</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02760"></a><span class="lineno"> 2760</span>&#160;</div><div class="line"><a name="l02761"></a><span class="lineno"> 2761</span>&#160;<span class="comment">// Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString.</span></div><div class="line"><a name="l02762"></a><span class="lineno"> 2762</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l02763"></a><span class="lineno"> 2763</span>&#160;    <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> VmaUint32ToStr(<span class="keywordtype">char</span>* outStr, <span class="keywordtype">size_t</span> strLen, uint32_t num)</div><div class="line"><a name="l02764"></a><span class="lineno"> 2764</span>&#160;    {</div><div class="line"><a name="l02765"></a><span class="lineno"> 2765</span>&#160;        snprintf(outStr, strLen, <span class="stringliteral">&quot;%u&quot;</span>, static_cast&lt;unsigned int&gt;(num));</div><div class="line"><a name="l02766"></a><span class="lineno"> 2766</span>&#160;    }</div><div class="line"><a name="l02767"></a><span class="lineno"> 2767</span>&#160;    <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> VmaUint64ToStr(<span class="keywordtype">char</span>* outStr, <span class="keywordtype">size_t</span> strLen, uint64_t num)</div><div class="line"><a name="l02768"></a><span class="lineno"> 2768</span>&#160;    {</div><div class="line"><a name="l02769"></a><span class="lineno"> 2769</span>&#160;        snprintf(outStr, strLen, <span class="stringliteral">&quot;%llu&quot;</span>, static_cast&lt;unsigned long long&gt;(num));</div><div class="line"><a name="l02770"></a><span class="lineno"> 2770</span>&#160;    }</div><div class="line"><a name="l02771"></a><span class="lineno"> 2771</span>&#160;    <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> VmaPtrToStr(<span class="keywordtype">char</span>* outStr, <span class="keywordtype">size_t</span> strLen, <span class="keyword">const</span> <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l02772"></a><span class="lineno"> 2772</span>&#160;    {</div><div class="line"><a name="l02773"></a><span class="lineno"> 2773</span>&#160;        snprintf(outStr, strLen, <span class="stringliteral">&quot;%p&quot;</span>, ptr);</div><div class="line"><a name="l02774"></a><span class="lineno"> 2774</span>&#160;    }</div><div class="line"><a name="l02775"></a><span class="lineno"> 2775</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02776"></a><span class="lineno"> 2776</span>&#160;</div><div class="line"><a name="l02777"></a><span class="lineno"> 2777</span>&#160;<span class="preprocessor">#ifndef VMA_MUTEX</span></div><div class="line"><a name="l02778"></a><span class="lineno"> 2778</span>&#160;    <span class="keyword">class </span>VmaMutex</div><div class="line"><a name="l02779"></a><span class="lineno"> 2779</span>&#160;    {</div><div class="line"><a name="l02780"></a><span class="lineno"> 2780</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l02781"></a><span class="lineno"> 2781</span>&#160;        VmaMutex() { }</div><div class="line"><a name="l02782"></a><span class="lineno"> 2782</span>&#160;        ~VmaMutex() { }</div><div class="line"><a name="l02783"></a><span class="lineno"> 2783</span>&#160;        <span class="keywordtype">void</span> Lock() { m_Mutex.lock(); }</div><div class="line"><a name="l02784"></a><span class="lineno"> 2784</span>&#160;        <span class="keywordtype">void</span> Unlock() { m_Mutex.unlock(); }</div><div class="line"><a name="l02785"></a><span class="lineno"> 2785</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l02786"></a><span class="lineno"> 2786</span>&#160;        std::mutex m_Mutex;</div><div class="line"><a name="l02787"></a><span class="lineno"> 2787</span>&#160;    };</div><div class="line"><a name="l02788"></a><span class="lineno"> 2788</span>&#160;<span class="preprocessor">    #define VMA_MUTEX VmaMutex</span></div><div class="line"><a name="l02789"></a><span class="lineno"> 2789</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02790"></a><span class="lineno"> 2790</span>&#160;</div><div class="line"><a name="l02791"></a><span class="lineno"> 2791</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02792"></a><span class="lineno"> 2792</span>&#160;<span class="comment">If providing your own implementation, you need to implement a subset of std::atomic:</span></div><div class="line"><a name="l02793"></a><span class="lineno"> 2793</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02794"></a><span class="lineno"> 2794</span>&#160;<span class="comment">- Constructor(uint32_t desired)</span></div><div class="line"><a name="l02795"></a><span class="lineno"> 2795</span>&#160;<span class="comment">- uint32_t load() const</span></div><div class="line"><a name="l02796"></a><span class="lineno"> 2796</span>&#160;<span class="comment">- void store(uint32_t desired)</span></div><div class="line"><a name="l02797"></a><span class="lineno"> 2797</span>&#160;<span class="comment">- bool compare_exchange_weak(uint32_t&amp; expected, uint32_t desired)</span></div><div class="line"><a name="l02798"></a><span class="lineno"> 2798</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02799"></a><span class="lineno"> 2799</span>&#160;<span class="preprocessor">#ifndef VMA_ATOMIC_UINT32</span></div><div class="line"><a name="l02800"></a><span class="lineno"> 2800</span>&#160;<span class="preprocessor">   #define VMA_ATOMIC_UINT32 std::atomic&lt;uint32_t&gt;</span></div><div class="line"><a name="l02801"></a><span class="lineno"> 2801</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02802"></a><span class="lineno"> 2802</span>&#160;</div><div class="line"><a name="l02803"></a><span class="lineno"> 2803</span>&#160;<span class="preprocessor">#ifndef VMA_BEST_FIT</span></div><div class="line"><a name="l02804"></a><span class="lineno"> 2804</span>&#160;</div><div class="line"><a name="l02816"></a><span class="lineno"> 2816</span>&#160;<span class="preprocessor">    #define VMA_BEST_FIT (1)</span></div><div class="line"><a name="l02817"></a><span class="lineno"> 2817</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02818"></a><span class="lineno"> 2818</span>&#160;</div><div class="line"><a name="l02819"></a><span class="lineno"> 2819</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_ALWAYS_DEDICATED_MEMORY</span></div><div class="line"><a name="l02820"></a><span class="lineno"> 2820</span>&#160;</div><div class="line"><a name="l02824"></a><span class="lineno"> 2824</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0)</span></div><div class="line"><a name="l02825"></a><span class="lineno"> 2825</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02826"></a><span class="lineno"> 2826</span>&#160;</div><div class="line"><a name="l02827"></a><span class="lineno"> 2827</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_ALIGNMENT</span></div><div class="line"><a name="l02828"></a><span class="lineno"> 2828</span>&#160;</div><div class="line"><a name="l02832"></a><span class="lineno"> 2832</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_ALIGNMENT (1)</span></div><div class="line"><a name="l02833"></a><span class="lineno"> 2833</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02834"></a><span class="lineno"> 2834</span>&#160;</div><div class="line"><a name="l02835"></a><span class="lineno"> 2835</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_MARGIN</span></div><div class="line"><a name="l02836"></a><span class="lineno"> 2836</span>&#160;</div><div class="line"><a name="l02840"></a><span class="lineno"> 2840</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_MARGIN (0)</span></div><div class="line"><a name="l02841"></a><span class="lineno"> 2841</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02842"></a><span class="lineno"> 2842</span>&#160;</div><div class="line"><a name="l02843"></a><span class="lineno"> 2843</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_INITIALIZE_ALLOCATIONS</span></div><div class="line"><a name="l02844"></a><span class="lineno"> 2844</span>&#160;</div><div class="line"><a name="l02848"></a><span class="lineno"> 2848</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_INITIALIZE_ALLOCATIONS (0)</span></div><div class="line"><a name="l02849"></a><span class="lineno"> 2849</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02850"></a><span class="lineno"> 2850</span>&#160;</div><div class="line"><a name="l02851"></a><span class="lineno"> 2851</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_DETECT_CORRUPTION</span></div><div class="line"><a name="l02852"></a><span class="lineno"> 2852</span>&#160;</div><div class="line"><a name="l02857"></a><span class="lineno"> 2857</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_DETECT_CORRUPTION (0)</span></div><div class="line"><a name="l02858"></a><span class="lineno"> 2858</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02859"></a><span class="lineno"> 2859</span>&#160;</div><div class="line"><a name="l02860"></a><span class="lineno"> 2860</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_GLOBAL_MUTEX</span></div><div class="line"><a name="l02861"></a><span class="lineno"> 2861</span>&#160;</div><div class="line"><a name="l02865"></a><span class="lineno"> 2865</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_GLOBAL_MUTEX (0)</span></div><div class="line"><a name="l02866"></a><span class="lineno"> 2866</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02867"></a><span class="lineno"> 2867</span>&#160;</div><div class="line"><a name="l02868"></a><span class="lineno"> 2868</span>&#160;<span class="preprocessor">#ifndef VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY</span></div><div class="line"><a name="l02869"></a><span class="lineno"> 2869</span>&#160;</div><div class="line"><a name="l02873"></a><span class="lineno"> 2873</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1)</span></div><div class="line"><a name="l02874"></a><span class="lineno"> 2874</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02875"></a><span class="lineno"> 2875</span>&#160;</div><div class="line"><a name="l02876"></a><span class="lineno"> 2876</span>&#160;<span class="preprocessor">#ifndef VMA_SMALL_HEAP_MAX_SIZE</span></div><div class="line"><a name="l02877"></a><span class="lineno"> 2877</span>&#160;<span class="preprocessor">   #define VMA_SMALL_HEAP_MAX_SIZE (1024ull * 1024 * 1024)</span></div><div class="line"><a name="l02879"></a><span class="lineno"> 2879</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02880"></a><span class="lineno"> 2880</span>&#160;</div><div class="line"><a name="l02881"></a><span class="lineno"> 2881</span>&#160;<span class="preprocessor">#ifndef VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE</span></div><div class="line"><a name="l02882"></a><span class="lineno"> 2882</span>&#160;<span class="preprocessor">   #define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256ull * 1024 * 1024)</span></div><div class="line"><a name="l02884"></a><span class="lineno"> 2884</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02885"></a><span class="lineno"> 2885</span>&#160;</div><div class="line"><a name="l02886"></a><span class="lineno"> 2886</span>&#160;<span class="preprocessor">#ifndef VMA_CLASS_NO_COPY</span></div><div class="line"><a name="l02887"></a><span class="lineno"> 2887</span>&#160;<span class="preprocessor">    #define VMA_CLASS_NO_COPY(className) \</span></div><div class="line"><a name="l02888"></a><span class="lineno"> 2888</span>&#160;<span class="preprocessor">        private: \</span></div><div class="line"><a name="l02889"></a><span class="lineno"> 2889</span>&#160;<span class="preprocessor">            className(const className&amp;) = delete; \</span></div><div class="line"><a name="l02890"></a><span class="lineno"> 2890</span>&#160;<span class="preprocessor">            className&amp; operator=(const className&amp;) = delete;</span></div><div class="line"><a name="l02891"></a><span class="lineno"> 2891</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l02892"></a><span class="lineno"> 2892</span>&#160;</div><div class="line"><a name="l02893"></a><span class="lineno"> 2893</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint32_t VMA_FRAME_INDEX_LOST = UINT32_MAX;</div><div class="line"><a name="l02894"></a><span class="lineno"> 2894</span>&#160;</div><div class="line"><a name="l02895"></a><span class="lineno"> 2895</span>&#160;<span class="comment">// Decimal 2139416166, float NaN, little-endian binary 66 E6 84 7F.</span></div><div class="line"><a name="l02896"></a><span class="lineno"> 2896</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666;</div><div class="line"><a name="l02897"></a><span class="lineno"> 2897</span>&#160;</div><div class="line"><a name="l02898"></a><span class="lineno"> 2898</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED   = 0xDC;</div><div class="line"><a name="l02899"></a><span class="lineno"> 2899</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF;</div><div class="line"><a name="l02900"></a><span class="lineno"> 2900</span>&#160;</div><div class="line"><a name="l02901"></a><span class="lineno"> 2901</span>&#160;<span class="comment">/*******************************************************************************</span></div><div class="line"><a name="l02902"></a><span class="lineno"> 2902</span>&#160;<span class="comment">END OF CONFIGURATION</span></div><div class="line"><a name="l02903"></a><span class="lineno"> 2903</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02904"></a><span class="lineno"> 2904</span>&#160;</div><div class="line"><a name="l02905"></a><span class="lineno"> 2905</span>&#160;<span class="keyword">static</span> VkAllocationCallbacks VmaEmptyAllocationCallbacks = {</div><div class="line"><a name="l02906"></a><span class="lineno"> 2906</span>&#160;    VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL };</div><div class="line"><a name="l02907"></a><span class="lineno"> 2907</span>&#160;</div><div class="line"><a name="l02908"></a><span class="lineno"> 2908</span>&#160;<span class="comment">// Returns number of bits set to 1 in (v).</span></div><div class="line"><a name="l02909"></a><span class="lineno"> 2909</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> uint32_t VmaCountBitsSet(uint32_t v)</div><div class="line"><a name="l02910"></a><span class="lineno"> 2910</span>&#160;{</div><div class="line"><a name="l02911"></a><span class="lineno"> 2911</span>&#160;    uint32_t c = v - ((v &gt;&gt; 1) &amp; 0x55555555);</div><div class="line"><a name="l02912"></a><span class="lineno"> 2912</span>&#160;    c = ((c &gt;&gt;  2) &amp; 0x33333333) + (c &amp; 0x33333333);</div><div class="line"><a name="l02913"></a><span class="lineno"> 2913</span>&#160;    c = ((c &gt;&gt;  4) + c) &amp; 0x0F0F0F0F;</div><div class="line"><a name="l02914"></a><span class="lineno"> 2914</span>&#160;    c = ((c &gt;&gt;  8) + c) &amp; 0x00FF00FF;</div><div class="line"><a name="l02915"></a><span class="lineno"> 2915</span>&#160;    c = ((c &gt;&gt; 16) + c) &amp; 0x0000FFFF;</div><div class="line"><a name="l02916"></a><span class="lineno"> 2916</span>&#160;    <span class="keywordflow">return</span> c;</div><div class="line"><a name="l02917"></a><span class="lineno"> 2917</span>&#160;}</div><div class="line"><a name="l02918"></a><span class="lineno"> 2918</span>&#160;</div><div class="line"><a name="l02919"></a><span class="lineno"> 2919</span>&#160;<span class="comment">// Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16.</span></div><div class="line"><a name="l02920"></a><span class="lineno"> 2920</span>&#160;<span class="comment">// Use types like uint32_t, uint64_t as T.</span></div><div class="line"><a name="l02921"></a><span class="lineno"> 2921</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02922"></a><span class="lineno"> 2922</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> T VmaAlignUp(T val, T align)</div><div class="line"><a name="l02923"></a><span class="lineno"> 2923</span>&#160;{</div><div class="line"><a name="l02924"></a><span class="lineno"> 2924</span>&#160;    <span class="keywordflow">return</span> (val + align - 1) / align * align;</div><div class="line"><a name="l02925"></a><span class="lineno"> 2925</span>&#160;}</div><div class="line"><a name="l02926"></a><span class="lineno"> 2926</span>&#160;<span class="comment">// Aligns given value down to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 8.</span></div><div class="line"><a name="l02927"></a><span class="lineno"> 2927</span>&#160;<span class="comment">// Use types like uint32_t, uint64_t as T.</span></div><div class="line"><a name="l02928"></a><span class="lineno"> 2928</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02929"></a><span class="lineno"> 2929</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> T VmaAlignDown(T val, T align)</div><div class="line"><a name="l02930"></a><span class="lineno"> 2930</span>&#160;{</div><div class="line"><a name="l02931"></a><span class="lineno"> 2931</span>&#160;    <span class="keywordflow">return</span> val / align * align;</div><div class="line"><a name="l02932"></a><span class="lineno"> 2932</span>&#160;}</div><div class="line"><a name="l02933"></a><span class="lineno"> 2933</span>&#160;</div><div class="line"><a name="l02934"></a><span class="lineno"> 2934</span>&#160;<span class="comment">// Division with mathematical rounding to nearest number.</span></div><div class="line"><a name="l02935"></a><span class="lineno"> 2935</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l02936"></a><span class="lineno"> 2936</span>&#160;<span class="keyword">inline</span> T VmaRoundDiv(T x, T y)</div><div class="line"><a name="l02937"></a><span class="lineno"> 2937</span>&#160;{</div><div class="line"><a name="l02938"></a><span class="lineno"> 2938</span>&#160;    <span class="keywordflow">return</span> (x + (y / (T)2)) / y;</div><div class="line"><a name="l02939"></a><span class="lineno"> 2939</span>&#160;}</div><div class="line"><a name="l02940"></a><span class="lineno"> 2940</span>&#160;</div><div class="line"><a name="l02941"></a><span class="lineno"> 2941</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> VmaStrIsEmpty(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l02942"></a><span class="lineno"> 2942</span>&#160;{</div><div class="line"><a name="l02943"></a><span class="lineno"> 2943</span>&#160;    <span class="keywordflow">return</span> pStr == VMA_NULL || *pStr == <span class="charliteral">&#39;\0&#39;</span>;</div><div class="line"><a name="l02944"></a><span class="lineno"> 2944</span>&#160;}</div><div class="line"><a name="l02945"></a><span class="lineno"> 2945</span>&#160;</div><div class="line"><a name="l02946"></a><span class="lineno"> 2946</span>&#160;<span class="preprocessor">#ifndef VMA_SORT</span></div><div class="line"><a name="l02947"></a><span class="lineno"> 2947</span>&#160;</div><div class="line"><a name="l02948"></a><span class="lineno"> 2948</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> Iterator, <span class="keyword">typename</span> Compare&gt;</div><div class="line"><a name="l02949"></a><span class="lineno"> 2949</span>&#160;Iterator VmaQuickSortPartition(Iterator beg, Iterator end, Compare cmp)</div><div class="line"><a name="l02950"></a><span class="lineno"> 2950</span>&#160;{</div><div class="line"><a name="l02951"></a><span class="lineno"> 2951</span>&#160;    Iterator centerValue = end; --centerValue;</div><div class="line"><a name="l02952"></a><span class="lineno"> 2952</span>&#160;    Iterator insertIndex = beg;</div><div class="line"><a name="l02953"></a><span class="lineno"> 2953</span>&#160;    <span class="keywordflow">for</span>(Iterator memTypeIndex = beg; memTypeIndex &lt; centerValue; ++memTypeIndex)</div><div class="line"><a name="l02954"></a><span class="lineno"> 2954</span>&#160;    {</div><div class="line"><a name="l02955"></a><span class="lineno"> 2955</span>&#160;        <span class="keywordflow">if</span>(cmp(*memTypeIndex, *centerValue))</div><div class="line"><a name="l02956"></a><span class="lineno"> 2956</span>&#160;        {</div><div class="line"><a name="l02957"></a><span class="lineno"> 2957</span>&#160;            <span class="keywordflow">if</span>(insertIndex != memTypeIndex)</div><div class="line"><a name="l02958"></a><span class="lineno"> 2958</span>&#160;            {</div><div class="line"><a name="l02959"></a><span class="lineno"> 2959</span>&#160;                VMA_SWAP(*memTypeIndex, *insertIndex);</div><div class="line"><a name="l02960"></a><span class="lineno"> 2960</span>&#160;            }</div><div class="line"><a name="l02961"></a><span class="lineno"> 2961</span>&#160;            ++insertIndex;</div><div class="line"><a name="l02962"></a><span class="lineno"> 2962</span>&#160;        }</div><div class="line"><a name="l02963"></a><span class="lineno"> 2963</span>&#160;    }</div><div class="line"><a name="l02964"></a><span class="lineno"> 2964</span>&#160;    <span class="keywordflow">if</span>(insertIndex != centerValue)</div><div class="line"><a name="l02965"></a><span class="lineno"> 2965</span>&#160;    {</div><div class="line"><a name="l02966"></a><span class="lineno"> 2966</span>&#160;        VMA_SWAP(*insertIndex, *centerValue);</div><div class="line"><a name="l02967"></a><span class="lineno"> 2967</span>&#160;    }</div><div class="line"><a name="l02968"></a><span class="lineno"> 2968</span>&#160;    <span class="keywordflow">return</span> insertIndex;</div><div class="line"><a name="l02969"></a><span class="lineno"> 2969</span>&#160;}</div><div class="line"><a name="l02970"></a><span class="lineno"> 2970</span>&#160;</div><div class="line"><a name="l02971"></a><span class="lineno"> 2971</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> Iterator, <span class="keyword">typename</span> Compare&gt;</div><div class="line"><a name="l02972"></a><span class="lineno"> 2972</span>&#160;<span class="keywordtype">void</span> VmaQuickSort(Iterator beg, Iterator end, Compare cmp)</div><div class="line"><a name="l02973"></a><span class="lineno"> 2973</span>&#160;{</div><div class="line"><a name="l02974"></a><span class="lineno"> 2974</span>&#160;    <span class="keywordflow">if</span>(beg &lt; end)</div><div class="line"><a name="l02975"></a><span class="lineno"> 2975</span>&#160;    {</div><div class="line"><a name="l02976"></a><span class="lineno"> 2976</span>&#160;        Iterator it = VmaQuickSortPartition&lt;Iterator, Compare&gt;(beg, end, cmp);</div><div class="line"><a name="l02977"></a><span class="lineno"> 2977</span>&#160;        VmaQuickSort&lt;Iterator, Compare&gt;(beg, it, cmp);</div><div class="line"><a name="l02978"></a><span class="lineno"> 2978</span>&#160;        VmaQuickSort&lt;Iterator, Compare&gt;(it + 1, end, cmp);</div><div class="line"><a name="l02979"></a><span class="lineno"> 2979</span>&#160;    }</div><div class="line"><a name="l02980"></a><span class="lineno"> 2980</span>&#160;}</div><div class="line"><a name="l02981"></a><span class="lineno"> 2981</span>&#160;</div><div class="line"><a name="l02982"></a><span class="lineno"> 2982</span>&#160;<span class="preprocessor">#define VMA_SORT(beg, end, cmp) VmaQuickSort(beg, end, cmp)</span></div><div class="line"><a name="l02983"></a><span class="lineno"> 2983</span>&#160;</div><div class="line"><a name="l02984"></a><span class="lineno"> 2984</span>&#160;<span class="preprocessor">#endif // #ifndef VMA_SORT</span></div><div class="line"><a name="l02985"></a><span class="lineno"> 2985</span>&#160;</div><div class="line"><a name="l02986"></a><span class="lineno"> 2986</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l02987"></a><span class="lineno"> 2987</span>&#160;<span class="comment">Returns true if two memory blocks occupy overlapping pages.</span></div><div class="line"><a name="l02988"></a><span class="lineno"> 2988</span>&#160;<span class="comment">ResourceA must be in less memory offset than ResourceB.</span></div><div class="line"><a name="l02989"></a><span class="lineno"> 2989</span>&#160;<span class="comment"></span></div><div class="line"><a name="l02990"></a><span class="lineno"> 2990</span>&#160;<span class="comment">Algorithm is based on &quot;Vulkan 1.0.39 - A Specification (with all registered Vulkan extensions)&quot;</span></div><div class="line"><a name="l02991"></a><span class="lineno"> 2991</span>&#160;<span class="comment">chapter 11.6 &quot;Resource Memory Association&quot;, paragraph &quot;Buffer-Image Granularity&quot;.</span></div><div class="line"><a name="l02992"></a><span class="lineno"> 2992</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l02993"></a><span class="lineno"> 2993</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> VmaBlocksOnSamePage(</div><div class="line"><a name="l02994"></a><span class="lineno"> 2994</span>&#160;    VkDeviceSize resourceAOffset,</div><div class="line"><a name="l02995"></a><span class="lineno"> 2995</span>&#160;    VkDeviceSize resourceASize,</div><div class="line"><a name="l02996"></a><span class="lineno"> 2996</span>&#160;    VkDeviceSize resourceBOffset,</div><div class="line"><a name="l02997"></a><span class="lineno"> 2997</span>&#160;    VkDeviceSize pageSize)</div><div class="line"><a name="l02998"></a><span class="lineno"> 2998</span>&#160;{</div><div class="line"><a name="l02999"></a><span class="lineno"> 2999</span>&#160;    VMA_ASSERT(resourceAOffset + resourceASize &lt;= resourceBOffset &amp;&amp; resourceASize &gt; 0 &amp;&amp; pageSize &gt; 0);</div><div class="line"><a name="l03000"></a><span class="lineno"> 3000</span>&#160;    VkDeviceSize resourceAEnd = resourceAOffset + resourceASize - 1;</div><div class="line"><a name="l03001"></a><span class="lineno"> 3001</span>&#160;    VkDeviceSize resourceAEndPage = resourceAEnd &amp; ~(pageSize - 1);</div><div class="line"><a name="l03002"></a><span class="lineno"> 3002</span>&#160;    VkDeviceSize resourceBStart = resourceBOffset;</div><div class="line"><a name="l03003"></a><span class="lineno"> 3003</span>&#160;    VkDeviceSize resourceBStartPage = resourceBStart &amp; ~(pageSize - 1);</div><div class="line"><a name="l03004"></a><span class="lineno"> 3004</span>&#160;    <span class="keywordflow">return</span> resourceAEndPage == resourceBStartPage;</div><div class="line"><a name="l03005"></a><span class="lineno"> 3005</span>&#160;}</div><div class="line"><a name="l03006"></a><span class="lineno"> 3006</span>&#160;</div><div class="line"><a name="l03007"></a><span class="lineno"> 3007</span>&#160;<span class="keyword">enum</span> VmaSuballocationType</div><div class="line"><a name="l03008"></a><span class="lineno"> 3008</span>&#160;{</div><div class="line"><a name="l03009"></a><span class="lineno"> 3009</span>&#160;    VMA_SUBALLOCATION_TYPE_FREE = 0,</div><div class="line"><a name="l03010"></a><span class="lineno"> 3010</span>&#160;    VMA_SUBALLOCATION_TYPE_UNKNOWN = 1,</div><div class="line"><a name="l03011"></a><span class="lineno"> 3011</span>&#160;    VMA_SUBALLOCATION_TYPE_BUFFER = 2,</div><div class="line"><a name="l03012"></a><span class="lineno"> 3012</span>&#160;    VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN = 3,</div><div class="line"><a name="l03013"></a><span class="lineno"> 3013</span>&#160;    VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR = 4,</div><div class="line"><a name="l03014"></a><span class="lineno"> 3014</span>&#160;    VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL = 5,</div><div class="line"><a name="l03015"></a><span class="lineno"> 3015</span>&#160;    VMA_SUBALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF</div><div class="line"><a name="l03016"></a><span class="lineno"> 3016</span>&#160;};</div><div class="line"><a name="l03017"></a><span class="lineno"> 3017</span>&#160;</div><div class="line"><a name="l03018"></a><span class="lineno"> 3018</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l03019"></a><span class="lineno"> 3019</span>&#160;<span class="comment">Returns true if given suballocation types could conflict and must respect</span></div><div class="line"><a name="l03020"></a><span class="lineno"> 3020</span>&#160;<span class="comment">VkPhysicalDeviceLimits::bufferImageGranularity. They conflict if one is buffer</span></div><div class="line"><a name="l03021"></a><span class="lineno"> 3021</span>&#160;<span class="comment">or linear image and another one is optimal image. If type is unknown, behave</span></div><div class="line"><a name="l03022"></a><span class="lineno"> 3022</span>&#160;<span class="comment">conservatively.</span></div><div class="line"><a name="l03023"></a><span class="lineno"> 3023</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03024"></a><span class="lineno"> 3024</span>&#160;<span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> VmaIsBufferImageGranularityConflict(</div><div class="line"><a name="l03025"></a><span class="lineno"> 3025</span>&#160;    VmaSuballocationType suballocType1,</div><div class="line"><a name="l03026"></a><span class="lineno"> 3026</span>&#160;    VmaSuballocationType suballocType2)</div><div class="line"><a name="l03027"></a><span class="lineno"> 3027</span>&#160;{</div><div class="line"><a name="l03028"></a><span class="lineno"> 3028</span>&#160;    <span class="keywordflow">if</span>(suballocType1 &gt; suballocType2)</div><div class="line"><a name="l03029"></a><span class="lineno"> 3029</span>&#160;    {</div><div class="line"><a name="l03030"></a><span class="lineno"> 3030</span>&#160;        VMA_SWAP(suballocType1, suballocType2);</div><div class="line"><a name="l03031"></a><span class="lineno"> 3031</span>&#160;    }</div><div class="line"><a name="l03032"></a><span class="lineno"> 3032</span>&#160;    </div><div class="line"><a name="l03033"></a><span class="lineno"> 3033</span>&#160;    <span class="keywordflow">switch</span>(suballocType1)</div><div class="line"><a name="l03034"></a><span class="lineno"> 3034</span>&#160;    {</div><div class="line"><a name="l03035"></a><span class="lineno"> 3035</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_FREE:</div><div class="line"><a name="l03036"></a><span class="lineno"> 3036</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l03037"></a><span class="lineno"> 3037</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_UNKNOWN:</div><div class="line"><a name="l03038"></a><span class="lineno"> 3038</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l03039"></a><span class="lineno"> 3039</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_BUFFER:</div><div class="line"><a name="l03040"></a><span class="lineno"> 3040</span>&#160;        <span class="keywordflow">return</span></div><div class="line"><a name="l03041"></a><span class="lineno"> 3041</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||</div><div class="line"><a name="l03042"></a><span class="lineno"> 3042</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;</div><div class="line"><a name="l03043"></a><span class="lineno"> 3043</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN:</div><div class="line"><a name="l03044"></a><span class="lineno"> 3044</span>&#160;        <span class="keywordflow">return</span></div><div class="line"><a name="l03045"></a><span class="lineno"> 3045</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||</div><div class="line"><a name="l03046"></a><span class="lineno"> 3046</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR ||</div><div class="line"><a name="l03047"></a><span class="lineno"> 3047</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;</div><div class="line"><a name="l03048"></a><span class="lineno"> 3048</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR:</div><div class="line"><a name="l03049"></a><span class="lineno"> 3049</span>&#160;        <span class="keywordflow">return</span></div><div class="line"><a name="l03050"></a><span class="lineno"> 3050</span>&#160;            suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;</div><div class="line"><a name="l03051"></a><span class="lineno"> 3051</span>&#160;    <span class="keywordflow">case</span> VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL:</div><div class="line"><a name="l03052"></a><span class="lineno"> 3052</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l03053"></a><span class="lineno"> 3053</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l03054"></a><span class="lineno"> 3054</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l03055"></a><span class="lineno"> 3055</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l03056"></a><span class="lineno"> 3056</span>&#160;    }</div><div class="line"><a name="l03057"></a><span class="lineno"> 3057</span>&#160;}</div><div class="line"><a name="l03058"></a><span class="lineno"> 3058</span>&#160;</div><div class="line"><a name="l03059"></a><span class="lineno"> 3059</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaWriteMagicValue(<span class="keywordtype">void</span>* pData, VkDeviceSize offset)</div><div class="line"><a name="l03060"></a><span class="lineno"> 3060</span>&#160;{</div><div class="line"><a name="l03061"></a><span class="lineno"> 3061</span>&#160;    uint32_t* pDst = (uint32_t*)((<span class="keywordtype">char</span>*)pData + offset);</div><div class="line"><a name="l03062"></a><span class="lineno"> 3062</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> numberCount = VMA_DEBUG_MARGIN / <span class="keyword">sizeof</span>(uint32_t);</div><div class="line"><a name="l03063"></a><span class="lineno"> 3063</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; numberCount; ++i, ++pDst)</div><div class="line"><a name="l03064"></a><span class="lineno"> 3064</span>&#160;    {</div><div class="line"><a name="l03065"></a><span class="lineno"> 3065</span>&#160;        *pDst = VMA_CORRUPTION_DETECTION_MAGIC_VALUE;</div><div class="line"><a name="l03066"></a><span class="lineno"> 3066</span>&#160;    }</div><div class="line"><a name="l03067"></a><span class="lineno"> 3067</span>&#160;}</div><div class="line"><a name="l03068"></a><span class="lineno"> 3068</span>&#160;</div><div class="line"><a name="l03069"></a><span class="lineno"> 3069</span>&#160;<span class="keyword">static</span> <span class="keywordtype">bool</span> VmaValidateMagicValue(<span class="keyword">const</span> <span class="keywordtype">void</span>* pData, VkDeviceSize offset)</div><div class="line"><a name="l03070"></a><span class="lineno"> 3070</span>&#160;{</div><div class="line"><a name="l03071"></a><span class="lineno"> 3071</span>&#160;    <span class="keyword">const</span> uint32_t* pSrc = (<span class="keyword">const</span> uint32_t*)((<span class="keyword">const</span> <span class="keywordtype">char</span>*)pData + offset);</div><div class="line"><a name="l03072"></a><span class="lineno"> 3072</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> numberCount = VMA_DEBUG_MARGIN / <span class="keyword">sizeof</span>(uint32_t);</div><div class="line"><a name="l03073"></a><span class="lineno"> 3073</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; numberCount; ++i, ++pSrc)</div><div class="line"><a name="l03074"></a><span class="lineno"> 3074</span>&#160;    {</div><div class="line"><a name="l03075"></a><span class="lineno"> 3075</span>&#160;        <span class="keywordflow">if</span>(*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE)</div><div class="line"><a name="l03076"></a><span class="lineno"> 3076</span>&#160;        {</div><div class="line"><a name="l03077"></a><span class="lineno"> 3077</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l03078"></a><span class="lineno"> 3078</span>&#160;        }</div><div class="line"><a name="l03079"></a><span class="lineno"> 3079</span>&#160;    }</div><div class="line"><a name="l03080"></a><span class="lineno"> 3080</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l03081"></a><span class="lineno"> 3081</span>&#160;}</div><div class="line"><a name="l03082"></a><span class="lineno"> 3082</span>&#160;</div><div class="line"><a name="l03083"></a><span class="lineno"> 3083</span>&#160;<span class="comment">// Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope).</span></div><div class="line"><a name="l03084"></a><span class="lineno"> 3084</span>&#160;<span class="keyword">struct </span>VmaMutexLock</div><div class="line"><a name="l03085"></a><span class="lineno"> 3085</span>&#160;{</div><div class="line"><a name="l03086"></a><span class="lineno"> 3086</span>&#160;    VMA_CLASS_NO_COPY(VmaMutexLock)</div><div class="line"><a name="l03087"></a><span class="lineno"> 3087</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03088"></a><span class="lineno"> 3088</span>&#160;    VmaMutexLock(VMA_MUTEX&amp; mutex, <span class="keywordtype">bool</span> useMutex) :</div><div class="line"><a name="l03089"></a><span class="lineno"> 3089</span>&#160;        m_pMutex(useMutex ? &amp;mutex : VMA_NULL)</div><div class="line"><a name="l03090"></a><span class="lineno"> 3090</span>&#160;    {</div><div class="line"><a name="l03091"></a><span class="lineno"> 3091</span>&#160;        <span class="keywordflow">if</span>(m_pMutex)</div><div class="line"><a name="l03092"></a><span class="lineno"> 3092</span>&#160;        {</div><div class="line"><a name="l03093"></a><span class="lineno"> 3093</span>&#160;            m_pMutex-&gt;Lock();</div><div class="line"><a name="l03094"></a><span class="lineno"> 3094</span>&#160;        }</div><div class="line"><a name="l03095"></a><span class="lineno"> 3095</span>&#160;    }</div><div class="line"><a name="l03096"></a><span class="lineno"> 3096</span>&#160;    </div><div class="line"><a name="l03097"></a><span class="lineno"> 3097</span>&#160;    ~VmaMutexLock()</div><div class="line"><a name="l03098"></a><span class="lineno"> 3098</span>&#160;    {</div><div class="line"><a name="l03099"></a><span class="lineno"> 3099</span>&#160;        <span class="keywordflow">if</span>(m_pMutex)</div><div class="line"><a name="l03100"></a><span class="lineno"> 3100</span>&#160;        {</div><div class="line"><a name="l03101"></a><span class="lineno"> 3101</span>&#160;            m_pMutex-&gt;Unlock();</div><div class="line"><a name="l03102"></a><span class="lineno"> 3102</span>&#160;        }</div><div class="line"><a name="l03103"></a><span class="lineno"> 3103</span>&#160;    }</div><div class="line"><a name="l03104"></a><span class="lineno"> 3104</span>&#160;</div><div class="line"><a name="l03105"></a><span class="lineno"> 3105</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03106"></a><span class="lineno"> 3106</span>&#160;    VMA_MUTEX* m_pMutex;</div><div class="line"><a name="l03107"></a><span class="lineno"> 3107</span>&#160;};</div><div class="line"><a name="l03108"></a><span class="lineno"> 3108</span>&#160;</div><div class="line"><a name="l03109"></a><span class="lineno"> 3109</span>&#160;<span class="preprocessor">#if VMA_DEBUG_GLOBAL_MUTEX</span></div><div class="line"><a name="l03110"></a><span class="lineno"> 3110</span>&#160;    <span class="keyword">static</span> VMA_MUTEX gDebugGlobalMutex;</div><div class="line"><a name="l03111"></a><span class="lineno"> 3111</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex, true);</span></div><div class="line"><a name="l03112"></a><span class="lineno"> 3112</span>&#160;<span class="preprocessor">#else</span></div><div class="line"><a name="l03113"></a><span class="lineno"> 3113</span>&#160;<span class="preprocessor">    #define VMA_DEBUG_GLOBAL_MUTEX_LOCK</span></div><div class="line"><a name="l03114"></a><span class="lineno"> 3114</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l03115"></a><span class="lineno"> 3115</span>&#160;</div><div class="line"><a name="l03116"></a><span class="lineno"> 3116</span>&#160;<span class="comment">// Minimum size of a free suballocation to register it in the free suballocation collection.</span></div><div class="line"><a name="l03117"></a><span class="lineno"> 3117</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> VkDeviceSize VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER = 16;</div><div class="line"><a name="l03118"></a><span class="lineno"> 3118</span>&#160;</div><div class="line"><a name="l03119"></a><span class="lineno"> 3119</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l03120"></a><span class="lineno"> 3120</span>&#160;<span class="comment">Performs binary search and returns iterator to first element that is greater or</span></div><div class="line"><a name="l03121"></a><span class="lineno"> 3121</span>&#160;<span class="comment">equal to (key), according to comparison (cmp).</span></div><div class="line"><a name="l03122"></a><span class="lineno"> 3122</span>&#160;<span class="comment"></span></div><div class="line"><a name="l03123"></a><span class="lineno"> 3123</span>&#160;<span class="comment">Cmp should return true if first argument is less than second argument.</span></div><div class="line"><a name="l03124"></a><span class="lineno"> 3124</span>&#160;<span class="comment"></span></div><div class="line"><a name="l03125"></a><span class="lineno"> 3125</span>&#160;<span class="comment">Returned value is the found element, if present in the collection or place where</span></div><div class="line"><a name="l03126"></a><span class="lineno"> 3126</span>&#160;<span class="comment">new element with value (key) should be inserted.</span></div><div class="line"><a name="l03127"></a><span class="lineno"> 3127</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03128"></a><span class="lineno"> 3128</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CmpLess, <span class="keyword">typename</span> IterT, <span class="keyword">typename</span> KeyT&gt;</div><div class="line"><a name="l03129"></a><span class="lineno"> 3129</span>&#160;<span class="keyword">static</span> IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, <span class="keyword">const</span> KeyT &amp;key, CmpLess cmp)</div><div class="line"><a name="l03130"></a><span class="lineno"> 3130</span>&#160;{</div><div class="line"><a name="l03131"></a><span class="lineno"> 3131</span>&#160;    <span class="keywordtype">size_t</span> down = 0, up = (end - beg);</div><div class="line"><a name="l03132"></a><span class="lineno"> 3132</span>&#160;    <span class="keywordflow">while</span>(down &lt; up)</div><div class="line"><a name="l03133"></a><span class="lineno"> 3133</span>&#160;    {</div><div class="line"><a name="l03134"></a><span class="lineno"> 3134</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> mid = (down + up) / 2;</div><div class="line"><a name="l03135"></a><span class="lineno"> 3135</span>&#160;        <span class="keywordflow">if</span>(cmp(*(beg+mid), key))</div><div class="line"><a name="l03136"></a><span class="lineno"> 3136</span>&#160;        {</div><div class="line"><a name="l03137"></a><span class="lineno"> 3137</span>&#160;            down = mid + 1;</div><div class="line"><a name="l03138"></a><span class="lineno"> 3138</span>&#160;        }</div><div class="line"><a name="l03139"></a><span class="lineno"> 3139</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l03140"></a><span class="lineno"> 3140</span>&#160;        {</div><div class="line"><a name="l03141"></a><span class="lineno"> 3141</span>&#160;            up = mid;</div><div class="line"><a name="l03142"></a><span class="lineno"> 3142</span>&#160;        }</div><div class="line"><a name="l03143"></a><span class="lineno"> 3143</span>&#160;    }</div><div class="line"><a name="l03144"></a><span class="lineno"> 3144</span>&#160;    <span class="keywordflow">return</span> beg + down;</div><div class="line"><a name="l03145"></a><span class="lineno"> 3145</span>&#160;}</div><div class="line"><a name="l03146"></a><span class="lineno"> 3146</span>&#160;</div><div class="line"><a name="l03148"></a><span class="lineno"> 3148</span>&#160;<span class="comment">// Memory allocation</span></div><div class="line"><a name="l03149"></a><span class="lineno"> 3149</span>&#160;</div><div class="line"><a name="l03150"></a><span class="lineno"> 3150</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span>* VmaMalloc(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment)</div><div class="line"><a name="l03151"></a><span class="lineno"> 3151</span>&#160;{</div><div class="line"><a name="l03152"></a><span class="lineno"> 3152</span>&#160;    <span class="keywordflow">if</span>((pAllocationCallbacks != VMA_NULL) &amp;&amp;</div><div class="line"><a name="l03153"></a><span class="lineno"> 3153</span>&#160;        (pAllocationCallbacks-&gt;pfnAllocation != VMA_NULL))</div><div class="line"><a name="l03154"></a><span class="lineno"> 3154</span>&#160;    {</div><div class="line"><a name="l03155"></a><span class="lineno"> 3155</span>&#160;        <span class="keywordflow">return</span> (*pAllocationCallbacks-&gt;pfnAllocation)(</div><div class="line"><a name="l03156"></a><span class="lineno"> 3156</span>&#160;            pAllocationCallbacks-&gt;pUserData,</div><div class="line"><a name="l03157"></a><span class="lineno"> 3157</span>&#160;            size,</div><div class="line"><a name="l03158"></a><span class="lineno"> 3158</span>&#160;            alignment,</div><div class="line"><a name="l03159"></a><span class="lineno"> 3159</span>&#160;            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);</div><div class="line"><a name="l03160"></a><span class="lineno"> 3160</span>&#160;    }</div><div class="line"><a name="l03161"></a><span class="lineno"> 3161</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03162"></a><span class="lineno"> 3162</span>&#160;    {</div><div class="line"><a name="l03163"></a><span class="lineno"> 3163</span>&#160;        <span class="keywordflow">return</span> VMA_SYSTEM_ALIGNED_MALLOC(size, alignment);</div><div class="line"><a name="l03164"></a><span class="lineno"> 3164</span>&#160;    }</div><div class="line"><a name="l03165"></a><span class="lineno"> 3165</span>&#160;}</div><div class="line"><a name="l03166"></a><span class="lineno"> 3166</span>&#160;</div><div class="line"><a name="l03167"></a><span class="lineno"> 3167</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaFree(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l03168"></a><span class="lineno"> 3168</span>&#160;{</div><div class="line"><a name="l03169"></a><span class="lineno"> 3169</span>&#160;    <span class="keywordflow">if</span>((pAllocationCallbacks != VMA_NULL) &amp;&amp;</div><div class="line"><a name="l03170"></a><span class="lineno"> 3170</span>&#160;        (pAllocationCallbacks-&gt;pfnFree != VMA_NULL))</div><div class="line"><a name="l03171"></a><span class="lineno"> 3171</span>&#160;    {</div><div class="line"><a name="l03172"></a><span class="lineno"> 3172</span>&#160;        (*pAllocationCallbacks-&gt;pfnFree)(pAllocationCallbacks-&gt;pUserData, ptr);</div><div class="line"><a name="l03173"></a><span class="lineno"> 3173</span>&#160;    }</div><div class="line"><a name="l03174"></a><span class="lineno"> 3174</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03175"></a><span class="lineno"> 3175</span>&#160;    {</div><div class="line"><a name="l03176"></a><span class="lineno"> 3176</span>&#160;        VMA_SYSTEM_FREE(ptr);</div><div class="line"><a name="l03177"></a><span class="lineno"> 3177</span>&#160;    }</div><div class="line"><a name="l03178"></a><span class="lineno"> 3178</span>&#160;}</div><div class="line"><a name="l03179"></a><span class="lineno"> 3179</span>&#160;</div><div class="line"><a name="l03180"></a><span class="lineno"> 3180</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03181"></a><span class="lineno"> 3181</span>&#160;<span class="keyword">static</span> T* VmaAllocate(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks)</div><div class="line"><a name="l03182"></a><span class="lineno"> 3182</span>&#160;{</div><div class="line"><a name="l03183"></a><span class="lineno"> 3183</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(pAllocationCallbacks, <span class="keyword">sizeof</span>(T), VMA_ALIGN_OF(T));</div><div class="line"><a name="l03184"></a><span class="lineno"> 3184</span>&#160;}</div><div class="line"><a name="l03185"></a><span class="lineno"> 3185</span>&#160;</div><div class="line"><a name="l03186"></a><span class="lineno"> 3186</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03187"></a><span class="lineno"> 3187</span>&#160;<span class="keyword">static</span> T* VmaAllocateArray(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l03188"></a><span class="lineno"> 3188</span>&#160;{</div><div class="line"><a name="l03189"></a><span class="lineno"> 3189</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(pAllocationCallbacks, <span class="keyword">sizeof</span>(T) * count, VMA_ALIGN_OF(T));</div><div class="line"><a name="l03190"></a><span class="lineno"> 3190</span>&#160;}</div><div class="line"><a name="l03191"></a><span class="lineno"> 3191</span>&#160;</div><div class="line"><a name="l03192"></a><span class="lineno"> 3192</span>&#160;<span class="preprocessor">#define vma_new(allocator, type)   new(VmaAllocate&lt;type&gt;(allocator))(type)</span></div><div class="line"><a name="l03193"></a><span class="lineno"> 3193</span>&#160;</div><div class="line"><a name="l03194"></a><span class="lineno"> 3194</span>&#160;<span class="preprocessor">#define vma_new_array(allocator, type, count)   new(VmaAllocateArray&lt;type&gt;((allocator), (count)))(type)</span></div><div class="line"><a name="l03195"></a><span class="lineno"> 3195</span>&#160;</div><div class="line"><a name="l03196"></a><span class="lineno"> 3196</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03197"></a><span class="lineno"> 3197</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, T* ptr)</div><div class="line"><a name="l03198"></a><span class="lineno"> 3198</span>&#160;{</div><div class="line"><a name="l03199"></a><span class="lineno"> 3199</span>&#160;    ptr-&gt;~T();</div><div class="line"><a name="l03200"></a><span class="lineno"> 3200</span>&#160;    VmaFree(pAllocationCallbacks, ptr);</div><div class="line"><a name="l03201"></a><span class="lineno"> 3201</span>&#160;}</div><div class="line"><a name="l03202"></a><span class="lineno"> 3202</span>&#160;</div><div class="line"><a name="l03203"></a><span class="lineno"> 3203</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03204"></a><span class="lineno"> 3204</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete_array(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, T* ptr, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l03205"></a><span class="lineno"> 3205</span>&#160;{</div><div class="line"><a name="l03206"></a><span class="lineno"> 3206</span>&#160;    <span class="keywordflow">if</span>(ptr != VMA_NULL)</div><div class="line"><a name="l03207"></a><span class="lineno"> 3207</span>&#160;    {</div><div class="line"><a name="l03208"></a><span class="lineno"> 3208</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = count; i--; )</div><div class="line"><a name="l03209"></a><span class="lineno"> 3209</span>&#160;        {</div><div class="line"><a name="l03210"></a><span class="lineno"> 3210</span>&#160;            ptr[i].~T();</div><div class="line"><a name="l03211"></a><span class="lineno"> 3211</span>&#160;        }</div><div class="line"><a name="l03212"></a><span class="lineno"> 3212</span>&#160;        VmaFree(pAllocationCallbacks, ptr);</div><div class="line"><a name="l03213"></a><span class="lineno"> 3213</span>&#160;    }</div><div class="line"><a name="l03214"></a><span class="lineno"> 3214</span>&#160;}</div><div class="line"><a name="l03215"></a><span class="lineno"> 3215</span>&#160;</div><div class="line"><a name="l03216"></a><span class="lineno"> 3216</span>&#160;<span class="comment">// STL-compatible allocator.</span></div><div class="line"><a name="l03217"></a><span class="lineno"> 3217</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03218"></a><span class="lineno"> 3218</span>&#160;<span class="keyword">class </span>VmaStlAllocator</div><div class="line"><a name="l03219"></a><span class="lineno"> 3219</span>&#160;{</div><div class="line"><a name="l03220"></a><span class="lineno"> 3220</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03221"></a><span class="lineno"> 3221</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* <span class="keyword">const</span> m_pCallbacks;</div><div class="line"><a name="l03222"></a><span class="lineno"> 3222</span>&#160;    <span class="keyword">typedef</span> T value_type;</div><div class="line"><a name="l03223"></a><span class="lineno"> 3223</span>&#160;    </div><div class="line"><a name="l03224"></a><span class="lineno"> 3224</span>&#160;    VmaStlAllocator(<span class="keyword">const</span> VkAllocationCallbacks* pCallbacks) : m_pCallbacks(pCallbacks) { }</div><div class="line"><a name="l03225"></a><span class="lineno"> 3225</span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> U&gt; VmaStlAllocator(<span class="keyword">const</span> VmaStlAllocator&lt;U&gt;&amp; src) : m_pCallbacks(src.m_pCallbacks) { }</div><div class="line"><a name="l03226"></a><span class="lineno"> 3226</span>&#160;</div><div class="line"><a name="l03227"></a><span class="lineno"> 3227</span>&#160;    T* allocate(<span class="keywordtype">size_t</span> n) { <span class="keywordflow">return</span> VmaAllocateArray&lt;T&gt;(m_pCallbacks, n); }</div><div class="line"><a name="l03228"></a><span class="lineno"> 3228</span>&#160;    <span class="keywordtype">void</span> deallocate(T* p, <span class="keywordtype">size_t</span> n) { VmaFree(m_pCallbacks, p); }</div><div class="line"><a name="l03229"></a><span class="lineno"> 3229</span>&#160;</div><div class="line"><a name="l03230"></a><span class="lineno"> 3230</span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> U&gt;</div><div class="line"><a name="l03231"></a><span class="lineno"> 3231</span>&#160;    <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> VmaStlAllocator&lt;U&gt;&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03232"></a><span class="lineno"> 3232</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03233"></a><span class="lineno"> 3233</span>&#160;        <span class="keywordflow">return</span> m_pCallbacks == rhs.m_pCallbacks;</div><div class="line"><a name="l03234"></a><span class="lineno"> 3234</span>&#160;    }</div><div class="line"><a name="l03235"></a><span class="lineno"> 3235</span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> U&gt;</div><div class="line"><a name="l03236"></a><span class="lineno"> 3236</span>&#160;    <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> VmaStlAllocator&lt;U&gt;&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03237"></a><span class="lineno"> 3237</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03238"></a><span class="lineno"> 3238</span>&#160;        <span class="keywordflow">return</span> m_pCallbacks != rhs.m_pCallbacks;</div><div class="line"><a name="l03239"></a><span class="lineno"> 3239</span>&#160;    }</div><div class="line"><a name="l03240"></a><span class="lineno"> 3240</span>&#160;</div><div class="line"><a name="l03241"></a><span class="lineno"> 3241</span>&#160;    VmaStlAllocator&amp; operator=(<span class="keyword">const</span> VmaStlAllocator&amp; x) = <span class="keyword">delete</span>;</div><div class="line"><a name="l03242"></a><span class="lineno"> 3242</span>&#160;};</div><div class="line"><a name="l03243"></a><span class="lineno"> 3243</span>&#160;</div><div class="line"><a name="l03244"></a><span class="lineno"> 3244</span>&#160;<span class="preprocessor">#if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l03245"></a><span class="lineno"> 3245</span>&#160;</div><div class="line"><a name="l03246"></a><span class="lineno"> 3246</span>&#160;<span class="preprocessor">#define VmaVector std::vector</span></div><div class="line"><a name="l03247"></a><span class="lineno"> 3247</span>&#160;</div><div class="line"><a name="l03248"></a><span class="lineno"> 3248</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l03249"></a><span class="lineno"> 3249</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorInsert(std::vector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index, <span class="keyword">const</span> T&amp; item)</div><div class="line"><a name="l03250"></a><span class="lineno"> 3250</span>&#160;{</div><div class="line"><a name="l03251"></a><span class="lineno"> 3251</span>&#160;    vec.insert(vec.begin() + index, item);</div><div class="line"><a name="l03252"></a><span class="lineno"> 3252</span>&#160;}</div><div class="line"><a name="l03253"></a><span class="lineno"> 3253</span>&#160;</div><div class="line"><a name="l03254"></a><span class="lineno"> 3254</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l03255"></a><span class="lineno"> 3255</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorRemove(std::vector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l03256"></a><span class="lineno"> 3256</span>&#160;{</div><div class="line"><a name="l03257"></a><span class="lineno"> 3257</span>&#160;    vec.erase(vec.begin() + index);</div><div class="line"><a name="l03258"></a><span class="lineno"> 3258</span>&#160;}</div><div class="line"><a name="l03259"></a><span class="lineno"> 3259</span>&#160;</div><div class="line"><a name="l03260"></a><span class="lineno"> 3260</span>&#160;<span class="preprocessor">#else // #if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l03261"></a><span class="lineno"> 3261</span>&#160;</div><div class="line"><a name="l03262"></a><span class="lineno"> 3262</span>&#160;<span class="comment">/* Class with interface compatible with subset of std::vector.</span></div><div class="line"><a name="l03263"></a><span class="lineno"> 3263</span>&#160;<span class="comment">T must be POD because constructors and destructors are not called and memcpy is</span></div><div class="line"><a name="l03264"></a><span class="lineno"> 3264</span>&#160;<span class="comment">used for these objects. */</span></div><div class="line"><a name="l03265"></a><span class="lineno"> 3265</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> AllocatorT&gt;</div><div class="line"><a name="l03266"></a><span class="lineno"> 3266</span>&#160;<span class="keyword">class </span>VmaVector</div><div class="line"><a name="l03267"></a><span class="lineno"> 3267</span>&#160;{</div><div class="line"><a name="l03268"></a><span class="lineno"> 3268</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03269"></a><span class="lineno"> 3269</span>&#160;    <span class="keyword">typedef</span> T value_type;</div><div class="line"><a name="l03270"></a><span class="lineno"> 3270</span>&#160;</div><div class="line"><a name="l03271"></a><span class="lineno"> 3271</span>&#160;    VmaVector(<span class="keyword">const</span> AllocatorT&amp; allocator) :</div><div class="line"><a name="l03272"></a><span class="lineno"> 3272</span>&#160;        m_Allocator(allocator),</div><div class="line"><a name="l03273"></a><span class="lineno"> 3273</span>&#160;        m_pArray(VMA_NULL),</div><div class="line"><a name="l03274"></a><span class="lineno"> 3274</span>&#160;        m_Count(0),</div><div class="line"><a name="l03275"></a><span class="lineno"> 3275</span>&#160;        m_Capacity(0)</div><div class="line"><a name="l03276"></a><span class="lineno"> 3276</span>&#160;    {</div><div class="line"><a name="l03277"></a><span class="lineno"> 3277</span>&#160;    }</div><div class="line"><a name="l03278"></a><span class="lineno"> 3278</span>&#160;</div><div class="line"><a name="l03279"></a><span class="lineno"> 3279</span>&#160;    VmaVector(<span class="keywordtype">size_t</span> count, <span class="keyword">const</span> AllocatorT&amp; allocator) :</div><div class="line"><a name="l03280"></a><span class="lineno"> 3280</span>&#160;        m_Allocator(allocator),</div><div class="line"><a name="l03281"></a><span class="lineno"> 3281</span>&#160;        m_pArray(count ? (T*)VmaAllocateArray&lt;T&gt;(allocator.m_pCallbacks, count) : VMA_NULL),</div><div class="line"><a name="l03282"></a><span class="lineno"> 3282</span>&#160;        m_Count(count),</div><div class="line"><a name="l03283"></a><span class="lineno"> 3283</span>&#160;        m_Capacity(count)</div><div class="line"><a name="l03284"></a><span class="lineno"> 3284</span>&#160;    {</div><div class="line"><a name="l03285"></a><span class="lineno"> 3285</span>&#160;    }</div><div class="line"><a name="l03286"></a><span class="lineno"> 3286</span>&#160;    </div><div class="line"><a name="l03287"></a><span class="lineno"> 3287</span>&#160;    VmaVector(<span class="keyword">const</span> VmaVector&lt;T, AllocatorT&gt;&amp; src) :</div><div class="line"><a name="l03288"></a><span class="lineno"> 3288</span>&#160;        m_Allocator(src.m_Allocator),</div><div class="line"><a name="l03289"></a><span class="lineno"> 3289</span>&#160;        m_pArray(src.m_Count ? (T*)VmaAllocateArray&lt;T&gt;(src.m_Allocator.m_pCallbacks, src.m_Count) : VMA_NULL),</div><div class="line"><a name="l03290"></a><span class="lineno"> 3290</span>&#160;        m_Count(src.m_Count),</div><div class="line"><a name="l03291"></a><span class="lineno"> 3291</span>&#160;        m_Capacity(src.m_Count)</div><div class="line"><a name="l03292"></a><span class="lineno"> 3292</span>&#160;    {</div><div class="line"><a name="l03293"></a><span class="lineno"> 3293</span>&#160;        <span class="keywordflow">if</span>(m_Count != 0)</div><div class="line"><a name="l03294"></a><span class="lineno"> 3294</span>&#160;        {</div><div class="line"><a name="l03295"></a><span class="lineno"> 3295</span>&#160;            memcpy(m_pArray, src.m_pArray, m_Count * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l03296"></a><span class="lineno"> 3296</span>&#160;        }</div><div class="line"><a name="l03297"></a><span class="lineno"> 3297</span>&#160;    }</div><div class="line"><a name="l03298"></a><span class="lineno"> 3298</span>&#160;    </div><div class="line"><a name="l03299"></a><span class="lineno"> 3299</span>&#160;    ~VmaVector()</div><div class="line"><a name="l03300"></a><span class="lineno"> 3300</span>&#160;    {</div><div class="line"><a name="l03301"></a><span class="lineno"> 3301</span>&#160;        VmaFree(m_Allocator.m_pCallbacks, m_pArray);</div><div class="line"><a name="l03302"></a><span class="lineno"> 3302</span>&#160;    }</div><div class="line"><a name="l03303"></a><span class="lineno"> 3303</span>&#160;</div><div class="line"><a name="l03304"></a><span class="lineno"> 3304</span>&#160;    VmaVector&amp; operator=(<span class="keyword">const</span> VmaVector&lt;T, AllocatorT&gt;&amp; rhs)</div><div class="line"><a name="l03305"></a><span class="lineno"> 3305</span>&#160;    {</div><div class="line"><a name="l03306"></a><span class="lineno"> 3306</span>&#160;        <span class="keywordflow">if</span>(&amp;rhs != <span class="keyword">this</span>)</div><div class="line"><a name="l03307"></a><span class="lineno"> 3307</span>&#160;        {</div><div class="line"><a name="l03308"></a><span class="lineno"> 3308</span>&#160;            resize(rhs.m_Count);</div><div class="line"><a name="l03309"></a><span class="lineno"> 3309</span>&#160;            <span class="keywordflow">if</span>(m_Count != 0)</div><div class="line"><a name="l03310"></a><span class="lineno"> 3310</span>&#160;            {</div><div class="line"><a name="l03311"></a><span class="lineno"> 3311</span>&#160;                memcpy(m_pArray, rhs.m_pArray, m_Count * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l03312"></a><span class="lineno"> 3312</span>&#160;            }</div><div class="line"><a name="l03313"></a><span class="lineno"> 3313</span>&#160;        }</div><div class="line"><a name="l03314"></a><span class="lineno"> 3314</span>&#160;        <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l03315"></a><span class="lineno"> 3315</span>&#160;    }</div><div class="line"><a name="l03316"></a><span class="lineno"> 3316</span>&#160;    </div><div class="line"><a name="l03317"></a><span class="lineno"> 3317</span>&#160;    <span class="keywordtype">bool</span> empty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count == 0; }</div><div class="line"><a name="l03318"></a><span class="lineno"> 3318</span>&#160;    <span class="keywordtype">size_t</span> size()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count; }</div><div class="line"><a name="l03319"></a><span class="lineno"> 3319</span>&#160;    T* data() { <span class="keywordflow">return</span> m_pArray; }</div><div class="line"><a name="l03320"></a><span class="lineno"> 3320</span>&#160;    <span class="keyword">const</span> T* data()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pArray; }</div><div class="line"><a name="l03321"></a><span class="lineno"> 3321</span>&#160;    </div><div class="line"><a name="l03322"></a><span class="lineno"> 3322</span>&#160;    T&amp; operator[](<span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l03323"></a><span class="lineno"> 3323</span>&#160;    {</div><div class="line"><a name="l03324"></a><span class="lineno"> 3324</span>&#160;        VMA_HEAVY_ASSERT(index &lt; m_Count);</div><div class="line"><a name="l03325"></a><span class="lineno"> 3325</span>&#160;        <span class="keywordflow">return</span> m_pArray[index];</div><div class="line"><a name="l03326"></a><span class="lineno"> 3326</span>&#160;    }</div><div class="line"><a name="l03327"></a><span class="lineno"> 3327</span>&#160;    <span class="keyword">const</span> T&amp; operator[](<span class="keywordtype">size_t</span> index)<span class="keyword"> const</span></div><div class="line"><a name="l03328"></a><span class="lineno"> 3328</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03329"></a><span class="lineno"> 3329</span>&#160;        VMA_HEAVY_ASSERT(index &lt; m_Count);</div><div class="line"><a name="l03330"></a><span class="lineno"> 3330</span>&#160;        <span class="keywordflow">return</span> m_pArray[index];</div><div class="line"><a name="l03331"></a><span class="lineno"> 3331</span>&#160;    }</div><div class="line"><a name="l03332"></a><span class="lineno"> 3332</span>&#160;</div><div class="line"><a name="l03333"></a><span class="lineno"> 3333</span>&#160;    T&amp; front()</div><div class="line"><a name="l03334"></a><span class="lineno"> 3334</span>&#160;    {</div><div class="line"><a name="l03335"></a><span class="lineno"> 3335</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03336"></a><span class="lineno"> 3336</span>&#160;        <span class="keywordflow">return</span> m_pArray[0];</div><div class="line"><a name="l03337"></a><span class="lineno"> 3337</span>&#160;    }</div><div class="line"><a name="l03338"></a><span class="lineno"> 3338</span>&#160;    <span class="keyword">const</span> T&amp; front()<span class="keyword"> const</span></div><div class="line"><a name="l03339"></a><span class="lineno"> 3339</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03340"></a><span class="lineno"> 3340</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03341"></a><span class="lineno"> 3341</span>&#160;        <span class="keywordflow">return</span> m_pArray[0];</div><div class="line"><a name="l03342"></a><span class="lineno"> 3342</span>&#160;    }</div><div class="line"><a name="l03343"></a><span class="lineno"> 3343</span>&#160;    T&amp; back()</div><div class="line"><a name="l03344"></a><span class="lineno"> 3344</span>&#160;    {</div><div class="line"><a name="l03345"></a><span class="lineno"> 3345</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03346"></a><span class="lineno"> 3346</span>&#160;        <span class="keywordflow">return</span> m_pArray[m_Count - 1];</div><div class="line"><a name="l03347"></a><span class="lineno"> 3347</span>&#160;    }</div><div class="line"><a name="l03348"></a><span class="lineno"> 3348</span>&#160;    <span class="keyword">const</span> T&amp; back()<span class="keyword"> const</span></div><div class="line"><a name="l03349"></a><span class="lineno"> 3349</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l03350"></a><span class="lineno"> 3350</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03351"></a><span class="lineno"> 3351</span>&#160;        <span class="keywordflow">return</span> m_pArray[m_Count - 1];</div><div class="line"><a name="l03352"></a><span class="lineno"> 3352</span>&#160;    }</div><div class="line"><a name="l03353"></a><span class="lineno"> 3353</span>&#160;</div><div class="line"><a name="l03354"></a><span class="lineno"> 3354</span>&#160;    <span class="keywordtype">void</span> reserve(<span class="keywordtype">size_t</span> newCapacity, <span class="keywordtype">bool</span> freeMemory = <span class="keyword">false</span>)</div><div class="line"><a name="l03355"></a><span class="lineno"> 3355</span>&#160;    {</div><div class="line"><a name="l03356"></a><span class="lineno"> 3356</span>&#160;        newCapacity = VMA_MAX(newCapacity, m_Count);</div><div class="line"><a name="l03357"></a><span class="lineno"> 3357</span>&#160;        </div><div class="line"><a name="l03358"></a><span class="lineno"> 3358</span>&#160;        <span class="keywordflow">if</span>((newCapacity &lt; m_Capacity) &amp;&amp; !freeMemory)</div><div class="line"><a name="l03359"></a><span class="lineno"> 3359</span>&#160;        {</div><div class="line"><a name="l03360"></a><span class="lineno"> 3360</span>&#160;            newCapacity = m_Capacity;</div><div class="line"><a name="l03361"></a><span class="lineno"> 3361</span>&#160;        }</div><div class="line"><a name="l03362"></a><span class="lineno"> 3362</span>&#160;        </div><div class="line"><a name="l03363"></a><span class="lineno"> 3363</span>&#160;        <span class="keywordflow">if</span>(newCapacity != m_Capacity)</div><div class="line"><a name="l03364"></a><span class="lineno"> 3364</span>&#160;        {</div><div class="line"><a name="l03365"></a><span class="lineno"> 3365</span>&#160;            T* <span class="keyword">const</span> newArray = newCapacity ? VmaAllocateArray&lt;T&gt;(m_Allocator, newCapacity) : VMA_NULL;</div><div class="line"><a name="l03366"></a><span class="lineno"> 3366</span>&#160;            <span class="keywordflow">if</span>(m_Count != 0)</div><div class="line"><a name="l03367"></a><span class="lineno"> 3367</span>&#160;            {</div><div class="line"><a name="l03368"></a><span class="lineno"> 3368</span>&#160;                memcpy(newArray, m_pArray, m_Count * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l03369"></a><span class="lineno"> 3369</span>&#160;            }</div><div class="line"><a name="l03370"></a><span class="lineno"> 3370</span>&#160;            VmaFree(m_Allocator.m_pCallbacks, m_pArray);</div><div class="line"><a name="l03371"></a><span class="lineno"> 3371</span>&#160;            m_Capacity = newCapacity;</div><div class="line"><a name="l03372"></a><span class="lineno"> 3372</span>&#160;            m_pArray = newArray;</div><div class="line"><a name="l03373"></a><span class="lineno"> 3373</span>&#160;        }</div><div class="line"><a name="l03374"></a><span class="lineno"> 3374</span>&#160;    }</div><div class="line"><a name="l03375"></a><span class="lineno"> 3375</span>&#160;</div><div class="line"><a name="l03376"></a><span class="lineno"> 3376</span>&#160;    <span class="keywordtype">void</span> resize(<span class="keywordtype">size_t</span> newCount, <span class="keywordtype">bool</span> freeMemory = <span class="keyword">false</span>)</div><div class="line"><a name="l03377"></a><span class="lineno"> 3377</span>&#160;    {</div><div class="line"><a name="l03378"></a><span class="lineno"> 3378</span>&#160;        <span class="keywordtype">size_t</span> newCapacity = m_Capacity;</div><div class="line"><a name="l03379"></a><span class="lineno"> 3379</span>&#160;        <span class="keywordflow">if</span>(newCount &gt; m_Capacity)</div><div class="line"><a name="l03380"></a><span class="lineno"> 3380</span>&#160;        {</div><div class="line"><a name="l03381"></a><span class="lineno"> 3381</span>&#160;            newCapacity = VMA_MAX(newCount, VMA_MAX(m_Capacity * 3 / 2, (<span class="keywordtype">size_t</span>)8));</div><div class="line"><a name="l03382"></a><span class="lineno"> 3382</span>&#160;        }</div><div class="line"><a name="l03383"></a><span class="lineno"> 3383</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(freeMemory)</div><div class="line"><a name="l03384"></a><span class="lineno"> 3384</span>&#160;        {</div><div class="line"><a name="l03385"></a><span class="lineno"> 3385</span>&#160;            newCapacity = newCount;</div><div class="line"><a name="l03386"></a><span class="lineno"> 3386</span>&#160;        }</div><div class="line"><a name="l03387"></a><span class="lineno"> 3387</span>&#160;</div><div class="line"><a name="l03388"></a><span class="lineno"> 3388</span>&#160;        <span class="keywordflow">if</span>(newCapacity != m_Capacity)</div><div class="line"><a name="l03389"></a><span class="lineno"> 3389</span>&#160;        {</div><div class="line"><a name="l03390"></a><span class="lineno"> 3390</span>&#160;            T* <span class="keyword">const</span> newArray = newCapacity ? VmaAllocateArray&lt;T&gt;(m_Allocator.m_pCallbacks, newCapacity) : VMA_NULL;</div><div class="line"><a name="l03391"></a><span class="lineno"> 3391</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> elementsToCopy = VMA_MIN(m_Count, newCount);</div><div class="line"><a name="l03392"></a><span class="lineno"> 3392</span>&#160;            <span class="keywordflow">if</span>(elementsToCopy != 0)</div><div class="line"><a name="l03393"></a><span class="lineno"> 3393</span>&#160;            {</div><div class="line"><a name="l03394"></a><span class="lineno"> 3394</span>&#160;                memcpy(newArray, m_pArray, elementsToCopy * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l03395"></a><span class="lineno"> 3395</span>&#160;            }</div><div class="line"><a name="l03396"></a><span class="lineno"> 3396</span>&#160;            VmaFree(m_Allocator.m_pCallbacks, m_pArray);</div><div class="line"><a name="l03397"></a><span class="lineno"> 3397</span>&#160;            m_Capacity = newCapacity;</div><div class="line"><a name="l03398"></a><span class="lineno"> 3398</span>&#160;            m_pArray = newArray;</div><div class="line"><a name="l03399"></a><span class="lineno"> 3399</span>&#160;        }</div><div class="line"><a name="l03400"></a><span class="lineno"> 3400</span>&#160;</div><div class="line"><a name="l03401"></a><span class="lineno"> 3401</span>&#160;        m_Count = newCount;</div><div class="line"><a name="l03402"></a><span class="lineno"> 3402</span>&#160;    }</div><div class="line"><a name="l03403"></a><span class="lineno"> 3403</span>&#160;</div><div class="line"><a name="l03404"></a><span class="lineno"> 3404</span>&#160;    <span class="keywordtype">void</span> clear(<span class="keywordtype">bool</span> freeMemory = <span class="keyword">false</span>)</div><div class="line"><a name="l03405"></a><span class="lineno"> 3405</span>&#160;    {</div><div class="line"><a name="l03406"></a><span class="lineno"> 3406</span>&#160;        resize(0, freeMemory);</div><div class="line"><a name="l03407"></a><span class="lineno"> 3407</span>&#160;    }</div><div class="line"><a name="l03408"></a><span class="lineno"> 3408</span>&#160;</div><div class="line"><a name="l03409"></a><span class="lineno"> 3409</span>&#160;    <span class="keywordtype">void</span> insert(<span class="keywordtype">size_t</span> index, <span class="keyword">const</span> T&amp; src)</div><div class="line"><a name="l03410"></a><span class="lineno"> 3410</span>&#160;    {</div><div class="line"><a name="l03411"></a><span class="lineno"> 3411</span>&#160;        VMA_HEAVY_ASSERT(index &lt;= m_Count);</div><div class="line"><a name="l03412"></a><span class="lineno"> 3412</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldCount = size();</div><div class="line"><a name="l03413"></a><span class="lineno"> 3413</span>&#160;        resize(oldCount + 1);</div><div class="line"><a name="l03414"></a><span class="lineno"> 3414</span>&#160;        <span class="keywordflow">if</span>(index &lt; oldCount)</div><div class="line"><a name="l03415"></a><span class="lineno"> 3415</span>&#160;        {</div><div class="line"><a name="l03416"></a><span class="lineno"> 3416</span>&#160;            memmove(m_pArray + (index + 1), m_pArray + index, (oldCount - index) * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l03417"></a><span class="lineno"> 3417</span>&#160;        }</div><div class="line"><a name="l03418"></a><span class="lineno"> 3418</span>&#160;        m_pArray[index] = src;</div><div class="line"><a name="l03419"></a><span class="lineno"> 3419</span>&#160;    }</div><div class="line"><a name="l03420"></a><span class="lineno"> 3420</span>&#160;</div><div class="line"><a name="l03421"></a><span class="lineno"> 3421</span>&#160;    <span class="keywordtype">void</span> <span class="keyword">remove</span>(<span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l03422"></a><span class="lineno"> 3422</span>&#160;    {</div><div class="line"><a name="l03423"></a><span class="lineno"> 3423</span>&#160;        VMA_HEAVY_ASSERT(index &lt; m_Count);</div><div class="line"><a name="l03424"></a><span class="lineno"> 3424</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldCount = size();</div><div class="line"><a name="l03425"></a><span class="lineno"> 3425</span>&#160;        <span class="keywordflow">if</span>(index &lt; oldCount - 1)</div><div class="line"><a name="l03426"></a><span class="lineno"> 3426</span>&#160;        {</div><div class="line"><a name="l03427"></a><span class="lineno"> 3427</span>&#160;            memmove(m_pArray + index, m_pArray + (index + 1), (oldCount - index - 1) * <span class="keyword">sizeof</span>(T));</div><div class="line"><a name="l03428"></a><span class="lineno"> 3428</span>&#160;        }</div><div class="line"><a name="l03429"></a><span class="lineno"> 3429</span>&#160;        resize(oldCount - 1);</div><div class="line"><a name="l03430"></a><span class="lineno"> 3430</span>&#160;    }</div><div class="line"><a name="l03431"></a><span class="lineno"> 3431</span>&#160;</div><div class="line"><a name="l03432"></a><span class="lineno"> 3432</span>&#160;    <span class="keywordtype">void</span> push_back(<span class="keyword">const</span> T&amp; src)</div><div class="line"><a name="l03433"></a><span class="lineno"> 3433</span>&#160;    {</div><div class="line"><a name="l03434"></a><span class="lineno"> 3434</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> newIndex = size();</div><div class="line"><a name="l03435"></a><span class="lineno"> 3435</span>&#160;        resize(newIndex + 1);</div><div class="line"><a name="l03436"></a><span class="lineno"> 3436</span>&#160;        m_pArray[newIndex] = src;</div><div class="line"><a name="l03437"></a><span class="lineno"> 3437</span>&#160;    }</div><div class="line"><a name="l03438"></a><span class="lineno"> 3438</span>&#160;</div><div class="line"><a name="l03439"></a><span class="lineno"> 3439</span>&#160;    <span class="keywordtype">void</span> pop_back()</div><div class="line"><a name="l03440"></a><span class="lineno"> 3440</span>&#160;    {</div><div class="line"><a name="l03441"></a><span class="lineno"> 3441</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03442"></a><span class="lineno"> 3442</span>&#160;        resize(size() - 1);</div><div class="line"><a name="l03443"></a><span class="lineno"> 3443</span>&#160;    }</div><div class="line"><a name="l03444"></a><span class="lineno"> 3444</span>&#160;</div><div class="line"><a name="l03445"></a><span class="lineno"> 3445</span>&#160;    <span class="keywordtype">void</span> push_front(<span class="keyword">const</span> T&amp; src)</div><div class="line"><a name="l03446"></a><span class="lineno"> 3446</span>&#160;    {</div><div class="line"><a name="l03447"></a><span class="lineno"> 3447</span>&#160;        insert(0, src);</div><div class="line"><a name="l03448"></a><span class="lineno"> 3448</span>&#160;    }</div><div class="line"><a name="l03449"></a><span class="lineno"> 3449</span>&#160;</div><div class="line"><a name="l03450"></a><span class="lineno"> 3450</span>&#160;    <span class="keywordtype">void</span> pop_front()</div><div class="line"><a name="l03451"></a><span class="lineno"> 3451</span>&#160;    {</div><div class="line"><a name="l03452"></a><span class="lineno"> 3452</span>&#160;        VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03453"></a><span class="lineno"> 3453</span>&#160;        <span class="keyword">remove</span>(0);</div><div class="line"><a name="l03454"></a><span class="lineno"> 3454</span>&#160;    }</div><div class="line"><a name="l03455"></a><span class="lineno"> 3455</span>&#160;</div><div class="line"><a name="l03456"></a><span class="lineno"> 3456</span>&#160;    <span class="keyword">typedef</span> T* iterator;</div><div class="line"><a name="l03457"></a><span class="lineno"> 3457</span>&#160;</div><div class="line"><a name="l03458"></a><span class="lineno"> 3458</span>&#160;    iterator begin() { <span class="keywordflow">return</span> m_pArray; }</div><div class="line"><a name="l03459"></a><span class="lineno"> 3459</span>&#160;    iterator end() { <span class="keywordflow">return</span> m_pArray + m_Count; }</div><div class="line"><a name="l03460"></a><span class="lineno"> 3460</span>&#160;</div><div class="line"><a name="l03461"></a><span class="lineno"> 3461</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03462"></a><span class="lineno"> 3462</span>&#160;    AllocatorT m_Allocator;</div><div class="line"><a name="l03463"></a><span class="lineno"> 3463</span>&#160;    T* m_pArray;</div><div class="line"><a name="l03464"></a><span class="lineno"> 3464</span>&#160;    <span class="keywordtype">size_t</span> m_Count;</div><div class="line"><a name="l03465"></a><span class="lineno"> 3465</span>&#160;    <span class="keywordtype">size_t</span> m_Capacity;</div><div class="line"><a name="l03466"></a><span class="lineno"> 3466</span>&#160;};</div><div class="line"><a name="l03467"></a><span class="lineno"> 3467</span>&#160;</div><div class="line"><a name="l03468"></a><span class="lineno"> 3468</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l03469"></a><span class="lineno"> 3469</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorInsert(VmaVector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index, <span class="keyword">const</span> T&amp; item)</div><div class="line"><a name="l03470"></a><span class="lineno"> 3470</span>&#160;{</div><div class="line"><a name="l03471"></a><span class="lineno"> 3471</span>&#160;    vec.insert(index, item);</div><div class="line"><a name="l03472"></a><span class="lineno"> 3472</span>&#160;}</div><div class="line"><a name="l03473"></a><span class="lineno"> 3473</span>&#160;</div><div class="line"><a name="l03474"></a><span class="lineno"> 3474</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> allocatorT&gt;</div><div class="line"><a name="l03475"></a><span class="lineno"> 3475</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaVectorRemove(VmaVector&lt;T, allocatorT&gt;&amp; vec, <span class="keywordtype">size_t</span> index)</div><div class="line"><a name="l03476"></a><span class="lineno"> 3476</span>&#160;{</div><div class="line"><a name="l03477"></a><span class="lineno"> 3477</span>&#160;    vec.remove(index);</div><div class="line"><a name="l03478"></a><span class="lineno"> 3478</span>&#160;}</div><div class="line"><a name="l03479"></a><span class="lineno"> 3479</span>&#160;</div><div class="line"><a name="l03480"></a><span class="lineno"> 3480</span>&#160;<span class="preprocessor">#endif // #if VMA_USE_STL_VECTOR</span></div><div class="line"><a name="l03481"></a><span class="lineno"> 3481</span>&#160;</div><div class="line"><a name="l03482"></a><span class="lineno"> 3482</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> CmpLess, <span class="keyword">typename</span> VectorT&gt;</div><div class="line"><a name="l03483"></a><span class="lineno"> 3483</span>&#160;<span class="keywordtype">size_t</span> VmaVectorInsertSorted(VectorT&amp; vector, <span class="keyword">const</span> <span class="keyword">typename</span> VectorT::value_type&amp; value)</div><div class="line"><a name="l03484"></a><span class="lineno"> 3484</span>&#160;{</div><div class="line"><a name="l03485"></a><span class="lineno"> 3485</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> indexToInsert = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l03486"></a><span class="lineno"> 3486</span>&#160;        vector.data(),</div><div class="line"><a name="l03487"></a><span class="lineno"> 3487</span>&#160;        vector.data() + vector.size(),</div><div class="line"><a name="l03488"></a><span class="lineno"> 3488</span>&#160;        value,</div><div class="line"><a name="l03489"></a><span class="lineno"> 3489</span>&#160;        CmpLess()) - vector.data();</div><div class="line"><a name="l03490"></a><span class="lineno"> 3490</span>&#160;    VmaVectorInsert(vector, indexToInsert, value);</div><div class="line"><a name="l03491"></a><span class="lineno"> 3491</span>&#160;    <span class="keywordflow">return</span> indexToInsert;</div><div class="line"><a name="l03492"></a><span class="lineno"> 3492</span>&#160;}</div><div class="line"><a name="l03493"></a><span class="lineno"> 3493</span>&#160;</div><div class="line"><a name="l03494"></a><span class="lineno"> 3494</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> CmpLess, <span class="keyword">typename</span> VectorT&gt;</div><div class="line"><a name="l03495"></a><span class="lineno"> 3495</span>&#160;<span class="keywordtype">bool</span> VmaVectorRemoveSorted(VectorT&amp; vector, <span class="keyword">const</span> <span class="keyword">typename</span> VectorT::value_type&amp; value)</div><div class="line"><a name="l03496"></a><span class="lineno"> 3496</span>&#160;{</div><div class="line"><a name="l03497"></a><span class="lineno"> 3497</span>&#160;    CmpLess comparator;</div><div class="line"><a name="l03498"></a><span class="lineno"> 3498</span>&#160;    <span class="keyword">typename</span> VectorT::iterator it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l03499"></a><span class="lineno"> 3499</span>&#160;        vector.begin(),</div><div class="line"><a name="l03500"></a><span class="lineno"> 3500</span>&#160;        vector.end(),</div><div class="line"><a name="l03501"></a><span class="lineno"> 3501</span>&#160;        value,</div><div class="line"><a name="l03502"></a><span class="lineno"> 3502</span>&#160;        comparator);</div><div class="line"><a name="l03503"></a><span class="lineno"> 3503</span>&#160;    <span class="keywordflow">if</span>((it != vector.end()) &amp;&amp; !comparator(*it, value) &amp;&amp; !comparator(value, *it))</div><div class="line"><a name="l03504"></a><span class="lineno"> 3504</span>&#160;    {</div><div class="line"><a name="l03505"></a><span class="lineno"> 3505</span>&#160;        <span class="keywordtype">size_t</span> indexToRemove = it - vector.begin();</div><div class="line"><a name="l03506"></a><span class="lineno"> 3506</span>&#160;        VmaVectorRemove(vector, indexToRemove);</div><div class="line"><a name="l03507"></a><span class="lineno"> 3507</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l03508"></a><span class="lineno"> 3508</span>&#160;    }</div><div class="line"><a name="l03509"></a><span class="lineno"> 3509</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l03510"></a><span class="lineno"> 3510</span>&#160;}</div><div class="line"><a name="l03511"></a><span class="lineno"> 3511</span>&#160;</div><div class="line"><a name="l03512"></a><span class="lineno"> 3512</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> CmpLess, <span class="keyword">typename</span> IterT, <span class="keyword">typename</span> KeyT&gt;</div><div class="line"><a name="l03513"></a><span class="lineno"> 3513</span>&#160;IterT VmaVectorFindSorted(<span class="keyword">const</span> IterT&amp; beg, <span class="keyword">const</span> IterT&amp; end, <span class="keyword">const</span> KeyT&amp; value)</div><div class="line"><a name="l03514"></a><span class="lineno"> 3514</span>&#160;{</div><div class="line"><a name="l03515"></a><span class="lineno"> 3515</span>&#160;    CmpLess comparator;</div><div class="line"><a name="l03516"></a><span class="lineno"> 3516</span>&#160;    <span class="keyword">typename</span> IterT it = VmaBinaryFindFirstNotLess&lt;CmpLess, IterT, KeyT&gt;(</div><div class="line"><a name="l03517"></a><span class="lineno"> 3517</span>&#160;        beg, end, value, comparator);</div><div class="line"><a name="l03518"></a><span class="lineno"> 3518</span>&#160;    <span class="keywordflow">if</span>(it == end ||</div><div class="line"><a name="l03519"></a><span class="lineno"> 3519</span>&#160;        !comparator(*it, value) &amp;&amp; !comparator(value, *it))</div><div class="line"><a name="l03520"></a><span class="lineno"> 3520</span>&#160;    {</div><div class="line"><a name="l03521"></a><span class="lineno"> 3521</span>&#160;        <span class="keywordflow">return</span> it;</div><div class="line"><a name="l03522"></a><span class="lineno"> 3522</span>&#160;    }</div><div class="line"><a name="l03523"></a><span class="lineno"> 3523</span>&#160;    <span class="keywordflow">return</span> end;</div><div class="line"><a name="l03524"></a><span class="lineno"> 3524</span>&#160;}</div><div class="line"><a name="l03525"></a><span class="lineno"> 3525</span>&#160;</div><div class="line"><a name="l03527"></a><span class="lineno"> 3527</span>&#160;<span class="comment">// class VmaPoolAllocator</span></div><div class="line"><a name="l03528"></a><span class="lineno"> 3528</span>&#160;</div><div class="line"><a name="l03529"></a><span class="lineno"> 3529</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l03530"></a><span class="lineno"> 3530</span>&#160;<span class="comment">Allocator for objects of type T using a list of arrays (pools) to speed up</span></div><div class="line"><a name="l03531"></a><span class="lineno"> 3531</span>&#160;<span class="comment">allocation. Number of elements that can be allocated is not bounded because</span></div><div class="line"><a name="l03532"></a><span class="lineno"> 3532</span>&#160;<span class="comment">allocator can create multiple blocks.</span></div><div class="line"><a name="l03533"></a><span class="lineno"> 3533</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l03534"></a><span class="lineno"> 3534</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03535"></a><span class="lineno"> 3535</span>&#160;<span class="keyword">class </span>VmaPoolAllocator</div><div class="line"><a name="l03536"></a><span class="lineno"> 3536</span>&#160;{</div><div class="line"><a name="l03537"></a><span class="lineno"> 3537</span>&#160;    VMA_CLASS_NO_COPY(VmaPoolAllocator)</div><div class="line"><a name="l03538"></a><span class="lineno"> 3538</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03539"></a><span class="lineno"> 3539</span>&#160;    VmaPoolAllocator(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> itemsPerBlock);</div><div class="line"><a name="l03540"></a><span class="lineno"> 3540</span>&#160;    ~VmaPoolAllocator();</div><div class="line"><a name="l03541"></a><span class="lineno"> 3541</span>&#160;    <span class="keywordtype">void</span> Clear();</div><div class="line"><a name="l03542"></a><span class="lineno"> 3542</span>&#160;    T* Alloc();</div><div class="line"><a name="l03543"></a><span class="lineno"> 3543</span>&#160;    <span class="keywordtype">void</span> Free(T* ptr);</div><div class="line"><a name="l03544"></a><span class="lineno"> 3544</span>&#160;</div><div class="line"><a name="l03545"></a><span class="lineno"> 3545</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03546"></a><span class="lineno"> 3546</span>&#160;    <span class="keyword">union </span>Item</div><div class="line"><a name="l03547"></a><span class="lineno"> 3547</span>&#160;    {</div><div class="line"><a name="l03548"></a><span class="lineno"> 3548</span>&#160;        uint32_t NextFreeIndex;</div><div class="line"><a name="l03549"></a><span class="lineno"> 3549</span>&#160;        T Value;</div><div class="line"><a name="l03550"></a><span class="lineno"> 3550</span>&#160;    };</div><div class="line"><a name="l03551"></a><span class="lineno"> 3551</span>&#160;</div><div class="line"><a name="l03552"></a><span class="lineno"> 3552</span>&#160;    <span class="keyword">struct </span>ItemBlock</div><div class="line"><a name="l03553"></a><span class="lineno"> 3553</span>&#160;    {</div><div class="line"><a name="l03554"></a><span class="lineno"> 3554</span>&#160;        Item* pItems;</div><div class="line"><a name="l03555"></a><span class="lineno"> 3555</span>&#160;        uint32_t FirstFreeIndex;</div><div class="line"><a name="l03556"></a><span class="lineno"> 3556</span>&#160;    };</div><div class="line"><a name="l03557"></a><span class="lineno"> 3557</span>&#160;    </div><div class="line"><a name="l03558"></a><span class="lineno"> 3558</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* m_pAllocationCallbacks;</div><div class="line"><a name="l03559"></a><span class="lineno"> 3559</span>&#160;    <span class="keywordtype">size_t</span> m_ItemsPerBlock;</div><div class="line"><a name="l03560"></a><span class="lineno"> 3560</span>&#160;    VmaVector&lt; ItemBlock, VmaStlAllocator&lt;ItemBlock&gt; &gt; m_ItemBlocks;</div><div class="line"><a name="l03561"></a><span class="lineno"> 3561</span>&#160;</div><div class="line"><a name="l03562"></a><span class="lineno"> 3562</span>&#160;    ItemBlock&amp; CreateNewBlock();</div><div class="line"><a name="l03563"></a><span class="lineno"> 3563</span>&#160;};</div><div class="line"><a name="l03564"></a><span class="lineno"> 3564</span>&#160;</div><div class="line"><a name="l03565"></a><span class="lineno"> 3565</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03566"></a><span class="lineno"> 3566</span>&#160;VmaPoolAllocator&lt;T&gt;::VmaPoolAllocator(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, <span class="keywordtype">size_t</span> itemsPerBlock) :</div><div class="line"><a name="l03567"></a><span class="lineno"> 3567</span>&#160;    m_pAllocationCallbacks(pAllocationCallbacks),</div><div class="line"><a name="l03568"></a><span class="lineno"> 3568</span>&#160;    m_ItemsPerBlock(itemsPerBlock),</div><div class="line"><a name="l03569"></a><span class="lineno"> 3569</span>&#160;    m_ItemBlocks(VmaStlAllocator&lt;ItemBlock&gt;(pAllocationCallbacks))</div><div class="line"><a name="l03570"></a><span class="lineno"> 3570</span>&#160;{</div><div class="line"><a name="l03571"></a><span class="lineno"> 3571</span>&#160;    VMA_ASSERT(itemsPerBlock &gt; 0);</div><div class="line"><a name="l03572"></a><span class="lineno"> 3572</span>&#160;}</div><div class="line"><a name="l03573"></a><span class="lineno"> 3573</span>&#160;</div><div class="line"><a name="l03574"></a><span class="lineno"> 3574</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03575"></a><span class="lineno"> 3575</span>&#160;VmaPoolAllocator&lt;T&gt;::~VmaPoolAllocator()</div><div class="line"><a name="l03576"></a><span class="lineno"> 3576</span>&#160;{</div><div class="line"><a name="l03577"></a><span class="lineno"> 3577</span>&#160;    Clear();</div><div class="line"><a name="l03578"></a><span class="lineno"> 3578</span>&#160;}</div><div class="line"><a name="l03579"></a><span class="lineno"> 3579</span>&#160;</div><div class="line"><a name="l03580"></a><span class="lineno"> 3580</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03581"></a><span class="lineno"> 3581</span>&#160;<span class="keywordtype">void</span> VmaPoolAllocator&lt;T&gt;::Clear()</div><div class="line"><a name="l03582"></a><span class="lineno"> 3582</span>&#160;{</div><div class="line"><a name="l03583"></a><span class="lineno"> 3583</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_ItemBlocks.size(); i--; )</div><div class="line"><a name="l03584"></a><span class="lineno"> 3584</span>&#160;        vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemsPerBlock);</div><div class="line"><a name="l03585"></a><span class="lineno"> 3585</span>&#160;    m_ItemBlocks.clear();</div><div class="line"><a name="l03586"></a><span class="lineno"> 3586</span>&#160;}</div><div class="line"><a name="l03587"></a><span class="lineno"> 3587</span>&#160;</div><div class="line"><a name="l03588"></a><span class="lineno"> 3588</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03589"></a><span class="lineno"> 3589</span>&#160;T* VmaPoolAllocator&lt;T&gt;::Alloc()</div><div class="line"><a name="l03590"></a><span class="lineno"> 3590</span>&#160;{</div><div class="line"><a name="l03591"></a><span class="lineno"> 3591</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_ItemBlocks.size(); i--; )</div><div class="line"><a name="l03592"></a><span class="lineno"> 3592</span>&#160;    {</div><div class="line"><a name="l03593"></a><span class="lineno"> 3593</span>&#160;        ItemBlock&amp; block = m_ItemBlocks[i];</div><div class="line"><a name="l03594"></a><span class="lineno"> 3594</span>&#160;        <span class="comment">// This block has some free items: Use first one.</span></div><div class="line"><a name="l03595"></a><span class="lineno"> 3595</span>&#160;        <span class="keywordflow">if</span>(block.FirstFreeIndex != UINT32_MAX)</div><div class="line"><a name="l03596"></a><span class="lineno"> 3596</span>&#160;        {</div><div class="line"><a name="l03597"></a><span class="lineno"> 3597</span>&#160;            Item* <span class="keyword">const</span> pItem = &amp;block.pItems[block.FirstFreeIndex];</div><div class="line"><a name="l03598"></a><span class="lineno"> 3598</span>&#160;            block.FirstFreeIndex = pItem-&gt;NextFreeIndex;</div><div class="line"><a name="l03599"></a><span class="lineno"> 3599</span>&#160;            <span class="keywordflow">return</span> &amp;pItem-&gt;Value;</div><div class="line"><a name="l03600"></a><span class="lineno"> 3600</span>&#160;        }</div><div class="line"><a name="l03601"></a><span class="lineno"> 3601</span>&#160;    }</div><div class="line"><a name="l03602"></a><span class="lineno"> 3602</span>&#160;</div><div class="line"><a name="l03603"></a><span class="lineno"> 3603</span>&#160;    <span class="comment">// No block has free item: Create new one and use it.</span></div><div class="line"><a name="l03604"></a><span class="lineno"> 3604</span>&#160;    ItemBlock&amp; newBlock = CreateNewBlock();</div><div class="line"><a name="l03605"></a><span class="lineno"> 3605</span>&#160;    Item* <span class="keyword">const</span> pItem = &amp;newBlock.pItems[0];</div><div class="line"><a name="l03606"></a><span class="lineno"> 3606</span>&#160;    newBlock.FirstFreeIndex = pItem-&gt;NextFreeIndex;</div><div class="line"><a name="l03607"></a><span class="lineno"> 3607</span>&#160;    <span class="keywordflow">return</span> &amp;pItem-&gt;Value;</div><div class="line"><a name="l03608"></a><span class="lineno"> 3608</span>&#160;}</div><div class="line"><a name="l03609"></a><span class="lineno"> 3609</span>&#160;</div><div class="line"><a name="l03610"></a><span class="lineno"> 3610</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03611"></a><span class="lineno"> 3611</span>&#160;<span class="keywordtype">void</span> VmaPoolAllocator&lt;T&gt;::Free(T* ptr)</div><div class="line"><a name="l03612"></a><span class="lineno"> 3612</span>&#160;{</div><div class="line"><a name="l03613"></a><span class="lineno"> 3613</span>&#160;    <span class="comment">// Search all memory blocks to find ptr.</span></div><div class="line"><a name="l03614"></a><span class="lineno"> 3614</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_ItemBlocks.size(); ++i)</div><div class="line"><a name="l03615"></a><span class="lineno"> 3615</span>&#160;    {</div><div class="line"><a name="l03616"></a><span class="lineno"> 3616</span>&#160;        ItemBlock&amp; block = m_ItemBlocks[i];</div><div class="line"><a name="l03617"></a><span class="lineno"> 3617</span>&#160;        </div><div class="line"><a name="l03618"></a><span class="lineno"> 3618</span>&#160;        <span class="comment">// Casting to union.</span></div><div class="line"><a name="l03619"></a><span class="lineno"> 3619</span>&#160;        Item* pItemPtr;</div><div class="line"><a name="l03620"></a><span class="lineno"> 3620</span>&#160;        memcpy(&amp;pItemPtr, &amp;ptr, <span class="keyword">sizeof</span>(pItemPtr));</div><div class="line"><a name="l03621"></a><span class="lineno"> 3621</span>&#160;        </div><div class="line"><a name="l03622"></a><span class="lineno"> 3622</span>&#160;        <span class="comment">// Check if pItemPtr is in address range of this block.</span></div><div class="line"><a name="l03623"></a><span class="lineno"> 3623</span>&#160;        <span class="keywordflow">if</span>((pItemPtr &gt;= block.pItems) &amp;&amp; (pItemPtr &lt; block.pItems + m_ItemsPerBlock))</div><div class="line"><a name="l03624"></a><span class="lineno"> 3624</span>&#160;        {</div><div class="line"><a name="l03625"></a><span class="lineno"> 3625</span>&#160;            <span class="keyword">const</span> uint32_t index = <span class="keyword">static_cast&lt;</span>uint32_t<span class="keyword">&gt;</span>(pItemPtr - block.pItems);</div><div class="line"><a name="l03626"></a><span class="lineno"> 3626</span>&#160;            pItemPtr-&gt;NextFreeIndex = block.FirstFreeIndex;</div><div class="line"><a name="l03627"></a><span class="lineno"> 3627</span>&#160;            block.FirstFreeIndex = index;</div><div class="line"><a name="l03628"></a><span class="lineno"> 3628</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l03629"></a><span class="lineno"> 3629</span>&#160;        }</div><div class="line"><a name="l03630"></a><span class="lineno"> 3630</span>&#160;    }</div><div class="line"><a name="l03631"></a><span class="lineno"> 3631</span>&#160;    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Pointer doesn&#39;t belong to this memory pool.&quot;</span>);</div><div class="line"><a name="l03632"></a><span class="lineno"> 3632</span>&#160;}</div><div class="line"><a name="l03633"></a><span class="lineno"> 3633</span>&#160;</div><div class="line"><a name="l03634"></a><span class="lineno"> 3634</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03635"></a><span class="lineno"> 3635</span>&#160;<span class="keyword">typename</span> VmaPoolAllocator&lt;T&gt;::ItemBlock&amp; VmaPoolAllocator&lt;T&gt;::CreateNewBlock()</div><div class="line"><a name="l03636"></a><span class="lineno"> 3636</span>&#160;{</div><div class="line"><a name="l03637"></a><span class="lineno"> 3637</span>&#160;    ItemBlock newBlock = {</div><div class="line"><a name="l03638"></a><span class="lineno"> 3638</span>&#160;        vma_new_array(m_pAllocationCallbacks, Item, m_ItemsPerBlock), 0 };</div><div class="line"><a name="l03639"></a><span class="lineno"> 3639</span>&#160;</div><div class="line"><a name="l03640"></a><span class="lineno"> 3640</span>&#160;    m_ItemBlocks.push_back(newBlock);</div><div class="line"><a name="l03641"></a><span class="lineno"> 3641</span>&#160;</div><div class="line"><a name="l03642"></a><span class="lineno"> 3642</span>&#160;    <span class="comment">// Setup singly-linked list of all free items in this block.</span></div><div class="line"><a name="l03643"></a><span class="lineno"> 3643</span>&#160;    <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; m_ItemsPerBlock - 1; ++i)</div><div class="line"><a name="l03644"></a><span class="lineno"> 3644</span>&#160;        newBlock.pItems[i].NextFreeIndex = i + 1;</div><div class="line"><a name="l03645"></a><span class="lineno"> 3645</span>&#160;    newBlock.pItems[m_ItemsPerBlock - 1].NextFreeIndex = UINT32_MAX;</div><div class="line"><a name="l03646"></a><span class="lineno"> 3646</span>&#160;    <span class="keywordflow">return</span> m_ItemBlocks.back();</div><div class="line"><a name="l03647"></a><span class="lineno"> 3647</span>&#160;}</div><div class="line"><a name="l03648"></a><span class="lineno"> 3648</span>&#160;</div><div class="line"><a name="l03650"></a><span class="lineno"> 3650</span>&#160;<span class="comment">// class VmaRawList, VmaList</span></div><div class="line"><a name="l03651"></a><span class="lineno"> 3651</span>&#160;</div><div class="line"><a name="l03652"></a><span class="lineno"> 3652</span>&#160;<span class="preprocessor">#if VMA_USE_STL_LIST</span></div><div class="line"><a name="l03653"></a><span class="lineno"> 3653</span>&#160;</div><div class="line"><a name="l03654"></a><span class="lineno"> 3654</span>&#160;<span class="preprocessor">#define VmaList std::list</span></div><div class="line"><a name="l03655"></a><span class="lineno"> 3655</span>&#160;</div><div class="line"><a name="l03656"></a><span class="lineno"> 3656</span>&#160;<span class="preprocessor">#else // #if VMA_USE_STL_LIST</span></div><div class="line"><a name="l03657"></a><span class="lineno"> 3657</span>&#160;</div><div class="line"><a name="l03658"></a><span class="lineno"> 3658</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03659"></a><span class="lineno"> 3659</span>&#160;<span class="keyword">struct </span>VmaListItem</div><div class="line"><a name="l03660"></a><span class="lineno"> 3660</span>&#160;{</div><div class="line"><a name="l03661"></a><span class="lineno"> 3661</span>&#160;    VmaListItem* pPrev;</div><div class="line"><a name="l03662"></a><span class="lineno"> 3662</span>&#160;    VmaListItem* pNext;</div><div class="line"><a name="l03663"></a><span class="lineno"> 3663</span>&#160;    T Value;</div><div class="line"><a name="l03664"></a><span class="lineno"> 3664</span>&#160;};</div><div class="line"><a name="l03665"></a><span class="lineno"> 3665</span>&#160;</div><div class="line"><a name="l03666"></a><span class="lineno"> 3666</span>&#160;<span class="comment">// Doubly linked list.</span></div><div class="line"><a name="l03667"></a><span class="lineno"> 3667</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03668"></a><span class="lineno"> 3668</span>&#160;<span class="keyword">class </span>VmaRawList</div><div class="line"><a name="l03669"></a><span class="lineno"> 3669</span>&#160;{</div><div class="line"><a name="l03670"></a><span class="lineno"> 3670</span>&#160;    VMA_CLASS_NO_COPY(VmaRawList)</div><div class="line"><a name="l03671"></a><span class="lineno"> 3671</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03672"></a><span class="lineno"> 3672</span>&#160;    <span class="keyword">typedef</span> VmaListItem&lt;T&gt; ItemType;</div><div class="line"><a name="l03673"></a><span class="lineno"> 3673</span>&#160;</div><div class="line"><a name="l03674"></a><span class="lineno"> 3674</span>&#160;    VmaRawList(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks);</div><div class="line"><a name="l03675"></a><span class="lineno"> 3675</span>&#160;    ~VmaRawList();</div><div class="line"><a name="l03676"></a><span class="lineno"> 3676</span>&#160;    <span class="keywordtype">void</span> Clear();</div><div class="line"><a name="l03677"></a><span class="lineno"> 3677</span>&#160;</div><div class="line"><a name="l03678"></a><span class="lineno"> 3678</span>&#160;    <span class="keywordtype">size_t</span> GetCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count; }</div><div class="line"><a name="l03679"></a><span class="lineno"> 3679</span>&#160;    <span class="keywordtype">bool</span> IsEmpty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Count == 0; }</div><div class="line"><a name="l03680"></a><span class="lineno"> 3680</span>&#160;</div><div class="line"><a name="l03681"></a><span class="lineno"> 3681</span>&#160;    ItemType* Front() { <span class="keywordflow">return</span> m_pFront; }</div><div class="line"><a name="l03682"></a><span class="lineno"> 3682</span>&#160;    <span class="keyword">const</span> ItemType* Front()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pFront; }</div><div class="line"><a name="l03683"></a><span class="lineno"> 3683</span>&#160;    ItemType* Back() { <span class="keywordflow">return</span> m_pBack; }</div><div class="line"><a name="l03684"></a><span class="lineno"> 3684</span>&#160;    <span class="keyword">const</span> ItemType* Back()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pBack; }</div><div class="line"><a name="l03685"></a><span class="lineno"> 3685</span>&#160;</div><div class="line"><a name="l03686"></a><span class="lineno"> 3686</span>&#160;    ItemType* PushBack();</div><div class="line"><a name="l03687"></a><span class="lineno"> 3687</span>&#160;    ItemType* PushFront();</div><div class="line"><a name="l03688"></a><span class="lineno"> 3688</span>&#160;    ItemType* PushBack(<span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03689"></a><span class="lineno"> 3689</span>&#160;    ItemType* PushFront(<span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03690"></a><span class="lineno"> 3690</span>&#160;    <span class="keywordtype">void</span> PopBack();</div><div class="line"><a name="l03691"></a><span class="lineno"> 3691</span>&#160;    <span class="keywordtype">void</span> PopFront();</div><div class="line"><a name="l03692"></a><span class="lineno"> 3692</span>&#160;    </div><div class="line"><a name="l03693"></a><span class="lineno"> 3693</span>&#160;    <span class="comment">// Item can be null - it means PushBack.</span></div><div class="line"><a name="l03694"></a><span class="lineno"> 3694</span>&#160;    ItemType* InsertBefore(ItemType* pItem);</div><div class="line"><a name="l03695"></a><span class="lineno"> 3695</span>&#160;    <span class="comment">// Item can be null - it means PushFront.</span></div><div class="line"><a name="l03696"></a><span class="lineno"> 3696</span>&#160;    ItemType* InsertAfter(ItemType* pItem);</div><div class="line"><a name="l03697"></a><span class="lineno"> 3697</span>&#160;</div><div class="line"><a name="l03698"></a><span class="lineno"> 3698</span>&#160;    ItemType* InsertBefore(ItemType* pItem, <span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03699"></a><span class="lineno"> 3699</span>&#160;    ItemType* InsertAfter(ItemType* pItem, <span class="keyword">const</span> T&amp; value);</div><div class="line"><a name="l03700"></a><span class="lineno"> 3700</span>&#160;</div><div class="line"><a name="l03701"></a><span class="lineno"> 3701</span>&#160;    <span class="keywordtype">void</span> Remove(ItemType* pItem);</div><div class="line"><a name="l03702"></a><span class="lineno"> 3702</span>&#160;</div><div class="line"><a name="l03703"></a><span class="lineno"> 3703</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l03704"></a><span class="lineno"> 3704</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* <span class="keyword">const</span> m_pAllocationCallbacks;</div><div class="line"><a name="l03705"></a><span class="lineno"> 3705</span>&#160;    VmaPoolAllocator&lt;ItemType&gt; m_ItemAllocator;</div><div class="line"><a name="l03706"></a><span class="lineno"> 3706</span>&#160;    ItemType* m_pFront;</div><div class="line"><a name="l03707"></a><span class="lineno"> 3707</span>&#160;    ItemType* m_pBack;</div><div class="line"><a name="l03708"></a><span class="lineno"> 3708</span>&#160;    <span class="keywordtype">size_t</span> m_Count;</div><div class="line"><a name="l03709"></a><span class="lineno"> 3709</span>&#160;};</div><div class="line"><a name="l03710"></a><span class="lineno"> 3710</span>&#160;</div><div class="line"><a name="l03711"></a><span class="lineno"> 3711</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03712"></a><span class="lineno"> 3712</span>&#160;VmaRawList&lt;T&gt;::VmaRawList(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks) :</div><div class="line"><a name="l03713"></a><span class="lineno"> 3713</span>&#160;    m_pAllocationCallbacks(pAllocationCallbacks),</div><div class="line"><a name="l03714"></a><span class="lineno"> 3714</span>&#160;    m_ItemAllocator(pAllocationCallbacks, 128),</div><div class="line"><a name="l03715"></a><span class="lineno"> 3715</span>&#160;    m_pFront(VMA_NULL),</div><div class="line"><a name="l03716"></a><span class="lineno"> 3716</span>&#160;    m_pBack(VMA_NULL),</div><div class="line"><a name="l03717"></a><span class="lineno"> 3717</span>&#160;    m_Count(0)</div><div class="line"><a name="l03718"></a><span class="lineno"> 3718</span>&#160;{</div><div class="line"><a name="l03719"></a><span class="lineno"> 3719</span>&#160;}</div><div class="line"><a name="l03720"></a><span class="lineno"> 3720</span>&#160;</div><div class="line"><a name="l03721"></a><span class="lineno"> 3721</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03722"></a><span class="lineno"> 3722</span>&#160;VmaRawList&lt;T&gt;::~VmaRawList()</div><div class="line"><a name="l03723"></a><span class="lineno"> 3723</span>&#160;{</div><div class="line"><a name="l03724"></a><span class="lineno"> 3724</span>&#160;    <span class="comment">// Intentionally not calling Clear, because that would be unnecessary</span></div><div class="line"><a name="l03725"></a><span class="lineno"> 3725</span>&#160;    <span class="comment">// computations to return all items to m_ItemAllocator as free.</span></div><div class="line"><a name="l03726"></a><span class="lineno"> 3726</span>&#160;}</div><div class="line"><a name="l03727"></a><span class="lineno"> 3727</span>&#160;</div><div class="line"><a name="l03728"></a><span class="lineno"> 3728</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03729"></a><span class="lineno"> 3729</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::Clear()</div><div class="line"><a name="l03730"></a><span class="lineno"> 3730</span>&#160;{</div><div class="line"><a name="l03731"></a><span class="lineno"> 3731</span>&#160;    <span class="keywordflow">if</span>(IsEmpty() == <span class="keyword">false</span>)</div><div class="line"><a name="l03732"></a><span class="lineno"> 3732</span>&#160;    {</div><div class="line"><a name="l03733"></a><span class="lineno"> 3733</span>&#160;        ItemType* pItem = m_pBack;</div><div class="line"><a name="l03734"></a><span class="lineno"> 3734</span>&#160;        <span class="keywordflow">while</span>(pItem != VMA_NULL)</div><div class="line"><a name="l03735"></a><span class="lineno"> 3735</span>&#160;        {</div><div class="line"><a name="l03736"></a><span class="lineno"> 3736</span>&#160;            ItemType* <span class="keyword">const</span> pPrevItem = pItem-&gt;pPrev;</div><div class="line"><a name="l03737"></a><span class="lineno"> 3737</span>&#160;            m_ItemAllocator.Free(pItem);</div><div class="line"><a name="l03738"></a><span class="lineno"> 3738</span>&#160;            pItem = pPrevItem;</div><div class="line"><a name="l03739"></a><span class="lineno"> 3739</span>&#160;        }</div><div class="line"><a name="l03740"></a><span class="lineno"> 3740</span>&#160;        m_pFront = VMA_NULL;</div><div class="line"><a name="l03741"></a><span class="lineno"> 3741</span>&#160;        m_pBack = VMA_NULL;</div><div class="line"><a name="l03742"></a><span class="lineno"> 3742</span>&#160;        m_Count = 0;</div><div class="line"><a name="l03743"></a><span class="lineno"> 3743</span>&#160;    }</div><div class="line"><a name="l03744"></a><span class="lineno"> 3744</span>&#160;}</div><div class="line"><a name="l03745"></a><span class="lineno"> 3745</span>&#160;</div><div class="line"><a name="l03746"></a><span class="lineno"> 3746</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03747"></a><span class="lineno"> 3747</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushBack()</div><div class="line"><a name="l03748"></a><span class="lineno"> 3748</span>&#160;{</div><div class="line"><a name="l03749"></a><span class="lineno"> 3749</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03750"></a><span class="lineno"> 3750</span>&#160;    pNewItem-&gt;pNext = VMA_NULL;</div><div class="line"><a name="l03751"></a><span class="lineno"> 3751</span>&#160;    <span class="keywordflow">if</span>(IsEmpty())</div><div class="line"><a name="l03752"></a><span class="lineno"> 3752</span>&#160;    {</div><div class="line"><a name="l03753"></a><span class="lineno"> 3753</span>&#160;        pNewItem-&gt;pPrev = VMA_NULL;</div><div class="line"><a name="l03754"></a><span class="lineno"> 3754</span>&#160;        m_pFront = pNewItem;</div><div class="line"><a name="l03755"></a><span class="lineno"> 3755</span>&#160;        m_pBack = pNewItem;</div><div class="line"><a name="l03756"></a><span class="lineno"> 3756</span>&#160;        m_Count = 1;</div><div class="line"><a name="l03757"></a><span class="lineno"> 3757</span>&#160;    }</div><div class="line"><a name="l03758"></a><span class="lineno"> 3758</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03759"></a><span class="lineno"> 3759</span>&#160;    {</div><div class="line"><a name="l03760"></a><span class="lineno"> 3760</span>&#160;        pNewItem-&gt;pPrev = m_pBack;</div><div class="line"><a name="l03761"></a><span class="lineno"> 3761</span>&#160;        m_pBack-&gt;pNext = pNewItem;</div><div class="line"><a name="l03762"></a><span class="lineno"> 3762</span>&#160;        m_pBack = pNewItem;</div><div class="line"><a name="l03763"></a><span class="lineno"> 3763</span>&#160;        ++m_Count;</div><div class="line"><a name="l03764"></a><span class="lineno"> 3764</span>&#160;    }</div><div class="line"><a name="l03765"></a><span class="lineno"> 3765</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03766"></a><span class="lineno"> 3766</span>&#160;}</div><div class="line"><a name="l03767"></a><span class="lineno"> 3767</span>&#160;</div><div class="line"><a name="l03768"></a><span class="lineno"> 3768</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03769"></a><span class="lineno"> 3769</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushFront()</div><div class="line"><a name="l03770"></a><span class="lineno"> 3770</span>&#160;{</div><div class="line"><a name="l03771"></a><span class="lineno"> 3771</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03772"></a><span class="lineno"> 3772</span>&#160;    pNewItem-&gt;pPrev = VMA_NULL;</div><div class="line"><a name="l03773"></a><span class="lineno"> 3773</span>&#160;    <span class="keywordflow">if</span>(IsEmpty())</div><div class="line"><a name="l03774"></a><span class="lineno"> 3774</span>&#160;    {</div><div class="line"><a name="l03775"></a><span class="lineno"> 3775</span>&#160;        pNewItem-&gt;pNext = VMA_NULL;</div><div class="line"><a name="l03776"></a><span class="lineno"> 3776</span>&#160;        m_pFront = pNewItem;</div><div class="line"><a name="l03777"></a><span class="lineno"> 3777</span>&#160;        m_pBack = pNewItem;</div><div class="line"><a name="l03778"></a><span class="lineno"> 3778</span>&#160;        m_Count = 1;</div><div class="line"><a name="l03779"></a><span class="lineno"> 3779</span>&#160;    }</div><div class="line"><a name="l03780"></a><span class="lineno"> 3780</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03781"></a><span class="lineno"> 3781</span>&#160;    {</div><div class="line"><a name="l03782"></a><span class="lineno"> 3782</span>&#160;        pNewItem-&gt;pNext = m_pFront;</div><div class="line"><a name="l03783"></a><span class="lineno"> 3783</span>&#160;        m_pFront-&gt;pPrev = pNewItem;</div><div class="line"><a name="l03784"></a><span class="lineno"> 3784</span>&#160;        m_pFront = pNewItem;</div><div class="line"><a name="l03785"></a><span class="lineno"> 3785</span>&#160;        ++m_Count;</div><div class="line"><a name="l03786"></a><span class="lineno"> 3786</span>&#160;    }</div><div class="line"><a name="l03787"></a><span class="lineno"> 3787</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03788"></a><span class="lineno"> 3788</span>&#160;}</div><div class="line"><a name="l03789"></a><span class="lineno"> 3789</span>&#160;</div><div class="line"><a name="l03790"></a><span class="lineno"> 3790</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03791"></a><span class="lineno"> 3791</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushBack(<span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03792"></a><span class="lineno"> 3792</span>&#160;{</div><div class="line"><a name="l03793"></a><span class="lineno"> 3793</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = PushBack();</div><div class="line"><a name="l03794"></a><span class="lineno"> 3794</span>&#160;    pNewItem-&gt;Value = value;</div><div class="line"><a name="l03795"></a><span class="lineno"> 3795</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03796"></a><span class="lineno"> 3796</span>&#160;}</div><div class="line"><a name="l03797"></a><span class="lineno"> 3797</span>&#160;</div><div class="line"><a name="l03798"></a><span class="lineno"> 3798</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03799"></a><span class="lineno"> 3799</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::PushFront(<span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03800"></a><span class="lineno"> 3800</span>&#160;{</div><div class="line"><a name="l03801"></a><span class="lineno"> 3801</span>&#160;    ItemType* <span class="keyword">const</span> pNewItem = PushFront();</div><div class="line"><a name="l03802"></a><span class="lineno"> 3802</span>&#160;    pNewItem-&gt;Value = value;</div><div class="line"><a name="l03803"></a><span class="lineno"> 3803</span>&#160;    <span class="keywordflow">return</span> pNewItem;</div><div class="line"><a name="l03804"></a><span class="lineno"> 3804</span>&#160;}</div><div class="line"><a name="l03805"></a><span class="lineno"> 3805</span>&#160;</div><div class="line"><a name="l03806"></a><span class="lineno"> 3806</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03807"></a><span class="lineno"> 3807</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::PopBack()</div><div class="line"><a name="l03808"></a><span class="lineno"> 3808</span>&#160;{</div><div class="line"><a name="l03809"></a><span class="lineno"> 3809</span>&#160;    VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03810"></a><span class="lineno"> 3810</span>&#160;    ItemType* <span class="keyword">const</span> pBackItem = m_pBack;</div><div class="line"><a name="l03811"></a><span class="lineno"> 3811</span>&#160;    ItemType* <span class="keyword">const</span> pPrevItem = pBackItem-&gt;pPrev;</div><div class="line"><a name="l03812"></a><span class="lineno"> 3812</span>&#160;    <span class="keywordflow">if</span>(pPrevItem != VMA_NULL)</div><div class="line"><a name="l03813"></a><span class="lineno"> 3813</span>&#160;    {</div><div class="line"><a name="l03814"></a><span class="lineno"> 3814</span>&#160;        pPrevItem-&gt;pNext = VMA_NULL;</div><div class="line"><a name="l03815"></a><span class="lineno"> 3815</span>&#160;    }</div><div class="line"><a name="l03816"></a><span class="lineno"> 3816</span>&#160;    m_pBack = pPrevItem;</div><div class="line"><a name="l03817"></a><span class="lineno"> 3817</span>&#160;    m_ItemAllocator.Free(pBackItem);</div><div class="line"><a name="l03818"></a><span class="lineno"> 3818</span>&#160;    --m_Count;</div><div class="line"><a name="l03819"></a><span class="lineno"> 3819</span>&#160;}</div><div class="line"><a name="l03820"></a><span class="lineno"> 3820</span>&#160;</div><div class="line"><a name="l03821"></a><span class="lineno"> 3821</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03822"></a><span class="lineno"> 3822</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::PopFront()</div><div class="line"><a name="l03823"></a><span class="lineno"> 3823</span>&#160;{</div><div class="line"><a name="l03824"></a><span class="lineno"> 3824</span>&#160;    VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03825"></a><span class="lineno"> 3825</span>&#160;    ItemType* <span class="keyword">const</span> pFrontItem = m_pFront;</div><div class="line"><a name="l03826"></a><span class="lineno"> 3826</span>&#160;    ItemType* <span class="keyword">const</span> pNextItem = pFrontItem-&gt;pNext;</div><div class="line"><a name="l03827"></a><span class="lineno"> 3827</span>&#160;    <span class="keywordflow">if</span>(pNextItem != VMA_NULL)</div><div class="line"><a name="l03828"></a><span class="lineno"> 3828</span>&#160;    {</div><div class="line"><a name="l03829"></a><span class="lineno"> 3829</span>&#160;        pNextItem-&gt;pPrev = VMA_NULL;</div><div class="line"><a name="l03830"></a><span class="lineno"> 3830</span>&#160;    }</div><div class="line"><a name="l03831"></a><span class="lineno"> 3831</span>&#160;    m_pFront = pNextItem;</div><div class="line"><a name="l03832"></a><span class="lineno"> 3832</span>&#160;    m_ItemAllocator.Free(pFrontItem);</div><div class="line"><a name="l03833"></a><span class="lineno"> 3833</span>&#160;    --m_Count;</div><div class="line"><a name="l03834"></a><span class="lineno"> 3834</span>&#160;}</div><div class="line"><a name="l03835"></a><span class="lineno"> 3835</span>&#160;</div><div class="line"><a name="l03836"></a><span class="lineno"> 3836</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03837"></a><span class="lineno"> 3837</span>&#160;<span class="keywordtype">void</span> VmaRawList&lt;T&gt;::Remove(ItemType* pItem)</div><div class="line"><a name="l03838"></a><span class="lineno"> 3838</span>&#160;{</div><div class="line"><a name="l03839"></a><span class="lineno"> 3839</span>&#160;    VMA_HEAVY_ASSERT(pItem != VMA_NULL);</div><div class="line"><a name="l03840"></a><span class="lineno"> 3840</span>&#160;    VMA_HEAVY_ASSERT(m_Count &gt; 0);</div><div class="line"><a name="l03841"></a><span class="lineno"> 3841</span>&#160;</div><div class="line"><a name="l03842"></a><span class="lineno"> 3842</span>&#160;    <span class="keywordflow">if</span>(pItem-&gt;pPrev != VMA_NULL)</div><div class="line"><a name="l03843"></a><span class="lineno"> 3843</span>&#160;    {</div><div class="line"><a name="l03844"></a><span class="lineno"> 3844</span>&#160;        pItem-&gt;pPrev-&gt;pNext = pItem-&gt;pNext;</div><div class="line"><a name="l03845"></a><span class="lineno"> 3845</span>&#160;    }</div><div class="line"><a name="l03846"></a><span class="lineno"> 3846</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03847"></a><span class="lineno"> 3847</span>&#160;    {</div><div class="line"><a name="l03848"></a><span class="lineno"> 3848</span>&#160;        VMA_HEAVY_ASSERT(m_pFront == pItem);</div><div class="line"><a name="l03849"></a><span class="lineno"> 3849</span>&#160;        m_pFront = pItem-&gt;pNext;</div><div class="line"><a name="l03850"></a><span class="lineno"> 3850</span>&#160;    }</div><div class="line"><a name="l03851"></a><span class="lineno"> 3851</span>&#160;</div><div class="line"><a name="l03852"></a><span class="lineno"> 3852</span>&#160;    <span class="keywordflow">if</span>(pItem-&gt;pNext != VMA_NULL)</div><div class="line"><a name="l03853"></a><span class="lineno"> 3853</span>&#160;    {</div><div class="line"><a name="l03854"></a><span class="lineno"> 3854</span>&#160;        pItem-&gt;pNext-&gt;pPrev = pItem-&gt;pPrev;</div><div class="line"><a name="l03855"></a><span class="lineno"> 3855</span>&#160;    }</div><div class="line"><a name="l03856"></a><span class="lineno"> 3856</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03857"></a><span class="lineno"> 3857</span>&#160;    {</div><div class="line"><a name="l03858"></a><span class="lineno"> 3858</span>&#160;        VMA_HEAVY_ASSERT(m_pBack == pItem);</div><div class="line"><a name="l03859"></a><span class="lineno"> 3859</span>&#160;        m_pBack = pItem-&gt;pPrev;</div><div class="line"><a name="l03860"></a><span class="lineno"> 3860</span>&#160;    }</div><div class="line"><a name="l03861"></a><span class="lineno"> 3861</span>&#160;</div><div class="line"><a name="l03862"></a><span class="lineno"> 3862</span>&#160;    m_ItemAllocator.Free(pItem);</div><div class="line"><a name="l03863"></a><span class="lineno"> 3863</span>&#160;    --m_Count;</div><div class="line"><a name="l03864"></a><span class="lineno"> 3864</span>&#160;}</div><div class="line"><a name="l03865"></a><span class="lineno"> 3865</span>&#160;</div><div class="line"><a name="l03866"></a><span class="lineno"> 3866</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03867"></a><span class="lineno"> 3867</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertBefore(ItemType* pItem)</div><div class="line"><a name="l03868"></a><span class="lineno"> 3868</span>&#160;{</div><div class="line"><a name="l03869"></a><span class="lineno"> 3869</span>&#160;    <span class="keywordflow">if</span>(pItem != VMA_NULL)</div><div class="line"><a name="l03870"></a><span class="lineno"> 3870</span>&#160;    {</div><div class="line"><a name="l03871"></a><span class="lineno"> 3871</span>&#160;        ItemType* <span class="keyword">const</span> prevItem = pItem-&gt;pPrev;</div><div class="line"><a name="l03872"></a><span class="lineno"> 3872</span>&#160;        ItemType* <span class="keyword">const</span> newItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03873"></a><span class="lineno"> 3873</span>&#160;        newItem-&gt;pPrev = prevItem;</div><div class="line"><a name="l03874"></a><span class="lineno"> 3874</span>&#160;        newItem-&gt;pNext = pItem;</div><div class="line"><a name="l03875"></a><span class="lineno"> 3875</span>&#160;        pItem-&gt;pPrev = newItem;</div><div class="line"><a name="l03876"></a><span class="lineno"> 3876</span>&#160;        <span class="keywordflow">if</span>(prevItem != VMA_NULL)</div><div class="line"><a name="l03877"></a><span class="lineno"> 3877</span>&#160;        {</div><div class="line"><a name="l03878"></a><span class="lineno"> 3878</span>&#160;            prevItem-&gt;pNext = newItem;</div><div class="line"><a name="l03879"></a><span class="lineno"> 3879</span>&#160;        }</div><div class="line"><a name="l03880"></a><span class="lineno"> 3880</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l03881"></a><span class="lineno"> 3881</span>&#160;        {</div><div class="line"><a name="l03882"></a><span class="lineno"> 3882</span>&#160;            VMA_HEAVY_ASSERT(m_pFront == pItem);</div><div class="line"><a name="l03883"></a><span class="lineno"> 3883</span>&#160;            m_pFront = newItem;</div><div class="line"><a name="l03884"></a><span class="lineno"> 3884</span>&#160;        }</div><div class="line"><a name="l03885"></a><span class="lineno"> 3885</span>&#160;        ++m_Count;</div><div class="line"><a name="l03886"></a><span class="lineno"> 3886</span>&#160;        <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03887"></a><span class="lineno"> 3887</span>&#160;    }</div><div class="line"><a name="l03888"></a><span class="lineno"> 3888</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03889"></a><span class="lineno"> 3889</span>&#160;        <span class="keywordflow">return</span> PushBack();</div><div class="line"><a name="l03890"></a><span class="lineno"> 3890</span>&#160;}</div><div class="line"><a name="l03891"></a><span class="lineno"> 3891</span>&#160;</div><div class="line"><a name="l03892"></a><span class="lineno"> 3892</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03893"></a><span class="lineno"> 3893</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertAfter(ItemType* pItem)</div><div class="line"><a name="l03894"></a><span class="lineno"> 3894</span>&#160;{</div><div class="line"><a name="l03895"></a><span class="lineno"> 3895</span>&#160;    <span class="keywordflow">if</span>(pItem != VMA_NULL)</div><div class="line"><a name="l03896"></a><span class="lineno"> 3896</span>&#160;    {</div><div class="line"><a name="l03897"></a><span class="lineno"> 3897</span>&#160;        ItemType* <span class="keyword">const</span> nextItem = pItem-&gt;pNext;</div><div class="line"><a name="l03898"></a><span class="lineno"> 3898</span>&#160;        ItemType* <span class="keyword">const</span> newItem = m_ItemAllocator.Alloc();</div><div class="line"><a name="l03899"></a><span class="lineno"> 3899</span>&#160;        newItem-&gt;pNext = nextItem;</div><div class="line"><a name="l03900"></a><span class="lineno"> 3900</span>&#160;        newItem-&gt;pPrev = pItem;</div><div class="line"><a name="l03901"></a><span class="lineno"> 3901</span>&#160;        pItem-&gt;pNext = newItem;</div><div class="line"><a name="l03902"></a><span class="lineno"> 3902</span>&#160;        <span class="keywordflow">if</span>(nextItem != VMA_NULL)</div><div class="line"><a name="l03903"></a><span class="lineno"> 3903</span>&#160;        {</div><div class="line"><a name="l03904"></a><span class="lineno"> 3904</span>&#160;            nextItem-&gt;pPrev = newItem;</div><div class="line"><a name="l03905"></a><span class="lineno"> 3905</span>&#160;        }</div><div class="line"><a name="l03906"></a><span class="lineno"> 3906</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l03907"></a><span class="lineno"> 3907</span>&#160;        {</div><div class="line"><a name="l03908"></a><span class="lineno"> 3908</span>&#160;            VMA_HEAVY_ASSERT(m_pBack == pItem);</div><div class="line"><a name="l03909"></a><span class="lineno"> 3909</span>&#160;            m_pBack = newItem;</div><div class="line"><a name="l03910"></a><span class="lineno"> 3910</span>&#160;        }</div><div class="line"><a name="l03911"></a><span class="lineno"> 3911</span>&#160;        ++m_Count;</div><div class="line"><a name="l03912"></a><span class="lineno"> 3912</span>&#160;        <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03913"></a><span class="lineno"> 3913</span>&#160;    }</div><div class="line"><a name="l03914"></a><span class="lineno"> 3914</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l03915"></a><span class="lineno"> 3915</span>&#160;        <span class="keywordflow">return</span> PushFront();</div><div class="line"><a name="l03916"></a><span class="lineno"> 3916</span>&#160;}</div><div class="line"><a name="l03917"></a><span class="lineno"> 3917</span>&#160;</div><div class="line"><a name="l03918"></a><span class="lineno"> 3918</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03919"></a><span class="lineno"> 3919</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertBefore(ItemType* pItem, <span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03920"></a><span class="lineno"> 3920</span>&#160;{</div><div class="line"><a name="l03921"></a><span class="lineno"> 3921</span>&#160;    ItemType* <span class="keyword">const</span> newItem = InsertBefore(pItem);</div><div class="line"><a name="l03922"></a><span class="lineno"> 3922</span>&#160;    newItem-&gt;Value = value;</div><div class="line"><a name="l03923"></a><span class="lineno"> 3923</span>&#160;    <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03924"></a><span class="lineno"> 3924</span>&#160;}</div><div class="line"><a name="l03925"></a><span class="lineno"> 3925</span>&#160;</div><div class="line"><a name="l03926"></a><span class="lineno"> 3926</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l03927"></a><span class="lineno"> 3927</span>&#160;VmaListItem&lt;T&gt;* VmaRawList&lt;T&gt;::InsertAfter(ItemType* pItem, <span class="keyword">const</span> T&amp; value)</div><div class="line"><a name="l03928"></a><span class="lineno"> 3928</span>&#160;{</div><div class="line"><a name="l03929"></a><span class="lineno"> 3929</span>&#160;    ItemType* <span class="keyword">const</span> newItem = InsertAfter(pItem);</div><div class="line"><a name="l03930"></a><span class="lineno"> 3930</span>&#160;    newItem-&gt;Value = value;</div><div class="line"><a name="l03931"></a><span class="lineno"> 3931</span>&#160;    <span class="keywordflow">return</span> newItem;</div><div class="line"><a name="l03932"></a><span class="lineno"> 3932</span>&#160;}</div><div class="line"><a name="l03933"></a><span class="lineno"> 3933</span>&#160;</div><div class="line"><a name="l03934"></a><span class="lineno"> 3934</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> AllocatorT&gt;</div><div class="line"><a name="l03935"></a><span class="lineno"> 3935</span>&#160;<span class="keyword">class </span>VmaList</div><div class="line"><a name="l03936"></a><span class="lineno"> 3936</span>&#160;{</div><div class="line"><a name="l03937"></a><span class="lineno"> 3937</span>&#160;    VMA_CLASS_NO_COPY(VmaList)</div><div class="line"><a name="l03938"></a><span class="lineno"> 3938</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l03939"></a><span class="lineno"> 3939</span>&#160;    <span class="keyword">class </span>iterator</div><div class="line"><a name="l03940"></a><span class="lineno"> 3940</span>&#160;    {</div><div class="line"><a name="l03941"></a><span class="lineno"> 3941</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l03942"></a><span class="lineno"> 3942</span>&#160;        iterator() :</div><div class="line"><a name="l03943"></a><span class="lineno"> 3943</span>&#160;            m_pList(VMA_NULL),</div><div class="line"><a name="l03944"></a><span class="lineno"> 3944</span>&#160;            m_pItem(VMA_NULL)</div><div class="line"><a name="l03945"></a><span class="lineno"> 3945</span>&#160;        {</div><div class="line"><a name="l03946"></a><span class="lineno"> 3946</span>&#160;        }</div><div class="line"><a name="l03947"></a><span class="lineno"> 3947</span>&#160;</div><div class="line"><a name="l03948"></a><span class="lineno"> 3948</span>&#160;        T&amp; operator*()<span class="keyword"> const</span></div><div class="line"><a name="l03949"></a><span class="lineno"> 3949</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03950"></a><span class="lineno"> 3950</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03951"></a><span class="lineno"> 3951</span>&#160;            <span class="keywordflow">return</span> m_pItem-&gt;Value;</div><div class="line"><a name="l03952"></a><span class="lineno"> 3952</span>&#160;        }</div><div class="line"><a name="l03953"></a><span class="lineno"> 3953</span>&#160;        T* operator-&gt;()<span class="keyword"> const</span></div><div class="line"><a name="l03954"></a><span class="lineno"> 3954</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03955"></a><span class="lineno"> 3955</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03956"></a><span class="lineno"> 3956</span>&#160;            <span class="keywordflow">return</span> &amp;m_pItem-&gt;Value;</div><div class="line"><a name="l03957"></a><span class="lineno"> 3957</span>&#160;        }</div><div class="line"><a name="l03958"></a><span class="lineno"> 3958</span>&#160;</div><div class="line"><a name="l03959"></a><span class="lineno"> 3959</span>&#160;        iterator&amp; operator++()</div><div class="line"><a name="l03960"></a><span class="lineno"> 3960</span>&#160;        {</div><div class="line"><a name="l03961"></a><span class="lineno"> 3961</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l03962"></a><span class="lineno"> 3962</span>&#160;            m_pItem = m_pItem-&gt;pNext;</div><div class="line"><a name="l03963"></a><span class="lineno"> 3963</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l03964"></a><span class="lineno"> 3964</span>&#160;        }</div><div class="line"><a name="l03965"></a><span class="lineno"> 3965</span>&#160;        iterator&amp; operator--()</div><div class="line"><a name="l03966"></a><span class="lineno"> 3966</span>&#160;        {</div><div class="line"><a name="l03967"></a><span class="lineno"> 3967</span>&#160;            <span class="keywordflow">if</span>(m_pItem != VMA_NULL)</div><div class="line"><a name="l03968"></a><span class="lineno"> 3968</span>&#160;            {</div><div class="line"><a name="l03969"></a><span class="lineno"> 3969</span>&#160;                m_pItem = m_pItem-&gt;pPrev;</div><div class="line"><a name="l03970"></a><span class="lineno"> 3970</span>&#160;            }</div><div class="line"><a name="l03971"></a><span class="lineno"> 3971</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l03972"></a><span class="lineno"> 3972</span>&#160;            {</div><div class="line"><a name="l03973"></a><span class="lineno"> 3973</span>&#160;                VMA_HEAVY_ASSERT(!m_pList-&gt;IsEmpty());</div><div class="line"><a name="l03974"></a><span class="lineno"> 3974</span>&#160;                m_pItem = m_pList-&gt;Back();</div><div class="line"><a name="l03975"></a><span class="lineno"> 3975</span>&#160;            }</div><div class="line"><a name="l03976"></a><span class="lineno"> 3976</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l03977"></a><span class="lineno"> 3977</span>&#160;        }</div><div class="line"><a name="l03978"></a><span class="lineno"> 3978</span>&#160;</div><div class="line"><a name="l03979"></a><span class="lineno"> 3979</span>&#160;        iterator operator++(<span class="keywordtype">int</span>)</div><div class="line"><a name="l03980"></a><span class="lineno"> 3980</span>&#160;        {</div><div class="line"><a name="l03981"></a><span class="lineno"> 3981</span>&#160;            iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l03982"></a><span class="lineno"> 3982</span>&#160;            ++*<span class="keyword">this</span>;</div><div class="line"><a name="l03983"></a><span class="lineno"> 3983</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l03984"></a><span class="lineno"> 3984</span>&#160;        }</div><div class="line"><a name="l03985"></a><span class="lineno"> 3985</span>&#160;        iterator operator--(<span class="keywordtype">int</span>)</div><div class="line"><a name="l03986"></a><span class="lineno"> 3986</span>&#160;        {</div><div class="line"><a name="l03987"></a><span class="lineno"> 3987</span>&#160;            iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l03988"></a><span class="lineno"> 3988</span>&#160;            --*<span class="keyword">this</span>;</div><div class="line"><a name="l03989"></a><span class="lineno"> 3989</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l03990"></a><span class="lineno"> 3990</span>&#160;        }</div><div class="line"><a name="l03991"></a><span class="lineno"> 3991</span>&#160;</div><div class="line"><a name="l03992"></a><span class="lineno"> 3992</span>&#160;        <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03993"></a><span class="lineno"> 3993</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03994"></a><span class="lineno"> 3994</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l03995"></a><span class="lineno"> 3995</span>&#160;            <span class="keywordflow">return</span> m_pItem == rhs.m_pItem;</div><div class="line"><a name="l03996"></a><span class="lineno"> 3996</span>&#160;        }</div><div class="line"><a name="l03997"></a><span class="lineno"> 3997</span>&#160;        <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l03998"></a><span class="lineno"> 3998</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l03999"></a><span class="lineno"> 3999</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l04000"></a><span class="lineno"> 4000</span>&#160;            <span class="keywordflow">return</span> m_pItem != rhs.m_pItem;</div><div class="line"><a name="l04001"></a><span class="lineno"> 4001</span>&#160;        }</div><div class="line"><a name="l04002"></a><span class="lineno"> 4002</span>&#160;        </div><div class="line"><a name="l04003"></a><span class="lineno"> 4003</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l04004"></a><span class="lineno"> 4004</span>&#160;        VmaRawList&lt;T&gt;* m_pList;</div><div class="line"><a name="l04005"></a><span class="lineno"> 4005</span>&#160;        VmaListItem&lt;T&gt;* m_pItem;</div><div class="line"><a name="l04006"></a><span class="lineno"> 4006</span>&#160;</div><div class="line"><a name="l04007"></a><span class="lineno"> 4007</span>&#160;        iterator(VmaRawList&lt;T&gt;* pList, VmaListItem&lt;T&gt;* pItem) :</div><div class="line"><a name="l04008"></a><span class="lineno"> 4008</span>&#160;            m_pList(pList),</div><div class="line"><a name="l04009"></a><span class="lineno"> 4009</span>&#160;            m_pItem(pItem)</div><div class="line"><a name="l04010"></a><span class="lineno"> 4010</span>&#160;        {</div><div class="line"><a name="l04011"></a><span class="lineno"> 4011</span>&#160;        }</div><div class="line"><a name="l04012"></a><span class="lineno"> 4012</span>&#160;</div><div class="line"><a name="l04013"></a><span class="lineno"> 4013</span>&#160;        <span class="keyword">friend</span> <span class="keyword">class </span>VmaList&lt;T, AllocatorT&gt;;</div><div class="line"><a name="l04014"></a><span class="lineno"> 4014</span>&#160;    };</div><div class="line"><a name="l04015"></a><span class="lineno"> 4015</span>&#160;</div><div class="line"><a name="l04016"></a><span class="lineno"> 4016</span>&#160;    <span class="keyword">class </span>const_iterator</div><div class="line"><a name="l04017"></a><span class="lineno"> 4017</span>&#160;    {</div><div class="line"><a name="l04018"></a><span class="lineno"> 4018</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l04019"></a><span class="lineno"> 4019</span>&#160;        const_iterator() :</div><div class="line"><a name="l04020"></a><span class="lineno"> 4020</span>&#160;            m_pList(VMA_NULL),</div><div class="line"><a name="l04021"></a><span class="lineno"> 4021</span>&#160;            m_pItem(VMA_NULL)</div><div class="line"><a name="l04022"></a><span class="lineno"> 4022</span>&#160;        {</div><div class="line"><a name="l04023"></a><span class="lineno"> 4023</span>&#160;        }</div><div class="line"><a name="l04024"></a><span class="lineno"> 4024</span>&#160;</div><div class="line"><a name="l04025"></a><span class="lineno"> 4025</span>&#160;        const_iterator(<span class="keyword">const</span> iterator&amp; src) :</div><div class="line"><a name="l04026"></a><span class="lineno"> 4026</span>&#160;            m_pList(src.m_pList),</div><div class="line"><a name="l04027"></a><span class="lineno"> 4027</span>&#160;            m_pItem(src.m_pItem)</div><div class="line"><a name="l04028"></a><span class="lineno"> 4028</span>&#160;        {</div><div class="line"><a name="l04029"></a><span class="lineno"> 4029</span>&#160;        }</div><div class="line"><a name="l04030"></a><span class="lineno"> 4030</span>&#160;        </div><div class="line"><a name="l04031"></a><span class="lineno"> 4031</span>&#160;        <span class="keyword">const</span> T&amp; operator*()<span class="keyword"> const</span></div><div class="line"><a name="l04032"></a><span class="lineno"> 4032</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04033"></a><span class="lineno"> 4033</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l04034"></a><span class="lineno"> 4034</span>&#160;            <span class="keywordflow">return</span> m_pItem-&gt;Value;</div><div class="line"><a name="l04035"></a><span class="lineno"> 4035</span>&#160;        }</div><div class="line"><a name="l04036"></a><span class="lineno"> 4036</span>&#160;        <span class="keyword">const</span> T* operator-&gt;()<span class="keyword"> const</span></div><div class="line"><a name="l04037"></a><span class="lineno"> 4037</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04038"></a><span class="lineno"> 4038</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l04039"></a><span class="lineno"> 4039</span>&#160;            <span class="keywordflow">return</span> &amp;m_pItem-&gt;Value;</div><div class="line"><a name="l04040"></a><span class="lineno"> 4040</span>&#160;        }</div><div class="line"><a name="l04041"></a><span class="lineno"> 4041</span>&#160;</div><div class="line"><a name="l04042"></a><span class="lineno"> 4042</span>&#160;        const_iterator&amp; operator++()</div><div class="line"><a name="l04043"></a><span class="lineno"> 4043</span>&#160;        {</div><div class="line"><a name="l04044"></a><span class="lineno"> 4044</span>&#160;            VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);</div><div class="line"><a name="l04045"></a><span class="lineno"> 4045</span>&#160;            m_pItem = m_pItem-&gt;pNext;</div><div class="line"><a name="l04046"></a><span class="lineno"> 4046</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l04047"></a><span class="lineno"> 4047</span>&#160;        }</div><div class="line"><a name="l04048"></a><span class="lineno"> 4048</span>&#160;        const_iterator&amp; operator--()</div><div class="line"><a name="l04049"></a><span class="lineno"> 4049</span>&#160;        {</div><div class="line"><a name="l04050"></a><span class="lineno"> 4050</span>&#160;            <span class="keywordflow">if</span>(m_pItem != VMA_NULL)</div><div class="line"><a name="l04051"></a><span class="lineno"> 4051</span>&#160;            {</div><div class="line"><a name="l04052"></a><span class="lineno"> 4052</span>&#160;                m_pItem = m_pItem-&gt;pPrev;</div><div class="line"><a name="l04053"></a><span class="lineno"> 4053</span>&#160;            }</div><div class="line"><a name="l04054"></a><span class="lineno"> 4054</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l04055"></a><span class="lineno"> 4055</span>&#160;            {</div><div class="line"><a name="l04056"></a><span class="lineno"> 4056</span>&#160;                VMA_HEAVY_ASSERT(!m_pList-&gt;IsEmpty());</div><div class="line"><a name="l04057"></a><span class="lineno"> 4057</span>&#160;                m_pItem = m_pList-&gt;Back();</div><div class="line"><a name="l04058"></a><span class="lineno"> 4058</span>&#160;            }</div><div class="line"><a name="l04059"></a><span class="lineno"> 4059</span>&#160;            <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l04060"></a><span class="lineno"> 4060</span>&#160;        }</div><div class="line"><a name="l04061"></a><span class="lineno"> 4061</span>&#160;</div><div class="line"><a name="l04062"></a><span class="lineno"> 4062</span>&#160;        const_iterator operator++(<span class="keywordtype">int</span>)</div><div class="line"><a name="l04063"></a><span class="lineno"> 4063</span>&#160;        {</div><div class="line"><a name="l04064"></a><span class="lineno"> 4064</span>&#160;            const_iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l04065"></a><span class="lineno"> 4065</span>&#160;            ++*<span class="keyword">this</span>;</div><div class="line"><a name="l04066"></a><span class="lineno"> 4066</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l04067"></a><span class="lineno"> 4067</span>&#160;        }</div><div class="line"><a name="l04068"></a><span class="lineno"> 4068</span>&#160;        const_iterator operator--(<span class="keywordtype">int</span>)</div><div class="line"><a name="l04069"></a><span class="lineno"> 4069</span>&#160;        {</div><div class="line"><a name="l04070"></a><span class="lineno"> 4070</span>&#160;            const_iterator result = *<span class="keyword">this</span>;</div><div class="line"><a name="l04071"></a><span class="lineno"> 4071</span>&#160;            --*<span class="keyword">this</span>;</div><div class="line"><a name="l04072"></a><span class="lineno"> 4072</span>&#160;            <span class="keywordflow">return</span> result;</div><div class="line"><a name="l04073"></a><span class="lineno"> 4073</span>&#160;        }</div><div class="line"><a name="l04074"></a><span class="lineno"> 4074</span>&#160;</div><div class="line"><a name="l04075"></a><span class="lineno"> 4075</span>&#160;        <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> const_iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04076"></a><span class="lineno"> 4076</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04077"></a><span class="lineno"> 4077</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l04078"></a><span class="lineno"> 4078</span>&#160;            <span class="keywordflow">return</span> m_pItem == rhs.m_pItem;</div><div class="line"><a name="l04079"></a><span class="lineno"> 4079</span>&#160;        }</div><div class="line"><a name="l04080"></a><span class="lineno"> 4080</span>&#160;        <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> const_iterator&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04081"></a><span class="lineno"> 4081</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l04082"></a><span class="lineno"> 4082</span>&#160;            VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);</div><div class="line"><a name="l04083"></a><span class="lineno"> 4083</span>&#160;            <span class="keywordflow">return</span> m_pItem != rhs.m_pItem;</div><div class="line"><a name="l04084"></a><span class="lineno"> 4084</span>&#160;        }</div><div class="line"><a name="l04085"></a><span class="lineno"> 4085</span>&#160;        </div><div class="line"><a name="l04086"></a><span class="lineno"> 4086</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l04087"></a><span class="lineno"> 4087</span>&#160;        const_iterator(<span class="keyword">const</span> VmaRawList&lt;T&gt;* pList, <span class="keyword">const</span> VmaListItem&lt;T&gt;* pItem) :</div><div class="line"><a name="l04088"></a><span class="lineno"> 4088</span>&#160;            m_pList(pList),</div><div class="line"><a name="l04089"></a><span class="lineno"> 4089</span>&#160;            m_pItem(pItem)</div><div class="line"><a name="l04090"></a><span class="lineno"> 4090</span>&#160;        {</div><div class="line"><a name="l04091"></a><span class="lineno"> 4091</span>&#160;        }</div><div class="line"><a name="l04092"></a><span class="lineno"> 4092</span>&#160;</div><div class="line"><a name="l04093"></a><span class="lineno"> 4093</span>&#160;        <span class="keyword">const</span> VmaRawList&lt;T&gt;* m_pList;</div><div class="line"><a name="l04094"></a><span class="lineno"> 4094</span>&#160;        <span class="keyword">const</span> VmaListItem&lt;T&gt;* m_pItem;</div><div class="line"><a name="l04095"></a><span class="lineno"> 4095</span>&#160;</div><div class="line"><a name="l04096"></a><span class="lineno"> 4096</span>&#160;        <span class="keyword">friend</span> <span class="keyword">class </span>VmaList&lt;T, AllocatorT&gt;;</div><div class="line"><a name="l04097"></a><span class="lineno"> 4097</span>&#160;    };</div><div class="line"><a name="l04098"></a><span class="lineno"> 4098</span>&#160;</div><div class="line"><a name="l04099"></a><span class="lineno"> 4099</span>&#160;    VmaList(<span class="keyword">const</span> AllocatorT&amp; allocator) : m_RawList(allocator.m_pCallbacks) { }</div><div class="line"><a name="l04100"></a><span class="lineno"> 4100</span>&#160;</div><div class="line"><a name="l04101"></a><span class="lineno"> 4101</span>&#160;    <span class="keywordtype">bool</span> empty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_RawList.IsEmpty(); }</div><div class="line"><a name="l04102"></a><span class="lineno"> 4102</span>&#160;    <span class="keywordtype">size_t</span> size()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_RawList.GetCount(); }</div><div class="line"><a name="l04103"></a><span class="lineno"> 4103</span>&#160;</div><div class="line"><a name="l04104"></a><span class="lineno"> 4104</span>&#160;    iterator begin() { <span class="keywordflow">return</span> iterator(&amp;m_RawList, m_RawList.Front()); }</div><div class="line"><a name="l04105"></a><span class="lineno"> 4105</span>&#160;    iterator end() { <span class="keywordflow">return</span> iterator(&amp;m_RawList, VMA_NULL); }</div><div class="line"><a name="l04106"></a><span class="lineno"> 4106</span>&#160;</div><div class="line"><a name="l04107"></a><span class="lineno"> 4107</span>&#160;    const_iterator cbegin()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> const_iterator(&amp;m_RawList, m_RawList.Front()); }</div><div class="line"><a name="l04108"></a><span class="lineno"> 4108</span>&#160;    const_iterator cend()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> const_iterator(&amp;m_RawList, VMA_NULL); }</div><div class="line"><a name="l04109"></a><span class="lineno"> 4109</span>&#160;</div><div class="line"><a name="l04110"></a><span class="lineno"> 4110</span>&#160;    <span class="keywordtype">void</span> clear() { m_RawList.Clear(); }</div><div class="line"><a name="l04111"></a><span class="lineno"> 4111</span>&#160;    <span class="keywordtype">void</span> push_back(<span class="keyword">const</span> T&amp; value) { m_RawList.PushBack(value); }</div><div class="line"><a name="l04112"></a><span class="lineno"> 4112</span>&#160;    <span class="keywordtype">void</span> erase(iterator it) { m_RawList.Remove(it.m_pItem); }</div><div class="line"><a name="l04113"></a><span class="lineno"> 4113</span>&#160;    iterator insert(iterator it, <span class="keyword">const</span> T&amp; value) { <span class="keywordflow">return</span> iterator(&amp;m_RawList, m_RawList.InsertBefore(it.m_pItem, value)); }</div><div class="line"><a name="l04114"></a><span class="lineno"> 4114</span>&#160;</div><div class="line"><a name="l04115"></a><span class="lineno"> 4115</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04116"></a><span class="lineno"> 4116</span>&#160;    VmaRawList&lt;T&gt; m_RawList;</div><div class="line"><a name="l04117"></a><span class="lineno"> 4117</span>&#160;};</div><div class="line"><a name="l04118"></a><span class="lineno"> 4118</span>&#160;</div><div class="line"><a name="l04119"></a><span class="lineno"> 4119</span>&#160;<span class="preprocessor">#endif // #if VMA_USE_STL_LIST</span></div><div class="line"><a name="l04120"></a><span class="lineno"> 4120</span>&#160;</div><div class="line"><a name="l04122"></a><span class="lineno"> 4122</span>&#160;<span class="comment">// class VmaMap</span></div><div class="line"><a name="l04123"></a><span class="lineno"> 4123</span>&#160;</div><div class="line"><a name="l04124"></a><span class="lineno"> 4124</span>&#160;<span class="comment">// Unused in this version.</span></div><div class="line"><a name="l04125"></a><span class="lineno"> 4125</span>&#160;<span class="preprocessor">#if 0</span></div><div class="line"><a name="l04126"></a><span class="lineno"> 4126</span>&#160;</div><div class="line"><a name="l04127"></a><span class="lineno"> 4127</span>&#160;<span class="preprocessor">#if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l04128"></a><span class="lineno"> 4128</span>&#160;</div><div class="line"><a name="l04129"></a><span class="lineno"> 4129</span>&#160;<span class="preprocessor">#define VmaPair std::pair</span></div><div class="line"><a name="l04130"></a><span class="lineno"> 4130</span>&#160;</div><div class="line"><a name="l04131"></a><span class="lineno"> 4131</span>&#160;<span class="preprocessor">#define VMA_MAP_TYPE(KeyT, ValueT) \</span></div><div class="line"><a name="l04132"></a><span class="lineno"> 4132</span>&#160;<span class="preprocessor">    std::unordered_map&lt; KeyT, ValueT, std::hash&lt;KeyT&gt;, std::equal_to&lt;KeyT&gt;, VmaStlAllocator&lt; std::pair&lt;KeyT, ValueT&gt; &gt; &gt;</span></div><div class="line"><a name="l04133"></a><span class="lineno"> 4133</span>&#160;</div><div class="line"><a name="l04134"></a><span class="lineno"> 4134</span>&#160;<span class="preprocessor">#else // #if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l04135"></a><span class="lineno"> 4135</span>&#160;</div><div class="line"><a name="l04136"></a><span class="lineno"> 4136</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T1, <span class="keyword">typename</span> T2&gt;</div><div class="line"><a name="l04137"></a><span class="lineno"> 4137</span>&#160;<span class="keyword">struct </span>VmaPair</div><div class="line"><a name="l04138"></a><span class="lineno"> 4138</span>&#160;{</div><div class="line"><a name="l04139"></a><span class="lineno"> 4139</span>&#160;    T1 first;</div><div class="line"><a name="l04140"></a><span class="lineno"> 4140</span>&#160;    T2 second;</div><div class="line"><a name="l04141"></a><span class="lineno"> 4141</span>&#160;</div><div class="line"><a name="l04142"></a><span class="lineno"> 4142</span>&#160;    VmaPair() : first(), second() { }</div><div class="line"><a name="l04143"></a><span class="lineno"> 4143</span>&#160;    VmaPair(<span class="keyword">const</span> T1&amp; firstSrc, <span class="keyword">const</span> T2&amp; secondSrc) : first(firstSrc), second(secondSrc) { }</div><div class="line"><a name="l04144"></a><span class="lineno"> 4144</span>&#160;};</div><div class="line"><a name="l04145"></a><span class="lineno"> 4145</span>&#160;</div><div class="line"><a name="l04146"></a><span class="lineno"> 4146</span>&#160;<span class="comment">/* Class compatible with subset of interface of std::unordered_map.</span></div><div class="line"><a name="l04147"></a><span class="lineno"> 4147</span>&#160;<span class="comment">KeyT, ValueT must be POD because they will be stored in VmaVector.</span></div><div class="line"><a name="l04148"></a><span class="lineno"> 4148</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04149"></a><span class="lineno"> 4149</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l04150"></a><span class="lineno"> 4150</span>&#160;<span class="keyword">class </span>VmaMap</div><div class="line"><a name="l04151"></a><span class="lineno"> 4151</span>&#160;{</div><div class="line"><a name="l04152"></a><span class="lineno"> 4152</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04153"></a><span class="lineno"> 4153</span>&#160;    <span class="keyword">typedef</span> VmaPair&lt;KeyT, ValueT&gt; PairType;</div><div class="line"><a name="l04154"></a><span class="lineno"> 4154</span>&#160;    <span class="keyword">typedef</span> PairType* iterator;</div><div class="line"><a name="l04155"></a><span class="lineno"> 4155</span>&#160;</div><div class="line"><a name="l04156"></a><span class="lineno"> 4156</span>&#160;    VmaMap(<span class="keyword">const</span> VmaStlAllocator&lt;PairType&gt;&amp; allocator) : m_Vector(allocator) { }</div><div class="line"><a name="l04157"></a><span class="lineno"> 4157</span>&#160;</div><div class="line"><a name="l04158"></a><span class="lineno"> 4158</span>&#160;    iterator begin() { <span class="keywordflow">return</span> m_Vector.begin(); }</div><div class="line"><a name="l04159"></a><span class="lineno"> 4159</span>&#160;    iterator end() { <span class="keywordflow">return</span> m_Vector.end(); }</div><div class="line"><a name="l04160"></a><span class="lineno"> 4160</span>&#160;</div><div class="line"><a name="l04161"></a><span class="lineno"> 4161</span>&#160;    <span class="keywordtype">void</span> insert(<span class="keyword">const</span> PairType&amp; pair);</div><div class="line"><a name="l04162"></a><span class="lineno"> 4162</span>&#160;    iterator find(<span class="keyword">const</span> KeyT&amp; key);</div><div class="line"><a name="l04163"></a><span class="lineno"> 4163</span>&#160;    <span class="keywordtype">void</span> erase(iterator it);</div><div class="line"><a name="l04164"></a><span class="lineno"> 4164</span>&#160;    </div><div class="line"><a name="l04165"></a><span class="lineno"> 4165</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04166"></a><span class="lineno"> 4166</span>&#160;    VmaVector&lt; PairType, VmaStlAllocator&lt;PairType&gt; &gt; m_Vector;</div><div class="line"><a name="l04167"></a><span class="lineno"> 4167</span>&#160;};</div><div class="line"><a name="l04168"></a><span class="lineno"> 4168</span>&#160;</div><div class="line"><a name="l04169"></a><span class="lineno"> 4169</span>&#160;<span class="preprocessor">#define VMA_MAP_TYPE(KeyT, ValueT) VmaMap&lt;KeyT, ValueT&gt;</span></div><div class="line"><a name="l04170"></a><span class="lineno"> 4170</span>&#160;</div><div class="line"><a name="l04171"></a><span class="lineno"> 4171</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> FirstT, <span class="keyword">typename</span> SecondT&gt;</div><div class="line"><a name="l04172"></a><span class="lineno"> 4172</span>&#160;<span class="keyword">struct </span>VmaPairFirstLess</div><div class="line"><a name="l04173"></a><span class="lineno"> 4173</span>&#160;{</div><div class="line"><a name="l04174"></a><span class="lineno"> 4174</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> VmaPair&lt;FirstT, SecondT&gt;&amp; lhs, <span class="keyword">const</span> VmaPair&lt;FirstT, SecondT&gt;&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04175"></a><span class="lineno"> 4175</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04176"></a><span class="lineno"> 4176</span>&#160;        <span class="keywordflow">return</span> lhs.first &lt; rhs.first;</div><div class="line"><a name="l04177"></a><span class="lineno"> 4177</span>&#160;    }</div><div class="line"><a name="l04178"></a><span class="lineno"> 4178</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> VmaPair&lt;FirstT, SecondT&gt;&amp; lhs, <span class="keyword">const</span> FirstT&amp; rhsFirst)<span class="keyword"> const</span></div><div class="line"><a name="l04179"></a><span class="lineno"> 4179</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04180"></a><span class="lineno"> 4180</span>&#160;        <span class="keywordflow">return</span> lhs.first &lt; rhsFirst;</div><div class="line"><a name="l04181"></a><span class="lineno"> 4181</span>&#160;    }</div><div class="line"><a name="l04182"></a><span class="lineno"> 4182</span>&#160;};</div><div class="line"><a name="l04183"></a><span class="lineno"> 4183</span>&#160;</div><div class="line"><a name="l04184"></a><span class="lineno"> 4184</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l04185"></a><span class="lineno"> 4185</span>&#160;<span class="keywordtype">void</span> VmaMap&lt;KeyT, ValueT&gt;::insert(<span class="keyword">const</span> PairType&amp; pair)</div><div class="line"><a name="l04186"></a><span class="lineno"> 4186</span>&#160;{</div><div class="line"><a name="l04187"></a><span class="lineno"> 4187</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> indexToInsert = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l04188"></a><span class="lineno"> 4188</span>&#160;        m_Vector.data(),</div><div class="line"><a name="l04189"></a><span class="lineno"> 4189</span>&#160;        m_Vector.data() + m_Vector.size(),</div><div class="line"><a name="l04190"></a><span class="lineno"> 4190</span>&#160;        pair,</div><div class="line"><a name="l04191"></a><span class="lineno"> 4191</span>&#160;        VmaPairFirstLess&lt;KeyT, ValueT&gt;()) - m_Vector.data();</div><div class="line"><a name="l04192"></a><span class="lineno"> 4192</span>&#160;    VmaVectorInsert(m_Vector, indexToInsert, pair);</div><div class="line"><a name="l04193"></a><span class="lineno"> 4193</span>&#160;}</div><div class="line"><a name="l04194"></a><span class="lineno"> 4194</span>&#160;</div><div class="line"><a name="l04195"></a><span class="lineno"> 4195</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l04196"></a><span class="lineno"> 4196</span>&#160;VmaPair&lt;KeyT, ValueT&gt;* VmaMap&lt;KeyT, ValueT&gt;::find(<span class="keyword">const</span> KeyT&amp; key)</div><div class="line"><a name="l04197"></a><span class="lineno"> 4197</span>&#160;{</div><div class="line"><a name="l04198"></a><span class="lineno"> 4198</span>&#160;    PairType* it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l04199"></a><span class="lineno"> 4199</span>&#160;        m_Vector.data(),</div><div class="line"><a name="l04200"></a><span class="lineno"> 4200</span>&#160;        m_Vector.data() + m_Vector.size(),</div><div class="line"><a name="l04201"></a><span class="lineno"> 4201</span>&#160;        key,</div><div class="line"><a name="l04202"></a><span class="lineno"> 4202</span>&#160;        VmaPairFirstLess&lt;KeyT, ValueT&gt;());</div><div class="line"><a name="l04203"></a><span class="lineno"> 4203</span>&#160;    <span class="keywordflow">if</span>((it != m_Vector.end()) &amp;&amp; (it-&gt;first == key))</div><div class="line"><a name="l04204"></a><span class="lineno"> 4204</span>&#160;    {</div><div class="line"><a name="l04205"></a><span class="lineno"> 4205</span>&#160;        <span class="keywordflow">return</span> it;</div><div class="line"><a name="l04206"></a><span class="lineno"> 4206</span>&#160;    }</div><div class="line"><a name="l04207"></a><span class="lineno"> 4207</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l04208"></a><span class="lineno"> 4208</span>&#160;    {</div><div class="line"><a name="l04209"></a><span class="lineno"> 4209</span>&#160;        <span class="keywordflow">return</span> m_Vector.end();</div><div class="line"><a name="l04210"></a><span class="lineno"> 4210</span>&#160;    }</div><div class="line"><a name="l04211"></a><span class="lineno"> 4211</span>&#160;}</div><div class="line"><a name="l04212"></a><span class="lineno"> 4212</span>&#160;</div><div class="line"><a name="l04213"></a><span class="lineno"> 4213</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> KeyT, <span class="keyword">typename</span> ValueT&gt;</div><div class="line"><a name="l04214"></a><span class="lineno"> 4214</span>&#160;<span class="keywordtype">void</span> VmaMap&lt;KeyT, ValueT&gt;::erase(iterator it)</div><div class="line"><a name="l04215"></a><span class="lineno"> 4215</span>&#160;{</div><div class="line"><a name="l04216"></a><span class="lineno"> 4216</span>&#160;    VmaVectorRemove(m_Vector, it - m_Vector.begin());</div><div class="line"><a name="l04217"></a><span class="lineno"> 4217</span>&#160;}</div><div class="line"><a name="l04218"></a><span class="lineno"> 4218</span>&#160;</div><div class="line"><a name="l04219"></a><span class="lineno"> 4219</span>&#160;<span class="preprocessor">#endif // #if VMA_USE_STL_UNORDERED_MAP</span></div><div class="line"><a name="l04220"></a><span class="lineno"> 4220</span>&#160;</div><div class="line"><a name="l04221"></a><span class="lineno"> 4221</span>&#160;<span class="preprocessor">#endif // #if 0</span></div><div class="line"><a name="l04222"></a><span class="lineno"> 4222</span>&#160;</div><div class="line"><a name="l04224"></a><span class="lineno"> 4224</span>&#160;</div><div class="line"><a name="l04225"></a><span class="lineno"> 4225</span>&#160;<span class="keyword">class </span>VmaDeviceMemoryBlock;</div><div class="line"><a name="l04226"></a><span class="lineno"> 4226</span>&#160;</div><div class="line"><a name="l04227"></a><span class="lineno"> 4227</span>&#160;<span class="keyword">enum</span> VMA_CACHE_OPERATION { VMA_CACHE_FLUSH, VMA_CACHE_INVALIDATE };</div><div class="line"><a name="l04228"></a><span class="lineno"> 4228</span>&#160;</div><div class="line"><a name="l04229"></a><span class="lineno"> 4229</span>&#160;<span class="keyword">struct </span>VmaAllocation_T</div><div class="line"><a name="l04230"></a><span class="lineno"> 4230</span>&#160;{</div><div class="line"><a name="l04231"></a><span class="lineno"> 4231</span>&#160;    VMA_CLASS_NO_COPY(VmaAllocation_T)</div><div class="line"><a name="l04232"></a><span class="lineno"> 4232</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04233"></a><span class="lineno"> 4233</span>&#160;    <span class="keyword">static</span> <span class="keyword">const</span> uint8_t MAP_COUNT_FLAG_PERSISTENT_MAP = 0x80;</div><div class="line"><a name="l04234"></a><span class="lineno"> 4234</span>&#160;</div><div class="line"><a name="l04235"></a><span class="lineno"> 4235</span>&#160;    <span class="keyword">enum</span> FLAGS</div><div class="line"><a name="l04236"></a><span class="lineno"> 4236</span>&#160;    {</div><div class="line"><a name="l04237"></a><span class="lineno"> 4237</span>&#160;        FLAG_USER_DATA_STRING = 0x01,</div><div class="line"><a name="l04238"></a><span class="lineno"> 4238</span>&#160;    };</div><div class="line"><a name="l04239"></a><span class="lineno"> 4239</span>&#160;</div><div class="line"><a name="l04240"></a><span class="lineno"> 4240</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04241"></a><span class="lineno"> 4241</span>&#160;    <span class="keyword">enum</span> ALLOCATION_TYPE</div><div class="line"><a name="l04242"></a><span class="lineno"> 4242</span>&#160;    {</div><div class="line"><a name="l04243"></a><span class="lineno"> 4243</span>&#160;        ALLOCATION_TYPE_NONE,</div><div class="line"><a name="l04244"></a><span class="lineno"> 4244</span>&#160;        ALLOCATION_TYPE_BLOCK,</div><div class="line"><a name="l04245"></a><span class="lineno"> 4245</span>&#160;        ALLOCATION_TYPE_DEDICATED,</div><div class="line"><a name="l04246"></a><span class="lineno"> 4246</span>&#160;    };</div><div class="line"><a name="l04247"></a><span class="lineno"> 4247</span>&#160;</div><div class="line"><a name="l04248"></a><span class="lineno"> 4248</span>&#160;    VmaAllocation_T(uint32_t currentFrameIndex, <span class="keywordtype">bool</span> userDataString) :</div><div class="line"><a name="l04249"></a><span class="lineno"> 4249</span>&#160;        m_Alignment(1),</div><div class="line"><a name="l04250"></a><span class="lineno"> 4250</span>&#160;        m_Size(0),</div><div class="line"><a name="l04251"></a><span class="lineno"> 4251</span>&#160;        m_pUserData(VMA_NULL),</div><div class="line"><a name="l04252"></a><span class="lineno"> 4252</span>&#160;        m_LastUseFrameIndex(currentFrameIndex),</div><div class="line"><a name="l04253"></a><span class="lineno"> 4253</span>&#160;        m_Type((uint8_t)ALLOCATION_TYPE_NONE),</div><div class="line"><a name="l04254"></a><span class="lineno"> 4254</span>&#160;        m_SuballocationType((uint8_t)VMA_SUBALLOCATION_TYPE_UNKNOWN),</div><div class="line"><a name="l04255"></a><span class="lineno"> 4255</span>&#160;        m_MapCount(0),</div><div class="line"><a name="l04256"></a><span class="lineno"> 4256</span>&#160;        m_Flags(userDataString ? (uint8_t)FLAG_USER_DATA_STRING : 0)</div><div class="line"><a name="l04257"></a><span class="lineno"> 4257</span>&#160;    {</div><div class="line"><a name="l04258"></a><span class="lineno"> 4258</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04259"></a><span class="lineno"> 4259</span>&#160;        m_CreationFrameIndex = currentFrameIndex;</div><div class="line"><a name="l04260"></a><span class="lineno"> 4260</span>&#160;        m_BufferImageUsage = 0;</div><div class="line"><a name="l04261"></a><span class="lineno"> 4261</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04262"></a><span class="lineno"> 4262</span>&#160;    }</div><div class="line"><a name="l04263"></a><span class="lineno"> 4263</span>&#160;</div><div class="line"><a name="l04264"></a><span class="lineno"> 4264</span>&#160;    ~VmaAllocation_T()</div><div class="line"><a name="l04265"></a><span class="lineno"> 4265</span>&#160;    {</div><div class="line"><a name="l04266"></a><span class="lineno"> 4266</span>&#160;        VMA_ASSERT((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) == 0 &amp;&amp; <span class="stringliteral">&quot;Allocation was not unmapped before destruction.&quot;</span>);</div><div class="line"><a name="l04267"></a><span class="lineno"> 4267</span>&#160;</div><div class="line"><a name="l04268"></a><span class="lineno"> 4268</span>&#160;        <span class="comment">// Check if owned string was freed.</span></div><div class="line"><a name="l04269"></a><span class="lineno"> 4269</span>&#160;        VMA_ASSERT(m_pUserData == VMA_NULL);</div><div class="line"><a name="l04270"></a><span class="lineno"> 4270</span>&#160;    }</div><div class="line"><a name="l04271"></a><span class="lineno"> 4271</span>&#160;</div><div class="line"><a name="l04272"></a><span class="lineno"> 4272</span>&#160;    <span class="keywordtype">void</span> InitBlockAllocation(</div><div class="line"><a name="l04273"></a><span class="lineno"> 4273</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool,</div><div class="line"><a name="l04274"></a><span class="lineno"> 4274</span>&#160;        VmaDeviceMemoryBlock* block,</div><div class="line"><a name="l04275"></a><span class="lineno"> 4275</span>&#160;        VkDeviceSize offset,</div><div class="line"><a name="l04276"></a><span class="lineno"> 4276</span>&#160;        VkDeviceSize alignment,</div><div class="line"><a name="l04277"></a><span class="lineno"> 4277</span>&#160;        VkDeviceSize size,</div><div class="line"><a name="l04278"></a><span class="lineno"> 4278</span>&#160;        VmaSuballocationType suballocationType,</div><div class="line"><a name="l04279"></a><span class="lineno"> 4279</span>&#160;        <span class="keywordtype">bool</span> mapped,</div><div class="line"><a name="l04280"></a><span class="lineno"> 4280</span>&#160;        <span class="keywordtype">bool</span> canBecomeLost)</div><div class="line"><a name="l04281"></a><span class="lineno"> 4281</span>&#160;    {</div><div class="line"><a name="l04282"></a><span class="lineno"> 4282</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);</div><div class="line"><a name="l04283"></a><span class="lineno"> 4283</span>&#160;        VMA_ASSERT(block != VMA_NULL);</div><div class="line"><a name="l04284"></a><span class="lineno"> 4284</span>&#160;        m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK;</div><div class="line"><a name="l04285"></a><span class="lineno"> 4285</span>&#160;        m_Alignment = alignment;</div><div class="line"><a name="l04286"></a><span class="lineno"> 4286</span>&#160;        m_Size = size;</div><div class="line"><a name="l04287"></a><span class="lineno"> 4287</span>&#160;        m_MapCount = mapped ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0;</div><div class="line"><a name="l04288"></a><span class="lineno"> 4288</span>&#160;        m_SuballocationType = (uint8_t)suballocationType;</div><div class="line"><a name="l04289"></a><span class="lineno"> 4289</span>&#160;        m_BlockAllocation.m_hPool = hPool;</div><div class="line"><a name="l04290"></a><span class="lineno"> 4290</span>&#160;        m_BlockAllocation.m_Block = block;</div><div class="line"><a name="l04291"></a><span class="lineno"> 4291</span>&#160;        m_BlockAllocation.m_Offset = offset;</div><div class="line"><a name="l04292"></a><span class="lineno"> 4292</span>&#160;        m_BlockAllocation.m_CanBecomeLost = canBecomeLost;</div><div class="line"><a name="l04293"></a><span class="lineno"> 4293</span>&#160;    }</div><div class="line"><a name="l04294"></a><span class="lineno"> 4294</span>&#160;</div><div class="line"><a name="l04295"></a><span class="lineno"> 4295</span>&#160;    <span class="keywordtype">void</span> InitLost()</div><div class="line"><a name="l04296"></a><span class="lineno"> 4296</span>&#160;    {</div><div class="line"><a name="l04297"></a><span class="lineno"> 4297</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);</div><div class="line"><a name="l04298"></a><span class="lineno"> 4298</span>&#160;        VMA_ASSERT(m_LastUseFrameIndex.load() == VMA_FRAME_INDEX_LOST);</div><div class="line"><a name="l04299"></a><span class="lineno"> 4299</span>&#160;        m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK;</div><div class="line"><a name="l04300"></a><span class="lineno"> 4300</span>&#160;        m_BlockAllocation.m_hPool = VK_NULL_HANDLE;</div><div class="line"><a name="l04301"></a><span class="lineno"> 4301</span>&#160;        m_BlockAllocation.m_Block = VMA_NULL;</div><div class="line"><a name="l04302"></a><span class="lineno"> 4302</span>&#160;        m_BlockAllocation.m_Offset = 0;</div><div class="line"><a name="l04303"></a><span class="lineno"> 4303</span>&#160;        m_BlockAllocation.m_CanBecomeLost = <span class="keyword">true</span>;</div><div class="line"><a name="l04304"></a><span class="lineno"> 4304</span>&#160;    }</div><div class="line"><a name="l04305"></a><span class="lineno"> 4305</span>&#160;</div><div class="line"><a name="l04306"></a><span class="lineno"> 4306</span>&#160;    <span class="keywordtype">void</span> ChangeBlockAllocation(</div><div class="line"><a name="l04307"></a><span class="lineno"> 4307</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04308"></a><span class="lineno"> 4308</span>&#160;        VmaDeviceMemoryBlock* block,</div><div class="line"><a name="l04309"></a><span class="lineno"> 4309</span>&#160;        VkDeviceSize offset);</div><div class="line"><a name="l04310"></a><span class="lineno"> 4310</span>&#160;</div><div class="line"><a name="l04311"></a><span class="lineno"> 4311</span>&#160;    <span class="comment">// pMappedData not null means allocation is created with MAPPED flag.</span></div><div class="line"><a name="l04312"></a><span class="lineno"> 4312</span>&#160;    <span class="keywordtype">void</span> InitDedicatedAllocation(</div><div class="line"><a name="l04313"></a><span class="lineno"> 4313</span>&#160;        uint32_t memoryTypeIndex,</div><div class="line"><a name="l04314"></a><span class="lineno"> 4314</span>&#160;        VkDeviceMemory hMemory,</div><div class="line"><a name="l04315"></a><span class="lineno"> 4315</span>&#160;        VmaSuballocationType suballocationType,</div><div class="line"><a name="l04316"></a><span class="lineno"> 4316</span>&#160;        <span class="keywordtype">void</span>* pMappedData,</div><div class="line"><a name="l04317"></a><span class="lineno"> 4317</span>&#160;        VkDeviceSize size)</div><div class="line"><a name="l04318"></a><span class="lineno"> 4318</span>&#160;    {</div><div class="line"><a name="l04319"></a><span class="lineno"> 4319</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);</div><div class="line"><a name="l04320"></a><span class="lineno"> 4320</span>&#160;        VMA_ASSERT(hMemory != VK_NULL_HANDLE);</div><div class="line"><a name="l04321"></a><span class="lineno"> 4321</span>&#160;        m_Type = (uint8_t)ALLOCATION_TYPE_DEDICATED;</div><div class="line"><a name="l04322"></a><span class="lineno"> 4322</span>&#160;        m_Alignment = 0;</div><div class="line"><a name="l04323"></a><span class="lineno"> 4323</span>&#160;        m_Size = size;</div><div class="line"><a name="l04324"></a><span class="lineno"> 4324</span>&#160;        m_SuballocationType = (uint8_t)suballocationType;</div><div class="line"><a name="l04325"></a><span class="lineno"> 4325</span>&#160;        m_MapCount = (pMappedData != VMA_NULL) ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0;</div><div class="line"><a name="l04326"></a><span class="lineno"> 4326</span>&#160;        m_DedicatedAllocation.m_MemoryTypeIndex = memoryTypeIndex;</div><div class="line"><a name="l04327"></a><span class="lineno"> 4327</span>&#160;        m_DedicatedAllocation.m_hMemory = hMemory;</div><div class="line"><a name="l04328"></a><span class="lineno"> 4328</span>&#160;        m_DedicatedAllocation.m_pMappedData = pMappedData;</div><div class="line"><a name="l04329"></a><span class="lineno"> 4329</span>&#160;    }</div><div class="line"><a name="l04330"></a><span class="lineno"> 4330</span>&#160;</div><div class="line"><a name="l04331"></a><span class="lineno"> 4331</span>&#160;    ALLOCATION_TYPE GetType()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (ALLOCATION_TYPE)m_Type; }</div><div class="line"><a name="l04332"></a><span class="lineno"> 4332</span>&#160;    VkDeviceSize GetAlignment()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Alignment; }</div><div class="line"><a name="l04333"></a><span class="lineno"> 4333</span>&#160;    VkDeviceSize GetSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Size; }</div><div class="line"><a name="l04334"></a><span class="lineno"> 4334</span>&#160;    <span class="keywordtype">bool</span> IsUserDataString()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (m_Flags &amp; FLAG_USER_DATA_STRING) != 0; }</div><div class="line"><a name="l04335"></a><span class="lineno"> 4335</span>&#160;    <span class="keywordtype">void</span>* GetUserData()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pUserData; }</div><div class="line"><a name="l04336"></a><span class="lineno"> 4336</span>&#160;    <span class="keywordtype">void</span> SetUserData(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>* pUserData);</div><div class="line"><a name="l04337"></a><span class="lineno"> 4337</span>&#160;    VmaSuballocationType GetSuballocationType()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (VmaSuballocationType)m_SuballocationType; }</div><div class="line"><a name="l04338"></a><span class="lineno"> 4338</span>&#160;</div><div class="line"><a name="l04339"></a><span class="lineno"> 4339</span>&#160;    VmaDeviceMemoryBlock* GetBlock()<span class="keyword"> const</span></div><div class="line"><a name="l04340"></a><span class="lineno"> 4340</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04341"></a><span class="lineno"> 4341</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l04342"></a><span class="lineno"> 4342</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Block;</div><div class="line"><a name="l04343"></a><span class="lineno"> 4343</span>&#160;    }</div><div class="line"><a name="l04344"></a><span class="lineno"> 4344</span>&#160;    VkDeviceSize GetOffset() <span class="keyword">const</span>;</div><div class="line"><a name="l04345"></a><span class="lineno"> 4345</span>&#160;    VkDeviceMemory GetMemory() <span class="keyword">const</span>;</div><div class="line"><a name="l04346"></a><span class="lineno"> 4346</span>&#160;    uint32_t GetMemoryTypeIndex() <span class="keyword">const</span>;</div><div class="line"><a name="l04347"></a><span class="lineno"> 4347</span>&#160;    <span class="keywordtype">bool</span> IsPersistentMap()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> (m_MapCount &amp; MAP_COUNT_FLAG_PERSISTENT_MAP) != 0; }</div><div class="line"><a name="l04348"></a><span class="lineno"> 4348</span>&#160;    <span class="keywordtype">void</span>* GetMappedData() <span class="keyword">const</span>;</div><div class="line"><a name="l04349"></a><span class="lineno"> 4349</span>&#160;    <span class="keywordtype">bool</span> CanBecomeLost() <span class="keyword">const</span>;</div><div class="line"><a name="l04350"></a><span class="lineno"> 4350</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> GetPool() <span class="keyword">const</span>;</div><div class="line"><a name="l04351"></a><span class="lineno"> 4351</span>&#160;    </div><div class="line"><a name="l04352"></a><span class="lineno"> 4352</span>&#160;    uint32_t GetLastUseFrameIndex()<span class="keyword"> const</span></div><div class="line"><a name="l04353"></a><span class="lineno"> 4353</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04354"></a><span class="lineno"> 4354</span>&#160;        <span class="keywordflow">return</span> m_LastUseFrameIndex.load();</div><div class="line"><a name="l04355"></a><span class="lineno"> 4355</span>&#160;    }</div><div class="line"><a name="l04356"></a><span class="lineno"> 4356</span>&#160;    <span class="keywordtype">bool</span> CompareExchangeLastUseFrameIndex(uint32_t&amp; expected, uint32_t desired)</div><div class="line"><a name="l04357"></a><span class="lineno"> 4357</span>&#160;    {</div><div class="line"><a name="l04358"></a><span class="lineno"> 4358</span>&#160;        <span class="keywordflow">return</span> m_LastUseFrameIndex.compare_exchange_weak(expected, desired);</div><div class="line"><a name="l04359"></a><span class="lineno"> 4359</span>&#160;    }</div><div class="line"><a name="l04360"></a><span class="lineno"> 4360</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l04361"></a><span class="lineno"> 4361</span>&#160;<span class="comment">    - If hAllocation.LastUseFrameIndex + frameInUseCount &lt; allocator.CurrentFrameIndex,</span></div><div class="line"><a name="l04362"></a><span class="lineno"> 4362</span>&#160;<span class="comment">      makes it lost by setting LastUseFrameIndex = VMA_FRAME_INDEX_LOST and returns true.</span></div><div class="line"><a name="l04363"></a><span class="lineno"> 4363</span>&#160;<span class="comment">    - Else, returns false.</span></div><div class="line"><a name="l04364"></a><span class="lineno"> 4364</span>&#160;<span class="comment">    </span></div><div class="line"><a name="l04365"></a><span class="lineno"> 4365</span>&#160;<span class="comment">    If hAllocation is already lost, assert - you should not call it then.</span></div><div class="line"><a name="l04366"></a><span class="lineno"> 4366</span>&#160;<span class="comment">    If hAllocation was not created with CAN_BECOME_LOST_BIT, assert.</span></div><div class="line"><a name="l04367"></a><span class="lineno"> 4367</span>&#160;<span class="comment">    */</span></div><div class="line"><a name="l04368"></a><span class="lineno"> 4368</span>&#160;    <span class="keywordtype">bool</span> MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);</div><div class="line"><a name="l04369"></a><span class="lineno"> 4369</span>&#160;</div><div class="line"><a name="l04370"></a><span class="lineno"> 4370</span>&#160;    <span class="keywordtype">void</span> DedicatedAllocCalcStatsInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo)</div><div class="line"><a name="l04371"></a><span class="lineno"> 4371</span>&#160;    {</div><div class="line"><a name="l04372"></a><span class="lineno"> 4372</span>&#160;        VMA_ASSERT(m_Type == ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l04373"></a><span class="lineno"> 4373</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> = 1;</div><div class="line"><a name="l04374"></a><span class="lineno"> 4374</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> = 1;</div><div class="line"><a name="l04375"></a><span class="lineno"> 4375</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> = 0;</div><div class="line"><a name="l04376"></a><span class="lineno"> 4376</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> = m_Size;</div><div class="line"><a name="l04377"></a><span class="lineno"> 4377</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> = 0;</div><div class="line"><a name="l04378"></a><span class="lineno"> 4378</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = m_Size;</div><div class="line"><a name="l04379"></a><span class="lineno"> 4379</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l04380"></a><span class="lineno"> 4380</span>&#160;        outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = 0;</div><div class="line"><a name="l04381"></a><span class="lineno"> 4381</span>&#160;    }</div><div class="line"><a name="l04382"></a><span class="lineno"> 4382</span>&#160;</div><div class="line"><a name="l04383"></a><span class="lineno"> 4383</span>&#160;    <span class="keywordtype">void</span> BlockAllocMap();</div><div class="line"><a name="l04384"></a><span class="lineno"> 4384</span>&#160;    <span class="keywordtype">void</span> BlockAllocUnmap();</div><div class="line"><a name="l04385"></a><span class="lineno"> 4385</span>&#160;    VkResult DedicatedAllocMap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l04386"></a><span class="lineno"> 4386</span>&#160;    <span class="keywordtype">void</span> DedicatedAllocUnmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04387"></a><span class="lineno"> 4387</span>&#160;</div><div class="line"><a name="l04388"></a><span class="lineno"> 4388</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04389"></a><span class="lineno"> 4389</span>&#160;    uint32_t GetCreationFrameIndex()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_CreationFrameIndex; }</div><div class="line"><a name="l04390"></a><span class="lineno"> 4390</span>&#160;    uint32_t GetBufferImageUsage()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_BufferImageUsage; }</div><div class="line"><a name="l04391"></a><span class="lineno"> 4391</span>&#160;</div><div class="line"><a name="l04392"></a><span class="lineno"> 4392</span>&#160;    <span class="keywordtype">void</span> InitBufferImageUsage(uint32_t bufferImageUsage)</div><div class="line"><a name="l04393"></a><span class="lineno"> 4393</span>&#160;    {</div><div class="line"><a name="l04394"></a><span class="lineno"> 4394</span>&#160;        VMA_ASSERT(m_BufferImageUsage == 0);</div><div class="line"><a name="l04395"></a><span class="lineno"> 4395</span>&#160;        m_BufferImageUsage = bufferImageUsage;</div><div class="line"><a name="l04396"></a><span class="lineno"> 4396</span>&#160;    }</div><div class="line"><a name="l04397"></a><span class="lineno"> 4397</span>&#160;</div><div class="line"><a name="l04398"></a><span class="lineno"> 4398</span>&#160;    <span class="keywordtype">void</span> PrintParameters(<span class="keyword">class</span> VmaJsonWriter&amp; json) <span class="keyword">const</span>;</div><div class="line"><a name="l04399"></a><span class="lineno"> 4399</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04400"></a><span class="lineno"> 4400</span>&#160;</div><div class="line"><a name="l04401"></a><span class="lineno"> 4401</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04402"></a><span class="lineno"> 4402</span>&#160;    VkDeviceSize m_Alignment;</div><div class="line"><a name="l04403"></a><span class="lineno"> 4403</span>&#160;    VkDeviceSize m_Size;</div><div class="line"><a name="l04404"></a><span class="lineno"> 4404</span>&#160;    <span class="keywordtype">void</span>* m_pUserData;</div><div class="line"><a name="l04405"></a><span class="lineno"> 4405</span>&#160;    VMA_ATOMIC_UINT32 m_LastUseFrameIndex;</div><div class="line"><a name="l04406"></a><span class="lineno"> 4406</span>&#160;    uint8_t m_Type; <span class="comment">// ALLOCATION_TYPE</span></div><div class="line"><a name="l04407"></a><span class="lineno"> 4407</span>&#160;    uint8_t m_SuballocationType; <span class="comment">// VmaSuballocationType</span></div><div class="line"><a name="l04408"></a><span class="lineno"> 4408</span>&#160;    <span class="comment">// Bit 0x80 is set when allocation was created with VMA_ALLOCATION_CREATE_MAPPED_BIT.</span></div><div class="line"><a name="l04409"></a><span class="lineno"> 4409</span>&#160;    <span class="comment">// Bits with mask 0x7F are reference counter for vmaMapMemory()/vmaUnmapMemory().</span></div><div class="line"><a name="l04410"></a><span class="lineno"> 4410</span>&#160;    uint8_t m_MapCount;</div><div class="line"><a name="l04411"></a><span class="lineno"> 4411</span>&#160;    uint8_t m_Flags; <span class="comment">// enum FLAGS</span></div><div class="line"><a name="l04412"></a><span class="lineno"> 4412</span>&#160;</div><div class="line"><a name="l04413"></a><span class="lineno"> 4413</span>&#160;    <span class="comment">// Allocation out of VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l04414"></a><span class="lineno"> 4414</span>&#160;    <span class="keyword">struct </span>BlockAllocation</div><div class="line"><a name="l04415"></a><span class="lineno"> 4415</span>&#160;    {</div><div class="line"><a name="l04416"></a><span class="lineno"> 4416</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> m_hPool; <span class="comment">// Null if belongs to general memory.</span></div><div class="line"><a name="l04417"></a><span class="lineno"> 4417</span>&#160;        VmaDeviceMemoryBlock* m_Block;</div><div class="line"><a name="l04418"></a><span class="lineno"> 4418</span>&#160;        VkDeviceSize m_Offset;</div><div class="line"><a name="l04419"></a><span class="lineno"> 4419</span>&#160;        <span class="keywordtype">bool</span> m_CanBecomeLost;</div><div class="line"><a name="l04420"></a><span class="lineno"> 4420</span>&#160;    };</div><div class="line"><a name="l04421"></a><span class="lineno"> 4421</span>&#160;</div><div class="line"><a name="l04422"></a><span class="lineno"> 4422</span>&#160;    <span class="comment">// Allocation for an object that has its own private VkDeviceMemory.</span></div><div class="line"><a name="l04423"></a><span class="lineno"> 4423</span>&#160;    <span class="keyword">struct </span>DedicatedAllocation</div><div class="line"><a name="l04424"></a><span class="lineno"> 4424</span>&#160;    {</div><div class="line"><a name="l04425"></a><span class="lineno"> 4425</span>&#160;        uint32_t m_MemoryTypeIndex;</div><div class="line"><a name="l04426"></a><span class="lineno"> 4426</span>&#160;        VkDeviceMemory m_hMemory;</div><div class="line"><a name="l04427"></a><span class="lineno"> 4427</span>&#160;        <span class="keywordtype">void</span>* m_pMappedData; <span class="comment">// Not null means memory is mapped.</span></div><div class="line"><a name="l04428"></a><span class="lineno"> 4428</span>&#160;    };</div><div class="line"><a name="l04429"></a><span class="lineno"> 4429</span>&#160;</div><div class="line"><a name="l04430"></a><span class="lineno"> 4430</span>&#160;    <span class="keyword">union</span></div><div class="line"><a name="l04431"></a><span class="lineno"> 4431</span>&#160;    {</div><div class="line"><a name="l04432"></a><span class="lineno"> 4432</span>&#160;        <span class="comment">// Allocation out of VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l04433"></a><span class="lineno"> 4433</span>&#160;        BlockAllocation m_BlockAllocation;</div><div class="line"><a name="l04434"></a><span class="lineno"> 4434</span>&#160;        <span class="comment">// Allocation for an object that has its own private VkDeviceMemory.</span></div><div class="line"><a name="l04435"></a><span class="lineno"> 4435</span>&#160;        DedicatedAllocation m_DedicatedAllocation;</div><div class="line"><a name="l04436"></a><span class="lineno"> 4436</span>&#160;    };</div><div class="line"><a name="l04437"></a><span class="lineno"> 4437</span>&#160;</div><div class="line"><a name="l04438"></a><span class="lineno"> 4438</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04439"></a><span class="lineno"> 4439</span>&#160;    uint32_t m_CreationFrameIndex;</div><div class="line"><a name="l04440"></a><span class="lineno"> 4440</span>&#160;    uint32_t m_BufferImageUsage; <span class="comment">// 0 if unknown.</span></div><div class="line"><a name="l04441"></a><span class="lineno"> 4441</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04442"></a><span class="lineno"> 4442</span>&#160;</div><div class="line"><a name="l04443"></a><span class="lineno"> 4443</span>&#160;    <span class="keywordtype">void</span> FreeUserDataString(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04444"></a><span class="lineno"> 4444</span>&#160;};</div><div class="line"><a name="l04445"></a><span class="lineno"> 4445</span>&#160;</div><div class="line"><a name="l04446"></a><span class="lineno"> 4446</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04447"></a><span class="lineno"> 4447</span>&#160;<span class="comment">Represents a region of VmaDeviceMemoryBlock that is either assigned and returned as</span></div><div class="line"><a name="l04448"></a><span class="lineno"> 4448</span>&#160;<span class="comment">allocated memory block or free.</span></div><div class="line"><a name="l04449"></a><span class="lineno"> 4449</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04450"></a><span class="lineno"> 4450</span>&#160;<span class="keyword">struct </span>VmaSuballocation</div><div class="line"><a name="l04451"></a><span class="lineno"> 4451</span>&#160;{</div><div class="line"><a name="l04452"></a><span class="lineno"> 4452</span>&#160;    VkDeviceSize offset;</div><div class="line"><a name="l04453"></a><span class="lineno"> 4453</span>&#160;    VkDeviceSize size;</div><div class="line"><a name="l04454"></a><span class="lineno"> 4454</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation;</div><div class="line"><a name="l04455"></a><span class="lineno"> 4455</span>&#160;    VmaSuballocationType type;</div><div class="line"><a name="l04456"></a><span class="lineno"> 4456</span>&#160;};</div><div class="line"><a name="l04457"></a><span class="lineno"> 4457</span>&#160;</div><div class="line"><a name="l04458"></a><span class="lineno"> 4458</span>&#160;<span class="comment">// Comparator for offsets.</span></div><div class="line"><a name="l04459"></a><span class="lineno"> 4459</span>&#160;<span class="keyword">struct </span>VmaSuballocationOffsetLess</div><div class="line"><a name="l04460"></a><span class="lineno"> 4460</span>&#160;{</div><div class="line"><a name="l04461"></a><span class="lineno"> 4461</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> VmaSuballocation&amp; lhs, <span class="keyword">const</span> VmaSuballocation&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04462"></a><span class="lineno"> 4462</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04463"></a><span class="lineno"> 4463</span>&#160;        <span class="keywordflow">return</span> lhs.offset &lt; rhs.offset;</div><div class="line"><a name="l04464"></a><span class="lineno"> 4464</span>&#160;    }</div><div class="line"><a name="l04465"></a><span class="lineno"> 4465</span>&#160;};</div><div class="line"><a name="l04466"></a><span class="lineno"> 4466</span>&#160;<span class="keyword">struct </span>VmaSuballocationOffsetGreater</div><div class="line"><a name="l04467"></a><span class="lineno"> 4467</span>&#160;{</div><div class="line"><a name="l04468"></a><span class="lineno"> 4468</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> VmaSuballocation&amp; lhs, <span class="keyword">const</span> VmaSuballocation&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04469"></a><span class="lineno"> 4469</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04470"></a><span class="lineno"> 4470</span>&#160;        <span class="keywordflow">return</span> lhs.offset &gt; rhs.offset;</div><div class="line"><a name="l04471"></a><span class="lineno"> 4471</span>&#160;    }</div><div class="line"><a name="l04472"></a><span class="lineno"> 4472</span>&#160;};</div><div class="line"><a name="l04473"></a><span class="lineno"> 4473</span>&#160;</div><div class="line"><a name="l04474"></a><span class="lineno"> 4474</span>&#160;<span class="keyword">typedef</span> VmaList&lt; VmaSuballocation, VmaStlAllocator&lt;VmaSuballocation&gt; &gt; VmaSuballocationList;</div><div class="line"><a name="l04475"></a><span class="lineno"> 4475</span>&#160;</div><div class="line"><a name="l04476"></a><span class="lineno"> 4476</span>&#160;<span class="comment">// Cost of one additional allocation lost, as equivalent in bytes.</span></div><div class="line"><a name="l04477"></a><span class="lineno"> 4477</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> VkDeviceSize VMA_LOST_ALLOCATION_COST = 1048576;</div><div class="line"><a name="l04478"></a><span class="lineno"> 4478</span>&#160;</div><div class="line"><a name="l04479"></a><span class="lineno"> 4479</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04480"></a><span class="lineno"> 4480</span>&#160;<span class="comment">Parameters of planned allocation inside a VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l04481"></a><span class="lineno"> 4481</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04482"></a><span class="lineno"> 4482</span>&#160;<span class="comment">If canMakeOtherLost was false:</span></div><div class="line"><a name="l04483"></a><span class="lineno"> 4483</span>&#160;<span class="comment">- item points to a FREE suballocation.</span></div><div class="line"><a name="l04484"></a><span class="lineno"> 4484</span>&#160;<span class="comment">- itemsToMakeLostCount is 0.</span></div><div class="line"><a name="l04485"></a><span class="lineno"> 4485</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04486"></a><span class="lineno"> 4486</span>&#160;<span class="comment">If canMakeOtherLost was true:</span></div><div class="line"><a name="l04487"></a><span class="lineno"> 4487</span>&#160;<span class="comment">- item points to first of sequence of suballocations, which are either FREE,</span></div><div class="line"><a name="l04488"></a><span class="lineno"> 4488</span>&#160;<span class="comment">  or point to VmaAllocations that can become lost.</span></div><div class="line"><a name="l04489"></a><span class="lineno"> 4489</span>&#160;<span class="comment">- itemsToMakeLostCount is the number of VmaAllocations that need to be made lost for</span></div><div class="line"><a name="l04490"></a><span class="lineno"> 4490</span>&#160;<span class="comment">  the requested allocation to succeed.</span></div><div class="line"><a name="l04491"></a><span class="lineno"> 4491</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04492"></a><span class="lineno"> 4492</span>&#160;<span class="keyword">struct </span>VmaAllocationRequest</div><div class="line"><a name="l04493"></a><span class="lineno"> 4493</span>&#160;{</div><div class="line"><a name="l04494"></a><span class="lineno"> 4494</span>&#160;    VkDeviceSize offset;</div><div class="line"><a name="l04495"></a><span class="lineno"> 4495</span>&#160;    VkDeviceSize sumFreeSize; <span class="comment">// Sum size of free items that overlap with proposed allocation.</span></div><div class="line"><a name="l04496"></a><span class="lineno"> 4496</span>&#160;    VkDeviceSize sumItemSize; <span class="comment">// Sum size of items to make lost that overlap with proposed allocation.</span></div><div class="line"><a name="l04497"></a><span class="lineno"> 4497</span>&#160;    VmaSuballocationList::iterator item;</div><div class="line"><a name="l04498"></a><span class="lineno"> 4498</span>&#160;    <span class="keywordtype">size_t</span> itemsToMakeLostCount;</div><div class="line"><a name="l04499"></a><span class="lineno"> 4499</span>&#160;</div><div class="line"><a name="l04500"></a><span class="lineno"> 4500</span>&#160;    VkDeviceSize CalcCost()<span class="keyword"> const</span></div><div class="line"><a name="l04501"></a><span class="lineno"> 4501</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04502"></a><span class="lineno"> 4502</span>&#160;        <span class="keywordflow">return</span> sumItemSize + itemsToMakeLostCount * VMA_LOST_ALLOCATION_COST;</div><div class="line"><a name="l04503"></a><span class="lineno"> 4503</span>&#160;    }</div><div class="line"><a name="l04504"></a><span class="lineno"> 4504</span>&#160;};</div><div class="line"><a name="l04505"></a><span class="lineno"> 4505</span>&#160;</div><div class="line"><a name="l04506"></a><span class="lineno"> 4506</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04507"></a><span class="lineno"> 4507</span>&#160;<span class="comment">Data structure used for bookkeeping of allocations and unused ranges of memory</span></div><div class="line"><a name="l04508"></a><span class="lineno"> 4508</span>&#160;<span class="comment">in a single VkDeviceMemory block.</span></div><div class="line"><a name="l04509"></a><span class="lineno"> 4509</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04510"></a><span class="lineno"> 4510</span>&#160;<span class="keyword">class </span>VmaBlockMetadata</div><div class="line"><a name="l04511"></a><span class="lineno"> 4511</span>&#160;{</div><div class="line"><a name="l04512"></a><span class="lineno"> 4512</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04513"></a><span class="lineno"> 4513</span>&#160;    VmaBlockMetadata() : m_Size(0) { }</div><div class="line"><a name="l04514"></a><span class="lineno"> 4514</span>&#160;    <span class="keyword">virtual</span> ~VmaBlockMetadata() { }</div><div class="line"><a name="l04515"></a><span class="lineno"> 4515</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Init(VkDeviceSize size) { m_Size = size; }</div><div class="line"><a name="l04516"></a><span class="lineno"> 4516</span>&#160;</div><div class="line"><a name="l04517"></a><span class="lineno"> 4517</span>&#160;    <span class="comment">// Validates all data structures inside this object. If not valid, returns false.</span></div><div class="line"><a name="l04518"></a><span class="lineno"> 4518</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Validate() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04519"></a><span class="lineno"> 4519</span>&#160;    VkDeviceSize GetSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Size; }</div><div class="line"><a name="l04520"></a><span class="lineno"> 4520</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">size_t</span> GetAllocationCount() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04521"></a><span class="lineno"> 4521</span>&#160;    <span class="keyword">virtual</span> VkDeviceSize GetSumFreeSize() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04522"></a><span class="lineno"> 4522</span>&#160;    <span class="keyword">virtual</span> VkDeviceSize GetUnusedRangeSizeMax() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04523"></a><span class="lineno"> 4523</span>&#160;    <span class="comment">// Returns true if this block is empty - contains only single free suballocation.</span></div><div class="line"><a name="l04524"></a><span class="lineno"> 4524</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsEmpty() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04525"></a><span class="lineno"> 4525</span>&#160;</div><div class="line"><a name="l04526"></a><span class="lineno"> 4526</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> CalcAllocationStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo) <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04527"></a><span class="lineno"> 4527</span>&#160;    <span class="comment">// Shouldn&#39;t modify blockCount.</span></div><div class="line"><a name="l04528"></a><span class="lineno"> 4528</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> AddPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>&amp; inoutStats) <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04529"></a><span class="lineno"> 4529</span>&#160;</div><div class="line"><a name="l04530"></a><span class="lineno"> 4530</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04531"></a><span class="lineno"> 4531</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json) <span class="keyword">const</span> = 0;</div><div class="line"><a name="l04532"></a><span class="lineno"> 4532</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04533"></a><span class="lineno"> 4533</span>&#160;</div><div class="line"><a name="l04534"></a><span class="lineno"> 4534</span>&#160;    <span class="comment">// Tries to find a place for suballocation with given parameters inside this block.</span></div><div class="line"><a name="l04535"></a><span class="lineno"> 4535</span>&#160;    <span class="comment">// If succeeded, fills pAllocationRequest and returns true.</span></div><div class="line"><a name="l04536"></a><span class="lineno"> 4536</span>&#160;    <span class="comment">// If failed, returns false.</span></div><div class="line"><a name="l04537"></a><span class="lineno"> 4537</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> CreateAllocationRequest(</div><div class="line"><a name="l04538"></a><span class="lineno"> 4538</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04539"></a><span class="lineno"> 4539</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04540"></a><span class="lineno"> 4540</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04541"></a><span class="lineno"> 4541</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04542"></a><span class="lineno"> 4542</span>&#160;        VkDeviceSize allocAlignment,</div><div class="line"><a name="l04543"></a><span class="lineno"> 4543</span>&#160;        <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l04544"></a><span class="lineno"> 4544</span>&#160;        VmaSuballocationType allocType,</div><div class="line"><a name="l04545"></a><span class="lineno"> 4545</span>&#160;        <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l04546"></a><span class="lineno"> 4546</span>&#160;        VmaAllocationRequest* pAllocationRequest) = 0;</div><div class="line"><a name="l04547"></a><span class="lineno"> 4547</span>&#160;</div><div class="line"><a name="l04548"></a><span class="lineno"> 4548</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> MakeRequestedAllocationsLost(</div><div class="line"><a name="l04549"></a><span class="lineno"> 4549</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04550"></a><span class="lineno"> 4550</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04551"></a><span class="lineno"> 4551</span>&#160;        VmaAllocationRequest* pAllocationRequest) = 0;</div><div class="line"><a name="l04552"></a><span class="lineno"> 4552</span>&#160;</div><div class="line"><a name="l04553"></a><span class="lineno"> 4553</span>&#160;    <span class="keyword">virtual</span> uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) = 0;</div><div class="line"><a name="l04554"></a><span class="lineno"> 4554</span>&#160;</div><div class="line"><a name="l04555"></a><span class="lineno"> 4555</span>&#160;    <span class="keyword">virtual</span> VkResult CheckCorruption(<span class="keyword">const</span> <span class="keywordtype">void</span>* pBlockData) = 0;</div><div class="line"><a name="l04556"></a><span class="lineno"> 4556</span>&#160;</div><div class="line"><a name="l04557"></a><span class="lineno"> 4557</span>&#160;    <span class="comment">// Makes actual allocation based on request. Request must already be checked and valid.</span></div><div class="line"><a name="l04558"></a><span class="lineno"> 4558</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Alloc(</div><div class="line"><a name="l04559"></a><span class="lineno"> 4559</span>&#160;        <span class="keyword">const</span> VmaAllocationRequest&amp; request,</div><div class="line"><a name="l04560"></a><span class="lineno"> 4560</span>&#160;        VmaSuballocationType type,</div><div class="line"><a name="l04561"></a><span class="lineno"> 4561</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04562"></a><span class="lineno"> 4562</span>&#160;        <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l04563"></a><span class="lineno"> 4563</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation) = 0;</div><div class="line"><a name="l04564"></a><span class="lineno"> 4564</span>&#160;</div><div class="line"><a name="l04565"></a><span class="lineno"> 4565</span>&#160;    <span class="comment">// Frees suballocation assigned to given memory region.</span></div><div class="line"><a name="l04566"></a><span class="lineno"> 4566</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Free(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation) = 0;</div><div class="line"><a name="l04567"></a><span class="lineno"> 4567</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> FreeAtOffset(VkDeviceSize offset) = 0;</div><div class="line"><a name="l04568"></a><span class="lineno"> 4568</span>&#160;</div><div class="line"><a name="l04569"></a><span class="lineno"> 4569</span>&#160;<span class="keyword">protected</span>:</div><div class="line"><a name="l04570"></a><span class="lineno"> 4570</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04571"></a><span class="lineno"> 4571</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap_Begin(<span class="keyword">class</span> VmaJsonWriter&amp; json,</div><div class="line"><a name="l04572"></a><span class="lineno"> 4572</span>&#160;        VkDeviceSize unusedBytes,</div><div class="line"><a name="l04573"></a><span class="lineno"> 4573</span>&#160;        <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l04574"></a><span class="lineno"> 4574</span>&#160;        <span class="keywordtype">size_t</span> unusedRangeCount) <span class="keyword">const</span>;</div><div class="line"><a name="l04575"></a><span class="lineno"> 4575</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap_Allocation(<span class="keyword">class</span> VmaJsonWriter&amp; json,</div><div class="line"><a name="l04576"></a><span class="lineno"> 4576</span>&#160;        VkDeviceSize offset,</div><div class="line"><a name="l04577"></a><span class="lineno"> 4577</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation) <span class="keyword">const</span>;</div><div class="line"><a name="l04578"></a><span class="lineno"> 4578</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap_UnusedRange(<span class="keyword">class</span> VmaJsonWriter&amp; json,</div><div class="line"><a name="l04579"></a><span class="lineno"> 4579</span>&#160;        VkDeviceSize offset,</div><div class="line"><a name="l04580"></a><span class="lineno"> 4580</span>&#160;        VkDeviceSize size) <span class="keyword">const</span>;</div><div class="line"><a name="l04581"></a><span class="lineno"> 4581</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap_End(<span class="keyword">class</span> VmaJsonWriter&amp; json) <span class="keyword">const</span>;</div><div class="line"><a name="l04582"></a><span class="lineno"> 4582</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04583"></a><span class="lineno"> 4583</span>&#160;</div><div class="line"><a name="l04584"></a><span class="lineno"> 4584</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04585"></a><span class="lineno"> 4585</span>&#160;    VkDeviceSize m_Size;</div><div class="line"><a name="l04586"></a><span class="lineno"> 4586</span>&#160;};</div><div class="line"><a name="l04587"></a><span class="lineno"> 4587</span>&#160;</div><div class="line"><a name="l04588"></a><span class="lineno"> 4588</span>&#160;<span class="keyword">class </span>VmaBlockMetadata_Generic : <span class="keyword">public</span> VmaBlockMetadata</div><div class="line"><a name="l04589"></a><span class="lineno"> 4589</span>&#160;{</div><div class="line"><a name="l04590"></a><span class="lineno"> 4590</span>&#160;    VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic)</div><div class="line"><a name="l04591"></a><span class="lineno"> 4591</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04592"></a><span class="lineno"> 4592</span>&#160;    VmaBlockMetadata_Generic(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04593"></a><span class="lineno"> 4593</span>&#160;    <span class="keyword">virtual</span> ~VmaBlockMetadata_Generic();</div><div class="line"><a name="l04594"></a><span class="lineno"> 4594</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Init(VkDeviceSize size);</div><div class="line"><a name="l04595"></a><span class="lineno"> 4595</span>&#160;</div><div class="line"><a name="l04596"></a><span class="lineno"> 4596</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Validate() <span class="keyword">const</span>;</div><div class="line"><a name="l04597"></a><span class="lineno"> 4597</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">size_t</span> GetAllocationCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Suballocations.size() - m_FreeCount; }</div><div class="line"><a name="l04598"></a><span class="lineno"> 4598</span>&#160;    <span class="keyword">virtual</span> VkDeviceSize GetSumFreeSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_SumFreeSize; }</div><div class="line"><a name="l04599"></a><span class="lineno"> 4599</span>&#160;    <span class="keyword">virtual</span> VkDeviceSize GetUnusedRangeSizeMax() <span class="keyword">const</span>;</div><div class="line"><a name="l04600"></a><span class="lineno"> 4600</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsEmpty() <span class="keyword">const</span>;</div><div class="line"><a name="l04601"></a><span class="lineno"> 4601</span>&#160;</div><div class="line"><a name="l04602"></a><span class="lineno"> 4602</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> CalcAllocationStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo) <span class="keyword">const</span>;</div><div class="line"><a name="l04603"></a><span class="lineno"> 4603</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> AddPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>&amp; inoutStats) <span class="keyword">const</span>;</div><div class="line"><a name="l04604"></a><span class="lineno"> 4604</span>&#160;</div><div class="line"><a name="l04605"></a><span class="lineno"> 4605</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04606"></a><span class="lineno"> 4606</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json) <span class="keyword">const</span>;</div><div class="line"><a name="l04607"></a><span class="lineno"> 4607</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04608"></a><span class="lineno"> 4608</span>&#160;</div><div class="line"><a name="l04609"></a><span class="lineno"> 4609</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> CreateAllocationRequest(</div><div class="line"><a name="l04610"></a><span class="lineno"> 4610</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04611"></a><span class="lineno"> 4611</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04612"></a><span class="lineno"> 4612</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04613"></a><span class="lineno"> 4613</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04614"></a><span class="lineno"> 4614</span>&#160;        VkDeviceSize allocAlignment,</div><div class="line"><a name="l04615"></a><span class="lineno"> 4615</span>&#160;        <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l04616"></a><span class="lineno"> 4616</span>&#160;        VmaSuballocationType allocType,</div><div class="line"><a name="l04617"></a><span class="lineno"> 4617</span>&#160;        <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l04618"></a><span class="lineno"> 4618</span>&#160;        VmaAllocationRequest* pAllocationRequest);</div><div class="line"><a name="l04619"></a><span class="lineno"> 4619</span>&#160;</div><div class="line"><a name="l04620"></a><span class="lineno"> 4620</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> MakeRequestedAllocationsLost(</div><div class="line"><a name="l04621"></a><span class="lineno"> 4621</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04622"></a><span class="lineno"> 4622</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04623"></a><span class="lineno"> 4623</span>&#160;        VmaAllocationRequest* pAllocationRequest);</div><div class="line"><a name="l04624"></a><span class="lineno"> 4624</span>&#160;</div><div class="line"><a name="l04625"></a><span class="lineno"> 4625</span>&#160;    <span class="keyword">virtual</span> uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);</div><div class="line"><a name="l04626"></a><span class="lineno"> 4626</span>&#160;</div><div class="line"><a name="l04627"></a><span class="lineno"> 4627</span>&#160;    <span class="keyword">virtual</span> VkResult CheckCorruption(<span class="keyword">const</span> <span class="keywordtype">void</span>* pBlockData);</div><div class="line"><a name="l04628"></a><span class="lineno"> 4628</span>&#160;</div><div class="line"><a name="l04629"></a><span class="lineno"> 4629</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Alloc(</div><div class="line"><a name="l04630"></a><span class="lineno"> 4630</span>&#160;        <span class="keyword">const</span> VmaAllocationRequest&amp; request,</div><div class="line"><a name="l04631"></a><span class="lineno"> 4631</span>&#160;        VmaSuballocationType type,</div><div class="line"><a name="l04632"></a><span class="lineno"> 4632</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04633"></a><span class="lineno"> 4633</span>&#160;        <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l04634"></a><span class="lineno"> 4634</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l04635"></a><span class="lineno"> 4635</span>&#160;</div><div class="line"><a name="l04636"></a><span class="lineno"> 4636</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Free(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l04637"></a><span class="lineno"> 4637</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> FreeAtOffset(VkDeviceSize offset);</div><div class="line"><a name="l04638"></a><span class="lineno"> 4638</span>&#160;</div><div class="line"><a name="l04639"></a><span class="lineno"> 4639</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04640"></a><span class="lineno"> 4640</span>&#160;    uint32_t m_FreeCount;</div><div class="line"><a name="l04641"></a><span class="lineno"> 4641</span>&#160;    VkDeviceSize m_SumFreeSize;</div><div class="line"><a name="l04642"></a><span class="lineno"> 4642</span>&#160;    VmaSuballocationList m_Suballocations;</div><div class="line"><a name="l04643"></a><span class="lineno"> 4643</span>&#160;    <span class="comment">// Suballocations that are free and have size greater than certain threshold.</span></div><div class="line"><a name="l04644"></a><span class="lineno"> 4644</span>&#160;    <span class="comment">// Sorted by size, ascending.</span></div><div class="line"><a name="l04645"></a><span class="lineno"> 4645</span>&#160;    VmaVector&lt; VmaSuballocationList::iterator, VmaStlAllocator&lt; VmaSuballocationList::iterator &gt; &gt; m_FreeSuballocationsBySize;</div><div class="line"><a name="l04646"></a><span class="lineno"> 4646</span>&#160;</div><div class="line"><a name="l04647"></a><span class="lineno"> 4647</span>&#160;    <span class="keywordtype">bool</span> ValidateFreeSuballocationList() <span class="keyword">const</span>;</div><div class="line"><a name="l04648"></a><span class="lineno"> 4648</span>&#160;</div><div class="line"><a name="l04649"></a><span class="lineno"> 4649</span>&#160;    <span class="comment">// Checks if requested suballocation with given parameters can be placed in given pFreeSuballocItem.</span></div><div class="line"><a name="l04650"></a><span class="lineno"> 4650</span>&#160;    <span class="comment">// If yes, fills pOffset and returns true. If no, returns false.</span></div><div class="line"><a name="l04651"></a><span class="lineno"> 4651</span>&#160;    <span class="keywordtype">bool</span> CheckAllocation(</div><div class="line"><a name="l04652"></a><span class="lineno"> 4652</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04653"></a><span class="lineno"> 4653</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04654"></a><span class="lineno"> 4654</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04655"></a><span class="lineno"> 4655</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04656"></a><span class="lineno"> 4656</span>&#160;        VkDeviceSize allocAlignment,</div><div class="line"><a name="l04657"></a><span class="lineno"> 4657</span>&#160;        VmaSuballocationType allocType,</div><div class="line"><a name="l04658"></a><span class="lineno"> 4658</span>&#160;        VmaSuballocationList::const_iterator suballocItem,</div><div class="line"><a name="l04659"></a><span class="lineno"> 4659</span>&#160;        <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l04660"></a><span class="lineno"> 4660</span>&#160;        VkDeviceSize* pOffset,</div><div class="line"><a name="l04661"></a><span class="lineno"> 4661</span>&#160;        <span class="keywordtype">size_t</span>* itemsToMakeLostCount,</div><div class="line"><a name="l04662"></a><span class="lineno"> 4662</span>&#160;        VkDeviceSize* pSumFreeSize,</div><div class="line"><a name="l04663"></a><span class="lineno"> 4663</span>&#160;        VkDeviceSize* pSumItemSize) <span class="keyword">const</span>;</div><div class="line"><a name="l04664"></a><span class="lineno"> 4664</span>&#160;    <span class="comment">// Given free suballocation, it merges it with following one, which must also be free.</span></div><div class="line"><a name="l04665"></a><span class="lineno"> 4665</span>&#160;    <span class="keywordtype">void</span> MergeFreeWithNext(VmaSuballocationList::iterator item);</div><div class="line"><a name="l04666"></a><span class="lineno"> 4666</span>&#160;    <span class="comment">// Releases given suballocation, making it free.</span></div><div class="line"><a name="l04667"></a><span class="lineno"> 4667</span>&#160;    <span class="comment">// Merges it with adjacent free suballocations if applicable.</span></div><div class="line"><a name="l04668"></a><span class="lineno"> 4668</span>&#160;    <span class="comment">// Returns iterator to new free suballocation at this place.</span></div><div class="line"><a name="l04669"></a><span class="lineno"> 4669</span>&#160;    VmaSuballocationList::iterator FreeSuballocation(VmaSuballocationList::iterator suballocItem);</div><div class="line"><a name="l04670"></a><span class="lineno"> 4670</span>&#160;    <span class="comment">// Given free suballocation, it inserts it into sorted list of</span></div><div class="line"><a name="l04671"></a><span class="lineno"> 4671</span>&#160;    <span class="comment">// m_FreeSuballocationsBySize if it&#39;s suitable.</span></div><div class="line"><a name="l04672"></a><span class="lineno"> 4672</span>&#160;    <span class="keywordtype">void</span> RegisterFreeSuballocation(VmaSuballocationList::iterator item);</div><div class="line"><a name="l04673"></a><span class="lineno"> 4673</span>&#160;    <span class="comment">// Given free suballocation, it removes it from sorted list of</span></div><div class="line"><a name="l04674"></a><span class="lineno"> 4674</span>&#160;    <span class="comment">// m_FreeSuballocationsBySize if it&#39;s suitable.</span></div><div class="line"><a name="l04675"></a><span class="lineno"> 4675</span>&#160;    <span class="keywordtype">void</span> UnregisterFreeSuballocation(VmaSuballocationList::iterator item);</div><div class="line"><a name="l04676"></a><span class="lineno"> 4676</span>&#160;};</div><div class="line"><a name="l04677"></a><span class="lineno"> 4677</span>&#160;</div><div class="line"><a name="l04678"></a><span class="lineno"> 4678</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04679"></a><span class="lineno"> 4679</span>&#160;<span class="comment">Allocations and their references in internal data structure look like this:</span></div><div class="line"><a name="l04680"></a><span class="lineno"> 4680</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04681"></a><span class="lineno"> 4681</span>&#160;<span class="comment">if(m_2ndVectorMode == SECOND_VECTOR_EMPTY):</span></div><div class="line"><a name="l04682"></a><span class="lineno"> 4682</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04683"></a><span class="lineno"> 4683</span>&#160;<span class="comment">        0 +-------+</span></div><div class="line"><a name="l04684"></a><span class="lineno"> 4684</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04685"></a><span class="lineno"> 4685</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04686"></a><span class="lineno"> 4686</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04687"></a><span class="lineno"> 4687</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04688"></a><span class="lineno"> 4688</span>&#160;<span class="comment">          | Alloc |  1st[m_1stNullItemsBeginCount]</span></div><div class="line"><a name="l04689"></a><span class="lineno"> 4689</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04690"></a><span class="lineno"> 4690</span>&#160;<span class="comment">          | Alloc |  1st[m_1stNullItemsBeginCount + 1]</span></div><div class="line"><a name="l04691"></a><span class="lineno"> 4691</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04692"></a><span class="lineno"> 4692</span>&#160;<span class="comment">          |  ...  |</span></div><div class="line"><a name="l04693"></a><span class="lineno"> 4693</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04694"></a><span class="lineno"> 4694</span>&#160;<span class="comment">          | Alloc |  1st[1st.size() - 1]</span></div><div class="line"><a name="l04695"></a><span class="lineno"> 4695</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04696"></a><span class="lineno"> 4696</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04697"></a><span class="lineno"> 4697</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04698"></a><span class="lineno"> 4698</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04699"></a><span class="lineno"> 4699</span>&#160;<span class="comment">GetSize() +-------+</span></div><div class="line"><a name="l04700"></a><span class="lineno"> 4700</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04701"></a><span class="lineno"> 4701</span>&#160;<span class="comment">if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER):</span></div><div class="line"><a name="l04702"></a><span class="lineno"> 4702</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04703"></a><span class="lineno"> 4703</span>&#160;<span class="comment">        0 +-------+</span></div><div class="line"><a name="l04704"></a><span class="lineno"> 4704</span>&#160;<span class="comment">          | Alloc |  2nd[0]</span></div><div class="line"><a name="l04705"></a><span class="lineno"> 4705</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04706"></a><span class="lineno"> 4706</span>&#160;<span class="comment">          | Alloc |  2nd[1]</span></div><div class="line"><a name="l04707"></a><span class="lineno"> 4707</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04708"></a><span class="lineno"> 4708</span>&#160;<span class="comment">          |  ...  |</span></div><div class="line"><a name="l04709"></a><span class="lineno"> 4709</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04710"></a><span class="lineno"> 4710</span>&#160;<span class="comment">          | Alloc |  2nd[2nd.size() - 1]</span></div><div class="line"><a name="l04711"></a><span class="lineno"> 4711</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04712"></a><span class="lineno"> 4712</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04713"></a><span class="lineno"> 4713</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04714"></a><span class="lineno"> 4714</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04715"></a><span class="lineno"> 4715</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04716"></a><span class="lineno"> 4716</span>&#160;<span class="comment">          | Alloc |  1st[m_1stNullItemsBeginCount]</span></div><div class="line"><a name="l04717"></a><span class="lineno"> 4717</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04718"></a><span class="lineno"> 4718</span>&#160;<span class="comment">          | Alloc |  1st[m_1stNullItemsBeginCount + 1]</span></div><div class="line"><a name="l04719"></a><span class="lineno"> 4719</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04720"></a><span class="lineno"> 4720</span>&#160;<span class="comment">          |  ...  |</span></div><div class="line"><a name="l04721"></a><span class="lineno"> 4721</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04722"></a><span class="lineno"> 4722</span>&#160;<span class="comment">          | Alloc |  1st[1st.size() - 1]</span></div><div class="line"><a name="l04723"></a><span class="lineno"> 4723</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04724"></a><span class="lineno"> 4724</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04725"></a><span class="lineno"> 4725</span>&#160;<span class="comment">GetSize() +-------+</span></div><div class="line"><a name="l04726"></a><span class="lineno"> 4726</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04727"></a><span class="lineno"> 4727</span>&#160;<span class="comment">if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK):</span></div><div class="line"><a name="l04728"></a><span class="lineno"> 4728</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04729"></a><span class="lineno"> 4729</span>&#160;<span class="comment">        0 +-------+</span></div><div class="line"><a name="l04730"></a><span class="lineno"> 4730</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04731"></a><span class="lineno"> 4731</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04732"></a><span class="lineno"> 4732</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04733"></a><span class="lineno"> 4733</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04734"></a><span class="lineno"> 4734</span>&#160;<span class="comment">          | Alloc |  1st[m_1stNullItemsBeginCount]</span></div><div class="line"><a name="l04735"></a><span class="lineno"> 4735</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04736"></a><span class="lineno"> 4736</span>&#160;<span class="comment">          | Alloc |  1st[m_1stNullItemsBeginCount + 1]</span></div><div class="line"><a name="l04737"></a><span class="lineno"> 4737</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04738"></a><span class="lineno"> 4738</span>&#160;<span class="comment">          |  ...  |</span></div><div class="line"><a name="l04739"></a><span class="lineno"> 4739</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04740"></a><span class="lineno"> 4740</span>&#160;<span class="comment">          | Alloc |  1st[1st.size() - 1]</span></div><div class="line"><a name="l04741"></a><span class="lineno"> 4741</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04742"></a><span class="lineno"> 4742</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04743"></a><span class="lineno"> 4743</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04744"></a><span class="lineno"> 4744</span>&#160;<span class="comment">          |       |</span></div><div class="line"><a name="l04745"></a><span class="lineno"> 4745</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04746"></a><span class="lineno"> 4746</span>&#160;<span class="comment">          | Alloc |  2nd[2nd.size() - 1]</span></div><div class="line"><a name="l04747"></a><span class="lineno"> 4747</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04748"></a><span class="lineno"> 4748</span>&#160;<span class="comment">          |  ...  |</span></div><div class="line"><a name="l04749"></a><span class="lineno"> 4749</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04750"></a><span class="lineno"> 4750</span>&#160;<span class="comment">          | Alloc |  2nd[1]</span></div><div class="line"><a name="l04751"></a><span class="lineno"> 4751</span>&#160;<span class="comment">          +-------+</span></div><div class="line"><a name="l04752"></a><span class="lineno"> 4752</span>&#160;<span class="comment">          | Alloc |  2nd[0]</span></div><div class="line"><a name="l04753"></a><span class="lineno"> 4753</span>&#160;<span class="comment">GetSize() +-------+</span></div><div class="line"><a name="l04754"></a><span class="lineno"> 4754</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04755"></a><span class="lineno"> 4755</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04756"></a><span class="lineno"> 4756</span>&#160;<span class="keyword">class </span>VmaBlockMetadata_Linear : <span class="keyword">public</span> VmaBlockMetadata</div><div class="line"><a name="l04757"></a><span class="lineno"> 4757</span>&#160;{</div><div class="line"><a name="l04758"></a><span class="lineno"> 4758</span>&#160;    VMA_CLASS_NO_COPY(VmaBlockMetadata_Linear)</div><div class="line"><a name="l04759"></a><span class="lineno"> 4759</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04760"></a><span class="lineno"> 4760</span>&#160;    VmaBlockMetadata_Linear(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04761"></a><span class="lineno"> 4761</span>&#160;    <span class="keyword">virtual</span> ~VmaBlockMetadata_Linear();</div><div class="line"><a name="l04762"></a><span class="lineno"> 4762</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Init(VkDeviceSize size);</div><div class="line"><a name="l04763"></a><span class="lineno"> 4763</span>&#160;</div><div class="line"><a name="l04764"></a><span class="lineno"> 4764</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Validate() <span class="keyword">const</span>;</div><div class="line"><a name="l04765"></a><span class="lineno"> 4765</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">size_t</span> GetAllocationCount() <span class="keyword">const</span>;</div><div class="line"><a name="l04766"></a><span class="lineno"> 4766</span>&#160;    <span class="keyword">virtual</span> VkDeviceSize GetSumFreeSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_SumFreeSize; }</div><div class="line"><a name="l04767"></a><span class="lineno"> 4767</span>&#160;    <span class="keyword">virtual</span> VkDeviceSize GetUnusedRangeSizeMax() <span class="keyword">const</span>;</div><div class="line"><a name="l04768"></a><span class="lineno"> 4768</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsEmpty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> GetAllocationCount() == 0; }</div><div class="line"><a name="l04769"></a><span class="lineno"> 4769</span>&#160;</div><div class="line"><a name="l04770"></a><span class="lineno"> 4770</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> CalcAllocationStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo) <span class="keyword">const</span>;</div><div class="line"><a name="l04771"></a><span class="lineno"> 4771</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> AddPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>&amp; inoutStats) <span class="keyword">const</span>;</div><div class="line"><a name="l04772"></a><span class="lineno"> 4772</span>&#160;</div><div class="line"><a name="l04773"></a><span class="lineno"> 4773</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04774"></a><span class="lineno"> 4774</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json) <span class="keyword">const</span>;</div><div class="line"><a name="l04775"></a><span class="lineno"> 4775</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04776"></a><span class="lineno"> 4776</span>&#160;</div><div class="line"><a name="l04777"></a><span class="lineno"> 4777</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> CreateAllocationRequest(</div><div class="line"><a name="l04778"></a><span class="lineno"> 4778</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04779"></a><span class="lineno"> 4779</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04780"></a><span class="lineno"> 4780</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04781"></a><span class="lineno"> 4781</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04782"></a><span class="lineno"> 4782</span>&#160;        VkDeviceSize allocAlignment,</div><div class="line"><a name="l04783"></a><span class="lineno"> 4783</span>&#160;        <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l04784"></a><span class="lineno"> 4784</span>&#160;        VmaSuballocationType allocType,</div><div class="line"><a name="l04785"></a><span class="lineno"> 4785</span>&#160;        <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l04786"></a><span class="lineno"> 4786</span>&#160;        VmaAllocationRequest* pAllocationRequest);</div><div class="line"><a name="l04787"></a><span class="lineno"> 4787</span>&#160;</div><div class="line"><a name="l04788"></a><span class="lineno"> 4788</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> MakeRequestedAllocationsLost(</div><div class="line"><a name="l04789"></a><span class="lineno"> 4789</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04790"></a><span class="lineno"> 4790</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04791"></a><span class="lineno"> 4791</span>&#160;        VmaAllocationRequest* pAllocationRequest);</div><div class="line"><a name="l04792"></a><span class="lineno"> 4792</span>&#160;</div><div class="line"><a name="l04793"></a><span class="lineno"> 4793</span>&#160;    <span class="keyword">virtual</span> uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);</div><div class="line"><a name="l04794"></a><span class="lineno"> 4794</span>&#160;</div><div class="line"><a name="l04795"></a><span class="lineno"> 4795</span>&#160;    <span class="keyword">virtual</span> VkResult CheckCorruption(<span class="keyword">const</span> <span class="keywordtype">void</span>* pBlockData);</div><div class="line"><a name="l04796"></a><span class="lineno"> 4796</span>&#160;</div><div class="line"><a name="l04797"></a><span class="lineno"> 4797</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Alloc(</div><div class="line"><a name="l04798"></a><span class="lineno"> 4798</span>&#160;        <span class="keyword">const</span> VmaAllocationRequest&amp; request,</div><div class="line"><a name="l04799"></a><span class="lineno"> 4799</span>&#160;        VmaSuballocationType type,</div><div class="line"><a name="l04800"></a><span class="lineno"> 4800</span>&#160;        VkDeviceSize allocSize,</div><div class="line"><a name="l04801"></a><span class="lineno"> 4801</span>&#160;        <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l04802"></a><span class="lineno"> 4802</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l04803"></a><span class="lineno"> 4803</span>&#160;</div><div class="line"><a name="l04804"></a><span class="lineno"> 4804</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> Free(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l04805"></a><span class="lineno"> 4805</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> FreeAtOffset(VkDeviceSize offset);</div><div class="line"><a name="l04806"></a><span class="lineno"> 4806</span>&#160;</div><div class="line"><a name="l04807"></a><span class="lineno"> 4807</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04808"></a><span class="lineno"> 4808</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l04809"></a><span class="lineno"> 4809</span>&#160;<span class="comment">    There are two suballocation vectors, used in ping-pong way.</span></div><div class="line"><a name="l04810"></a><span class="lineno"> 4810</span>&#160;<span class="comment">    The one with index m_1stVectorIndex is called 1st.</span></div><div class="line"><a name="l04811"></a><span class="lineno"> 4811</span>&#160;<span class="comment">    The one with index (m_1stVectorIndex ^ 1) is called 2nd.</span></div><div class="line"><a name="l04812"></a><span class="lineno"> 4812</span>&#160;<span class="comment">    2nd can be non-empty only when 1st is not empty.</span></div><div class="line"><a name="l04813"></a><span class="lineno"> 4813</span>&#160;<span class="comment">    When 2nd is not empty, m_2ndVectorMode indicates its mode of operation.</span></div><div class="line"><a name="l04814"></a><span class="lineno"> 4814</span>&#160;<span class="comment">    */</span></div><div class="line"><a name="l04815"></a><span class="lineno"> 4815</span>&#160;    <span class="keyword">typedef</span> VmaVector&lt; VmaSuballocation, VmaStlAllocator&lt;VmaSuballocation&gt; &gt; SuballocationVectorType;</div><div class="line"><a name="l04816"></a><span class="lineno"> 4816</span>&#160;</div><div class="line"><a name="l04817"></a><span class="lineno"> 4817</span>&#160;    <span class="keyword">enum</span> SECOND_VECTOR_MODE</div><div class="line"><a name="l04818"></a><span class="lineno"> 4818</span>&#160;    {</div><div class="line"><a name="l04819"></a><span class="lineno"> 4819</span>&#160;        SECOND_VECTOR_EMPTY,</div><div class="line"><a name="l04820"></a><span class="lineno"> 4820</span>&#160;        <span class="comment">/*</span></div><div class="line"><a name="l04821"></a><span class="lineno"> 4821</span>&#160;<span class="comment">        Suballocations in 2nd vector are created later than the ones in 1st, but they</span></div><div class="line"><a name="l04822"></a><span class="lineno"> 4822</span>&#160;<span class="comment">        all have smaller offset.</span></div><div class="line"><a name="l04823"></a><span class="lineno"> 4823</span>&#160;<span class="comment">        */</span></div><div class="line"><a name="l04824"></a><span class="lineno"> 4824</span>&#160;        SECOND_VECTOR_RING_BUFFER,</div><div class="line"><a name="l04825"></a><span class="lineno"> 4825</span>&#160;        <span class="comment">/*</span></div><div class="line"><a name="l04826"></a><span class="lineno"> 4826</span>&#160;<span class="comment">        Suballocations in 2nd vector are upper side of double stack.</span></div><div class="line"><a name="l04827"></a><span class="lineno"> 4827</span>&#160;<span class="comment">        They all have offsets higher than those in 1st vector.</span></div><div class="line"><a name="l04828"></a><span class="lineno"> 4828</span>&#160;<span class="comment">        Top of this stack means smaller offsets, but higher indices in this vector.</span></div><div class="line"><a name="l04829"></a><span class="lineno"> 4829</span>&#160;<span class="comment">        */</span></div><div class="line"><a name="l04830"></a><span class="lineno"> 4830</span>&#160;        SECOND_VECTOR_DOUBLE_STACK,</div><div class="line"><a name="l04831"></a><span class="lineno"> 4831</span>&#160;    };</div><div class="line"><a name="l04832"></a><span class="lineno"> 4832</span>&#160;</div><div class="line"><a name="l04833"></a><span class="lineno"> 4833</span>&#160;    VkDeviceSize m_SumFreeSize;</div><div class="line"><a name="l04834"></a><span class="lineno"> 4834</span>&#160;    SuballocationVectorType m_Suballocations0, m_Suballocations1;</div><div class="line"><a name="l04835"></a><span class="lineno"> 4835</span>&#160;    uint32_t m_1stVectorIndex;</div><div class="line"><a name="l04836"></a><span class="lineno"> 4836</span>&#160;    SECOND_VECTOR_MODE m_2ndVectorMode;</div><div class="line"><a name="l04837"></a><span class="lineno"> 4837</span>&#160;</div><div class="line"><a name="l04838"></a><span class="lineno"> 4838</span>&#160;    SuballocationVectorType&amp; AccessSuballocations1st() { <span class="keywordflow">return</span> m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; }</div><div class="line"><a name="l04839"></a><span class="lineno"> 4839</span>&#160;    SuballocationVectorType&amp; AccessSuballocations2nd() { <span class="keywordflow">return</span> m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; }</div><div class="line"><a name="l04840"></a><span class="lineno"> 4840</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; AccessSuballocations1st()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; }</div><div class="line"><a name="l04841"></a><span class="lineno"> 4841</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; AccessSuballocations2nd()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; }</div><div class="line"><a name="l04842"></a><span class="lineno"> 4842</span>&#160;    </div><div class="line"><a name="l04843"></a><span class="lineno"> 4843</span>&#160;    <span class="comment">// Number of items in 1st vector with hAllocation = null at the beginning.</span></div><div class="line"><a name="l04844"></a><span class="lineno"> 4844</span>&#160;    <span class="keywordtype">size_t</span> m_1stNullItemsBeginCount;</div><div class="line"><a name="l04845"></a><span class="lineno"> 4845</span>&#160;    <span class="comment">// Number of other items in 1st vector with hAllocation = null somewhere in the middle.</span></div><div class="line"><a name="l04846"></a><span class="lineno"> 4846</span>&#160;    <span class="keywordtype">size_t</span> m_1stNullItemsMiddleCount;</div><div class="line"><a name="l04847"></a><span class="lineno"> 4847</span>&#160;    <span class="comment">// Number of items in 2nd vector with hAllocation = null.</span></div><div class="line"><a name="l04848"></a><span class="lineno"> 4848</span>&#160;    <span class="keywordtype">size_t</span> m_2ndNullItemsCount;</div><div class="line"><a name="l04849"></a><span class="lineno"> 4849</span>&#160;</div><div class="line"><a name="l04850"></a><span class="lineno"> 4850</span>&#160;    <span class="keywordtype">bool</span> ShouldCompact1st() <span class="keyword">const</span>;</div><div class="line"><a name="l04851"></a><span class="lineno"> 4851</span>&#160;    <span class="keywordtype">void</span> CleanupAfterFree();</div><div class="line"><a name="l04852"></a><span class="lineno"> 4852</span>&#160;};</div><div class="line"><a name="l04853"></a><span class="lineno"> 4853</span>&#160;</div><div class="line"><a name="l04854"></a><span class="lineno"> 4854</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04855"></a><span class="lineno"> 4855</span>&#160;<span class="comment">Represents a single block of device memory (`VkDeviceMemory`) with all the</span></div><div class="line"><a name="l04856"></a><span class="lineno"> 4856</span>&#160;<span class="comment">data about its regions (aka suballocations, #VmaAllocation), assigned and free.</span></div><div class="line"><a name="l04857"></a><span class="lineno"> 4857</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04858"></a><span class="lineno"> 4858</span>&#160;<span class="comment">Thread-safety: This class must be externally synchronized.</span></div><div class="line"><a name="l04859"></a><span class="lineno"> 4859</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04860"></a><span class="lineno"> 4860</span>&#160;<span class="keyword">class </span>VmaDeviceMemoryBlock</div><div class="line"><a name="l04861"></a><span class="lineno"> 4861</span>&#160;{</div><div class="line"><a name="l04862"></a><span class="lineno"> 4862</span>&#160;    VMA_CLASS_NO_COPY(VmaDeviceMemoryBlock)</div><div class="line"><a name="l04863"></a><span class="lineno"> 4863</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04864"></a><span class="lineno"> 4864</span>&#160;    VmaBlockMetadata* m_pMetadata;</div><div class="line"><a name="l04865"></a><span class="lineno"> 4865</span>&#160;</div><div class="line"><a name="l04866"></a><span class="lineno"> 4866</span>&#160;    VmaDeviceMemoryBlock(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04867"></a><span class="lineno"> 4867</span>&#160;</div><div class="line"><a name="l04868"></a><span class="lineno"> 4868</span>&#160;    ~VmaDeviceMemoryBlock()</div><div class="line"><a name="l04869"></a><span class="lineno"> 4869</span>&#160;    {</div><div class="line"><a name="l04870"></a><span class="lineno"> 4870</span>&#160;        VMA_ASSERT(m_MapCount == 0 &amp;&amp; <span class="stringliteral">&quot;VkDeviceMemory block is being destroyed while it is still mapped.&quot;</span>);</div><div class="line"><a name="l04871"></a><span class="lineno"> 4871</span>&#160;        VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);</div><div class="line"><a name="l04872"></a><span class="lineno"> 4872</span>&#160;    }</div><div class="line"><a name="l04873"></a><span class="lineno"> 4873</span>&#160;</div><div class="line"><a name="l04874"></a><span class="lineno"> 4874</span>&#160;    <span class="comment">// Always call after construction.</span></div><div class="line"><a name="l04875"></a><span class="lineno"> 4875</span>&#160;    <span class="keywordtype">void</span> Init(</div><div class="line"><a name="l04876"></a><span class="lineno"> 4876</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04877"></a><span class="lineno"> 4877</span>&#160;        uint32_t newMemoryTypeIndex,</div><div class="line"><a name="l04878"></a><span class="lineno"> 4878</span>&#160;        VkDeviceMemory newMemory,</div><div class="line"><a name="l04879"></a><span class="lineno"> 4879</span>&#160;        VkDeviceSize newSize,</div><div class="line"><a name="l04880"></a><span class="lineno"> 4880</span>&#160;        uint32_t <span class="keywordtype">id</span>,</div><div class="line"><a name="l04881"></a><span class="lineno"> 4881</span>&#160;        <span class="keywordtype">bool</span> linearAlgorithm);</div><div class="line"><a name="l04882"></a><span class="lineno"> 4882</span>&#160;    <span class="comment">// Always call before destruction.</span></div><div class="line"><a name="l04883"></a><span class="lineno"> 4883</span>&#160;    <span class="keywordtype">void</span> Destroy(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator);</div><div class="line"><a name="l04884"></a><span class="lineno"> 4884</span>&#160;    </div><div class="line"><a name="l04885"></a><span class="lineno"> 4885</span>&#160;    VkDeviceMemory GetDeviceMemory()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_hMemory; }</div><div class="line"><a name="l04886"></a><span class="lineno"> 4886</span>&#160;    uint32_t GetMemoryTypeIndex()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemoryTypeIndex; }</div><div class="line"><a name="l04887"></a><span class="lineno"> 4887</span>&#160;    uint32_t GetId()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Id; }</div><div class="line"><a name="l04888"></a><span class="lineno"> 4888</span>&#160;    <span class="keywordtype">void</span>* GetMappedData()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pMappedData; }</div><div class="line"><a name="l04889"></a><span class="lineno"> 4889</span>&#160;</div><div class="line"><a name="l04890"></a><span class="lineno"> 4890</span>&#160;    <span class="comment">// Validates all data structures inside this object. If not valid, returns false.</span></div><div class="line"><a name="l04891"></a><span class="lineno"> 4891</span>&#160;    <span class="keywordtype">bool</span> Validate() <span class="keyword">const</span>;</div><div class="line"><a name="l04892"></a><span class="lineno"> 4892</span>&#160;</div><div class="line"><a name="l04893"></a><span class="lineno"> 4893</span>&#160;    VkResult CheckCorruption(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l04894"></a><span class="lineno"> 4894</span>&#160;</div><div class="line"><a name="l04895"></a><span class="lineno"> 4895</span>&#160;    <span class="comment">// ppData can be null.</span></div><div class="line"><a name="l04896"></a><span class="lineno"> 4896</span>&#160;    VkResult Map(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count, <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l04897"></a><span class="lineno"> 4897</span>&#160;    <span class="keywordtype">void</span> Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count);</div><div class="line"><a name="l04898"></a><span class="lineno"> 4898</span>&#160;</div><div class="line"><a name="l04899"></a><span class="lineno"> 4899</span>&#160;    VkResult WriteMagicValueAroundAllocation(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize);</div><div class="line"><a name="l04900"></a><span class="lineno"> 4900</span>&#160;    VkResult ValidateMagicValueAroundAllocation(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize);</div><div class="line"><a name="l04901"></a><span class="lineno"> 4901</span>&#160;</div><div class="line"><a name="l04902"></a><span class="lineno"> 4902</span>&#160;    VkResult BindBufferMemory(</div><div class="line"><a name="l04903"></a><span class="lineno"> 4903</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04904"></a><span class="lineno"> 4904</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l04905"></a><span class="lineno"> 4905</span>&#160;        VkBuffer hBuffer);</div><div class="line"><a name="l04906"></a><span class="lineno"> 4906</span>&#160;    VkResult BindImageMemory(</div><div class="line"><a name="l04907"></a><span class="lineno"> 4907</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04908"></a><span class="lineno"> 4908</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l04909"></a><span class="lineno"> 4909</span>&#160;        VkImage hImage);</div><div class="line"><a name="l04910"></a><span class="lineno"> 4910</span>&#160;</div><div class="line"><a name="l04911"></a><span class="lineno"> 4911</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l04912"></a><span class="lineno"> 4912</span>&#160;    uint32_t m_MemoryTypeIndex;</div><div class="line"><a name="l04913"></a><span class="lineno"> 4913</span>&#160;    uint32_t m_Id;</div><div class="line"><a name="l04914"></a><span class="lineno"> 4914</span>&#160;    VkDeviceMemory m_hMemory;</div><div class="line"><a name="l04915"></a><span class="lineno"> 4915</span>&#160;</div><div class="line"><a name="l04916"></a><span class="lineno"> 4916</span>&#160;    <span class="comment">// Protects access to m_hMemory so it&#39;s not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.</span></div><div class="line"><a name="l04917"></a><span class="lineno"> 4917</span>&#160;    <span class="comment">// Also protects m_MapCount, m_pMappedData.</span></div><div class="line"><a name="l04918"></a><span class="lineno"> 4918</span>&#160;    VMA_MUTEX m_Mutex;</div><div class="line"><a name="l04919"></a><span class="lineno"> 4919</span>&#160;    uint32_t m_MapCount;</div><div class="line"><a name="l04920"></a><span class="lineno"> 4920</span>&#160;    <span class="keywordtype">void</span>* m_pMappedData;</div><div class="line"><a name="l04921"></a><span class="lineno"> 4921</span>&#160;};</div><div class="line"><a name="l04922"></a><span class="lineno"> 4922</span>&#160;</div><div class="line"><a name="l04923"></a><span class="lineno"> 4923</span>&#160;<span class="keyword">struct </span>VmaPointerLess</div><div class="line"><a name="l04924"></a><span class="lineno"> 4924</span>&#160;{</div><div class="line"><a name="l04925"></a><span class="lineno"> 4925</span>&#160;    <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> <span class="keywordtype">void</span>* lhs, <span class="keyword">const</span> <span class="keywordtype">void</span>* rhs)<span class="keyword"> const</span></div><div class="line"><a name="l04926"></a><span class="lineno"> 4926</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l04927"></a><span class="lineno"> 4927</span>&#160;        <span class="keywordflow">return</span> lhs &lt; rhs;</div><div class="line"><a name="l04928"></a><span class="lineno"> 4928</span>&#160;    }</div><div class="line"><a name="l04929"></a><span class="lineno"> 4929</span>&#160;};</div><div class="line"><a name="l04930"></a><span class="lineno"> 4930</span>&#160;</div><div class="line"><a name="l04931"></a><span class="lineno"> 4931</span>&#160;<span class="keyword">class </span>VmaDefragmentator;</div><div class="line"><a name="l04932"></a><span class="lineno"> 4932</span>&#160;</div><div class="line"><a name="l04933"></a><span class="lineno"> 4933</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l04934"></a><span class="lineno"> 4934</span>&#160;<span class="comment">Sequence of VmaDeviceMemoryBlock. Represents memory blocks allocated for a specific</span></div><div class="line"><a name="l04935"></a><span class="lineno"> 4935</span>&#160;<span class="comment">Vulkan memory type.</span></div><div class="line"><a name="l04936"></a><span class="lineno"> 4936</span>&#160;<span class="comment"></span></div><div class="line"><a name="l04937"></a><span class="lineno"> 4937</span>&#160;<span class="comment">Synchronized internally with a mutex.</span></div><div class="line"><a name="l04938"></a><span class="lineno"> 4938</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l04939"></a><span class="lineno"> 4939</span>&#160;<span class="keyword">struct </span>VmaBlockVector</div><div class="line"><a name="l04940"></a><span class="lineno"> 4940</span>&#160;{</div><div class="line"><a name="l04941"></a><span class="lineno"> 4941</span>&#160;    VMA_CLASS_NO_COPY(VmaBlockVector)</div><div class="line"><a name="l04942"></a><span class="lineno"> 4942</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l04943"></a><span class="lineno"> 4943</span>&#160;    VmaBlockVector(</div><div class="line"><a name="l04944"></a><span class="lineno"> 4944</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04945"></a><span class="lineno"> 4945</span>&#160;        uint32_t memoryTypeIndex,</div><div class="line"><a name="l04946"></a><span class="lineno"> 4946</span>&#160;        VkDeviceSize preferredBlockSize,</div><div class="line"><a name="l04947"></a><span class="lineno"> 4947</span>&#160;        <span class="keywordtype">size_t</span> minBlockCount,</div><div class="line"><a name="l04948"></a><span class="lineno"> 4948</span>&#160;        <span class="keywordtype">size_t</span> maxBlockCount,</div><div class="line"><a name="l04949"></a><span class="lineno"> 4949</span>&#160;        VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l04950"></a><span class="lineno"> 4950</span>&#160;        uint32_t frameInUseCount,</div><div class="line"><a name="l04951"></a><span class="lineno"> 4951</span>&#160;        <span class="keywordtype">bool</span> isCustomPool,</div><div class="line"><a name="l04952"></a><span class="lineno"> 4952</span>&#160;        <span class="keywordtype">bool</span> explicitBlockSize,</div><div class="line"><a name="l04953"></a><span class="lineno"> 4953</span>&#160;        <span class="keywordtype">bool</span> linearAlgorithm);</div><div class="line"><a name="l04954"></a><span class="lineno"> 4954</span>&#160;    ~VmaBlockVector();</div><div class="line"><a name="l04955"></a><span class="lineno"> 4955</span>&#160;</div><div class="line"><a name="l04956"></a><span class="lineno"> 4956</span>&#160;    VkResult CreateMinBlocks();</div><div class="line"><a name="l04957"></a><span class="lineno"> 4957</span>&#160;</div><div class="line"><a name="l04958"></a><span class="lineno"> 4958</span>&#160;    uint32_t GetMemoryTypeIndex()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemoryTypeIndex; }</div><div class="line"><a name="l04959"></a><span class="lineno"> 4959</span>&#160;    VkDeviceSize GetPreferredBlockSize()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_PreferredBlockSize; }</div><div class="line"><a name="l04960"></a><span class="lineno"> 4960</span>&#160;    VkDeviceSize GetBufferImageGranularity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_BufferImageGranularity; }</div><div class="line"><a name="l04961"></a><span class="lineno"> 4961</span>&#160;    uint32_t GetFrameInUseCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_FrameInUseCount; }</div><div class="line"><a name="l04962"></a><span class="lineno"> 4962</span>&#160;    <span class="keywordtype">bool</span> UsesLinearAlgorithm()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_LinearAlgorithm; }</div><div class="line"><a name="l04963"></a><span class="lineno"> 4963</span>&#160;</div><div class="line"><a name="l04964"></a><span class="lineno"> 4964</span>&#160;    <span class="keywordtype">void</span> GetPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pStats);</div><div class="line"><a name="l04965"></a><span class="lineno"> 4965</span>&#160;</div><div class="line"><a name="l04966"></a><span class="lineno"> 4966</span>&#160;    <span class="keywordtype">bool</span> IsEmpty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Blocks.empty(); }</div><div class="line"><a name="l04967"></a><span class="lineno"> 4967</span>&#160;    <span class="keywordtype">bool</span> IsCorruptionDetectionEnabled() <span class="keyword">const</span>;</div><div class="line"><a name="l04968"></a><span class="lineno"> 4968</span>&#160;</div><div class="line"><a name="l04969"></a><span class="lineno"> 4969</span>&#160;    VkResult Allocate(</div><div class="line"><a name="l04970"></a><span class="lineno"> 4970</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> hCurrentPool,</div><div class="line"><a name="l04971"></a><span class="lineno"> 4971</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04972"></a><span class="lineno"> 4972</span>&#160;        VkDeviceSize size,</div><div class="line"><a name="l04973"></a><span class="lineno"> 4973</span>&#160;        VkDeviceSize alignment,</div><div class="line"><a name="l04974"></a><span class="lineno"> 4974</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l04975"></a><span class="lineno"> 4975</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l04976"></a><span class="lineno"> 4976</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l04977"></a><span class="lineno"> 4977</span>&#160;</div><div class="line"><a name="l04978"></a><span class="lineno"> 4978</span>&#160;    <span class="keywordtype">void</span> Free(</div><div class="line"><a name="l04979"></a><span class="lineno"> 4979</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l04980"></a><span class="lineno"> 4980</span>&#160;</div><div class="line"><a name="l04981"></a><span class="lineno"> 4981</span>&#160;    <span class="comment">// Adds statistics of this BlockVector to pStats.</span></div><div class="line"><a name="l04982"></a><span class="lineno"> 4982</span>&#160;    <span class="keywordtype">void</span> AddStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats);</div><div class="line"><a name="l04983"></a><span class="lineno"> 4983</span>&#160;</div><div class="line"><a name="l04984"></a><span class="lineno"> 4984</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l04985"></a><span class="lineno"> 4985</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json);</div><div class="line"><a name="l04986"></a><span class="lineno"> 4986</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l04987"></a><span class="lineno"> 4987</span>&#160;</div><div class="line"><a name="l04988"></a><span class="lineno"> 4988</span>&#160;    <span class="keywordtype">void</span> MakePoolAllocationsLost(</div><div class="line"><a name="l04989"></a><span class="lineno"> 4989</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l04990"></a><span class="lineno"> 4990</span>&#160;        <span class="keywordtype">size_t</span>* pLostAllocationCount);</div><div class="line"><a name="l04991"></a><span class="lineno"> 4991</span>&#160;    VkResult CheckCorruption();</div><div class="line"><a name="l04992"></a><span class="lineno"> 4992</span>&#160;</div><div class="line"><a name="l04993"></a><span class="lineno"> 4993</span>&#160;    VmaDefragmentator* EnsureDefragmentator(</div><div class="line"><a name="l04994"></a><span class="lineno"> 4994</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l04995"></a><span class="lineno"> 4995</span>&#160;        uint32_t currentFrameIndex);</div><div class="line"><a name="l04996"></a><span class="lineno"> 4996</span>&#160;</div><div class="line"><a name="l04997"></a><span class="lineno"> 4997</span>&#160;    VkResult Defragment(</div><div class="line"><a name="l04998"></a><span class="lineno"> 4998</span>&#160;        <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats,</div><div class="line"><a name="l04999"></a><span class="lineno"> 4999</span>&#160;        VkDeviceSize&amp; maxBytesToMove,</div><div class="line"><a name="l05000"></a><span class="lineno"> 5000</span>&#160;        uint32_t&amp; maxAllocationsToMove);</div><div class="line"><a name="l05001"></a><span class="lineno"> 5001</span>&#160;</div><div class="line"><a name="l05002"></a><span class="lineno"> 5002</span>&#160;    <span class="keywordtype">void</span> DestroyDefragmentator();</div><div class="line"><a name="l05003"></a><span class="lineno"> 5003</span>&#160;</div><div class="line"><a name="l05004"></a><span class="lineno"> 5004</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l05005"></a><span class="lineno"> 5005</span>&#160;    <span class="keyword">friend</span> <span class="keyword">class </span>VmaDefragmentator;</div><div class="line"><a name="l05006"></a><span class="lineno"> 5006</span>&#160;</div><div class="line"><a name="l05007"></a><span class="lineno"> 5007</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> m_hAllocator;</div><div class="line"><a name="l05008"></a><span class="lineno"> 5008</span>&#160;    <span class="keyword">const</span> uint32_t m_MemoryTypeIndex;</div><div class="line"><a name="l05009"></a><span class="lineno"> 5009</span>&#160;    <span class="keyword">const</span> VkDeviceSize m_PreferredBlockSize;</div><div class="line"><a name="l05010"></a><span class="lineno"> 5010</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> m_MinBlockCount;</div><div class="line"><a name="l05011"></a><span class="lineno"> 5011</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> m_MaxBlockCount;</div><div class="line"><a name="l05012"></a><span class="lineno"> 5012</span>&#160;    <span class="keyword">const</span> VkDeviceSize m_BufferImageGranularity;</div><div class="line"><a name="l05013"></a><span class="lineno"> 5013</span>&#160;    <span class="keyword">const</span> uint32_t m_FrameInUseCount;</div><div class="line"><a name="l05014"></a><span class="lineno"> 5014</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> m_IsCustomPool;</div><div class="line"><a name="l05015"></a><span class="lineno"> 5015</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> m_ExplicitBlockSize;</div><div class="line"><a name="l05016"></a><span class="lineno"> 5016</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> m_LinearAlgorithm;</div><div class="line"><a name="l05017"></a><span class="lineno"> 5017</span>&#160;    <span class="keywordtype">bool</span> m_HasEmptyBlock;</div><div class="line"><a name="l05018"></a><span class="lineno"> 5018</span>&#160;    VMA_MUTEX m_Mutex;</div><div class="line"><a name="l05019"></a><span class="lineno"> 5019</span>&#160;    <span class="comment">// Incrementally sorted by sumFreeSize, ascending.</span></div><div class="line"><a name="l05020"></a><span class="lineno"> 5020</span>&#160;    VmaVector&lt; VmaDeviceMemoryBlock*, VmaStlAllocator&lt;VmaDeviceMemoryBlock*&gt; &gt; m_Blocks;</div><div class="line"><a name="l05021"></a><span class="lineno"> 5021</span>&#160;    <span class="comment">/* There can be at most one allocation that is completely empty - a</span></div><div class="line"><a name="l05022"></a><span class="lineno"> 5022</span>&#160;<span class="comment">    hysteresis to avoid pessimistic case of alternating creation and destruction</span></div><div class="line"><a name="l05023"></a><span class="lineno"> 5023</span>&#160;<span class="comment">    of a VkDeviceMemory. */</span></div><div class="line"><a name="l05024"></a><span class="lineno"> 5024</span>&#160;    VmaDefragmentator* m_pDefragmentator;</div><div class="line"><a name="l05025"></a><span class="lineno"> 5025</span>&#160;    uint32_t m_NextBlockId;</div><div class="line"><a name="l05026"></a><span class="lineno"> 5026</span>&#160;</div><div class="line"><a name="l05027"></a><span class="lineno"> 5027</span>&#160;    VkDeviceSize CalcMaxBlockSize() <span class="keyword">const</span>;</div><div class="line"><a name="l05028"></a><span class="lineno"> 5028</span>&#160;</div><div class="line"><a name="l05029"></a><span class="lineno"> 5029</span>&#160;    <span class="comment">// Finds and removes given block from vector.</span></div><div class="line"><a name="l05030"></a><span class="lineno"> 5030</span>&#160;    <span class="keywordtype">void</span> Remove(VmaDeviceMemoryBlock* pBlock);</div><div class="line"><a name="l05031"></a><span class="lineno"> 5031</span>&#160;</div><div class="line"><a name="l05032"></a><span class="lineno"> 5032</span>&#160;    <span class="comment">// Performs single step in sorting m_Blocks. They may not be fully sorted</span></div><div class="line"><a name="l05033"></a><span class="lineno"> 5033</span>&#160;    <span class="comment">// after this call.</span></div><div class="line"><a name="l05034"></a><span class="lineno"> 5034</span>&#160;    <span class="keywordtype">void</span> IncrementallySortBlocks();</div><div class="line"><a name="l05035"></a><span class="lineno"> 5035</span>&#160;</div><div class="line"><a name="l05036"></a><span class="lineno"> 5036</span>&#160;    <span class="comment">// To be used only without CAN_MAKE_OTHER_LOST flag.</span></div><div class="line"><a name="l05037"></a><span class="lineno"> 5037</span>&#160;    VkResult AllocateFromBlock(</div><div class="line"><a name="l05038"></a><span class="lineno"> 5038</span>&#160;        VmaDeviceMemoryBlock* pBlock,</div><div class="line"><a name="l05039"></a><span class="lineno"> 5039</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> hCurrentPool,</div><div class="line"><a name="l05040"></a><span class="lineno"> 5040</span>&#160;        uint32_t currentFrameIndex,</div><div class="line"><a name="l05041"></a><span class="lineno"> 5041</span>&#160;        VkDeviceSize size,</div><div class="line"><a name="l05042"></a><span class="lineno"> 5042</span>&#160;        VkDeviceSize alignment,</div><div class="line"><a name="l05043"></a><span class="lineno"> 5043</span>&#160;        <a class="code" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a> allocFlags,</div><div class="line"><a name="l05044"></a><span class="lineno"> 5044</span>&#160;        <span class="keywordtype">void</span>* pUserData,</div><div class="line"><a name="l05045"></a><span class="lineno"> 5045</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l05046"></a><span class="lineno"> 5046</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l05047"></a><span class="lineno"> 5047</span>&#160;</div><div class="line"><a name="l05048"></a><span class="lineno"> 5048</span>&#160;    VkResult CreateBlock(VkDeviceSize blockSize, <span class="keywordtype">size_t</span>* pNewBlockIndex);</div><div class="line"><a name="l05049"></a><span class="lineno"> 5049</span>&#160;};</div><div class="line"><a name="l05050"></a><span class="lineno"> 5050</span>&#160;</div><div class="line"><a name="l05051"></a><span class="lineno"> 5051</span>&#160;<span class="keyword">struct </span>VmaPool_T</div><div class="line"><a name="l05052"></a><span class="lineno"> 5052</span>&#160;{</div><div class="line"><a name="l05053"></a><span class="lineno"> 5053</span>&#160;    VMA_CLASS_NO_COPY(VmaPool_T)</div><div class="line"><a name="l05054"></a><span class="lineno"> 5054</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l05055"></a><span class="lineno"> 5055</span>&#160;    VmaBlockVector m_BlockVector;</div><div class="line"><a name="l05056"></a><span class="lineno"> 5056</span>&#160;</div><div class="line"><a name="l05057"></a><span class="lineno"> 5057</span>&#160;    VmaPool_T(</div><div class="line"><a name="l05058"></a><span class="lineno"> 5058</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l05059"></a><span class="lineno"> 5059</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l05060"></a><span class="lineno"> 5060</span>&#160;        VkDeviceSize preferredBlockSize);</div><div class="line"><a name="l05061"></a><span class="lineno"> 5061</span>&#160;    ~VmaPool_T();</div><div class="line"><a name="l05062"></a><span class="lineno"> 5062</span>&#160;</div><div class="line"><a name="l05063"></a><span class="lineno"> 5063</span>&#160;    uint32_t GetId()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Id; }</div><div class="line"><a name="l05064"></a><span class="lineno"> 5064</span>&#160;    <span class="keywordtype">void</span> SetId(uint32_t <span class="keywordtype">id</span>) { VMA_ASSERT(m_Id == 0); m_Id = id; }</div><div class="line"><a name="l05065"></a><span class="lineno"> 5065</span>&#160;</div><div class="line"><a name="l05066"></a><span class="lineno"> 5066</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05067"></a><span class="lineno"> 5067</span>&#160;    <span class="comment">//void PrintDetailedMap(class VmaStringBuilder&amp; sb);</span></div><div class="line"><a name="l05068"></a><span class="lineno"> 5068</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l05069"></a><span class="lineno"> 5069</span>&#160;</div><div class="line"><a name="l05070"></a><span class="lineno"> 5070</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l05071"></a><span class="lineno"> 5071</span>&#160;    uint32_t m_Id;</div><div class="line"><a name="l05072"></a><span class="lineno"> 5072</span>&#160;};</div><div class="line"><a name="l05073"></a><span class="lineno"> 5073</span>&#160;</div><div class="line"><a name="l05074"></a><span class="lineno"> 5074</span>&#160;<span class="keyword">class </span>VmaDefragmentator</div><div class="line"><a name="l05075"></a><span class="lineno"> 5075</span>&#160;{</div><div class="line"><a name="l05076"></a><span class="lineno"> 5076</span>&#160;    VMA_CLASS_NO_COPY(VmaDefragmentator)</div><div class="line"><a name="l05077"></a><span class="lineno"> 5077</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l05078"></a><span class="lineno"> 5078</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> m_hAllocator;</div><div class="line"><a name="l05079"></a><span class="lineno"> 5079</span>&#160;    VmaBlockVector* <span class="keyword">const</span> m_pBlockVector;</div><div class="line"><a name="l05080"></a><span class="lineno"> 5080</span>&#160;    uint32_t m_CurrentFrameIndex;</div><div class="line"><a name="l05081"></a><span class="lineno"> 5081</span>&#160;    VkDeviceSize m_BytesMoved;</div><div class="line"><a name="l05082"></a><span class="lineno"> 5082</span>&#160;    uint32_t m_AllocationsMoved;</div><div class="line"><a name="l05083"></a><span class="lineno"> 5083</span>&#160;</div><div class="line"><a name="l05084"></a><span class="lineno"> 5084</span>&#160;    <span class="keyword">struct </span>AllocationInfo</div><div class="line"><a name="l05085"></a><span class="lineno"> 5085</span>&#160;    {</div><div class="line"><a name="l05086"></a><span class="lineno"> 5086</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> m_hAllocation;</div><div class="line"><a name="l05087"></a><span class="lineno"> 5087</span>&#160;        VkBool32* m_pChanged;</div><div class="line"><a name="l05088"></a><span class="lineno"> 5088</span>&#160;</div><div class="line"><a name="l05089"></a><span class="lineno"> 5089</span>&#160;        AllocationInfo() :</div><div class="line"><a name="l05090"></a><span class="lineno"> 5090</span>&#160;            m_hAllocation(VK_NULL_HANDLE),</div><div class="line"><a name="l05091"></a><span class="lineno"> 5091</span>&#160;            m_pChanged(VMA_NULL)</div><div class="line"><a name="l05092"></a><span class="lineno"> 5092</span>&#160;        {</div><div class="line"><a name="l05093"></a><span class="lineno"> 5093</span>&#160;        }</div><div class="line"><a name="l05094"></a><span class="lineno"> 5094</span>&#160;    };</div><div class="line"><a name="l05095"></a><span class="lineno"> 5095</span>&#160;</div><div class="line"><a name="l05096"></a><span class="lineno"> 5096</span>&#160;    <span class="keyword">struct </span>AllocationInfoSizeGreater</div><div class="line"><a name="l05097"></a><span class="lineno"> 5097</span>&#160;    {</div><div class="line"><a name="l05098"></a><span class="lineno"> 5098</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> AllocationInfo&amp; lhs, <span class="keyword">const</span> AllocationInfo&amp; rhs)<span class="keyword"> const</span></div><div class="line"><a name="l05099"></a><span class="lineno"> 5099</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l05100"></a><span class="lineno"> 5100</span>&#160;            <span class="keywordflow">return</span> lhs.m_hAllocation-&gt;GetSize() &gt; rhs.m_hAllocation-&gt;GetSize();</div><div class="line"><a name="l05101"></a><span class="lineno"> 5101</span>&#160;        }</div><div class="line"><a name="l05102"></a><span class="lineno"> 5102</span>&#160;    };</div><div class="line"><a name="l05103"></a><span class="lineno"> 5103</span>&#160;</div><div class="line"><a name="l05104"></a><span class="lineno"> 5104</span>&#160;    <span class="comment">// Used between AddAllocation and Defragment.</span></div><div class="line"><a name="l05105"></a><span class="lineno"> 5105</span>&#160;    VmaVector&lt; AllocationInfo, VmaStlAllocator&lt;AllocationInfo&gt; &gt; m_Allocations;</div><div class="line"><a name="l05106"></a><span class="lineno"> 5106</span>&#160;</div><div class="line"><a name="l05107"></a><span class="lineno"> 5107</span>&#160;    <span class="keyword">struct </span>BlockInfo</div><div class="line"><a name="l05108"></a><span class="lineno"> 5108</span>&#160;    {</div><div class="line"><a name="l05109"></a><span class="lineno"> 5109</span>&#160;        VmaDeviceMemoryBlock* m_pBlock;</div><div class="line"><a name="l05110"></a><span class="lineno"> 5110</span>&#160;        <span class="keywordtype">bool</span> m_HasNonMovableAllocations;</div><div class="line"><a name="l05111"></a><span class="lineno"> 5111</span>&#160;        VmaVector&lt; AllocationInfo, VmaStlAllocator&lt;AllocationInfo&gt; &gt; m_Allocations;</div><div class="line"><a name="l05112"></a><span class="lineno"> 5112</span>&#160;</div><div class="line"><a name="l05113"></a><span class="lineno"> 5113</span>&#160;        BlockInfo(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks) :</div><div class="line"><a name="l05114"></a><span class="lineno"> 5114</span>&#160;            m_pBlock(VMA_NULL),</div><div class="line"><a name="l05115"></a><span class="lineno"> 5115</span>&#160;            m_HasNonMovableAllocations(true),</div><div class="line"><a name="l05116"></a><span class="lineno"> 5116</span>&#160;            m_Allocations(pAllocationCallbacks),</div><div class="line"><a name="l05117"></a><span class="lineno"> 5117</span>&#160;            m_pMappedDataForDefragmentation(VMA_NULL)</div><div class="line"><a name="l05118"></a><span class="lineno"> 5118</span>&#160;        {</div><div class="line"><a name="l05119"></a><span class="lineno"> 5119</span>&#160;        }</div><div class="line"><a name="l05120"></a><span class="lineno"> 5120</span>&#160;</div><div class="line"><a name="l05121"></a><span class="lineno"> 5121</span>&#160;        <span class="keywordtype">void</span> CalcHasNonMovableAllocations()</div><div class="line"><a name="l05122"></a><span class="lineno"> 5122</span>&#160;        {</div><div class="line"><a name="l05123"></a><span class="lineno"> 5123</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> blockAllocCount = m_pBlock-&gt;m_pMetadata-&gt;GetAllocationCount();</div><div class="line"><a name="l05124"></a><span class="lineno"> 5124</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> defragmentAllocCount = m_Allocations.size();</div><div class="line"><a name="l05125"></a><span class="lineno"> 5125</span>&#160;            m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount;</div><div class="line"><a name="l05126"></a><span class="lineno"> 5126</span>&#160;        }</div><div class="line"><a name="l05127"></a><span class="lineno"> 5127</span>&#160;</div><div class="line"><a name="l05128"></a><span class="lineno"> 5128</span>&#160;        <span class="keywordtype">void</span> SortAllocationsBySizeDescecnding()</div><div class="line"><a name="l05129"></a><span class="lineno"> 5129</span>&#160;        {</div><div class="line"><a name="l05130"></a><span class="lineno"> 5130</span>&#160;            VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater());</div><div class="line"><a name="l05131"></a><span class="lineno"> 5131</span>&#160;        }</div><div class="line"><a name="l05132"></a><span class="lineno"> 5132</span>&#160;</div><div class="line"><a name="l05133"></a><span class="lineno"> 5133</span>&#160;        VkResult EnsureMapping(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppMappedData);</div><div class="line"><a name="l05134"></a><span class="lineno"> 5134</span>&#160;        <span class="keywordtype">void</span> Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator);</div><div class="line"><a name="l05135"></a><span class="lineno"> 5135</span>&#160;</div><div class="line"><a name="l05136"></a><span class="lineno"> 5136</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l05137"></a><span class="lineno"> 5137</span>&#160;        <span class="comment">// Not null if mapped for defragmentation only, not originally mapped.</span></div><div class="line"><a name="l05138"></a><span class="lineno"> 5138</span>&#160;        <span class="keywordtype">void</span>* m_pMappedDataForDefragmentation;</div><div class="line"><a name="l05139"></a><span class="lineno"> 5139</span>&#160;    };</div><div class="line"><a name="l05140"></a><span class="lineno"> 5140</span>&#160;</div><div class="line"><a name="l05141"></a><span class="lineno"> 5141</span>&#160;    <span class="keyword">struct </span>BlockPointerLess</div><div class="line"><a name="l05142"></a><span class="lineno"> 5142</span>&#160;    {</div><div class="line"><a name="l05143"></a><span class="lineno"> 5143</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> BlockInfo* pLhsBlockInfo, <span class="keyword">const</span> VmaDeviceMemoryBlock* pRhsBlock)<span class="keyword"> const</span></div><div class="line"><a name="l05144"></a><span class="lineno"> 5144</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l05145"></a><span class="lineno"> 5145</span>&#160;            <span class="keywordflow">return</span> pLhsBlockInfo-&gt;m_pBlock &lt; pRhsBlock;</div><div class="line"><a name="l05146"></a><span class="lineno"> 5146</span>&#160;        }</div><div class="line"><a name="l05147"></a><span class="lineno"> 5147</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> BlockInfo* pLhsBlockInfo, <span class="keyword">const</span> BlockInfo* pRhsBlockInfo)<span class="keyword"> const</span></div><div class="line"><a name="l05148"></a><span class="lineno"> 5148</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l05149"></a><span class="lineno"> 5149</span>&#160;            <span class="keywordflow">return</span> pLhsBlockInfo-&gt;m_pBlock &lt; pRhsBlockInfo-&gt;m_pBlock;</div><div class="line"><a name="l05150"></a><span class="lineno"> 5150</span>&#160;        }</div><div class="line"><a name="l05151"></a><span class="lineno"> 5151</span>&#160;    };</div><div class="line"><a name="l05152"></a><span class="lineno"> 5152</span>&#160;</div><div class="line"><a name="l05153"></a><span class="lineno"> 5153</span>&#160;    <span class="comment">// 1. Blocks with some non-movable allocations go first.</span></div><div class="line"><a name="l05154"></a><span class="lineno"> 5154</span>&#160;    <span class="comment">// 2. Blocks with smaller sumFreeSize go first.</span></div><div class="line"><a name="l05155"></a><span class="lineno"> 5155</span>&#160;    <span class="keyword">struct </span>BlockInfoCompareMoveDestination</div><div class="line"><a name="l05156"></a><span class="lineno"> 5156</span>&#160;    {</div><div class="line"><a name="l05157"></a><span class="lineno"> 5157</span>&#160;        <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> BlockInfo* pLhsBlockInfo, <span class="keyword">const</span> BlockInfo* pRhsBlockInfo)<span class="keyword"> const</span></div><div class="line"><a name="l05158"></a><span class="lineno"> 5158</span>&#160;<span class="keyword">        </span>{</div><div class="line"><a name="l05159"></a><span class="lineno"> 5159</span>&#160;            <span class="keywordflow">if</span>(pLhsBlockInfo-&gt;m_HasNonMovableAllocations &amp;&amp; !pRhsBlockInfo-&gt;m_HasNonMovableAllocations)</div><div class="line"><a name="l05160"></a><span class="lineno"> 5160</span>&#160;            {</div><div class="line"><a name="l05161"></a><span class="lineno"> 5161</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05162"></a><span class="lineno"> 5162</span>&#160;            }</div><div class="line"><a name="l05163"></a><span class="lineno"> 5163</span>&#160;            <span class="keywordflow">if</span>(!pLhsBlockInfo-&gt;m_HasNonMovableAllocations &amp;&amp; pRhsBlockInfo-&gt;m_HasNonMovableAllocations)</div><div class="line"><a name="l05164"></a><span class="lineno"> 5164</span>&#160;            {</div><div class="line"><a name="l05165"></a><span class="lineno"> 5165</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05166"></a><span class="lineno"> 5166</span>&#160;            }</div><div class="line"><a name="l05167"></a><span class="lineno"> 5167</span>&#160;            <span class="keywordflow">if</span>(pLhsBlockInfo-&gt;m_pBlock-&gt;m_pMetadata-&gt;GetSumFreeSize() &lt; pRhsBlockInfo-&gt;m_pBlock-&gt;m_pMetadata-&gt;GetSumFreeSize())</div><div class="line"><a name="l05168"></a><span class="lineno"> 5168</span>&#160;            {</div><div class="line"><a name="l05169"></a><span class="lineno"> 5169</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l05170"></a><span class="lineno"> 5170</span>&#160;            }</div><div class="line"><a name="l05171"></a><span class="lineno"> 5171</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l05172"></a><span class="lineno"> 5172</span>&#160;        }</div><div class="line"><a name="l05173"></a><span class="lineno"> 5173</span>&#160;    };</div><div class="line"><a name="l05174"></a><span class="lineno"> 5174</span>&#160;</div><div class="line"><a name="l05175"></a><span class="lineno"> 5175</span>&#160;    <span class="keyword">typedef</span> VmaVector&lt; BlockInfo*, VmaStlAllocator&lt;BlockInfo*&gt; &gt; BlockInfoVector;</div><div class="line"><a name="l05176"></a><span class="lineno"> 5176</span>&#160;    BlockInfoVector m_Blocks;</div><div class="line"><a name="l05177"></a><span class="lineno"> 5177</span>&#160;</div><div class="line"><a name="l05178"></a><span class="lineno"> 5178</span>&#160;    VkResult DefragmentRound(</div><div class="line"><a name="l05179"></a><span class="lineno"> 5179</span>&#160;        VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l05180"></a><span class="lineno"> 5180</span>&#160;        uint32_t maxAllocationsToMove);</div><div class="line"><a name="l05181"></a><span class="lineno"> 5181</span>&#160;</div><div class="line"><a name="l05182"></a><span class="lineno"> 5182</span>&#160;    <span class="keyword">static</span> <span class="keywordtype">bool</span> MoveMakesSense(</div><div class="line"><a name="l05183"></a><span class="lineno"> 5183</span>&#160;        <span class="keywordtype">size_t</span> dstBlockIndex, VkDeviceSize dstOffset,</div><div class="line"><a name="l05184"></a><span class="lineno"> 5184</span>&#160;        <span class="keywordtype">size_t</span> srcBlockIndex, VkDeviceSize srcOffset);</div><div class="line"><a name="l05185"></a><span class="lineno"> 5185</span>&#160;</div><div class="line"><a name="l05186"></a><span class="lineno"> 5186</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l05187"></a><span class="lineno"> 5187</span>&#160;    VmaDefragmentator(</div><div class="line"><a name="l05188"></a><span class="lineno"> 5188</span>&#160;        <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l05189"></a><span class="lineno"> 5189</span>&#160;        VmaBlockVector* pBlockVector,</div><div class="line"><a name="l05190"></a><span class="lineno"> 5190</span>&#160;        uint32_t currentFrameIndex);</div><div class="line"><a name="l05191"></a><span class="lineno"> 5191</span>&#160;</div><div class="line"><a name="l05192"></a><span class="lineno"> 5192</span>&#160;    ~VmaDefragmentator();</div><div class="line"><a name="l05193"></a><span class="lineno"> 5193</span>&#160;</div><div class="line"><a name="l05194"></a><span class="lineno"> 5194</span>&#160;    VkDeviceSize GetBytesMoved()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_BytesMoved; }</div><div class="line"><a name="l05195"></a><span class="lineno"> 5195</span>&#160;    uint32_t GetAllocationsMoved()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_AllocationsMoved; }</div><div class="line"><a name="l05196"></a><span class="lineno"> 5196</span>&#160;</div><div class="line"><a name="l05197"></a><span class="lineno"> 5197</span>&#160;    <span class="keywordtype">void</span> AddAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc, VkBool32* pChanged);</div><div class="line"><a name="l05198"></a><span class="lineno"> 5198</span>&#160;</div><div class="line"><a name="l05199"></a><span class="lineno"> 5199</span>&#160;    VkResult Defragment(</div><div class="line"><a name="l05200"></a><span class="lineno"> 5200</span>&#160;        VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l05201"></a><span class="lineno"> 5201</span>&#160;        uint32_t maxAllocationsToMove);</div><div class="line"><a name="l05202"></a><span class="lineno"> 5202</span>&#160;};</div><div class="line"><a name="l05203"></a><span class="lineno"> 5203</span>&#160;</div><div class="line"><a name="l05204"></a><span class="lineno"> 5204</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l05205"></a><span class="lineno"> 5205</span>&#160;</div><div class="line"><a name="l05206"></a><span class="lineno"> 5206</span>&#160;<span class="keyword">class </span>VmaRecorder</div><div class="line"><a name="l05207"></a><span class="lineno"> 5207</span>&#160;{</div><div class="line"><a name="l05208"></a><span class="lineno"> 5208</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l05209"></a><span class="lineno"> 5209</span>&#160;    VmaRecorder();</div><div class="line"><a name="l05210"></a><span class="lineno"> 5210</span>&#160;    VkResult Init(<span class="keyword">const</span> <a class="code" href="struct_vma_record_settings.html">VmaRecordSettings</a>&amp; settings, <span class="keywordtype">bool</span> useMutex);</div><div class="line"><a name="l05211"></a><span class="lineno"> 5211</span>&#160;    <span class="keywordtype">void</span> WriteConfiguration(</div><div class="line"><a name="l05212"></a><span class="lineno"> 5212</span>&#160;        <span class="keyword">const</span> VkPhysicalDeviceProperties&amp; devProps,</div><div class="line"><a name="l05213"></a><span class="lineno"> 5213</span>&#160;        <span class="keyword">const</span> VkPhysicalDeviceMemoryProperties&amp; memProps,</div><div class="line"><a name="l05214"></a><span class="lineno"> 5214</span>&#160;        <span class="keywordtype">bool</span> dedicatedAllocationExtensionEnabled);</div><div class="line"><a name="l05215"></a><span class="lineno"> 5215</span>&#160;    ~VmaRecorder();</div><div class="line"><a name="l05216"></a><span class="lineno"> 5216</span>&#160;</div><div class="line"><a name="l05217"></a><span class="lineno"> 5217</span>&#160;    <span class="keywordtype">void</span> RecordCreateAllocator(uint32_t frameIndex);</div><div class="line"><a name="l05218"></a><span class="lineno"> 5218</span>&#160;    <span class="keywordtype">void</span> RecordDestroyAllocator(uint32_t frameIndex);</div><div class="line"><a name="l05219"></a><span class="lineno"> 5219</span>&#160;    <span class="keywordtype">void</span> RecordCreatePool(uint32_t frameIndex,</div><div class="line"><a name="l05220"></a><span class="lineno"> 5220</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l05221"></a><span class="lineno"> 5221</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l05222"></a><span class="lineno"> 5222</span>&#160;    <span class="keywordtype">void</span> RecordDestroyPool(uint32_t frameIndex, <a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l05223"></a><span class="lineno"> 5223</span>&#160;    <span class="keywordtype">void</span> RecordAllocateMemory(uint32_t frameIndex,</div><div class="line"><a name="l05224"></a><span class="lineno"> 5224</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l05225"></a><span class="lineno"> 5225</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l05226"></a><span class="lineno"> 5226</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05227"></a><span class="lineno"> 5227</span>&#160;    <span class="keywordtype">void</span> RecordAllocateMemoryForBuffer(uint32_t frameIndex,</div><div class="line"><a name="l05228"></a><span class="lineno"> 5228</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l05229"></a><span class="lineno"> 5229</span>&#160;        <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l05230"></a><span class="lineno"> 5230</span>&#160;        <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l05231"></a><span class="lineno"> 5231</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l05232"></a><span class="lineno"> 5232</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05233"></a><span class="lineno"> 5233</span>&#160;    <span class="keywordtype">void</span> RecordAllocateMemoryForImage(uint32_t frameIndex,</div><div class="line"><a name="l05234"></a><span class="lineno"> 5234</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l05235"></a><span class="lineno"> 5235</span>&#160;        <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l05236"></a><span class="lineno"> 5236</span>&#160;        <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l05237"></a><span class="lineno"> 5237</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l05238"></a><span class="lineno"> 5238</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05239"></a><span class="lineno"> 5239</span>&#160;    <span class="keywordtype">void</span> RecordFreeMemory(uint32_t frameIndex,</div><div class="line"><a name="l05240"></a><span class="lineno"> 5240</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05241"></a><span class="lineno"> 5241</span>&#160;    <span class="keywordtype">void</span> RecordSetAllocationUserData(uint32_t frameIndex,</div><div class="line"><a name="l05242"></a><span class="lineno"> 5242</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l05243"></a><span class="lineno"> 5243</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">void</span>* pUserData);</div><div class="line"><a name="l05244"></a><span class="lineno"> 5244</span>&#160;    <span class="keywordtype">void</span> RecordCreateLostAllocation(uint32_t frameIndex,</div><div class="line"><a name="l05245"></a><span class="lineno"> 5245</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05246"></a><span class="lineno"> 5246</span>&#160;    <span class="keywordtype">void</span> RecordMapMemory(uint32_t frameIndex,</div><div class="line"><a name="l05247"></a><span class="lineno"> 5247</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05248"></a><span class="lineno"> 5248</span>&#160;    <span class="keywordtype">void</span> RecordUnmapMemory(uint32_t frameIndex,</div><div class="line"><a name="l05249"></a><span class="lineno"> 5249</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05250"></a><span class="lineno"> 5250</span>&#160;    <span class="keywordtype">void</span> RecordFlushAllocation(uint32_t frameIndex,</div><div class="line"><a name="l05251"></a><span class="lineno"> 5251</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size);</div><div class="line"><a name="l05252"></a><span class="lineno"> 5252</span>&#160;    <span class="keywordtype">void</span> RecordInvalidateAllocation(uint32_t frameIndex,</div><div class="line"><a name="l05253"></a><span class="lineno"> 5253</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size);</div><div class="line"><a name="l05254"></a><span class="lineno"> 5254</span>&#160;    <span class="keywordtype">void</span> RecordCreateBuffer(uint32_t frameIndex,</div><div class="line"><a name="l05255"></a><span class="lineno"> 5255</span>&#160;        <span class="keyword">const</span> VkBufferCreateInfo&amp; bufCreateInfo,</div><div class="line"><a name="l05256"></a><span class="lineno"> 5256</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; allocCreateInfo,</div><div class="line"><a name="l05257"></a><span class="lineno"> 5257</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05258"></a><span class="lineno"> 5258</span>&#160;    <span class="keywordtype">void</span> RecordCreateImage(uint32_t frameIndex,</div><div class="line"><a name="l05259"></a><span class="lineno"> 5259</span>&#160;        <span class="keyword">const</span> VkImageCreateInfo&amp; imageCreateInfo,</div><div class="line"><a name="l05260"></a><span class="lineno"> 5260</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; allocCreateInfo,</div><div class="line"><a name="l05261"></a><span class="lineno"> 5261</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05262"></a><span class="lineno"> 5262</span>&#160;    <span class="keywordtype">void</span> RecordDestroyBuffer(uint32_t frameIndex,</div><div class="line"><a name="l05263"></a><span class="lineno"> 5263</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05264"></a><span class="lineno"> 5264</span>&#160;    <span class="keywordtype">void</span> RecordDestroyImage(uint32_t frameIndex,</div><div class="line"><a name="l05265"></a><span class="lineno"> 5265</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05266"></a><span class="lineno"> 5266</span>&#160;    <span class="keywordtype">void</span> RecordTouchAllocation(uint32_t frameIndex,</div><div class="line"><a name="l05267"></a><span class="lineno"> 5267</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05268"></a><span class="lineno"> 5268</span>&#160;    <span class="keywordtype">void</span> RecordGetAllocationInfo(uint32_t frameIndex,</div><div class="line"><a name="l05269"></a><span class="lineno"> 5269</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05270"></a><span class="lineno"> 5270</span>&#160;    <span class="keywordtype">void</span> RecordMakePoolAllocationsLost(uint32_t frameIndex,</div><div class="line"><a name="l05271"></a><span class="lineno"> 5271</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l05272"></a><span class="lineno"> 5272</span>&#160;</div><div class="line"><a name="l05273"></a><span class="lineno"> 5273</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l05274"></a><span class="lineno"> 5274</span>&#160;    <span class="keyword">struct </span>CallParams</div><div class="line"><a name="l05275"></a><span class="lineno"> 5275</span>&#160;    {</div><div class="line"><a name="l05276"></a><span class="lineno"> 5276</span>&#160;        uint32_t threadId;</div><div class="line"><a name="l05277"></a><span class="lineno"> 5277</span>&#160;        <span class="keywordtype">double</span> time;</div><div class="line"><a name="l05278"></a><span class="lineno"> 5278</span>&#160;    };</div><div class="line"><a name="l05279"></a><span class="lineno"> 5279</span>&#160;</div><div class="line"><a name="l05280"></a><span class="lineno"> 5280</span>&#160;    <span class="keyword">class </span>UserDataString</div><div class="line"><a name="l05281"></a><span class="lineno"> 5281</span>&#160;    {</div><div class="line"><a name="l05282"></a><span class="lineno"> 5282</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l05283"></a><span class="lineno"> 5283</span>&#160;        UserDataString(<a class="code" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a> allocFlags, <span class="keyword">const</span> <span class="keywordtype">void</span>* pUserData);</div><div class="line"><a name="l05284"></a><span class="lineno"> 5284</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">char</span>* GetString()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Str; }</div><div class="line"><a name="l05285"></a><span class="lineno"> 5285</span>&#160;</div><div class="line"><a name="l05286"></a><span class="lineno"> 5286</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l05287"></a><span class="lineno"> 5287</span>&#160;        <span class="keywordtype">char</span> m_PtrStr[17];</div><div class="line"><a name="l05288"></a><span class="lineno"> 5288</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">char</span>* m_Str;</div><div class="line"><a name="l05289"></a><span class="lineno"> 5289</span>&#160;    };</div><div class="line"><a name="l05290"></a><span class="lineno"> 5290</span>&#160;</div><div class="line"><a name="l05291"></a><span class="lineno"> 5291</span>&#160;    <span class="keywordtype">bool</span> m_UseMutex;</div><div class="line"><a name="l05292"></a><span class="lineno"> 5292</span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">VmaRecordFlags</a> m_Flags;</div><div class="line"><a name="l05293"></a><span class="lineno"> 5293</span>&#160;    FILE* m_File;</div><div class="line"><a name="l05294"></a><span class="lineno"> 5294</span>&#160;    VMA_MUTEX m_FileMutex;</div><div class="line"><a name="l05295"></a><span class="lineno"> 5295</span>&#160;    int64_t m_Freq;</div><div class="line"><a name="l05296"></a><span class="lineno"> 5296</span>&#160;    int64_t m_StartCounter;</div><div class="line"><a name="l05297"></a><span class="lineno"> 5297</span>&#160;</div><div class="line"><a name="l05298"></a><span class="lineno"> 5298</span>&#160;    <span class="keywordtype">void</span> GetBasicParams(CallParams&amp; outParams);</div><div class="line"><a name="l05299"></a><span class="lineno"> 5299</span>&#160;    <span class="keywordtype">void</span> Flush();</div><div class="line"><a name="l05300"></a><span class="lineno"> 5300</span>&#160;};</div><div class="line"><a name="l05301"></a><span class="lineno"> 5301</span>&#160;</div><div class="line"><a name="l05302"></a><span class="lineno"> 5302</span>&#160;<span class="preprocessor">#endif // #if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l05303"></a><span class="lineno"> 5303</span>&#160;</div><div class="line"><a name="l05304"></a><span class="lineno"> 5304</span>&#160;<span class="comment">// Main allocator object.</span></div><div class="line"><a name="l05305"></a><span class="lineno"> 5305</span>&#160;<span class="keyword">struct </span>VmaAllocator_T</div><div class="line"><a name="l05306"></a><span class="lineno"> 5306</span>&#160;{</div><div class="line"><a name="l05307"></a><span class="lineno"> 5307</span>&#160;    VMA_CLASS_NO_COPY(VmaAllocator_T)</div><div class="line"><a name="l05308"></a><span class="lineno"> 5308</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l05309"></a><span class="lineno"> 5309</span>&#160;    <span class="keywordtype">bool</span> m_UseMutex;</div><div class="line"><a name="l05310"></a><span class="lineno"> 5310</span>&#160;    <span class="keywordtype">bool</span> m_UseKhrDedicatedAllocation;</div><div class="line"><a name="l05311"></a><span class="lineno"> 5311</span>&#160;    VkDevice m_hDevice;</div><div class="line"><a name="l05312"></a><span class="lineno"> 5312</span>&#160;    <span class="keywordtype">bool</span> m_AllocationCallbacksSpecified;</div><div class="line"><a name="l05313"></a><span class="lineno"> 5313</span>&#160;    VkAllocationCallbacks m_AllocationCallbacks;</div><div class="line"><a name="l05314"></a><span class="lineno"> 5314</span>&#160;    <a class="code" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a> m_DeviceMemoryCallbacks;</div><div class="line"><a name="l05315"></a><span class="lineno"> 5315</span>&#160;    </div><div class="line"><a name="l05316"></a><span class="lineno"> 5316</span>&#160;    <span class="comment">// Number of bytes free out of limit, or VK_WHOLE_SIZE if not limit for that heap.</span></div><div class="line"><a name="l05317"></a><span class="lineno"> 5317</span>&#160;    VkDeviceSize m_HeapSizeLimit[VK_MAX_MEMORY_HEAPS];</div><div class="line"><a name="l05318"></a><span class="lineno"> 5318</span>&#160;    VMA_MUTEX m_HeapSizeLimitMutex;</div><div class="line"><a name="l05319"></a><span class="lineno"> 5319</span>&#160;</div><div class="line"><a name="l05320"></a><span class="lineno"> 5320</span>&#160;    VkPhysicalDeviceProperties m_PhysicalDeviceProperties;</div><div class="line"><a name="l05321"></a><span class="lineno"> 5321</span>&#160;    VkPhysicalDeviceMemoryProperties m_MemProps;</div><div class="line"><a name="l05322"></a><span class="lineno"> 5322</span>&#160;</div><div class="line"><a name="l05323"></a><span class="lineno"> 5323</span>&#160;    <span class="comment">// Default pools.</span></div><div class="line"><a name="l05324"></a><span class="lineno"> 5324</span>&#160;    VmaBlockVector* m_pBlockVectors[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l05325"></a><span class="lineno"> 5325</span>&#160;</div><div class="line"><a name="l05326"></a><span class="lineno"> 5326</span>&#160;    <span class="comment">// Each vector is sorted by memory (handle value).</span></div><div class="line"><a name="l05327"></a><span class="lineno"> 5327</span>&#160;    <span class="keyword">typedef</span> VmaVector&lt; VmaAllocation, VmaStlAllocator&lt;VmaAllocation&gt; &gt; AllocationVectorType;</div><div class="line"><a name="l05328"></a><span class="lineno"> 5328</span>&#160;    AllocationVectorType* m_pDedicatedAllocations[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l05329"></a><span class="lineno"> 5329</span>&#160;    VMA_MUTEX m_DedicatedAllocationsMutex[VK_MAX_MEMORY_TYPES];</div><div class="line"><a name="l05330"></a><span class="lineno"> 5330</span>&#160;</div><div class="line"><a name="l05331"></a><span class="lineno"> 5331</span>&#160;    VmaAllocator_T(<span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo);</div><div class="line"><a name="l05332"></a><span class="lineno"> 5332</span>&#160;    VkResult Init(<span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo);</div><div class="line"><a name="l05333"></a><span class="lineno"> 5333</span>&#160;    ~VmaAllocator_T();</div><div class="line"><a name="l05334"></a><span class="lineno"> 5334</span>&#160;</div><div class="line"><a name="l05335"></a><span class="lineno"> 5335</span>&#160;    <span class="keyword">const</span> VkAllocationCallbacks* GetAllocationCallbacks()<span class="keyword"> const</span></div><div class="line"><a name="l05336"></a><span class="lineno"> 5336</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05337"></a><span class="lineno"> 5337</span>&#160;        <span class="keywordflow">return</span> m_AllocationCallbacksSpecified ? &amp;m_AllocationCallbacks : 0;</div><div class="line"><a name="l05338"></a><span class="lineno"> 5338</span>&#160;    }</div><div class="line"><a name="l05339"></a><span class="lineno"> 5339</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>&amp; GetVulkanFunctions()<span class="keyword"> const</span></div><div class="line"><a name="l05340"></a><span class="lineno"> 5340</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05341"></a><span class="lineno"> 5341</span>&#160;        <span class="keywordflow">return</span> m_VulkanFunctions;</div><div class="line"><a name="l05342"></a><span class="lineno"> 5342</span>&#160;    }</div><div class="line"><a name="l05343"></a><span class="lineno"> 5343</span>&#160;</div><div class="line"><a name="l05344"></a><span class="lineno"> 5344</span>&#160;    VkDeviceSize GetBufferImageGranularity()<span class="keyword"> const</span></div><div class="line"><a name="l05345"></a><span class="lineno"> 5345</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05346"></a><span class="lineno"> 5346</span>&#160;        <span class="keywordflow">return</span> VMA_MAX(</div><div class="line"><a name="l05347"></a><span class="lineno"> 5347</span>&#160;            static_cast&lt;VkDeviceSize&gt;(VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY),</div><div class="line"><a name="l05348"></a><span class="lineno"> 5348</span>&#160;            m_PhysicalDeviceProperties.limits.bufferImageGranularity);</div><div class="line"><a name="l05349"></a><span class="lineno"> 5349</span>&#160;    }</div><div class="line"><a name="l05350"></a><span class="lineno"> 5350</span>&#160;</div><div class="line"><a name="l05351"></a><span class="lineno"> 5351</span>&#160;    uint32_t GetMemoryHeapCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemProps.memoryHeapCount; }</div><div class="line"><a name="l05352"></a><span class="lineno"> 5352</span>&#160;    uint32_t GetMemoryTypeCount()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_MemProps.memoryTypeCount; }</div><div class="line"><a name="l05353"></a><span class="lineno"> 5353</span>&#160;</div><div class="line"><a name="l05354"></a><span class="lineno"> 5354</span>&#160;    uint32_t MemoryTypeIndexToHeapIndex(uint32_t memTypeIndex)<span class="keyword"> const</span></div><div class="line"><a name="l05355"></a><span class="lineno"> 5355</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05356"></a><span class="lineno"> 5356</span>&#160;        VMA_ASSERT(memTypeIndex &lt; m_MemProps.memoryTypeCount);</div><div class="line"><a name="l05357"></a><span class="lineno"> 5357</span>&#160;        <span class="keywordflow">return</span> m_MemProps.memoryTypes[memTypeIndex].heapIndex;</div><div class="line"><a name="l05358"></a><span class="lineno"> 5358</span>&#160;    }</div><div class="line"><a name="l05359"></a><span class="lineno"> 5359</span>&#160;    <span class="comment">// True when specific memory type is HOST_VISIBLE but not HOST_COHERENT.</span></div><div class="line"><a name="l05360"></a><span class="lineno"> 5360</span>&#160;    <span class="keywordtype">bool</span> IsMemoryTypeNonCoherent(uint32_t memTypeIndex)<span class="keyword"> const</span></div><div class="line"><a name="l05361"></a><span class="lineno"> 5361</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05362"></a><span class="lineno"> 5362</span>&#160;        <span class="keywordflow">return</span> (m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) ==</div><div class="line"><a name="l05363"></a><span class="lineno"> 5363</span>&#160;            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;</div><div class="line"><a name="l05364"></a><span class="lineno"> 5364</span>&#160;    }</div><div class="line"><a name="l05365"></a><span class="lineno"> 5365</span>&#160;    <span class="comment">// Minimum alignment for all allocations in specific memory type.</span></div><div class="line"><a name="l05366"></a><span class="lineno"> 5366</span>&#160;    VkDeviceSize GetMemoryTypeMinAlignment(uint32_t memTypeIndex)<span class="keyword"> const</span></div><div class="line"><a name="l05367"></a><span class="lineno"> 5367</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05368"></a><span class="lineno"> 5368</span>&#160;        <span class="keywordflow">return</span> IsMemoryTypeNonCoherent(memTypeIndex) ?</div><div class="line"><a name="l05369"></a><span class="lineno"> 5369</span>&#160;            VMA_MAX((VkDeviceSize)VMA_DEBUG_ALIGNMENT, m_PhysicalDeviceProperties.limits.nonCoherentAtomSize) :</div><div class="line"><a name="l05370"></a><span class="lineno"> 5370</span>&#160;            (VkDeviceSize)VMA_DEBUG_ALIGNMENT;</div><div class="line"><a name="l05371"></a><span class="lineno"> 5371</span>&#160;    }</div><div class="line"><a name="l05372"></a><span class="lineno"> 5372</span>&#160;</div><div class="line"><a name="l05373"></a><span class="lineno"> 5373</span>&#160;    <span class="keywordtype">bool</span> IsIntegratedGpu()<span class="keyword"> const</span></div><div class="line"><a name="l05374"></a><span class="lineno"> 5374</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l05375"></a><span class="lineno"> 5375</span>&#160;        <span class="keywordflow">return</span> m_PhysicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;</div><div class="line"><a name="l05376"></a><span class="lineno"> 5376</span>&#160;    }</div><div class="line"><a name="l05377"></a><span class="lineno"> 5377</span>&#160;</div><div class="line"><a name="l05378"></a><span class="lineno"> 5378</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l05379"></a><span class="lineno"> 5379</span>&#160;    VmaRecorder* GetRecorder()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_pRecorder; }</div><div class="line"><a name="l05380"></a><span class="lineno"> 5380</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l05381"></a><span class="lineno"> 5381</span>&#160;</div><div class="line"><a name="l05382"></a><span class="lineno"> 5382</span>&#160;    <span class="keywordtype">void</span> GetBufferMemoryRequirements(</div><div class="line"><a name="l05383"></a><span class="lineno"> 5383</span>&#160;        VkBuffer hBuffer,</div><div class="line"><a name="l05384"></a><span class="lineno"> 5384</span>&#160;        VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l05385"></a><span class="lineno"> 5385</span>&#160;        <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l05386"></a><span class="lineno"> 5386</span>&#160;        <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation) <span class="keyword">const</span>;</div><div class="line"><a name="l05387"></a><span class="lineno"> 5387</span>&#160;    <span class="keywordtype">void</span> GetImageMemoryRequirements(</div><div class="line"><a name="l05388"></a><span class="lineno"> 5388</span>&#160;        VkImage hImage,</div><div class="line"><a name="l05389"></a><span class="lineno"> 5389</span>&#160;        VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l05390"></a><span class="lineno"> 5390</span>&#160;        <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l05391"></a><span class="lineno"> 5391</span>&#160;        <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation) <span class="keyword">const</span>;</div><div class="line"><a name="l05392"></a><span class="lineno"> 5392</span>&#160;</div><div class="line"><a name="l05393"></a><span class="lineno"> 5393</span>&#160;    <span class="comment">// Main allocation function.</span></div><div class="line"><a name="l05394"></a><span class="lineno"> 5394</span>&#160;    VkResult AllocateMemory(</div><div class="line"><a name="l05395"></a><span class="lineno"> 5395</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l05396"></a><span class="lineno"> 5396</span>&#160;        <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l05397"></a><span class="lineno"> 5397</span>&#160;        <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l05398"></a><span class="lineno"> 5398</span>&#160;        VkBuffer dedicatedBuffer,</div><div class="line"><a name="l05399"></a><span class="lineno"> 5399</span>&#160;        VkImage dedicatedImage,</div><div class="line"><a name="l05400"></a><span class="lineno"> 5400</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l05401"></a><span class="lineno"> 5401</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l05402"></a><span class="lineno"> 5402</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l05403"></a><span class="lineno"> 5403</span>&#160;</div><div class="line"><a name="l05404"></a><span class="lineno"> 5404</span>&#160;    <span class="comment">// Main deallocation function.</span></div><div class="line"><a name="l05405"></a><span class="lineno"> 5405</span>&#160;    <span class="keywordtype">void</span> FreeMemory(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05406"></a><span class="lineno"> 5406</span>&#160;</div><div class="line"><a name="l05407"></a><span class="lineno"> 5407</span>&#160;    <span class="keywordtype">void</span> CalculateStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats);</div><div class="line"><a name="l05408"></a><span class="lineno"> 5408</span>&#160;</div><div class="line"><a name="l05409"></a><span class="lineno"> 5409</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05410"></a><span class="lineno"> 5410</span>&#160;    <span class="keywordtype">void</span> PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json);</div><div class="line"><a name="l05411"></a><span class="lineno"> 5411</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l05412"></a><span class="lineno"> 5412</span>&#160;</div><div class="line"><a name="l05413"></a><span class="lineno"> 5413</span>&#160;    VkResult Defragment(</div><div class="line"><a name="l05414"></a><span class="lineno"> 5414</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l05415"></a><span class="lineno"> 5415</span>&#160;        <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l05416"></a><span class="lineno"> 5416</span>&#160;        VkBool32* pAllocationsChanged,</div><div class="line"><a name="l05417"></a><span class="lineno"> 5417</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>* pDefragmentationInfo,</div><div class="line"><a name="l05418"></a><span class="lineno"> 5418</span>&#160;        <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats);</div><div class="line"><a name="l05419"></a><span class="lineno"> 5419</span>&#160;</div><div class="line"><a name="l05420"></a><span class="lineno"> 5420</span>&#160;    <span class="keywordtype">void</span> GetAllocationInfo(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo);</div><div class="line"><a name="l05421"></a><span class="lineno"> 5421</span>&#160;    <span class="keywordtype">bool</span> TouchAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l05422"></a><span class="lineno"> 5422</span>&#160;</div><div class="line"><a name="l05423"></a><span class="lineno"> 5423</span>&#160;    VkResult CreatePool(<span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo, <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool);</div><div class="line"><a name="l05424"></a><span class="lineno"> 5424</span>&#160;    <span class="keywordtype">void</span> DestroyPool(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool);</div><div class="line"><a name="l05425"></a><span class="lineno"> 5425</span>&#160;    <span class="keywordtype">void</span> GetPoolStats(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool, <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats);</div><div class="line"><a name="l05426"></a><span class="lineno"> 5426</span>&#160;</div><div class="line"><a name="l05427"></a><span class="lineno"> 5427</span>&#160;    <span class="keywordtype">void</span> SetCurrentFrameIndex(uint32_t frameIndex);</div><div class="line"><a name="l05428"></a><span class="lineno"> 5428</span>&#160;    uint32_t GetCurrentFrameIndex()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_CurrentFrameIndex.load(); }</div><div class="line"><a name="l05429"></a><span class="lineno"> 5429</span>&#160;</div><div class="line"><a name="l05430"></a><span class="lineno"> 5430</span>&#160;    <span class="keywordtype">void</span> MakePoolAllocationsLost(</div><div class="line"><a name="l05431"></a><span class="lineno"> 5431</span>&#160;        <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool,</div><div class="line"><a name="l05432"></a><span class="lineno"> 5432</span>&#160;        <span class="keywordtype">size_t</span>* pLostAllocationCount);</div><div class="line"><a name="l05433"></a><span class="lineno"> 5433</span>&#160;    VkResult CheckPoolCorruption(<a class="code" href="struct_vma_pool.html">VmaPool</a> hPool);</div><div class="line"><a name="l05434"></a><span class="lineno"> 5434</span>&#160;    VkResult CheckCorruption(uint32_t memoryTypeBits);</div><div class="line"><a name="l05435"></a><span class="lineno"> 5435</span>&#160;</div><div class="line"><a name="l05436"></a><span class="lineno"> 5436</span>&#160;    <span class="keywordtype">void</span> CreateLostAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l05437"></a><span class="lineno"> 5437</span>&#160;</div><div class="line"><a name="l05438"></a><span class="lineno"> 5438</span>&#160;    VkResult AllocateVulkanMemory(<span class="keyword">const</span> VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory);</div><div class="line"><a name="l05439"></a><span class="lineno"> 5439</span>&#160;    <span class="keywordtype">void</span> FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory);</div><div class="line"><a name="l05440"></a><span class="lineno"> 5440</span>&#160;</div><div class="line"><a name="l05441"></a><span class="lineno"> 5441</span>&#160;    VkResult Map(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <span class="keywordtype">void</span>** ppData);</div><div class="line"><a name="l05442"></a><span class="lineno"> 5442</span>&#160;    <span class="keywordtype">void</span> Unmap(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation);</div><div class="line"><a name="l05443"></a><span class="lineno"> 5443</span>&#160;</div><div class="line"><a name="l05444"></a><span class="lineno"> 5444</span>&#160;    VkResult BindBufferMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkBuffer hBuffer);</div><div class="line"><a name="l05445"></a><span class="lineno"> 5445</span>&#160;    VkResult BindImageMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkImage hImage);</div><div class="line"><a name="l05446"></a><span class="lineno"> 5446</span>&#160;</div><div class="line"><a name="l05447"></a><span class="lineno"> 5447</span>&#160;    <span class="keywordtype">void</span> FlushOrInvalidateAllocation(</div><div class="line"><a name="l05448"></a><span class="lineno"> 5448</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l05449"></a><span class="lineno"> 5449</span>&#160;        VkDeviceSize offset, VkDeviceSize size,</div><div class="line"><a name="l05450"></a><span class="lineno"> 5450</span>&#160;        VMA_CACHE_OPERATION op);</div><div class="line"><a name="l05451"></a><span class="lineno"> 5451</span>&#160;</div><div class="line"><a name="l05452"></a><span class="lineno"> 5452</span>&#160;    <span class="keywordtype">void</span> FillAllocation(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, uint8_t pattern);</div><div class="line"><a name="l05453"></a><span class="lineno"> 5453</span>&#160;</div><div class="line"><a name="l05454"></a><span class="lineno"> 5454</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l05455"></a><span class="lineno"> 5455</span>&#160;    VkDeviceSize m_PreferredLargeHeapBlockSize;</div><div class="line"><a name="l05456"></a><span class="lineno"> 5456</span>&#160;</div><div class="line"><a name="l05457"></a><span class="lineno"> 5457</span>&#160;    VkPhysicalDevice m_PhysicalDevice;</div><div class="line"><a name="l05458"></a><span class="lineno"> 5458</span>&#160;    VMA_ATOMIC_UINT32 m_CurrentFrameIndex;</div><div class="line"><a name="l05459"></a><span class="lineno"> 5459</span>&#160;    </div><div class="line"><a name="l05460"></a><span class="lineno"> 5460</span>&#160;    VMA_MUTEX m_PoolsMutex;</div><div class="line"><a name="l05461"></a><span class="lineno"> 5461</span>&#160;    <span class="comment">// Protected by m_PoolsMutex. Sorted by pointer value.</span></div><div class="line"><a name="l05462"></a><span class="lineno"> 5462</span>&#160;    VmaVector&lt;VmaPool, VmaStlAllocator&lt;VmaPool&gt; &gt; m_Pools;</div><div class="line"><a name="l05463"></a><span class="lineno"> 5463</span>&#160;    uint32_t m_NextPoolId;</div><div class="line"><a name="l05464"></a><span class="lineno"> 5464</span>&#160;</div><div class="line"><a name="l05465"></a><span class="lineno"> 5465</span>&#160;    <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a> m_VulkanFunctions;</div><div class="line"><a name="l05466"></a><span class="lineno"> 5466</span>&#160;</div><div class="line"><a name="l05467"></a><span class="lineno"> 5467</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l05468"></a><span class="lineno"> 5468</span>&#160;    VmaRecorder* m_pRecorder;</div><div class="line"><a name="l05469"></a><span class="lineno"> 5469</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l05470"></a><span class="lineno"> 5470</span>&#160;</div><div class="line"><a name="l05471"></a><span class="lineno"> 5471</span>&#160;    <span class="keywordtype">void</span> ImportVulkanFunctions(<span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>* pVulkanFunctions);</div><div class="line"><a name="l05472"></a><span class="lineno"> 5472</span>&#160;</div><div class="line"><a name="l05473"></a><span class="lineno"> 5473</span>&#160;    VkDeviceSize CalcPreferredBlockSize(uint32_t memTypeIndex);</div><div class="line"><a name="l05474"></a><span class="lineno"> 5474</span>&#160;</div><div class="line"><a name="l05475"></a><span class="lineno"> 5475</span>&#160;    VkResult AllocateMemoryOfType(</div><div class="line"><a name="l05476"></a><span class="lineno"> 5476</span>&#160;        VkDeviceSize size,</div><div class="line"><a name="l05477"></a><span class="lineno"> 5477</span>&#160;        VkDeviceSize alignment,</div><div class="line"><a name="l05478"></a><span class="lineno"> 5478</span>&#160;        <span class="keywordtype">bool</span> dedicatedAllocation,</div><div class="line"><a name="l05479"></a><span class="lineno"> 5479</span>&#160;        VkBuffer dedicatedBuffer,</div><div class="line"><a name="l05480"></a><span class="lineno"> 5480</span>&#160;        VkImage dedicatedImage,</div><div class="line"><a name="l05481"></a><span class="lineno"> 5481</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l05482"></a><span class="lineno"> 5482</span>&#160;        uint32_t memTypeIndex,</div><div class="line"><a name="l05483"></a><span class="lineno"> 5483</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l05484"></a><span class="lineno"> 5484</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l05485"></a><span class="lineno"> 5485</span>&#160;</div><div class="line"><a name="l05486"></a><span class="lineno"> 5486</span>&#160;    <span class="comment">// Allocates and registers new VkDeviceMemory specifically for single allocation.</span></div><div class="line"><a name="l05487"></a><span class="lineno"> 5487</span>&#160;    VkResult AllocateDedicatedMemory(</div><div class="line"><a name="l05488"></a><span class="lineno"> 5488</span>&#160;        VkDeviceSize size,</div><div class="line"><a name="l05489"></a><span class="lineno"> 5489</span>&#160;        VmaSuballocationType suballocType,</div><div class="line"><a name="l05490"></a><span class="lineno"> 5490</span>&#160;        uint32_t memTypeIndex,</div><div class="line"><a name="l05491"></a><span class="lineno"> 5491</span>&#160;        <span class="keywordtype">bool</span> map,</div><div class="line"><a name="l05492"></a><span class="lineno"> 5492</span>&#160;        <span class="keywordtype">bool</span> isUserDataString,</div><div class="line"><a name="l05493"></a><span class="lineno"> 5493</span>&#160;        <span class="keywordtype">void</span>* pUserData,</div><div class="line"><a name="l05494"></a><span class="lineno"> 5494</span>&#160;        VkBuffer dedicatedBuffer,</div><div class="line"><a name="l05495"></a><span class="lineno"> 5495</span>&#160;        VkImage dedicatedImage,</div><div class="line"><a name="l05496"></a><span class="lineno"> 5496</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation);</div><div class="line"><a name="l05497"></a><span class="lineno"> 5497</span>&#160;</div><div class="line"><a name="l05498"></a><span class="lineno"> 5498</span>&#160;    <span class="comment">// Tries to free pMemory as Dedicated Memory. Returns true if found and freed.</span></div><div class="line"><a name="l05499"></a><span class="lineno"> 5499</span>&#160;    <span class="keywordtype">void</span> FreeDedicatedMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation);</div><div class="line"><a name="l05500"></a><span class="lineno"> 5500</span>&#160;};</div><div class="line"><a name="l05501"></a><span class="lineno"> 5501</span>&#160;</div><div class="line"><a name="l05503"></a><span class="lineno"> 5503</span>&#160;<span class="comment">// Memory allocation #2 after VmaAllocator_T definition</span></div><div class="line"><a name="l05504"></a><span class="lineno"> 5504</span>&#160;</div><div class="line"><a name="l05505"></a><span class="lineno"> 5505</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span>* VmaMalloc(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment)</div><div class="line"><a name="l05506"></a><span class="lineno"> 5506</span>&#160;{</div><div class="line"><a name="l05507"></a><span class="lineno"> 5507</span>&#160;    <span class="keywordflow">return</span> VmaMalloc(&amp;hAllocator-&gt;m_AllocationCallbacks, size, alignment);</div><div class="line"><a name="l05508"></a><span class="lineno"> 5508</span>&#160;}</div><div class="line"><a name="l05509"></a><span class="lineno"> 5509</span>&#160;</div><div class="line"><a name="l05510"></a><span class="lineno"> 5510</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaFree(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l05511"></a><span class="lineno"> 5511</span>&#160;{</div><div class="line"><a name="l05512"></a><span class="lineno"> 5512</span>&#160;    VmaFree(&amp;hAllocator-&gt;m_AllocationCallbacks, ptr);</div><div class="line"><a name="l05513"></a><span class="lineno"> 5513</span>&#160;}</div><div class="line"><a name="l05514"></a><span class="lineno"> 5514</span>&#160;</div><div class="line"><a name="l05515"></a><span class="lineno"> 5515</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l05516"></a><span class="lineno"> 5516</span>&#160;<span class="keyword">static</span> T* VmaAllocate(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l05517"></a><span class="lineno"> 5517</span>&#160;{</div><div class="line"><a name="l05518"></a><span class="lineno"> 5518</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(hAllocator, <span class="keyword">sizeof</span>(T), VMA_ALIGN_OF(T));</div><div class="line"><a name="l05519"></a><span class="lineno"> 5519</span>&#160;}</div><div class="line"><a name="l05520"></a><span class="lineno"> 5520</span>&#160;</div><div class="line"><a name="l05521"></a><span class="lineno"> 5521</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l05522"></a><span class="lineno"> 5522</span>&#160;<span class="keyword">static</span> T* VmaAllocateArray(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l05523"></a><span class="lineno"> 5523</span>&#160;{</div><div class="line"><a name="l05524"></a><span class="lineno"> 5524</span>&#160;    <span class="keywordflow">return</span> (T*)VmaMalloc(hAllocator, <span class="keyword">sizeof</span>(T) * count, VMA_ALIGN_OF(T));</div><div class="line"><a name="l05525"></a><span class="lineno"> 5525</span>&#160;}</div><div class="line"><a name="l05526"></a><span class="lineno"> 5526</span>&#160;</div><div class="line"><a name="l05527"></a><span class="lineno"> 5527</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l05528"></a><span class="lineno"> 5528</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, T* ptr)</div><div class="line"><a name="l05529"></a><span class="lineno"> 5529</span>&#160;{</div><div class="line"><a name="l05530"></a><span class="lineno"> 5530</span>&#160;    <span class="keywordflow">if</span>(ptr != VMA_NULL)</div><div class="line"><a name="l05531"></a><span class="lineno"> 5531</span>&#160;    {</div><div class="line"><a name="l05532"></a><span class="lineno"> 5532</span>&#160;        ptr-&gt;~T();</div><div class="line"><a name="l05533"></a><span class="lineno"> 5533</span>&#160;        VmaFree(hAllocator, ptr);</div><div class="line"><a name="l05534"></a><span class="lineno"> 5534</span>&#160;    }</div><div class="line"><a name="l05535"></a><span class="lineno"> 5535</span>&#160;}</div><div class="line"><a name="l05536"></a><span class="lineno"> 5536</span>&#160;</div><div class="line"><a name="l05537"></a><span class="lineno"> 5537</span>&#160;<span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l05538"></a><span class="lineno"> 5538</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> vma_delete_array(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, T* ptr, <span class="keywordtype">size_t</span> count)</div><div class="line"><a name="l05539"></a><span class="lineno"> 5539</span>&#160;{</div><div class="line"><a name="l05540"></a><span class="lineno"> 5540</span>&#160;    <span class="keywordflow">if</span>(ptr != VMA_NULL)</div><div class="line"><a name="l05541"></a><span class="lineno"> 5541</span>&#160;    {</div><div class="line"><a name="l05542"></a><span class="lineno"> 5542</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = count; i--; )</div><div class="line"><a name="l05543"></a><span class="lineno"> 5543</span>&#160;            ptr[i].~T();</div><div class="line"><a name="l05544"></a><span class="lineno"> 5544</span>&#160;        VmaFree(hAllocator, ptr);</div><div class="line"><a name="l05545"></a><span class="lineno"> 5545</span>&#160;    }</div><div class="line"><a name="l05546"></a><span class="lineno"> 5546</span>&#160;}</div><div class="line"><a name="l05547"></a><span class="lineno"> 5547</span>&#160;</div><div class="line"><a name="l05549"></a><span class="lineno"> 5549</span>&#160;<span class="comment">// VmaStringBuilder</span></div><div class="line"><a name="l05550"></a><span class="lineno"> 5550</span>&#160;</div><div class="line"><a name="l05551"></a><span class="lineno"> 5551</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05552"></a><span class="lineno"> 5552</span>&#160;</div><div class="line"><a name="l05553"></a><span class="lineno"> 5553</span>&#160;<span class="keyword">class </span>VmaStringBuilder</div><div class="line"><a name="l05554"></a><span class="lineno"> 5554</span>&#160;{</div><div class="line"><a name="l05555"></a><span class="lineno"> 5555</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l05556"></a><span class="lineno"> 5556</span>&#160;    VmaStringBuilder(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> alloc) : m_Data(VmaStlAllocator&lt;char&gt;(alloc-&gt;GetAllocationCallbacks())) { }</div><div class="line"><a name="l05557"></a><span class="lineno"> 5557</span>&#160;    <span class="keywordtype">size_t</span> GetLength()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Data.size(); }</div><div class="line"><a name="l05558"></a><span class="lineno"> 5558</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">char</span>* GetData()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_Data.data(); }</div><div class="line"><a name="l05559"></a><span class="lineno"> 5559</span>&#160;</div><div class="line"><a name="l05560"></a><span class="lineno"> 5560</span>&#160;    <span class="keywordtype">void</span> Add(<span class="keywordtype">char</span> ch) { m_Data.push_back(ch); }</div><div class="line"><a name="l05561"></a><span class="lineno"> 5561</span>&#160;    <span class="keywordtype">void</span> Add(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr);</div><div class="line"><a name="l05562"></a><span class="lineno"> 5562</span>&#160;    <span class="keywordtype">void</span> AddNewLine() { Add(<span class="charliteral">&#39;\n&#39;</span>); }</div><div class="line"><a name="l05563"></a><span class="lineno"> 5563</span>&#160;    <span class="keywordtype">void</span> AddNumber(uint32_t num);</div><div class="line"><a name="l05564"></a><span class="lineno"> 5564</span>&#160;    <span class="keywordtype">void</span> AddNumber(uint64_t num);</div><div class="line"><a name="l05565"></a><span class="lineno"> 5565</span>&#160;    <span class="keywordtype">void</span> AddPointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr);</div><div class="line"><a name="l05566"></a><span class="lineno"> 5566</span>&#160;</div><div class="line"><a name="l05567"></a><span class="lineno"> 5567</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l05568"></a><span class="lineno"> 5568</span>&#160;    VmaVector&lt; char, VmaStlAllocator&lt;char&gt; &gt; m_Data;</div><div class="line"><a name="l05569"></a><span class="lineno"> 5569</span>&#160;};</div><div class="line"><a name="l05570"></a><span class="lineno"> 5570</span>&#160;</div><div class="line"><a name="l05571"></a><span class="lineno"> 5571</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::Add(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l05572"></a><span class="lineno"> 5572</span>&#160;{</div><div class="line"><a name="l05573"></a><span class="lineno"> 5573</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> strLen = strlen(pStr);</div><div class="line"><a name="l05574"></a><span class="lineno"> 5574</span>&#160;    <span class="keywordflow">if</span>(strLen &gt; 0)</div><div class="line"><a name="l05575"></a><span class="lineno"> 5575</span>&#160;    {</div><div class="line"><a name="l05576"></a><span class="lineno"> 5576</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldCount = m_Data.size();</div><div class="line"><a name="l05577"></a><span class="lineno"> 5577</span>&#160;        m_Data.resize(oldCount + strLen);</div><div class="line"><a name="l05578"></a><span class="lineno"> 5578</span>&#160;        memcpy(m_Data.data() + oldCount, pStr, strLen);</div><div class="line"><a name="l05579"></a><span class="lineno"> 5579</span>&#160;    }</div><div class="line"><a name="l05580"></a><span class="lineno"> 5580</span>&#160;}</div><div class="line"><a name="l05581"></a><span class="lineno"> 5581</span>&#160;</div><div class="line"><a name="l05582"></a><span class="lineno"> 5582</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::AddNumber(uint32_t num)</div><div class="line"><a name="l05583"></a><span class="lineno"> 5583</span>&#160;{</div><div class="line"><a name="l05584"></a><span class="lineno"> 5584</span>&#160;    <span class="keywordtype">char</span> buf[11];</div><div class="line"><a name="l05585"></a><span class="lineno"> 5585</span>&#160;    VmaUint32ToStr(buf, <span class="keyword">sizeof</span>(buf), num);</div><div class="line"><a name="l05586"></a><span class="lineno"> 5586</span>&#160;    Add(buf);</div><div class="line"><a name="l05587"></a><span class="lineno"> 5587</span>&#160;}</div><div class="line"><a name="l05588"></a><span class="lineno"> 5588</span>&#160;</div><div class="line"><a name="l05589"></a><span class="lineno"> 5589</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::AddNumber(uint64_t num)</div><div class="line"><a name="l05590"></a><span class="lineno"> 5590</span>&#160;{</div><div class="line"><a name="l05591"></a><span class="lineno"> 5591</span>&#160;    <span class="keywordtype">char</span> buf[21];</div><div class="line"><a name="l05592"></a><span class="lineno"> 5592</span>&#160;    VmaUint64ToStr(buf, <span class="keyword">sizeof</span>(buf), num);</div><div class="line"><a name="l05593"></a><span class="lineno"> 5593</span>&#160;    Add(buf);</div><div class="line"><a name="l05594"></a><span class="lineno"> 5594</span>&#160;}</div><div class="line"><a name="l05595"></a><span class="lineno"> 5595</span>&#160;</div><div class="line"><a name="l05596"></a><span class="lineno"> 5596</span>&#160;<span class="keywordtype">void</span> VmaStringBuilder::AddPointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l05597"></a><span class="lineno"> 5597</span>&#160;{</div><div class="line"><a name="l05598"></a><span class="lineno"> 5598</span>&#160;    <span class="keywordtype">char</span> buf[21];</div><div class="line"><a name="l05599"></a><span class="lineno"> 5599</span>&#160;    VmaPtrToStr(buf, <span class="keyword">sizeof</span>(buf), ptr);</div><div class="line"><a name="l05600"></a><span class="lineno"> 5600</span>&#160;    Add(buf);</div><div class="line"><a name="l05601"></a><span class="lineno"> 5601</span>&#160;}</div><div class="line"><a name="l05602"></a><span class="lineno"> 5602</span>&#160;</div><div class="line"><a name="l05603"></a><span class="lineno"> 5603</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05604"></a><span class="lineno"> 5604</span>&#160;</div><div class="line"><a name="l05606"></a><span class="lineno"> 5606</span>&#160;<span class="comment">// VmaJsonWriter</span></div><div class="line"><a name="l05607"></a><span class="lineno"> 5607</span>&#160;</div><div class="line"><a name="l05608"></a><span class="lineno"> 5608</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05609"></a><span class="lineno"> 5609</span>&#160;</div><div class="line"><a name="l05610"></a><span class="lineno"> 5610</span>&#160;<span class="keyword">class </span>VmaJsonWriter</div><div class="line"><a name="l05611"></a><span class="lineno"> 5611</span>&#160;{</div><div class="line"><a name="l05612"></a><span class="lineno"> 5612</span>&#160;    VMA_CLASS_NO_COPY(VmaJsonWriter)</div><div class="line"><a name="l05613"></a><span class="lineno"> 5613</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l05614"></a><span class="lineno"> 5614</span>&#160;    VmaJsonWriter(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder&amp; sb);</div><div class="line"><a name="l05615"></a><span class="lineno"> 5615</span>&#160;    ~VmaJsonWriter();</div><div class="line"><a name="l05616"></a><span class="lineno"> 5616</span>&#160;</div><div class="line"><a name="l05617"></a><span class="lineno"> 5617</span>&#160;    <span class="keywordtype">void</span> BeginObject(<span class="keywordtype">bool</span> singleLine = <span class="keyword">false</span>);</div><div class="line"><a name="l05618"></a><span class="lineno"> 5618</span>&#160;    <span class="keywordtype">void</span> EndObject();</div><div class="line"><a name="l05619"></a><span class="lineno"> 5619</span>&#160;    </div><div class="line"><a name="l05620"></a><span class="lineno"> 5620</span>&#160;    <span class="keywordtype">void</span> BeginArray(<span class="keywordtype">bool</span> singleLine = <span class="keyword">false</span>);</div><div class="line"><a name="l05621"></a><span class="lineno"> 5621</span>&#160;    <span class="keywordtype">void</span> EndArray();</div><div class="line"><a name="l05622"></a><span class="lineno"> 5622</span>&#160;    </div><div class="line"><a name="l05623"></a><span class="lineno"> 5623</span>&#160;    <span class="keywordtype">void</span> WriteString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr);</div><div class="line"><a name="l05624"></a><span class="lineno"> 5624</span>&#160;    <span class="keywordtype">void</span> BeginString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr = VMA_NULL);</div><div class="line"><a name="l05625"></a><span class="lineno"> 5625</span>&#160;    <span class="keywordtype">void</span> ContinueString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr);</div><div class="line"><a name="l05626"></a><span class="lineno"> 5626</span>&#160;    <span class="keywordtype">void</span> ContinueString(uint32_t n);</div><div class="line"><a name="l05627"></a><span class="lineno"> 5627</span>&#160;    <span class="keywordtype">void</span> ContinueString(uint64_t n);</div><div class="line"><a name="l05628"></a><span class="lineno"> 5628</span>&#160;    <span class="keywordtype">void</span> ContinueString_Pointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr);</div><div class="line"><a name="l05629"></a><span class="lineno"> 5629</span>&#160;    <span class="keywordtype">void</span> EndString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr = VMA_NULL);</div><div class="line"><a name="l05630"></a><span class="lineno"> 5630</span>&#160;    </div><div class="line"><a name="l05631"></a><span class="lineno"> 5631</span>&#160;    <span class="keywordtype">void</span> WriteNumber(uint32_t n);</div><div class="line"><a name="l05632"></a><span class="lineno"> 5632</span>&#160;    <span class="keywordtype">void</span> WriteNumber(uint64_t n);</div><div class="line"><a name="l05633"></a><span class="lineno"> 5633</span>&#160;    <span class="keywordtype">void</span> WriteBool(<span class="keywordtype">bool</span> b);</div><div class="line"><a name="l05634"></a><span class="lineno"> 5634</span>&#160;    <span class="keywordtype">void</span> WriteNull();</div><div class="line"><a name="l05635"></a><span class="lineno"> 5635</span>&#160;</div><div class="line"><a name="l05636"></a><span class="lineno"> 5636</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l05637"></a><span class="lineno"> 5637</span>&#160;    <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span>* <span class="keyword">const</span> INDENT;</div><div class="line"><a name="l05638"></a><span class="lineno"> 5638</span>&#160;</div><div class="line"><a name="l05639"></a><span class="lineno"> 5639</span>&#160;    <span class="keyword">enum</span> COLLECTION_TYPE</div><div class="line"><a name="l05640"></a><span class="lineno"> 5640</span>&#160;    {</div><div class="line"><a name="l05641"></a><span class="lineno"> 5641</span>&#160;        COLLECTION_TYPE_OBJECT,</div><div class="line"><a name="l05642"></a><span class="lineno"> 5642</span>&#160;        COLLECTION_TYPE_ARRAY,</div><div class="line"><a name="l05643"></a><span class="lineno"> 5643</span>&#160;    };</div><div class="line"><a name="l05644"></a><span class="lineno"> 5644</span>&#160;    <span class="keyword">struct </span>StackItem</div><div class="line"><a name="l05645"></a><span class="lineno"> 5645</span>&#160;    {</div><div class="line"><a name="l05646"></a><span class="lineno"> 5646</span>&#160;        COLLECTION_TYPE type;</div><div class="line"><a name="l05647"></a><span class="lineno"> 5647</span>&#160;        uint32_t valueCount;</div><div class="line"><a name="l05648"></a><span class="lineno"> 5648</span>&#160;        <span class="keywordtype">bool</span> singleLineMode;</div><div class="line"><a name="l05649"></a><span class="lineno"> 5649</span>&#160;    };</div><div class="line"><a name="l05650"></a><span class="lineno"> 5650</span>&#160;</div><div class="line"><a name="l05651"></a><span class="lineno"> 5651</span>&#160;    VmaStringBuilder&amp; m_SB;</div><div class="line"><a name="l05652"></a><span class="lineno"> 5652</span>&#160;    VmaVector&lt; StackItem, VmaStlAllocator&lt;StackItem&gt; &gt; m_Stack;</div><div class="line"><a name="l05653"></a><span class="lineno"> 5653</span>&#160;    <span class="keywordtype">bool</span> m_InsideString;</div><div class="line"><a name="l05654"></a><span class="lineno"> 5654</span>&#160;</div><div class="line"><a name="l05655"></a><span class="lineno"> 5655</span>&#160;    <span class="keywordtype">void</span> BeginValue(<span class="keywordtype">bool</span> isString);</div><div class="line"><a name="l05656"></a><span class="lineno"> 5656</span>&#160;    <span class="keywordtype">void</span> WriteIndent(<span class="keywordtype">bool</span> oneLess = <span class="keyword">false</span>);</div><div class="line"><a name="l05657"></a><span class="lineno"> 5657</span>&#160;};</div><div class="line"><a name="l05658"></a><span class="lineno"> 5658</span>&#160;</div><div class="line"><a name="l05659"></a><span class="lineno"> 5659</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span>* <span class="keyword">const</span> VmaJsonWriter::INDENT = <span class="stringliteral">&quot;  &quot;</span>;</div><div class="line"><a name="l05660"></a><span class="lineno"> 5660</span>&#160;</div><div class="line"><a name="l05661"></a><span class="lineno"> 5661</span>&#160;VmaJsonWriter::VmaJsonWriter(<span class="keyword">const</span> VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder&amp; sb) :</div><div class="line"><a name="l05662"></a><span class="lineno"> 5662</span>&#160;    m_SB(sb),</div><div class="line"><a name="l05663"></a><span class="lineno"> 5663</span>&#160;    m_Stack(VmaStlAllocator&lt;StackItem&gt;(pAllocationCallbacks)),</div><div class="line"><a name="l05664"></a><span class="lineno"> 5664</span>&#160;    m_InsideString(false)</div><div class="line"><a name="l05665"></a><span class="lineno"> 5665</span>&#160;{</div><div class="line"><a name="l05666"></a><span class="lineno"> 5666</span>&#160;}</div><div class="line"><a name="l05667"></a><span class="lineno"> 5667</span>&#160;</div><div class="line"><a name="l05668"></a><span class="lineno"> 5668</span>&#160;VmaJsonWriter::~VmaJsonWriter()</div><div class="line"><a name="l05669"></a><span class="lineno"> 5669</span>&#160;{</div><div class="line"><a name="l05670"></a><span class="lineno"> 5670</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05671"></a><span class="lineno"> 5671</span>&#160;    VMA_ASSERT(m_Stack.empty());</div><div class="line"><a name="l05672"></a><span class="lineno"> 5672</span>&#160;}</div><div class="line"><a name="l05673"></a><span class="lineno"> 5673</span>&#160;</div><div class="line"><a name="l05674"></a><span class="lineno"> 5674</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginObject(<span class="keywordtype">bool</span> singleLine)</div><div class="line"><a name="l05675"></a><span class="lineno"> 5675</span>&#160;{</div><div class="line"><a name="l05676"></a><span class="lineno"> 5676</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05677"></a><span class="lineno"> 5677</span>&#160;</div><div class="line"><a name="l05678"></a><span class="lineno"> 5678</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l05679"></a><span class="lineno"> 5679</span>&#160;    m_SB.Add(<span class="charliteral">&#39;{&#39;</span>);</div><div class="line"><a name="l05680"></a><span class="lineno"> 5680</span>&#160;</div><div class="line"><a name="l05681"></a><span class="lineno"> 5681</span>&#160;    StackItem item;</div><div class="line"><a name="l05682"></a><span class="lineno"> 5682</span>&#160;    item.type = COLLECTION_TYPE_OBJECT;</div><div class="line"><a name="l05683"></a><span class="lineno"> 5683</span>&#160;    item.valueCount = 0;</div><div class="line"><a name="l05684"></a><span class="lineno"> 5684</span>&#160;    item.singleLineMode = singleLine;</div><div class="line"><a name="l05685"></a><span class="lineno"> 5685</span>&#160;    m_Stack.push_back(item);</div><div class="line"><a name="l05686"></a><span class="lineno"> 5686</span>&#160;}</div><div class="line"><a name="l05687"></a><span class="lineno"> 5687</span>&#160;</div><div class="line"><a name="l05688"></a><span class="lineno"> 5688</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::EndObject()</div><div class="line"><a name="l05689"></a><span class="lineno"> 5689</span>&#160;{</div><div class="line"><a name="l05690"></a><span class="lineno"> 5690</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05691"></a><span class="lineno"> 5691</span>&#160;</div><div class="line"><a name="l05692"></a><span class="lineno"> 5692</span>&#160;    WriteIndent(<span class="keyword">true</span>);</div><div class="line"><a name="l05693"></a><span class="lineno"> 5693</span>&#160;    m_SB.Add(<span class="charliteral">&#39;}&#39;</span>);</div><div class="line"><a name="l05694"></a><span class="lineno"> 5694</span>&#160;</div><div class="line"><a name="l05695"></a><span class="lineno"> 5695</span>&#160;    VMA_ASSERT(!m_Stack.empty() &amp;&amp; m_Stack.back().type == COLLECTION_TYPE_OBJECT);</div><div class="line"><a name="l05696"></a><span class="lineno"> 5696</span>&#160;    m_Stack.pop_back();</div><div class="line"><a name="l05697"></a><span class="lineno"> 5697</span>&#160;}</div><div class="line"><a name="l05698"></a><span class="lineno"> 5698</span>&#160;</div><div class="line"><a name="l05699"></a><span class="lineno"> 5699</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginArray(<span class="keywordtype">bool</span> singleLine)</div><div class="line"><a name="l05700"></a><span class="lineno"> 5700</span>&#160;{</div><div class="line"><a name="l05701"></a><span class="lineno"> 5701</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05702"></a><span class="lineno"> 5702</span>&#160;</div><div class="line"><a name="l05703"></a><span class="lineno"> 5703</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l05704"></a><span class="lineno"> 5704</span>&#160;    m_SB.Add(<span class="charliteral">&#39;[&#39;</span>);</div><div class="line"><a name="l05705"></a><span class="lineno"> 5705</span>&#160;</div><div class="line"><a name="l05706"></a><span class="lineno"> 5706</span>&#160;    StackItem item;</div><div class="line"><a name="l05707"></a><span class="lineno"> 5707</span>&#160;    item.type = COLLECTION_TYPE_ARRAY;</div><div class="line"><a name="l05708"></a><span class="lineno"> 5708</span>&#160;    item.valueCount = 0;</div><div class="line"><a name="l05709"></a><span class="lineno"> 5709</span>&#160;    item.singleLineMode = singleLine;</div><div class="line"><a name="l05710"></a><span class="lineno"> 5710</span>&#160;    m_Stack.push_back(item);</div><div class="line"><a name="l05711"></a><span class="lineno"> 5711</span>&#160;}</div><div class="line"><a name="l05712"></a><span class="lineno"> 5712</span>&#160;</div><div class="line"><a name="l05713"></a><span class="lineno"> 5713</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::EndArray()</div><div class="line"><a name="l05714"></a><span class="lineno"> 5714</span>&#160;{</div><div class="line"><a name="l05715"></a><span class="lineno"> 5715</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05716"></a><span class="lineno"> 5716</span>&#160;</div><div class="line"><a name="l05717"></a><span class="lineno"> 5717</span>&#160;    WriteIndent(<span class="keyword">true</span>);</div><div class="line"><a name="l05718"></a><span class="lineno"> 5718</span>&#160;    m_SB.Add(<span class="charliteral">&#39;]&#39;</span>);</div><div class="line"><a name="l05719"></a><span class="lineno"> 5719</span>&#160;</div><div class="line"><a name="l05720"></a><span class="lineno"> 5720</span>&#160;    VMA_ASSERT(!m_Stack.empty() &amp;&amp; m_Stack.back().type == COLLECTION_TYPE_ARRAY);</div><div class="line"><a name="l05721"></a><span class="lineno"> 5721</span>&#160;    m_Stack.pop_back();</div><div class="line"><a name="l05722"></a><span class="lineno"> 5722</span>&#160;}</div><div class="line"><a name="l05723"></a><span class="lineno"> 5723</span>&#160;</div><div class="line"><a name="l05724"></a><span class="lineno"> 5724</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l05725"></a><span class="lineno"> 5725</span>&#160;{</div><div class="line"><a name="l05726"></a><span class="lineno"> 5726</span>&#160;    BeginString(pStr);</div><div class="line"><a name="l05727"></a><span class="lineno"> 5727</span>&#160;    EndString();</div><div class="line"><a name="l05728"></a><span class="lineno"> 5728</span>&#160;}</div><div class="line"><a name="l05729"></a><span class="lineno"> 5729</span>&#160;</div><div class="line"><a name="l05730"></a><span class="lineno"> 5730</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l05731"></a><span class="lineno"> 5731</span>&#160;{</div><div class="line"><a name="l05732"></a><span class="lineno"> 5732</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05733"></a><span class="lineno"> 5733</span>&#160;</div><div class="line"><a name="l05734"></a><span class="lineno"> 5734</span>&#160;    BeginValue(<span class="keyword">true</span>);</div><div class="line"><a name="l05735"></a><span class="lineno"> 5735</span>&#160;    m_SB.Add(<span class="charliteral">&#39;&quot;&#39;</span>);</div><div class="line"><a name="l05736"></a><span class="lineno"> 5736</span>&#160;    m_InsideString = <span class="keyword">true</span>;</div><div class="line"><a name="l05737"></a><span class="lineno"> 5737</span>&#160;    <span class="keywordflow">if</span>(pStr != VMA_NULL &amp;&amp; pStr[0] != <span class="charliteral">&#39;\0&#39;</span>)</div><div class="line"><a name="l05738"></a><span class="lineno"> 5738</span>&#160;    {</div><div class="line"><a name="l05739"></a><span class="lineno"> 5739</span>&#160;        ContinueString(pStr);</div><div class="line"><a name="l05740"></a><span class="lineno"> 5740</span>&#160;    }</div><div class="line"><a name="l05741"></a><span class="lineno"> 5741</span>&#160;}</div><div class="line"><a name="l05742"></a><span class="lineno"> 5742</span>&#160;</div><div class="line"><a name="l05743"></a><span class="lineno"> 5743</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l05744"></a><span class="lineno"> 5744</span>&#160;{</div><div class="line"><a name="l05745"></a><span class="lineno"> 5745</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l05746"></a><span class="lineno"> 5746</span>&#160;</div><div class="line"><a name="l05747"></a><span class="lineno"> 5747</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> strLen = strlen(pStr);</div><div class="line"><a name="l05748"></a><span class="lineno"> 5748</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; strLen; ++i)</div><div class="line"><a name="l05749"></a><span class="lineno"> 5749</span>&#160;    {</div><div class="line"><a name="l05750"></a><span class="lineno"> 5750</span>&#160;        <span class="keywordtype">char</span> ch = pStr[i];</div><div class="line"><a name="l05751"></a><span class="lineno"> 5751</span>&#160;        <span class="keywordflow">if</span>(ch == <span class="charliteral">&#39;\\&#39;</span>)</div><div class="line"><a name="l05752"></a><span class="lineno"> 5752</span>&#160;        {</div><div class="line"><a name="l05753"></a><span class="lineno"> 5753</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\\\&quot;</span>);</div><div class="line"><a name="l05754"></a><span class="lineno"> 5754</span>&#160;        }</div><div class="line"><a name="l05755"></a><span class="lineno"> 5755</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(ch == <span class="charliteral">&#39;&quot;&#39;</span>)</div><div class="line"><a name="l05756"></a><span class="lineno"> 5756</span>&#160;        {</div><div class="line"><a name="l05757"></a><span class="lineno"> 5757</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\\&quot;&quot;</span>);</div><div class="line"><a name="l05758"></a><span class="lineno"> 5758</span>&#160;        }</div><div class="line"><a name="l05759"></a><span class="lineno"> 5759</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(ch &gt;= 32)</div><div class="line"><a name="l05760"></a><span class="lineno"> 5760</span>&#160;        {</div><div class="line"><a name="l05761"></a><span class="lineno"> 5761</span>&#160;            m_SB.Add(ch);</div><div class="line"><a name="l05762"></a><span class="lineno"> 5762</span>&#160;        }</div><div class="line"><a name="l05763"></a><span class="lineno"> 5763</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">switch</span>(ch)</div><div class="line"><a name="l05764"></a><span class="lineno"> 5764</span>&#160;        {</div><div class="line"><a name="l05765"></a><span class="lineno"> 5765</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\b&#39;</span>:</div><div class="line"><a name="l05766"></a><span class="lineno"> 5766</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\b&quot;</span>);</div><div class="line"><a name="l05767"></a><span class="lineno"> 5767</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l05768"></a><span class="lineno"> 5768</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\f&#39;</span>:</div><div class="line"><a name="l05769"></a><span class="lineno"> 5769</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\f&quot;</span>);</div><div class="line"><a name="l05770"></a><span class="lineno"> 5770</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l05771"></a><span class="lineno"> 5771</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\n&#39;</span>:</div><div class="line"><a name="l05772"></a><span class="lineno"> 5772</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\n&quot;</span>);</div><div class="line"><a name="l05773"></a><span class="lineno"> 5773</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l05774"></a><span class="lineno"> 5774</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\r&#39;</span>:</div><div class="line"><a name="l05775"></a><span class="lineno"> 5775</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\r&quot;</span>);</div><div class="line"><a name="l05776"></a><span class="lineno"> 5776</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l05777"></a><span class="lineno"> 5777</span>&#160;        <span class="keywordflow">case</span> <span class="charliteral">&#39;\t&#39;</span>:</div><div class="line"><a name="l05778"></a><span class="lineno"> 5778</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;\\t&quot;</span>);</div><div class="line"><a name="l05779"></a><span class="lineno"> 5779</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l05780"></a><span class="lineno"> 5780</span>&#160;        <span class="keywordflow">default</span>:</div><div class="line"><a name="l05781"></a><span class="lineno"> 5781</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Character not currently supported.&quot;</span>);</div><div class="line"><a name="l05782"></a><span class="lineno"> 5782</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l05783"></a><span class="lineno"> 5783</span>&#160;        }</div><div class="line"><a name="l05784"></a><span class="lineno"> 5784</span>&#160;    }</div><div class="line"><a name="l05785"></a><span class="lineno"> 5785</span>&#160;}</div><div class="line"><a name="l05786"></a><span class="lineno"> 5786</span>&#160;</div><div class="line"><a name="l05787"></a><span class="lineno"> 5787</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString(uint32_t n)</div><div class="line"><a name="l05788"></a><span class="lineno"> 5788</span>&#160;{</div><div class="line"><a name="l05789"></a><span class="lineno"> 5789</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l05790"></a><span class="lineno"> 5790</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l05791"></a><span class="lineno"> 5791</span>&#160;}</div><div class="line"><a name="l05792"></a><span class="lineno"> 5792</span>&#160;</div><div class="line"><a name="l05793"></a><span class="lineno"> 5793</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString(uint64_t n)</div><div class="line"><a name="l05794"></a><span class="lineno"> 5794</span>&#160;{</div><div class="line"><a name="l05795"></a><span class="lineno"> 5795</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l05796"></a><span class="lineno"> 5796</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l05797"></a><span class="lineno"> 5797</span>&#160;}</div><div class="line"><a name="l05798"></a><span class="lineno"> 5798</span>&#160;</div><div class="line"><a name="l05799"></a><span class="lineno"> 5799</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::ContinueString_Pointer(<span class="keyword">const</span> <span class="keywordtype">void</span>* ptr)</div><div class="line"><a name="l05800"></a><span class="lineno"> 5800</span>&#160;{</div><div class="line"><a name="l05801"></a><span class="lineno"> 5801</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l05802"></a><span class="lineno"> 5802</span>&#160;    m_SB.AddPointer(ptr);</div><div class="line"><a name="l05803"></a><span class="lineno"> 5803</span>&#160;}</div><div class="line"><a name="l05804"></a><span class="lineno"> 5804</span>&#160;</div><div class="line"><a name="l05805"></a><span class="lineno"> 5805</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::EndString(<span class="keyword">const</span> <span class="keywordtype">char</span>* pStr)</div><div class="line"><a name="l05806"></a><span class="lineno"> 5806</span>&#160;{</div><div class="line"><a name="l05807"></a><span class="lineno"> 5807</span>&#160;    VMA_ASSERT(m_InsideString);</div><div class="line"><a name="l05808"></a><span class="lineno"> 5808</span>&#160;    <span class="keywordflow">if</span>(pStr != VMA_NULL &amp;&amp; pStr[0] != <span class="charliteral">&#39;\0&#39;</span>)</div><div class="line"><a name="l05809"></a><span class="lineno"> 5809</span>&#160;    {</div><div class="line"><a name="l05810"></a><span class="lineno"> 5810</span>&#160;        ContinueString(pStr);</div><div class="line"><a name="l05811"></a><span class="lineno"> 5811</span>&#160;    }</div><div class="line"><a name="l05812"></a><span class="lineno"> 5812</span>&#160;    m_SB.Add(<span class="charliteral">&#39;&quot;&#39;</span>);</div><div class="line"><a name="l05813"></a><span class="lineno"> 5813</span>&#160;    m_InsideString = <span class="keyword">false</span>;</div><div class="line"><a name="l05814"></a><span class="lineno"> 5814</span>&#160;}</div><div class="line"><a name="l05815"></a><span class="lineno"> 5815</span>&#160;</div><div class="line"><a name="l05816"></a><span class="lineno"> 5816</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteNumber(uint32_t n)</div><div class="line"><a name="l05817"></a><span class="lineno"> 5817</span>&#160;{</div><div class="line"><a name="l05818"></a><span class="lineno"> 5818</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05819"></a><span class="lineno"> 5819</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l05820"></a><span class="lineno"> 5820</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l05821"></a><span class="lineno"> 5821</span>&#160;}</div><div class="line"><a name="l05822"></a><span class="lineno"> 5822</span>&#160;</div><div class="line"><a name="l05823"></a><span class="lineno"> 5823</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteNumber(uint64_t n)</div><div class="line"><a name="l05824"></a><span class="lineno"> 5824</span>&#160;{</div><div class="line"><a name="l05825"></a><span class="lineno"> 5825</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05826"></a><span class="lineno"> 5826</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l05827"></a><span class="lineno"> 5827</span>&#160;    m_SB.AddNumber(n);</div><div class="line"><a name="l05828"></a><span class="lineno"> 5828</span>&#160;}</div><div class="line"><a name="l05829"></a><span class="lineno"> 5829</span>&#160;</div><div class="line"><a name="l05830"></a><span class="lineno"> 5830</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteBool(<span class="keywordtype">bool</span> b)</div><div class="line"><a name="l05831"></a><span class="lineno"> 5831</span>&#160;{</div><div class="line"><a name="l05832"></a><span class="lineno"> 5832</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05833"></a><span class="lineno"> 5833</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l05834"></a><span class="lineno"> 5834</span>&#160;    m_SB.Add(b ? <span class="stringliteral">&quot;true&quot;</span> : <span class="stringliteral">&quot;false&quot;</span>);</div><div class="line"><a name="l05835"></a><span class="lineno"> 5835</span>&#160;}</div><div class="line"><a name="l05836"></a><span class="lineno"> 5836</span>&#160;</div><div class="line"><a name="l05837"></a><span class="lineno"> 5837</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteNull()</div><div class="line"><a name="l05838"></a><span class="lineno"> 5838</span>&#160;{</div><div class="line"><a name="l05839"></a><span class="lineno"> 5839</span>&#160;    VMA_ASSERT(!m_InsideString);</div><div class="line"><a name="l05840"></a><span class="lineno"> 5840</span>&#160;    BeginValue(<span class="keyword">false</span>);</div><div class="line"><a name="l05841"></a><span class="lineno"> 5841</span>&#160;    m_SB.Add(<span class="stringliteral">&quot;null&quot;</span>);</div><div class="line"><a name="l05842"></a><span class="lineno"> 5842</span>&#160;}</div><div class="line"><a name="l05843"></a><span class="lineno"> 5843</span>&#160;</div><div class="line"><a name="l05844"></a><span class="lineno"> 5844</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::BeginValue(<span class="keywordtype">bool</span> isString)</div><div class="line"><a name="l05845"></a><span class="lineno"> 5845</span>&#160;{</div><div class="line"><a name="l05846"></a><span class="lineno"> 5846</span>&#160;    <span class="keywordflow">if</span>(!m_Stack.empty())</div><div class="line"><a name="l05847"></a><span class="lineno"> 5847</span>&#160;    {</div><div class="line"><a name="l05848"></a><span class="lineno"> 5848</span>&#160;        StackItem&amp; currItem = m_Stack.back();</div><div class="line"><a name="l05849"></a><span class="lineno"> 5849</span>&#160;        <span class="keywordflow">if</span>(currItem.type == COLLECTION_TYPE_OBJECT &amp;&amp;</div><div class="line"><a name="l05850"></a><span class="lineno"> 5850</span>&#160;            currItem.valueCount % 2 == 0)</div><div class="line"><a name="l05851"></a><span class="lineno"> 5851</span>&#160;        {</div><div class="line"><a name="l05852"></a><span class="lineno"> 5852</span>&#160;            VMA_ASSERT(isString);</div><div class="line"><a name="l05853"></a><span class="lineno"> 5853</span>&#160;        }</div><div class="line"><a name="l05854"></a><span class="lineno"> 5854</span>&#160;</div><div class="line"><a name="l05855"></a><span class="lineno"> 5855</span>&#160;        <span class="keywordflow">if</span>(currItem.type == COLLECTION_TYPE_OBJECT &amp;&amp;</div><div class="line"><a name="l05856"></a><span class="lineno"> 5856</span>&#160;            currItem.valueCount % 2 != 0)</div><div class="line"><a name="l05857"></a><span class="lineno"> 5857</span>&#160;        {</div><div class="line"><a name="l05858"></a><span class="lineno"> 5858</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;: &quot;</span>);</div><div class="line"><a name="l05859"></a><span class="lineno"> 5859</span>&#160;        }</div><div class="line"><a name="l05860"></a><span class="lineno"> 5860</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(currItem.valueCount &gt; 0)</div><div class="line"><a name="l05861"></a><span class="lineno"> 5861</span>&#160;        {</div><div class="line"><a name="l05862"></a><span class="lineno"> 5862</span>&#160;            m_SB.Add(<span class="stringliteral">&quot;, &quot;</span>);</div><div class="line"><a name="l05863"></a><span class="lineno"> 5863</span>&#160;            WriteIndent();</div><div class="line"><a name="l05864"></a><span class="lineno"> 5864</span>&#160;        }</div><div class="line"><a name="l05865"></a><span class="lineno"> 5865</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05866"></a><span class="lineno"> 5866</span>&#160;        {</div><div class="line"><a name="l05867"></a><span class="lineno"> 5867</span>&#160;            WriteIndent();</div><div class="line"><a name="l05868"></a><span class="lineno"> 5868</span>&#160;        }</div><div class="line"><a name="l05869"></a><span class="lineno"> 5869</span>&#160;        ++currItem.valueCount;</div><div class="line"><a name="l05870"></a><span class="lineno"> 5870</span>&#160;    }</div><div class="line"><a name="l05871"></a><span class="lineno"> 5871</span>&#160;}</div><div class="line"><a name="l05872"></a><span class="lineno"> 5872</span>&#160;</div><div class="line"><a name="l05873"></a><span class="lineno"> 5873</span>&#160;<span class="keywordtype">void</span> VmaJsonWriter::WriteIndent(<span class="keywordtype">bool</span> oneLess)</div><div class="line"><a name="l05874"></a><span class="lineno"> 5874</span>&#160;{</div><div class="line"><a name="l05875"></a><span class="lineno"> 5875</span>&#160;    <span class="keywordflow">if</span>(!m_Stack.empty() &amp;&amp; !m_Stack.back().singleLineMode)</div><div class="line"><a name="l05876"></a><span class="lineno"> 5876</span>&#160;    {</div><div class="line"><a name="l05877"></a><span class="lineno"> 5877</span>&#160;        m_SB.AddNewLine();</div><div class="line"><a name="l05878"></a><span class="lineno"> 5878</span>&#160;        </div><div class="line"><a name="l05879"></a><span class="lineno"> 5879</span>&#160;        <span class="keywordtype">size_t</span> count = m_Stack.size();</div><div class="line"><a name="l05880"></a><span class="lineno"> 5880</span>&#160;        <span class="keywordflow">if</span>(count &gt; 0 &amp;&amp; oneLess)</div><div class="line"><a name="l05881"></a><span class="lineno"> 5881</span>&#160;        {</div><div class="line"><a name="l05882"></a><span class="lineno"> 5882</span>&#160;            --count;</div><div class="line"><a name="l05883"></a><span class="lineno"> 5883</span>&#160;        }</div><div class="line"><a name="l05884"></a><span class="lineno"> 5884</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; count; ++i)</div><div class="line"><a name="l05885"></a><span class="lineno"> 5885</span>&#160;        {</div><div class="line"><a name="l05886"></a><span class="lineno"> 5886</span>&#160;            m_SB.Add(INDENT);</div><div class="line"><a name="l05887"></a><span class="lineno"> 5887</span>&#160;        }</div><div class="line"><a name="l05888"></a><span class="lineno"> 5888</span>&#160;    }</div><div class="line"><a name="l05889"></a><span class="lineno"> 5889</span>&#160;}</div><div class="line"><a name="l05890"></a><span class="lineno"> 5890</span>&#160;</div><div class="line"><a name="l05891"></a><span class="lineno"> 5891</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l05892"></a><span class="lineno"> 5892</span>&#160;</div><div class="line"><a name="l05894"></a><span class="lineno"> 5894</span>&#160;</div><div class="line"><a name="l05895"></a><span class="lineno"> 5895</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::SetUserData(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>* pUserData)</div><div class="line"><a name="l05896"></a><span class="lineno"> 5896</span>&#160;{</div><div class="line"><a name="l05897"></a><span class="lineno"> 5897</span>&#160;    <span class="keywordflow">if</span>(IsUserDataString())</div><div class="line"><a name="l05898"></a><span class="lineno"> 5898</span>&#160;    {</div><div class="line"><a name="l05899"></a><span class="lineno"> 5899</span>&#160;        VMA_ASSERT(pUserData == VMA_NULL || pUserData != m_pUserData);</div><div class="line"><a name="l05900"></a><span class="lineno"> 5900</span>&#160;</div><div class="line"><a name="l05901"></a><span class="lineno"> 5901</span>&#160;        FreeUserDataString(hAllocator);</div><div class="line"><a name="l05902"></a><span class="lineno"> 5902</span>&#160;</div><div class="line"><a name="l05903"></a><span class="lineno"> 5903</span>&#160;        <span class="keywordflow">if</span>(pUserData != VMA_NULL)</div><div class="line"><a name="l05904"></a><span class="lineno"> 5904</span>&#160;        {</div><div class="line"><a name="l05905"></a><span class="lineno"> 5905</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">char</span>* <span class="keyword">const</span> newStrSrc = (<span class="keywordtype">char</span>*)pUserData;</div><div class="line"><a name="l05906"></a><span class="lineno"> 5906</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> newStrLen = strlen(newStrSrc);</div><div class="line"><a name="l05907"></a><span class="lineno"> 5907</span>&#160;            <span class="keywordtype">char</span>* <span class="keyword">const</span> newStrDst = vma_new_array(hAllocator, <span class="keywordtype">char</span>, newStrLen + 1);</div><div class="line"><a name="l05908"></a><span class="lineno"> 5908</span>&#160;            memcpy(newStrDst, newStrSrc, newStrLen + 1);</div><div class="line"><a name="l05909"></a><span class="lineno"> 5909</span>&#160;            m_pUserData = newStrDst;</div><div class="line"><a name="l05910"></a><span class="lineno"> 5910</span>&#160;        }</div><div class="line"><a name="l05911"></a><span class="lineno"> 5911</span>&#160;    }</div><div class="line"><a name="l05912"></a><span class="lineno"> 5912</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l05913"></a><span class="lineno"> 5913</span>&#160;    {</div><div class="line"><a name="l05914"></a><span class="lineno"> 5914</span>&#160;        m_pUserData = pUserData;</div><div class="line"><a name="l05915"></a><span class="lineno"> 5915</span>&#160;    }</div><div class="line"><a name="l05916"></a><span class="lineno"> 5916</span>&#160;}</div><div class="line"><a name="l05917"></a><span class="lineno"> 5917</span>&#160;</div><div class="line"><a name="l05918"></a><span class="lineno"> 5918</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::ChangeBlockAllocation(</div><div class="line"><a name="l05919"></a><span class="lineno"> 5919</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l05920"></a><span class="lineno"> 5920</span>&#160;    VmaDeviceMemoryBlock* block,</div><div class="line"><a name="l05921"></a><span class="lineno"> 5921</span>&#160;    VkDeviceSize offset)</div><div class="line"><a name="l05922"></a><span class="lineno"> 5922</span>&#160;{</div><div class="line"><a name="l05923"></a><span class="lineno"> 5923</span>&#160;    VMA_ASSERT(block != VMA_NULL);</div><div class="line"><a name="l05924"></a><span class="lineno"> 5924</span>&#160;    VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l05925"></a><span class="lineno"> 5925</span>&#160;</div><div class="line"><a name="l05926"></a><span class="lineno"> 5926</span>&#160;    <span class="comment">// Move mapping reference counter from old block to new block.</span></div><div class="line"><a name="l05927"></a><span class="lineno"> 5927</span>&#160;    <span class="keywordflow">if</span>(block != m_BlockAllocation.m_Block)</div><div class="line"><a name="l05928"></a><span class="lineno"> 5928</span>&#160;    {</div><div class="line"><a name="l05929"></a><span class="lineno"> 5929</span>&#160;        uint32_t mapRefCount = m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP;</div><div class="line"><a name="l05930"></a><span class="lineno"> 5930</span>&#160;        <span class="keywordflow">if</span>(IsPersistentMap())</div><div class="line"><a name="l05931"></a><span class="lineno"> 5931</span>&#160;            ++mapRefCount;</div><div class="line"><a name="l05932"></a><span class="lineno"> 5932</span>&#160;        m_BlockAllocation.m_Block-&gt;Unmap(hAllocator, mapRefCount);</div><div class="line"><a name="l05933"></a><span class="lineno"> 5933</span>&#160;        block-&gt;Map(hAllocator, mapRefCount, VMA_NULL);</div><div class="line"><a name="l05934"></a><span class="lineno"> 5934</span>&#160;    }</div><div class="line"><a name="l05935"></a><span class="lineno"> 5935</span>&#160;</div><div class="line"><a name="l05936"></a><span class="lineno"> 5936</span>&#160;    m_BlockAllocation.m_Block = block;</div><div class="line"><a name="l05937"></a><span class="lineno"> 5937</span>&#160;    m_BlockAllocation.m_Offset = offset;</div><div class="line"><a name="l05938"></a><span class="lineno"> 5938</span>&#160;}</div><div class="line"><a name="l05939"></a><span class="lineno"> 5939</span>&#160;</div><div class="line"><a name="l05940"></a><span class="lineno"> 5940</span>&#160;VkDeviceSize VmaAllocation_T::GetOffset()<span class="keyword"> const</span></div><div class="line"><a name="l05941"></a><span class="lineno"> 5941</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05942"></a><span class="lineno"> 5942</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l05943"></a><span class="lineno"> 5943</span>&#160;    {</div><div class="line"><a name="l05944"></a><span class="lineno"> 5944</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l05945"></a><span class="lineno"> 5945</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Offset;</div><div class="line"><a name="l05946"></a><span class="lineno"> 5946</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l05947"></a><span class="lineno"> 5947</span>&#160;        <span class="keywordflow">return</span> 0;</div><div class="line"><a name="l05948"></a><span class="lineno"> 5948</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l05949"></a><span class="lineno"> 5949</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l05950"></a><span class="lineno"> 5950</span>&#160;        <span class="keywordflow">return</span> 0;</div><div class="line"><a name="l05951"></a><span class="lineno"> 5951</span>&#160;    }</div><div class="line"><a name="l05952"></a><span class="lineno"> 5952</span>&#160;}</div><div class="line"><a name="l05953"></a><span class="lineno"> 5953</span>&#160;</div><div class="line"><a name="l05954"></a><span class="lineno"> 5954</span>&#160;VkDeviceMemory VmaAllocation_T::GetMemory()<span class="keyword"> const</span></div><div class="line"><a name="l05955"></a><span class="lineno"> 5955</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05956"></a><span class="lineno"> 5956</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l05957"></a><span class="lineno"> 5957</span>&#160;    {</div><div class="line"><a name="l05958"></a><span class="lineno"> 5958</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l05959"></a><span class="lineno"> 5959</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Block-&gt;GetDeviceMemory();</div><div class="line"><a name="l05960"></a><span class="lineno"> 5960</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l05961"></a><span class="lineno"> 5961</span>&#160;        <span class="keywordflow">return</span> m_DedicatedAllocation.m_hMemory;</div><div class="line"><a name="l05962"></a><span class="lineno"> 5962</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l05963"></a><span class="lineno"> 5963</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l05964"></a><span class="lineno"> 5964</span>&#160;        <span class="keywordflow">return</span> VK_NULL_HANDLE;</div><div class="line"><a name="l05965"></a><span class="lineno"> 5965</span>&#160;    }</div><div class="line"><a name="l05966"></a><span class="lineno"> 5966</span>&#160;}</div><div class="line"><a name="l05967"></a><span class="lineno"> 5967</span>&#160;</div><div class="line"><a name="l05968"></a><span class="lineno"> 5968</span>&#160;uint32_t VmaAllocation_T::GetMemoryTypeIndex()<span class="keyword"> const</span></div><div class="line"><a name="l05969"></a><span class="lineno"> 5969</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05970"></a><span class="lineno"> 5970</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l05971"></a><span class="lineno"> 5971</span>&#160;    {</div><div class="line"><a name="l05972"></a><span class="lineno"> 5972</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l05973"></a><span class="lineno"> 5973</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_Block-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l05974"></a><span class="lineno"> 5974</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l05975"></a><span class="lineno"> 5975</span>&#160;        <span class="keywordflow">return</span> m_DedicatedAllocation.m_MemoryTypeIndex;</div><div class="line"><a name="l05976"></a><span class="lineno"> 5976</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l05977"></a><span class="lineno"> 5977</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l05978"></a><span class="lineno"> 5978</span>&#160;        <span class="keywordflow">return</span> UINT32_MAX;</div><div class="line"><a name="l05979"></a><span class="lineno"> 5979</span>&#160;    }</div><div class="line"><a name="l05980"></a><span class="lineno"> 5980</span>&#160;}</div><div class="line"><a name="l05981"></a><span class="lineno"> 5981</span>&#160;</div><div class="line"><a name="l05982"></a><span class="lineno"> 5982</span>&#160;<span class="keywordtype">void</span>* VmaAllocation_T::GetMappedData()<span class="keyword"> const</span></div><div class="line"><a name="l05983"></a><span class="lineno"> 5983</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l05984"></a><span class="lineno"> 5984</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l05985"></a><span class="lineno"> 5985</span>&#160;    {</div><div class="line"><a name="l05986"></a><span class="lineno"> 5986</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l05987"></a><span class="lineno"> 5987</span>&#160;        <span class="keywordflow">if</span>(m_MapCount != 0)</div><div class="line"><a name="l05988"></a><span class="lineno"> 5988</span>&#160;        {</div><div class="line"><a name="l05989"></a><span class="lineno"> 5989</span>&#160;            <span class="keywordtype">void</span>* pBlockData = m_BlockAllocation.m_Block-&gt;GetMappedData();</div><div class="line"><a name="l05990"></a><span class="lineno"> 5990</span>&#160;            VMA_ASSERT(pBlockData != VMA_NULL);</div><div class="line"><a name="l05991"></a><span class="lineno"> 5991</span>&#160;            <span class="keywordflow">return</span> (<span class="keywordtype">char</span>*)pBlockData + m_BlockAllocation.m_Offset;</div><div class="line"><a name="l05992"></a><span class="lineno"> 5992</span>&#160;        }</div><div class="line"><a name="l05993"></a><span class="lineno"> 5993</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l05994"></a><span class="lineno"> 5994</span>&#160;        {</div><div class="line"><a name="l05995"></a><span class="lineno"> 5995</span>&#160;            <span class="keywordflow">return</span> VMA_NULL;</div><div class="line"><a name="l05996"></a><span class="lineno"> 5996</span>&#160;        }</div><div class="line"><a name="l05997"></a><span class="lineno"> 5997</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l05998"></a><span class="lineno"> 5998</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l05999"></a><span class="lineno"> 5999</span>&#160;        VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0));</div><div class="line"><a name="l06000"></a><span class="lineno"> 6000</span>&#160;        <span class="keywordflow">return</span> m_DedicatedAllocation.m_pMappedData;</div><div class="line"><a name="l06001"></a><span class="lineno"> 6001</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l06002"></a><span class="lineno"> 6002</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l06003"></a><span class="lineno"> 6003</span>&#160;        <span class="keywordflow">return</span> VMA_NULL;</div><div class="line"><a name="l06004"></a><span class="lineno"> 6004</span>&#160;    }</div><div class="line"><a name="l06005"></a><span class="lineno"> 6005</span>&#160;}</div><div class="line"><a name="l06006"></a><span class="lineno"> 6006</span>&#160;</div><div class="line"><a name="l06007"></a><span class="lineno"> 6007</span>&#160;<span class="keywordtype">bool</span> VmaAllocation_T::CanBecomeLost()<span class="keyword"> const</span></div><div class="line"><a name="l06008"></a><span class="lineno"> 6008</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06009"></a><span class="lineno"> 6009</span>&#160;    <span class="keywordflow">switch</span>(m_Type)</div><div class="line"><a name="l06010"></a><span class="lineno"> 6010</span>&#160;    {</div><div class="line"><a name="l06011"></a><span class="lineno"> 6011</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l06012"></a><span class="lineno"> 6012</span>&#160;        <span class="keywordflow">return</span> m_BlockAllocation.m_CanBecomeLost;</div><div class="line"><a name="l06013"></a><span class="lineno"> 6013</span>&#160;    <span class="keywordflow">case</span> ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l06014"></a><span class="lineno"> 6014</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06015"></a><span class="lineno"> 6015</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l06016"></a><span class="lineno"> 6016</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l06017"></a><span class="lineno"> 6017</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06018"></a><span class="lineno"> 6018</span>&#160;    }</div><div class="line"><a name="l06019"></a><span class="lineno"> 6019</span>&#160;}</div><div class="line"><a name="l06020"></a><span class="lineno"> 6020</span>&#160;</div><div class="line"><a name="l06021"></a><span class="lineno"> 6021</span>&#160;<a class="code" href="struct_vma_pool.html">VmaPool</a> VmaAllocation_T::GetPool()<span class="keyword"> const</span></div><div class="line"><a name="l06022"></a><span class="lineno"> 6022</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06023"></a><span class="lineno"> 6023</span>&#160;    VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l06024"></a><span class="lineno"> 6024</span>&#160;    <span class="keywordflow">return</span> m_BlockAllocation.m_hPool;</div><div class="line"><a name="l06025"></a><span class="lineno"> 6025</span>&#160;}</div><div class="line"><a name="l06026"></a><span class="lineno"> 6026</span>&#160;</div><div class="line"><a name="l06027"></a><span class="lineno"> 6027</span>&#160;<span class="keywordtype">bool</span> VmaAllocation_T::MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)</div><div class="line"><a name="l06028"></a><span class="lineno"> 6028</span>&#160;{</div><div class="line"><a name="l06029"></a><span class="lineno"> 6029</span>&#160;    VMA_ASSERT(CanBecomeLost());</div><div class="line"><a name="l06030"></a><span class="lineno"> 6030</span>&#160;</div><div class="line"><a name="l06031"></a><span class="lineno"> 6031</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l06032"></a><span class="lineno"> 6032</span>&#160;<span class="comment">    Warning: This is a carefully designed algorithm.</span></div><div class="line"><a name="l06033"></a><span class="lineno"> 6033</span>&#160;<span class="comment">    Do not modify unless you really know what you&#39;re doing :)</span></div><div class="line"><a name="l06034"></a><span class="lineno"> 6034</span>&#160;<span class="comment">    */</span></div><div class="line"><a name="l06035"></a><span class="lineno"> 6035</span>&#160;    uint32_t localLastUseFrameIndex = GetLastUseFrameIndex();</div><div class="line"><a name="l06036"></a><span class="lineno"> 6036</span>&#160;    <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l06037"></a><span class="lineno"> 6037</span>&#160;    {</div><div class="line"><a name="l06038"></a><span class="lineno"> 6038</span>&#160;        <span class="keywordflow">if</span>(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l06039"></a><span class="lineno"> 6039</span>&#160;        {</div><div class="line"><a name="l06040"></a><span class="lineno"> 6040</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l06041"></a><span class="lineno"> 6041</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06042"></a><span class="lineno"> 6042</span>&#160;        }</div><div class="line"><a name="l06043"></a><span class="lineno"> 6043</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(localLastUseFrameIndex + frameInUseCount &gt;= currentFrameIndex)</div><div class="line"><a name="l06044"></a><span class="lineno"> 6044</span>&#160;        {</div><div class="line"><a name="l06045"></a><span class="lineno"> 6045</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06046"></a><span class="lineno"> 6046</span>&#160;        }</div><div class="line"><a name="l06047"></a><span class="lineno"> 6047</span>&#160;        <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l06048"></a><span class="lineno"> 6048</span>&#160;        {</div><div class="line"><a name="l06049"></a><span class="lineno"> 6049</span>&#160;            <span class="keywordflow">if</span>(CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, VMA_FRAME_INDEX_LOST))</div><div class="line"><a name="l06050"></a><span class="lineno"> 6050</span>&#160;            {</div><div class="line"><a name="l06051"></a><span class="lineno"> 6051</span>&#160;                <span class="comment">// Setting hAllocation.LastUseFrameIndex atomic to VMA_FRAME_INDEX_LOST is enough to mark it as LOST.</span></div><div class="line"><a name="l06052"></a><span class="lineno"> 6052</span>&#160;                <span class="comment">// Calling code just needs to unregister this allocation in owning VmaDeviceMemoryBlock.</span></div><div class="line"><a name="l06053"></a><span class="lineno"> 6053</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06054"></a><span class="lineno"> 6054</span>&#160;            }</div><div class="line"><a name="l06055"></a><span class="lineno"> 6055</span>&#160;        }</div><div class="line"><a name="l06056"></a><span class="lineno"> 6056</span>&#160;    }</div><div class="line"><a name="l06057"></a><span class="lineno"> 6057</span>&#160;}</div><div class="line"><a name="l06058"></a><span class="lineno"> 6058</span>&#160;</div><div class="line"><a name="l06059"></a><span class="lineno"> 6059</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06060"></a><span class="lineno"> 6060</span>&#160;</div><div class="line"><a name="l06061"></a><span class="lineno"> 6061</span>&#160;<span class="comment">// Correspond to values of enum VmaSuballocationType.</span></div><div class="line"><a name="l06062"></a><span class="lineno"> 6062</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span>* VMA_SUBALLOCATION_TYPE_NAMES[] = {</div><div class="line"><a name="l06063"></a><span class="lineno"> 6063</span>&#160;    <span class="stringliteral">&quot;FREE&quot;</span>,</div><div class="line"><a name="l06064"></a><span class="lineno"> 6064</span>&#160;    <span class="stringliteral">&quot;UNKNOWN&quot;</span>,</div><div class="line"><a name="l06065"></a><span class="lineno"> 6065</span>&#160;    <span class="stringliteral">&quot;BUFFER&quot;</span>,</div><div class="line"><a name="l06066"></a><span class="lineno"> 6066</span>&#160;    <span class="stringliteral">&quot;IMAGE_UNKNOWN&quot;</span>,</div><div class="line"><a name="l06067"></a><span class="lineno"> 6067</span>&#160;    <span class="stringliteral">&quot;IMAGE_LINEAR&quot;</span>,</div><div class="line"><a name="l06068"></a><span class="lineno"> 6068</span>&#160;    <span class="stringliteral">&quot;IMAGE_OPTIMAL&quot;</span>,</div><div class="line"><a name="l06069"></a><span class="lineno"> 6069</span>&#160;};</div><div class="line"><a name="l06070"></a><span class="lineno"> 6070</span>&#160;</div><div class="line"><a name="l06071"></a><span class="lineno"> 6071</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::PrintParameters(<span class="keyword">class</span> VmaJsonWriter&amp; json)<span class="keyword"> const</span></div><div class="line"><a name="l06072"></a><span class="lineno"> 6072</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06073"></a><span class="lineno"> 6073</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Type&quot;</span>);</div><div class="line"><a name="l06074"></a><span class="lineno"> 6074</span>&#160;    json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[m_SuballocationType]);</div><div class="line"><a name="l06075"></a><span class="lineno"> 6075</span>&#160;</div><div class="line"><a name="l06076"></a><span class="lineno"> 6076</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Size&quot;</span>);</div><div class="line"><a name="l06077"></a><span class="lineno"> 6077</span>&#160;    json.WriteNumber(m_Size);</div><div class="line"><a name="l06078"></a><span class="lineno"> 6078</span>&#160;</div><div class="line"><a name="l06079"></a><span class="lineno"> 6079</span>&#160;    <span class="keywordflow">if</span>(m_pUserData != VMA_NULL)</div><div class="line"><a name="l06080"></a><span class="lineno"> 6080</span>&#160;    {</div><div class="line"><a name="l06081"></a><span class="lineno"> 6081</span>&#160;        json.WriteString(<span class="stringliteral">&quot;UserData&quot;</span>);</div><div class="line"><a name="l06082"></a><span class="lineno"> 6082</span>&#160;        <span class="keywordflow">if</span>(IsUserDataString())</div><div class="line"><a name="l06083"></a><span class="lineno"> 6083</span>&#160;        {</div><div class="line"><a name="l06084"></a><span class="lineno"> 6084</span>&#160;            json.WriteString((<span class="keyword">const</span> <span class="keywordtype">char</span>*)m_pUserData);</div><div class="line"><a name="l06085"></a><span class="lineno"> 6085</span>&#160;        }</div><div class="line"><a name="l06086"></a><span class="lineno"> 6086</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06087"></a><span class="lineno"> 6087</span>&#160;        {</div><div class="line"><a name="l06088"></a><span class="lineno"> 6088</span>&#160;            json.BeginString();</div><div class="line"><a name="l06089"></a><span class="lineno"> 6089</span>&#160;            json.ContinueString_Pointer(m_pUserData);</div><div class="line"><a name="l06090"></a><span class="lineno"> 6090</span>&#160;            json.EndString();</div><div class="line"><a name="l06091"></a><span class="lineno"> 6091</span>&#160;        }</div><div class="line"><a name="l06092"></a><span class="lineno"> 6092</span>&#160;    }</div><div class="line"><a name="l06093"></a><span class="lineno"> 6093</span>&#160;</div><div class="line"><a name="l06094"></a><span class="lineno"> 6094</span>&#160;    json.WriteString(<span class="stringliteral">&quot;CreationFrameIndex&quot;</span>);</div><div class="line"><a name="l06095"></a><span class="lineno"> 6095</span>&#160;    json.WriteNumber(m_CreationFrameIndex);</div><div class="line"><a name="l06096"></a><span class="lineno"> 6096</span>&#160;</div><div class="line"><a name="l06097"></a><span class="lineno"> 6097</span>&#160;    json.WriteString(<span class="stringliteral">&quot;LastUseFrameIndex&quot;</span>);</div><div class="line"><a name="l06098"></a><span class="lineno"> 6098</span>&#160;    json.WriteNumber(GetLastUseFrameIndex());</div><div class="line"><a name="l06099"></a><span class="lineno"> 6099</span>&#160;</div><div class="line"><a name="l06100"></a><span class="lineno"> 6100</span>&#160;    <span class="keywordflow">if</span>(m_BufferImageUsage != 0)</div><div class="line"><a name="l06101"></a><span class="lineno"> 6101</span>&#160;    {</div><div class="line"><a name="l06102"></a><span class="lineno"> 6102</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Usage&quot;</span>);</div><div class="line"><a name="l06103"></a><span class="lineno"> 6103</span>&#160;        json.WriteNumber(m_BufferImageUsage);</div><div class="line"><a name="l06104"></a><span class="lineno"> 6104</span>&#160;    }</div><div class="line"><a name="l06105"></a><span class="lineno"> 6105</span>&#160;}</div><div class="line"><a name="l06106"></a><span class="lineno"> 6106</span>&#160;</div><div class="line"><a name="l06107"></a><span class="lineno"> 6107</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l06108"></a><span class="lineno"> 6108</span>&#160;</div><div class="line"><a name="l06109"></a><span class="lineno"> 6109</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::FreeUserDataString(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l06110"></a><span class="lineno"> 6110</span>&#160;{</div><div class="line"><a name="l06111"></a><span class="lineno"> 6111</span>&#160;    VMA_ASSERT(IsUserDataString());</div><div class="line"><a name="l06112"></a><span class="lineno"> 6112</span>&#160;    <span class="keywordflow">if</span>(m_pUserData != VMA_NULL)</div><div class="line"><a name="l06113"></a><span class="lineno"> 6113</span>&#160;    {</div><div class="line"><a name="l06114"></a><span class="lineno"> 6114</span>&#160;        <span class="keywordtype">char</span>* <span class="keyword">const</span> oldStr = (<span class="keywordtype">char</span>*)m_pUserData;</div><div class="line"><a name="l06115"></a><span class="lineno"> 6115</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldStrLen = strlen(oldStr);</div><div class="line"><a name="l06116"></a><span class="lineno"> 6116</span>&#160;        vma_delete_array(hAllocator, oldStr, oldStrLen + 1);</div><div class="line"><a name="l06117"></a><span class="lineno"> 6117</span>&#160;        m_pUserData = VMA_NULL;</div><div class="line"><a name="l06118"></a><span class="lineno"> 6118</span>&#160;    }</div><div class="line"><a name="l06119"></a><span class="lineno"> 6119</span>&#160;}</div><div class="line"><a name="l06120"></a><span class="lineno"> 6120</span>&#160;</div><div class="line"><a name="l06121"></a><span class="lineno"> 6121</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::BlockAllocMap()</div><div class="line"><a name="l06122"></a><span class="lineno"> 6122</span>&#160;{</div><div class="line"><a name="l06123"></a><span class="lineno"> 6123</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l06124"></a><span class="lineno"> 6124</span>&#160;</div><div class="line"><a name="l06125"></a><span class="lineno"> 6125</span>&#160;    <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) &lt; 0x7F)</div><div class="line"><a name="l06126"></a><span class="lineno"> 6126</span>&#160;    {</div><div class="line"><a name="l06127"></a><span class="lineno"> 6127</span>&#160;        ++m_MapCount;</div><div class="line"><a name="l06128"></a><span class="lineno"> 6128</span>&#160;    }</div><div class="line"><a name="l06129"></a><span class="lineno"> 6129</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06130"></a><span class="lineno"> 6130</span>&#160;    {</div><div class="line"><a name="l06131"></a><span class="lineno"> 6131</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Allocation mapped too many times simultaneously.&quot;</span>);</div><div class="line"><a name="l06132"></a><span class="lineno"> 6132</span>&#160;    }</div><div class="line"><a name="l06133"></a><span class="lineno"> 6133</span>&#160;}</div><div class="line"><a name="l06134"></a><span class="lineno"> 6134</span>&#160;</div><div class="line"><a name="l06135"></a><span class="lineno"> 6135</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::BlockAllocUnmap()</div><div class="line"><a name="l06136"></a><span class="lineno"> 6136</span>&#160;{</div><div class="line"><a name="l06137"></a><span class="lineno"> 6137</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK);</div><div class="line"><a name="l06138"></a><span class="lineno"> 6138</span>&#160;</div><div class="line"><a name="l06139"></a><span class="lineno"> 6139</span>&#160;    <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) != 0)</div><div class="line"><a name="l06140"></a><span class="lineno"> 6140</span>&#160;    {</div><div class="line"><a name="l06141"></a><span class="lineno"> 6141</span>&#160;        --m_MapCount;</div><div class="line"><a name="l06142"></a><span class="lineno"> 6142</span>&#160;    }</div><div class="line"><a name="l06143"></a><span class="lineno"> 6143</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06144"></a><span class="lineno"> 6144</span>&#160;    {</div><div class="line"><a name="l06145"></a><span class="lineno"> 6145</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Unmapping allocation not previously mapped.&quot;</span>);</div><div class="line"><a name="l06146"></a><span class="lineno"> 6146</span>&#160;    }</div><div class="line"><a name="l06147"></a><span class="lineno"> 6147</span>&#160;}</div><div class="line"><a name="l06148"></a><span class="lineno"> 6148</span>&#160;</div><div class="line"><a name="l06149"></a><span class="lineno"> 6149</span>&#160;VkResult VmaAllocation_T::DedicatedAllocMap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l06150"></a><span class="lineno"> 6150</span>&#160;{</div><div class="line"><a name="l06151"></a><span class="lineno"> 6151</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l06152"></a><span class="lineno"> 6152</span>&#160;</div><div class="line"><a name="l06153"></a><span class="lineno"> 6153</span>&#160;    <span class="keywordflow">if</span>(m_MapCount != 0)</div><div class="line"><a name="l06154"></a><span class="lineno"> 6154</span>&#160;    {</div><div class="line"><a name="l06155"></a><span class="lineno"> 6155</span>&#160;        <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) &lt; 0x7F)</div><div class="line"><a name="l06156"></a><span class="lineno"> 6156</span>&#160;        {</div><div class="line"><a name="l06157"></a><span class="lineno"> 6157</span>&#160;            VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL);</div><div class="line"><a name="l06158"></a><span class="lineno"> 6158</span>&#160;            *ppData = m_DedicatedAllocation.m_pMappedData;</div><div class="line"><a name="l06159"></a><span class="lineno"> 6159</span>&#160;            ++m_MapCount;</div><div class="line"><a name="l06160"></a><span class="lineno"> 6160</span>&#160;            <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06161"></a><span class="lineno"> 6161</span>&#160;        }</div><div class="line"><a name="l06162"></a><span class="lineno"> 6162</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06163"></a><span class="lineno"> 6163</span>&#160;        {</div><div class="line"><a name="l06164"></a><span class="lineno"> 6164</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Dedicated allocation mapped too many times simultaneously.&quot;</span>);</div><div class="line"><a name="l06165"></a><span class="lineno"> 6165</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_MEMORY_MAP_FAILED;</div><div class="line"><a name="l06166"></a><span class="lineno"> 6166</span>&#160;        }</div><div class="line"><a name="l06167"></a><span class="lineno"> 6167</span>&#160;    }</div><div class="line"><a name="l06168"></a><span class="lineno"> 6168</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06169"></a><span class="lineno"> 6169</span>&#160;    {</div><div class="line"><a name="l06170"></a><span class="lineno"> 6170</span>&#160;        VkResult result = (*hAllocator-&gt;GetVulkanFunctions().vkMapMemory)(</div><div class="line"><a name="l06171"></a><span class="lineno"> 6171</span>&#160;            hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l06172"></a><span class="lineno"> 6172</span>&#160;            m_DedicatedAllocation.m_hMemory,</div><div class="line"><a name="l06173"></a><span class="lineno"> 6173</span>&#160;            0, <span class="comment">// offset</span></div><div class="line"><a name="l06174"></a><span class="lineno"> 6174</span>&#160;            VK_WHOLE_SIZE,</div><div class="line"><a name="l06175"></a><span class="lineno"> 6175</span>&#160;            0, <span class="comment">// flags</span></div><div class="line"><a name="l06176"></a><span class="lineno"> 6176</span>&#160;            ppData);</div><div class="line"><a name="l06177"></a><span class="lineno"> 6177</span>&#160;        <span class="keywordflow">if</span>(result == VK_SUCCESS)</div><div class="line"><a name="l06178"></a><span class="lineno"> 6178</span>&#160;        {</div><div class="line"><a name="l06179"></a><span class="lineno"> 6179</span>&#160;            m_DedicatedAllocation.m_pMappedData = *ppData;</div><div class="line"><a name="l06180"></a><span class="lineno"> 6180</span>&#160;            m_MapCount = 1;</div><div class="line"><a name="l06181"></a><span class="lineno"> 6181</span>&#160;        }</div><div class="line"><a name="l06182"></a><span class="lineno"> 6182</span>&#160;        <span class="keywordflow">return</span> result;</div><div class="line"><a name="l06183"></a><span class="lineno"> 6183</span>&#160;    }</div><div class="line"><a name="l06184"></a><span class="lineno"> 6184</span>&#160;}</div><div class="line"><a name="l06185"></a><span class="lineno"> 6185</span>&#160;</div><div class="line"><a name="l06186"></a><span class="lineno"> 6186</span>&#160;<span class="keywordtype">void</span> VmaAllocation_T::DedicatedAllocUnmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l06187"></a><span class="lineno"> 6187</span>&#160;{</div><div class="line"><a name="l06188"></a><span class="lineno"> 6188</span>&#160;    VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l06189"></a><span class="lineno"> 6189</span>&#160;</div><div class="line"><a name="l06190"></a><span class="lineno"> 6190</span>&#160;    <span class="keywordflow">if</span>((m_MapCount &amp; ~MAP_COUNT_FLAG_PERSISTENT_MAP) != 0)</div><div class="line"><a name="l06191"></a><span class="lineno"> 6191</span>&#160;    {</div><div class="line"><a name="l06192"></a><span class="lineno"> 6192</span>&#160;        --m_MapCount;</div><div class="line"><a name="l06193"></a><span class="lineno"> 6193</span>&#160;        <span class="keywordflow">if</span>(m_MapCount == 0)</div><div class="line"><a name="l06194"></a><span class="lineno"> 6194</span>&#160;        {</div><div class="line"><a name="l06195"></a><span class="lineno"> 6195</span>&#160;            m_DedicatedAllocation.m_pMappedData = VMA_NULL;</div><div class="line"><a name="l06196"></a><span class="lineno"> 6196</span>&#160;            (*hAllocator-&gt;GetVulkanFunctions().vkUnmapMemory)(</div><div class="line"><a name="l06197"></a><span class="lineno"> 6197</span>&#160;                hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l06198"></a><span class="lineno"> 6198</span>&#160;                m_DedicatedAllocation.m_hMemory);</div><div class="line"><a name="l06199"></a><span class="lineno"> 6199</span>&#160;        }</div><div class="line"><a name="l06200"></a><span class="lineno"> 6200</span>&#160;    }</div><div class="line"><a name="l06201"></a><span class="lineno"> 6201</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06202"></a><span class="lineno"> 6202</span>&#160;    {</div><div class="line"><a name="l06203"></a><span class="lineno"> 6203</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Unmapping dedicated allocation not previously mapped.&quot;</span>);</div><div class="line"><a name="l06204"></a><span class="lineno"> 6204</span>&#160;    }</div><div class="line"><a name="l06205"></a><span class="lineno"> 6205</span>&#160;}</div><div class="line"><a name="l06206"></a><span class="lineno"> 6206</span>&#160;</div><div class="line"><a name="l06207"></a><span class="lineno"> 6207</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06208"></a><span class="lineno"> 6208</span>&#160;</div><div class="line"><a name="l06209"></a><span class="lineno"> 6209</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaPrintStatInfo(VmaJsonWriter&amp; json, <span class="keyword">const</span> <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; stat)</div><div class="line"><a name="l06210"></a><span class="lineno"> 6210</span>&#160;{</div><div class="line"><a name="l06211"></a><span class="lineno"> 6211</span>&#160;    json.BeginObject();</div><div class="line"><a name="l06212"></a><span class="lineno"> 6212</span>&#160;</div><div class="line"><a name="l06213"></a><span class="lineno"> 6213</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Blocks&quot;</span>);</div><div class="line"><a name="l06214"></a><span class="lineno"> 6214</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a>);</div><div class="line"><a name="l06215"></a><span class="lineno"> 6215</span>&#160;</div><div class="line"><a name="l06216"></a><span class="lineno"> 6216</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Allocations&quot;</span>);</div><div class="line"><a name="l06217"></a><span class="lineno"> 6217</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>);</div><div class="line"><a name="l06218"></a><span class="lineno"> 6218</span>&#160;</div><div class="line"><a name="l06219"></a><span class="lineno"> 6219</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedRanges&quot;</span>);</div><div class="line"><a name="l06220"></a><span class="lineno"> 6220</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>);</div><div class="line"><a name="l06221"></a><span class="lineno"> 6221</span>&#160;</div><div class="line"><a name="l06222"></a><span class="lineno"> 6222</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UsedBytes&quot;</span>);</div><div class="line"><a name="l06223"></a><span class="lineno"> 6223</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>);</div><div class="line"><a name="l06224"></a><span class="lineno"> 6224</span>&#160;</div><div class="line"><a name="l06225"></a><span class="lineno"> 6225</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedBytes&quot;</span>);</div><div class="line"><a name="l06226"></a><span class="lineno"> 6226</span>&#160;    json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>);</div><div class="line"><a name="l06227"></a><span class="lineno"> 6227</span>&#160;</div><div class="line"><a name="l06228"></a><span class="lineno"> 6228</span>&#160;    <span class="keywordflow">if</span>(stat.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> &gt; 1)</div><div class="line"><a name="l06229"></a><span class="lineno"> 6229</span>&#160;    {</div><div class="line"><a name="l06230"></a><span class="lineno"> 6230</span>&#160;        json.WriteString(<span class="stringliteral">&quot;AllocationSize&quot;</span>);</div><div class="line"><a name="l06231"></a><span class="lineno"> 6231</span>&#160;        json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l06232"></a><span class="lineno"> 6232</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Min&quot;</span>);</div><div class="line"><a name="l06233"></a><span class="lineno"> 6233</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>);</div><div class="line"><a name="l06234"></a><span class="lineno"> 6234</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Avg&quot;</span>);</div><div class="line"><a name="l06235"></a><span class="lineno"> 6235</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a1081a039964e566c672e7a2347f9e599">allocationSizeAvg</a>);</div><div class="line"><a name="l06236"></a><span class="lineno"> 6236</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Max&quot;</span>);</div><div class="line"><a name="l06237"></a><span class="lineno"> 6237</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>);</div><div class="line"><a name="l06238"></a><span class="lineno"> 6238</span>&#160;        json.EndObject();</div><div class="line"><a name="l06239"></a><span class="lineno"> 6239</span>&#160;    }</div><div class="line"><a name="l06240"></a><span class="lineno"> 6240</span>&#160;</div><div class="line"><a name="l06241"></a><span class="lineno"> 6241</span>&#160;    <span class="keywordflow">if</span>(stat.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> &gt; 1)</div><div class="line"><a name="l06242"></a><span class="lineno"> 6242</span>&#160;    {</div><div class="line"><a name="l06243"></a><span class="lineno"> 6243</span>&#160;        json.WriteString(<span class="stringliteral">&quot;UnusedRangeSize&quot;</span>);</div><div class="line"><a name="l06244"></a><span class="lineno"> 6244</span>&#160;        json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l06245"></a><span class="lineno"> 6245</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Min&quot;</span>);</div><div class="line"><a name="l06246"></a><span class="lineno"> 6246</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>);</div><div class="line"><a name="l06247"></a><span class="lineno"> 6247</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Avg&quot;</span>);</div><div class="line"><a name="l06248"></a><span class="lineno"> 6248</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a2f9b3452af90c9768a30b7fb6ae194fc">unusedRangeSizeAvg</a>);</div><div class="line"><a name="l06249"></a><span class="lineno"> 6249</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Max&quot;</span>);</div><div class="line"><a name="l06250"></a><span class="lineno"> 6250</span>&#160;        json.WriteNumber(stat.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>);</div><div class="line"><a name="l06251"></a><span class="lineno"> 6251</span>&#160;        json.EndObject();</div><div class="line"><a name="l06252"></a><span class="lineno"> 6252</span>&#160;    }</div><div class="line"><a name="l06253"></a><span class="lineno"> 6253</span>&#160;</div><div class="line"><a name="l06254"></a><span class="lineno"> 6254</span>&#160;    json.EndObject();</div><div class="line"><a name="l06255"></a><span class="lineno"> 6255</span>&#160;}</div><div class="line"><a name="l06256"></a><span class="lineno"> 6256</span>&#160;</div><div class="line"><a name="l06257"></a><span class="lineno"> 6257</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06258"></a><span class="lineno"> 6258</span>&#160;</div><div class="line"><a name="l06259"></a><span class="lineno"> 6259</span>&#160;<span class="keyword">struct </span>VmaSuballocationItemSizeLess</div><div class="line"><a name="l06260"></a><span class="lineno"> 6260</span>&#160;{</div><div class="line"><a name="l06261"></a><span class="lineno"> 6261</span>&#160;    <span class="keywordtype">bool</span> operator()(</div><div class="line"><a name="l06262"></a><span class="lineno"> 6262</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator lhs,</div><div class="line"><a name="l06263"></a><span class="lineno"> 6263</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator rhs)<span class="keyword"> const</span></div><div class="line"><a name="l06264"></a><span class="lineno"> 6264</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l06265"></a><span class="lineno"> 6265</span>&#160;        <span class="keywordflow">return</span> lhs-&gt;size &lt; rhs-&gt;size;</div><div class="line"><a name="l06266"></a><span class="lineno"> 6266</span>&#160;    }</div><div class="line"><a name="l06267"></a><span class="lineno"> 6267</span>&#160;    <span class="keywordtype">bool</span> operator()(</div><div class="line"><a name="l06268"></a><span class="lineno"> 6268</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator lhs,</div><div class="line"><a name="l06269"></a><span class="lineno"> 6269</span>&#160;        VkDeviceSize rhsSize)<span class="keyword"> const</span></div><div class="line"><a name="l06270"></a><span class="lineno"> 6270</span>&#160;<span class="keyword">    </span>{</div><div class="line"><a name="l06271"></a><span class="lineno"> 6271</span>&#160;        <span class="keywordflow">return</span> lhs-&gt;size &lt; rhsSize;</div><div class="line"><a name="l06272"></a><span class="lineno"> 6272</span>&#160;    }</div><div class="line"><a name="l06273"></a><span class="lineno"> 6273</span>&#160;};</div><div class="line"><a name="l06274"></a><span class="lineno"> 6274</span>&#160;</div><div class="line"><a name="l06275"></a><span class="lineno"> 6275</span>&#160;</div><div class="line"><a name="l06277"></a><span class="lineno"> 6277</span>&#160;<span class="comment">// class VmaBlockMetadata</span></div><div class="line"><a name="l06278"></a><span class="lineno"> 6278</span>&#160;</div><div class="line"><a name="l06279"></a><span class="lineno"> 6279</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06280"></a><span class="lineno"> 6280</span>&#160;</div><div class="line"><a name="l06281"></a><span class="lineno"> 6281</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::PrintDetailedMap_Begin(<span class="keyword">class</span> VmaJsonWriter&amp; json,</div><div class="line"><a name="l06282"></a><span class="lineno"> 6282</span>&#160;    VkDeviceSize unusedBytes,</div><div class="line"><a name="l06283"></a><span class="lineno"> 6283</span>&#160;    <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l06284"></a><span class="lineno"> 6284</span>&#160;    <span class="keywordtype">size_t</span> unusedRangeCount)<span class="keyword"> const</span></div><div class="line"><a name="l06285"></a><span class="lineno"> 6285</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06286"></a><span class="lineno"> 6286</span>&#160;    json.BeginObject();</div><div class="line"><a name="l06287"></a><span class="lineno"> 6287</span>&#160;</div><div class="line"><a name="l06288"></a><span class="lineno"> 6288</span>&#160;    json.WriteString(<span class="stringliteral">&quot;TotalBytes&quot;</span>);</div><div class="line"><a name="l06289"></a><span class="lineno"> 6289</span>&#160;    json.WriteNumber(GetSize());</div><div class="line"><a name="l06290"></a><span class="lineno"> 6290</span>&#160;</div><div class="line"><a name="l06291"></a><span class="lineno"> 6291</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedBytes&quot;</span>);</div><div class="line"><a name="l06292"></a><span class="lineno"> 6292</span>&#160;    json.WriteNumber(unusedBytes);</div><div class="line"><a name="l06293"></a><span class="lineno"> 6293</span>&#160;</div><div class="line"><a name="l06294"></a><span class="lineno"> 6294</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Allocations&quot;</span>);</div><div class="line"><a name="l06295"></a><span class="lineno"> 6295</span>&#160;    json.WriteNumber((uint64_t)allocationCount);</div><div class="line"><a name="l06296"></a><span class="lineno"> 6296</span>&#160;</div><div class="line"><a name="l06297"></a><span class="lineno"> 6297</span>&#160;    json.WriteString(<span class="stringliteral">&quot;UnusedRanges&quot;</span>);</div><div class="line"><a name="l06298"></a><span class="lineno"> 6298</span>&#160;    json.WriteNumber((uint64_t)unusedRangeCount);</div><div class="line"><a name="l06299"></a><span class="lineno"> 6299</span>&#160;</div><div class="line"><a name="l06300"></a><span class="lineno"> 6300</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Suballocations&quot;</span>);</div><div class="line"><a name="l06301"></a><span class="lineno"> 6301</span>&#160;    json.BeginArray();</div><div class="line"><a name="l06302"></a><span class="lineno"> 6302</span>&#160;}</div><div class="line"><a name="l06303"></a><span class="lineno"> 6303</span>&#160;</div><div class="line"><a name="l06304"></a><span class="lineno"> 6304</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::PrintDetailedMap_Allocation(<span class="keyword">class</span> VmaJsonWriter&amp; json,</div><div class="line"><a name="l06305"></a><span class="lineno"> 6305</span>&#160;    VkDeviceSize offset,</div><div class="line"><a name="l06306"></a><span class="lineno"> 6306</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)<span class="keyword"> const</span></div><div class="line"><a name="l06307"></a><span class="lineno"> 6307</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06308"></a><span class="lineno"> 6308</span>&#160;    json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l06309"></a><span class="lineno"> 6309</span>&#160;        </div><div class="line"><a name="l06310"></a><span class="lineno"> 6310</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Offset&quot;</span>);</div><div class="line"><a name="l06311"></a><span class="lineno"> 6311</span>&#160;    json.WriteNumber(offset);</div><div class="line"><a name="l06312"></a><span class="lineno"> 6312</span>&#160;</div><div class="line"><a name="l06313"></a><span class="lineno"> 6313</span>&#160;    hAllocation-&gt;PrintParameters(json);</div><div class="line"><a name="l06314"></a><span class="lineno"> 6314</span>&#160;</div><div class="line"><a name="l06315"></a><span class="lineno"> 6315</span>&#160;    json.EndObject();</div><div class="line"><a name="l06316"></a><span class="lineno"> 6316</span>&#160;}</div><div class="line"><a name="l06317"></a><span class="lineno"> 6317</span>&#160;</div><div class="line"><a name="l06318"></a><span class="lineno"> 6318</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::PrintDetailedMap_UnusedRange(<span class="keyword">class</span> VmaJsonWriter&amp; json,</div><div class="line"><a name="l06319"></a><span class="lineno"> 6319</span>&#160;    VkDeviceSize offset,</div><div class="line"><a name="l06320"></a><span class="lineno"> 6320</span>&#160;    VkDeviceSize size)<span class="keyword"> const</span></div><div class="line"><a name="l06321"></a><span class="lineno"> 6321</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06322"></a><span class="lineno"> 6322</span>&#160;    json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l06323"></a><span class="lineno"> 6323</span>&#160;        </div><div class="line"><a name="l06324"></a><span class="lineno"> 6324</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Offset&quot;</span>);</div><div class="line"><a name="l06325"></a><span class="lineno"> 6325</span>&#160;    json.WriteNumber(offset);</div><div class="line"><a name="l06326"></a><span class="lineno"> 6326</span>&#160;</div><div class="line"><a name="l06327"></a><span class="lineno"> 6327</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Type&quot;</span>);</div><div class="line"><a name="l06328"></a><span class="lineno"> 6328</span>&#160;    json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[VMA_SUBALLOCATION_TYPE_FREE]);</div><div class="line"><a name="l06329"></a><span class="lineno"> 6329</span>&#160;</div><div class="line"><a name="l06330"></a><span class="lineno"> 6330</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Size&quot;</span>);</div><div class="line"><a name="l06331"></a><span class="lineno"> 6331</span>&#160;    json.WriteNumber(size);</div><div class="line"><a name="l06332"></a><span class="lineno"> 6332</span>&#160;</div><div class="line"><a name="l06333"></a><span class="lineno"> 6333</span>&#160;    json.EndObject();</div><div class="line"><a name="l06334"></a><span class="lineno"> 6334</span>&#160;}</div><div class="line"><a name="l06335"></a><span class="lineno"> 6335</span>&#160;</div><div class="line"><a name="l06336"></a><span class="lineno"> 6336</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata::PrintDetailedMap_End(<span class="keyword">class</span> VmaJsonWriter&amp; json)<span class="keyword"> const</span></div><div class="line"><a name="l06337"></a><span class="lineno"> 6337</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06338"></a><span class="lineno"> 6338</span>&#160;    json.EndArray();</div><div class="line"><a name="l06339"></a><span class="lineno"> 6339</span>&#160;    json.EndObject();</div><div class="line"><a name="l06340"></a><span class="lineno"> 6340</span>&#160;}</div><div class="line"><a name="l06341"></a><span class="lineno"> 6341</span>&#160;</div><div class="line"><a name="l06342"></a><span class="lineno"> 6342</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06343"></a><span class="lineno"> 6343</span>&#160;</div><div class="line"><a name="l06345"></a><span class="lineno"> 6345</span>&#160;<span class="comment">// class VmaBlockMetadata_Generic</span></div><div class="line"><a name="l06346"></a><span class="lineno"> 6346</span>&#160;</div><div class="line"><a name="l06347"></a><span class="lineno"> 6347</span>&#160;VmaBlockMetadata_Generic::VmaBlockMetadata_Generic(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator) :</div><div class="line"><a name="l06348"></a><span class="lineno"> 6348</span>&#160;    m_FreeCount(0),</div><div class="line"><a name="l06349"></a><span class="lineno"> 6349</span>&#160;    m_SumFreeSize(0),</div><div class="line"><a name="l06350"></a><span class="lineno"> 6350</span>&#160;    m_Suballocations(VmaStlAllocator&lt;VmaSuballocation&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l06351"></a><span class="lineno"> 6351</span>&#160;    m_FreeSuballocationsBySize(VmaStlAllocator&lt;VmaSuballocationList::iterator&gt;(hAllocator-&gt;GetAllocationCallbacks()))</div><div class="line"><a name="l06352"></a><span class="lineno"> 6352</span>&#160;{</div><div class="line"><a name="l06353"></a><span class="lineno"> 6353</span>&#160;}</div><div class="line"><a name="l06354"></a><span class="lineno"> 6354</span>&#160;</div><div class="line"><a name="l06355"></a><span class="lineno"> 6355</span>&#160;VmaBlockMetadata_Generic::~VmaBlockMetadata_Generic()</div><div class="line"><a name="l06356"></a><span class="lineno"> 6356</span>&#160;{</div><div class="line"><a name="l06357"></a><span class="lineno"> 6357</span>&#160;}</div><div class="line"><a name="l06358"></a><span class="lineno"> 6358</span>&#160;</div><div class="line"><a name="l06359"></a><span class="lineno"> 6359</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::Init(VkDeviceSize size)</div><div class="line"><a name="l06360"></a><span class="lineno"> 6360</span>&#160;{</div><div class="line"><a name="l06361"></a><span class="lineno"> 6361</span>&#160;    VmaBlockMetadata::Init(size);</div><div class="line"><a name="l06362"></a><span class="lineno"> 6362</span>&#160;    m_FreeCount = 1;</div><div class="line"><a name="l06363"></a><span class="lineno"> 6363</span>&#160;    m_SumFreeSize = size;</div><div class="line"><a name="l06364"></a><span class="lineno"> 6364</span>&#160;</div><div class="line"><a name="l06365"></a><span class="lineno"> 6365</span>&#160;    VmaSuballocation suballoc = {};</div><div class="line"><a name="l06366"></a><span class="lineno"> 6366</span>&#160;    suballoc.offset = 0;</div><div class="line"><a name="l06367"></a><span class="lineno"> 6367</span>&#160;    suballoc.size = size;</div><div class="line"><a name="l06368"></a><span class="lineno"> 6368</span>&#160;    suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l06369"></a><span class="lineno"> 6369</span>&#160;    suballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l06370"></a><span class="lineno"> 6370</span>&#160;</div><div class="line"><a name="l06371"></a><span class="lineno"> 6371</span>&#160;    m_Suballocations.push_back(suballoc);</div><div class="line"><a name="l06372"></a><span class="lineno"> 6372</span>&#160;    VmaSuballocationList::iterator suballocItem = m_Suballocations.end();</div><div class="line"><a name="l06373"></a><span class="lineno"> 6373</span>&#160;    --suballocItem;</div><div class="line"><a name="l06374"></a><span class="lineno"> 6374</span>&#160;    m_FreeSuballocationsBySize.push_back(suballocItem);</div><div class="line"><a name="l06375"></a><span class="lineno"> 6375</span>&#160;}</div><div class="line"><a name="l06376"></a><span class="lineno"> 6376</span>&#160;</div><div class="line"><a name="l06377"></a><span class="lineno"> 6377</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Generic::Validate()<span class="keyword"> const</span></div><div class="line"><a name="l06378"></a><span class="lineno"> 6378</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06379"></a><span class="lineno"> 6379</span>&#160;    <span class="keywordflow">if</span>(m_Suballocations.empty())</div><div class="line"><a name="l06380"></a><span class="lineno"> 6380</span>&#160;    {</div><div class="line"><a name="l06381"></a><span class="lineno"> 6381</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06382"></a><span class="lineno"> 6382</span>&#160;    }</div><div class="line"><a name="l06383"></a><span class="lineno"> 6383</span>&#160;    </div><div class="line"><a name="l06384"></a><span class="lineno"> 6384</span>&#160;    <span class="comment">// Expected offset of new suballocation as calculated from previous ones.</span></div><div class="line"><a name="l06385"></a><span class="lineno"> 6385</span>&#160;    VkDeviceSize calculatedOffset = 0;</div><div class="line"><a name="l06386"></a><span class="lineno"> 6386</span>&#160;    <span class="comment">// Expected number of free suballocations as calculated from traversing their list.</span></div><div class="line"><a name="l06387"></a><span class="lineno"> 6387</span>&#160;    uint32_t calculatedFreeCount = 0;</div><div class="line"><a name="l06388"></a><span class="lineno"> 6388</span>&#160;    <span class="comment">// Expected sum size of free suballocations as calculated from traversing their list.</span></div><div class="line"><a name="l06389"></a><span class="lineno"> 6389</span>&#160;    VkDeviceSize calculatedSumFreeSize = 0;</div><div class="line"><a name="l06390"></a><span class="lineno"> 6390</span>&#160;    <span class="comment">// Expected number of free suballocations that should be registered in</span></div><div class="line"><a name="l06391"></a><span class="lineno"> 6391</span>&#160;    <span class="comment">// m_FreeSuballocationsBySize calculated from traversing their list.</span></div><div class="line"><a name="l06392"></a><span class="lineno"> 6392</span>&#160;    <span class="keywordtype">size_t</span> freeSuballocationsToRegister = 0;</div><div class="line"><a name="l06393"></a><span class="lineno"> 6393</span>&#160;    <span class="comment">// True if previous visited suballocation was free.</span></div><div class="line"><a name="l06394"></a><span class="lineno"> 6394</span>&#160;    <span class="keywordtype">bool</span> prevFree = <span class="keyword">false</span>;</div><div class="line"><a name="l06395"></a><span class="lineno"> 6395</span>&#160;</div><div class="line"><a name="l06396"></a><span class="lineno"> 6396</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();</div><div class="line"><a name="l06397"></a><span class="lineno"> 6397</span>&#160;        suballocItem != m_Suballocations.cend();</div><div class="line"><a name="l06398"></a><span class="lineno"> 6398</span>&#160;        ++suballocItem)</div><div class="line"><a name="l06399"></a><span class="lineno"> 6399</span>&#160;    {</div><div class="line"><a name="l06400"></a><span class="lineno"> 6400</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; subAlloc = *suballocItem;</div><div class="line"><a name="l06401"></a><span class="lineno"> 6401</span>&#160;        </div><div class="line"><a name="l06402"></a><span class="lineno"> 6402</span>&#160;        <span class="comment">// Actual offset of this suballocation doesn&#39;t match expected one.</span></div><div class="line"><a name="l06403"></a><span class="lineno"> 6403</span>&#160;        <span class="keywordflow">if</span>(subAlloc.offset != calculatedOffset)</div><div class="line"><a name="l06404"></a><span class="lineno"> 6404</span>&#160;        {</div><div class="line"><a name="l06405"></a><span class="lineno"> 6405</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06406"></a><span class="lineno"> 6406</span>&#160;        }</div><div class="line"><a name="l06407"></a><span class="lineno"> 6407</span>&#160;</div><div class="line"><a name="l06408"></a><span class="lineno"> 6408</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">bool</span> currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06409"></a><span class="lineno"> 6409</span>&#160;        <span class="comment">// Two adjacent free suballocations are invalid. They should be merged.</span></div><div class="line"><a name="l06410"></a><span class="lineno"> 6410</span>&#160;        <span class="keywordflow">if</span>(prevFree &amp;&amp; currFree)</div><div class="line"><a name="l06411"></a><span class="lineno"> 6411</span>&#160;        {</div><div class="line"><a name="l06412"></a><span class="lineno"> 6412</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06413"></a><span class="lineno"> 6413</span>&#160;        }</div><div class="line"><a name="l06414"></a><span class="lineno"> 6414</span>&#160;</div><div class="line"><a name="l06415"></a><span class="lineno"> 6415</span>&#160;        <span class="keywordflow">if</span>(currFree != (subAlloc.hAllocation == VK_NULL_HANDLE))</div><div class="line"><a name="l06416"></a><span class="lineno"> 6416</span>&#160;        {</div><div class="line"><a name="l06417"></a><span class="lineno"> 6417</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06418"></a><span class="lineno"> 6418</span>&#160;        }</div><div class="line"><a name="l06419"></a><span class="lineno"> 6419</span>&#160;</div><div class="line"><a name="l06420"></a><span class="lineno"> 6420</span>&#160;        <span class="keywordflow">if</span>(currFree)</div><div class="line"><a name="l06421"></a><span class="lineno"> 6421</span>&#160;        {</div><div class="line"><a name="l06422"></a><span class="lineno"> 6422</span>&#160;            calculatedSumFreeSize += subAlloc.size;</div><div class="line"><a name="l06423"></a><span class="lineno"> 6423</span>&#160;            ++calculatedFreeCount;</div><div class="line"><a name="l06424"></a><span class="lineno"> 6424</span>&#160;            <span class="keywordflow">if</span>(subAlloc.size &gt;= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l06425"></a><span class="lineno"> 6425</span>&#160;            {</div><div class="line"><a name="l06426"></a><span class="lineno"> 6426</span>&#160;                ++freeSuballocationsToRegister;</div><div class="line"><a name="l06427"></a><span class="lineno"> 6427</span>&#160;            }</div><div class="line"><a name="l06428"></a><span class="lineno"> 6428</span>&#160;</div><div class="line"><a name="l06429"></a><span class="lineno"> 6429</span>&#160;            <span class="comment">// Margin required between allocations - every free space must be at least that large.</span></div><div class="line"><a name="l06430"></a><span class="lineno"> 6430</span>&#160;            <span class="keywordflow">if</span>(subAlloc.size &lt; VMA_DEBUG_MARGIN)</div><div class="line"><a name="l06431"></a><span class="lineno"> 6431</span>&#160;            {</div><div class="line"><a name="l06432"></a><span class="lineno"> 6432</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06433"></a><span class="lineno"> 6433</span>&#160;            }</div><div class="line"><a name="l06434"></a><span class="lineno"> 6434</span>&#160;        }</div><div class="line"><a name="l06435"></a><span class="lineno"> 6435</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06436"></a><span class="lineno"> 6436</span>&#160;        {</div><div class="line"><a name="l06437"></a><span class="lineno"> 6437</span>&#160;            <span class="keywordflow">if</span>(subAlloc.hAllocation-&gt;GetOffset() != subAlloc.offset)</div><div class="line"><a name="l06438"></a><span class="lineno"> 6438</span>&#160;            {</div><div class="line"><a name="l06439"></a><span class="lineno"> 6439</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06440"></a><span class="lineno"> 6440</span>&#160;            }</div><div class="line"><a name="l06441"></a><span class="lineno"> 6441</span>&#160;            <span class="keywordflow">if</span>(subAlloc.hAllocation-&gt;GetSize() != subAlloc.size)</div><div class="line"><a name="l06442"></a><span class="lineno"> 6442</span>&#160;            {</div><div class="line"><a name="l06443"></a><span class="lineno"> 6443</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06444"></a><span class="lineno"> 6444</span>&#160;            }</div><div class="line"><a name="l06445"></a><span class="lineno"> 6445</span>&#160;</div><div class="line"><a name="l06446"></a><span class="lineno"> 6446</span>&#160;            <span class="comment">// Margin required between allocations - previous allocation must be free.</span></div><div class="line"><a name="l06447"></a><span class="lineno"> 6447</span>&#160;            <span class="keywordflow">if</span>(VMA_DEBUG_MARGIN &gt; 0 &amp;&amp; !prevFree)</div><div class="line"><a name="l06448"></a><span class="lineno"> 6448</span>&#160;            {</div><div class="line"><a name="l06449"></a><span class="lineno"> 6449</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06450"></a><span class="lineno"> 6450</span>&#160;            }</div><div class="line"><a name="l06451"></a><span class="lineno"> 6451</span>&#160;        }</div><div class="line"><a name="l06452"></a><span class="lineno"> 6452</span>&#160;</div><div class="line"><a name="l06453"></a><span class="lineno"> 6453</span>&#160;        calculatedOffset += subAlloc.size;</div><div class="line"><a name="l06454"></a><span class="lineno"> 6454</span>&#160;        prevFree = currFree;</div><div class="line"><a name="l06455"></a><span class="lineno"> 6455</span>&#160;    }</div><div class="line"><a name="l06456"></a><span class="lineno"> 6456</span>&#160;</div><div class="line"><a name="l06457"></a><span class="lineno"> 6457</span>&#160;    <span class="comment">// Number of free suballocations registered in m_FreeSuballocationsBySize doesn&#39;t</span></div><div class="line"><a name="l06458"></a><span class="lineno"> 6458</span>&#160;    <span class="comment">// match expected one.</span></div><div class="line"><a name="l06459"></a><span class="lineno"> 6459</span>&#160;    <span class="keywordflow">if</span>(m_FreeSuballocationsBySize.size() != freeSuballocationsToRegister)</div><div class="line"><a name="l06460"></a><span class="lineno"> 6460</span>&#160;    {</div><div class="line"><a name="l06461"></a><span class="lineno"> 6461</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06462"></a><span class="lineno"> 6462</span>&#160;    }</div><div class="line"><a name="l06463"></a><span class="lineno"> 6463</span>&#160;</div><div class="line"><a name="l06464"></a><span class="lineno"> 6464</span>&#160;    VkDeviceSize lastSize = 0;</div><div class="line"><a name="l06465"></a><span class="lineno"> 6465</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_FreeSuballocationsBySize.size(); ++i)</div><div class="line"><a name="l06466"></a><span class="lineno"> 6466</span>&#160;    {</div><div class="line"><a name="l06467"></a><span class="lineno"> 6467</span>&#160;        VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i];</div><div class="line"><a name="l06468"></a><span class="lineno"> 6468</span>&#160;        </div><div class="line"><a name="l06469"></a><span class="lineno"> 6469</span>&#160;        <span class="comment">// Only free suballocations can be registered in m_FreeSuballocationsBySize.</span></div><div class="line"><a name="l06470"></a><span class="lineno"> 6470</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06471"></a><span class="lineno"> 6471</span>&#160;        {</div><div class="line"><a name="l06472"></a><span class="lineno"> 6472</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06473"></a><span class="lineno"> 6473</span>&#160;        }</div><div class="line"><a name="l06474"></a><span class="lineno"> 6474</span>&#160;        <span class="comment">// They must be sorted by size ascending.</span></div><div class="line"><a name="l06475"></a><span class="lineno"> 6475</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;size &lt; lastSize)</div><div class="line"><a name="l06476"></a><span class="lineno"> 6476</span>&#160;        {</div><div class="line"><a name="l06477"></a><span class="lineno"> 6477</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06478"></a><span class="lineno"> 6478</span>&#160;        }</div><div class="line"><a name="l06479"></a><span class="lineno"> 6479</span>&#160;</div><div class="line"><a name="l06480"></a><span class="lineno"> 6480</span>&#160;        lastSize = suballocItem-&gt;size;</div><div class="line"><a name="l06481"></a><span class="lineno"> 6481</span>&#160;    }</div><div class="line"><a name="l06482"></a><span class="lineno"> 6482</span>&#160;</div><div class="line"><a name="l06483"></a><span class="lineno"> 6483</span>&#160;    <span class="comment">// Check if totals match calculacted values.</span></div><div class="line"><a name="l06484"></a><span class="lineno"> 6484</span>&#160;    <span class="keywordflow">if</span>(!ValidateFreeSuballocationList() ||</div><div class="line"><a name="l06485"></a><span class="lineno"> 6485</span>&#160;        (calculatedOffset != GetSize()) ||</div><div class="line"><a name="l06486"></a><span class="lineno"> 6486</span>&#160;        (calculatedSumFreeSize != m_SumFreeSize) ||</div><div class="line"><a name="l06487"></a><span class="lineno"> 6487</span>&#160;        (calculatedFreeCount != m_FreeCount))</div><div class="line"><a name="l06488"></a><span class="lineno"> 6488</span>&#160;    {</div><div class="line"><a name="l06489"></a><span class="lineno"> 6489</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06490"></a><span class="lineno"> 6490</span>&#160;    }</div><div class="line"><a name="l06491"></a><span class="lineno"> 6491</span>&#160;</div><div class="line"><a name="l06492"></a><span class="lineno"> 6492</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06493"></a><span class="lineno"> 6493</span>&#160;}</div><div class="line"><a name="l06494"></a><span class="lineno"> 6494</span>&#160;</div><div class="line"><a name="l06495"></a><span class="lineno"> 6495</span>&#160;VkDeviceSize VmaBlockMetadata_Generic::GetUnusedRangeSizeMax()<span class="keyword"> const</span></div><div class="line"><a name="l06496"></a><span class="lineno"> 6496</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06497"></a><span class="lineno"> 6497</span>&#160;    <span class="keywordflow">if</span>(!m_FreeSuballocationsBySize.empty())</div><div class="line"><a name="l06498"></a><span class="lineno"> 6498</span>&#160;    {</div><div class="line"><a name="l06499"></a><span class="lineno"> 6499</span>&#160;        <span class="keywordflow">return</span> m_FreeSuballocationsBySize.back()-&gt;size;</div><div class="line"><a name="l06500"></a><span class="lineno"> 6500</span>&#160;    }</div><div class="line"><a name="l06501"></a><span class="lineno"> 6501</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l06502"></a><span class="lineno"> 6502</span>&#160;    {</div><div class="line"><a name="l06503"></a><span class="lineno"> 6503</span>&#160;        <span class="keywordflow">return</span> 0;</div><div class="line"><a name="l06504"></a><span class="lineno"> 6504</span>&#160;    }</div><div class="line"><a name="l06505"></a><span class="lineno"> 6505</span>&#160;}</div><div class="line"><a name="l06506"></a><span class="lineno"> 6506</span>&#160;</div><div class="line"><a name="l06507"></a><span class="lineno"> 6507</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Generic::IsEmpty()<span class="keyword"> const</span></div><div class="line"><a name="l06508"></a><span class="lineno"> 6508</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06509"></a><span class="lineno"> 6509</span>&#160;    <span class="keywordflow">return</span> (m_Suballocations.size() == 1) &amp;&amp; (m_FreeCount == 1);</div><div class="line"><a name="l06510"></a><span class="lineno"> 6510</span>&#160;}</div><div class="line"><a name="l06511"></a><span class="lineno"> 6511</span>&#160;</div><div class="line"><a name="l06512"></a><span class="lineno"> 6512</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::CalcAllocationStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo)<span class="keyword"> const</span></div><div class="line"><a name="l06513"></a><span class="lineno"> 6513</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06514"></a><span class="lineno"> 6514</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> = 1;</div><div class="line"><a name="l06515"></a><span class="lineno"> 6515</span>&#160;</div><div class="line"><a name="l06516"></a><span class="lineno"> 6516</span>&#160;    <span class="keyword">const</span> uint32_t rangeCount = (uint32_t)m_Suballocations.size();</div><div class="line"><a name="l06517"></a><span class="lineno"> 6517</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> = rangeCount - m_FreeCount;</div><div class="line"><a name="l06518"></a><span class="lineno"> 6518</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> = m_FreeCount;</div><div class="line"><a name="l06519"></a><span class="lineno"> 6519</span>&#160;    </div><div class="line"><a name="l06520"></a><span class="lineno"> 6520</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> = m_SumFreeSize;</div><div class="line"><a name="l06521"></a><span class="lineno"> 6521</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> = GetSize() - outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>;</div><div class="line"><a name="l06522"></a><span class="lineno"> 6522</span>&#160;</div><div class="line"><a name="l06523"></a><span class="lineno"> 6523</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l06524"></a><span class="lineno"> 6524</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = 0;</div><div class="line"><a name="l06525"></a><span class="lineno"> 6525</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l06526"></a><span class="lineno"> 6526</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = 0;</div><div class="line"><a name="l06527"></a><span class="lineno"> 6527</span>&#160;</div><div class="line"><a name="l06528"></a><span class="lineno"> 6528</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();</div><div class="line"><a name="l06529"></a><span class="lineno"> 6529</span>&#160;        suballocItem != m_Suballocations.cend();</div><div class="line"><a name="l06530"></a><span class="lineno"> 6530</span>&#160;        ++suballocItem)</div><div class="line"><a name="l06531"></a><span class="lineno"> 6531</span>&#160;    {</div><div class="line"><a name="l06532"></a><span class="lineno"> 6532</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l06533"></a><span class="lineno"> 6533</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06534"></a><span class="lineno"> 6534</span>&#160;        {</div><div class="line"><a name="l06535"></a><span class="lineno"> 6535</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, suballoc.size);</div><div class="line"><a name="l06536"></a><span class="lineno"> 6536</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = VMA_MAX(outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>, suballoc.size);</div><div class="line"><a name="l06537"></a><span class="lineno"> 6537</span>&#160;        }</div><div class="line"><a name="l06538"></a><span class="lineno"> 6538</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06539"></a><span class="lineno"> 6539</span>&#160;        {</div><div class="line"><a name="l06540"></a><span class="lineno"> 6540</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, suballoc.size);</div><div class="line"><a name="l06541"></a><span class="lineno"> 6541</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MAX(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, suballoc.size);</div><div class="line"><a name="l06542"></a><span class="lineno"> 6542</span>&#160;        }</div><div class="line"><a name="l06543"></a><span class="lineno"> 6543</span>&#160;    }</div><div class="line"><a name="l06544"></a><span class="lineno"> 6544</span>&#160;}</div><div class="line"><a name="l06545"></a><span class="lineno"> 6545</span>&#160;</div><div class="line"><a name="l06546"></a><span class="lineno"> 6546</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::AddPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>&amp; inoutStats)<span class="keyword"> const</span></div><div class="line"><a name="l06547"></a><span class="lineno"> 6547</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06548"></a><span class="lineno"> 6548</span>&#160;    <span class="keyword">const</span> uint32_t rangeCount = (uint32_t)m_Suballocations.size();</div><div class="line"><a name="l06549"></a><span class="lineno"> 6549</span>&#160;</div><div class="line"><a name="l06550"></a><span class="lineno"> 6550</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a> += GetSize();</div><div class="line"><a name="l06551"></a><span class="lineno"> 6551</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += m_SumFreeSize;</div><div class="line"><a name="l06552"></a><span class="lineno"> 6552</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a> += rangeCount - m_FreeCount;</div><div class="line"><a name="l06553"></a><span class="lineno"> 6553</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a> += m_FreeCount;</div><div class="line"><a name="l06554"></a><span class="lineno"> 6554</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, GetUnusedRangeSizeMax());</div><div class="line"><a name="l06555"></a><span class="lineno"> 6555</span>&#160;}</div><div class="line"><a name="l06556"></a><span class="lineno"> 6556</span>&#160;</div><div class="line"><a name="l06557"></a><span class="lineno"> 6557</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06558"></a><span class="lineno"> 6558</span>&#160;</div><div class="line"><a name="l06559"></a><span class="lineno"> 6559</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json)<span class="keyword"> const</span></div><div class="line"><a name="l06560"></a><span class="lineno"> 6560</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06561"></a><span class="lineno"> 6561</span>&#160;    PrintDetailedMap_Begin(json,</div><div class="line"><a name="l06562"></a><span class="lineno"> 6562</span>&#160;        m_SumFreeSize, <span class="comment">// unusedBytes</span></div><div class="line"><a name="l06563"></a><span class="lineno"> 6563</span>&#160;        m_Suballocations.size() - (size_t)m_FreeCount, <span class="comment">// allocationCount</span></div><div class="line"><a name="l06564"></a><span class="lineno"> 6564</span>&#160;        m_FreeCount); <span class="comment">// unusedRangeCount</span></div><div class="line"><a name="l06565"></a><span class="lineno"> 6565</span>&#160;</div><div class="line"><a name="l06566"></a><span class="lineno"> 6566</span>&#160;    <span class="keywordtype">size_t</span> i = 0;</div><div class="line"><a name="l06567"></a><span class="lineno"> 6567</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();</div><div class="line"><a name="l06568"></a><span class="lineno"> 6568</span>&#160;        suballocItem != m_Suballocations.cend();</div><div class="line"><a name="l06569"></a><span class="lineno"> 6569</span>&#160;        ++suballocItem, ++i)</div><div class="line"><a name="l06570"></a><span class="lineno"> 6570</span>&#160;    {</div><div class="line"><a name="l06571"></a><span class="lineno"> 6571</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06572"></a><span class="lineno"> 6572</span>&#160;        {</div><div class="line"><a name="l06573"></a><span class="lineno"> 6573</span>&#160;            PrintDetailedMap_UnusedRange(json, suballocItem-&gt;offset, suballocItem-&gt;size);</div><div class="line"><a name="l06574"></a><span class="lineno"> 6574</span>&#160;        }</div><div class="line"><a name="l06575"></a><span class="lineno"> 6575</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06576"></a><span class="lineno"> 6576</span>&#160;        {</div><div class="line"><a name="l06577"></a><span class="lineno"> 6577</span>&#160;            PrintDetailedMap_Allocation(json, suballocItem-&gt;offset, suballocItem-&gt;hAllocation);</div><div class="line"><a name="l06578"></a><span class="lineno"> 6578</span>&#160;        }</div><div class="line"><a name="l06579"></a><span class="lineno"> 6579</span>&#160;    }</div><div class="line"><a name="l06580"></a><span class="lineno"> 6580</span>&#160;</div><div class="line"><a name="l06581"></a><span class="lineno"> 6581</span>&#160;    PrintDetailedMap_End(json);</div><div class="line"><a name="l06582"></a><span class="lineno"> 6582</span>&#160;}</div><div class="line"><a name="l06583"></a><span class="lineno"> 6583</span>&#160;</div><div class="line"><a name="l06584"></a><span class="lineno"> 6584</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l06585"></a><span class="lineno"> 6585</span>&#160;</div><div class="line"><a name="l06586"></a><span class="lineno"> 6586</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l06587"></a><span class="lineno"> 6587</span>&#160;<span class="comment">How many suitable free suballocations to analyze before choosing best one.</span></div><div class="line"><a name="l06588"></a><span class="lineno"> 6588</span>&#160;<span class="comment">- Set to 1 to use First-Fit algorithm - first suitable free suballocation will</span></div><div class="line"><a name="l06589"></a><span class="lineno"> 6589</span>&#160;<span class="comment">  be chosen.</span></div><div class="line"><a name="l06590"></a><span class="lineno"> 6590</span>&#160;<span class="comment">- Set to UINT32_MAX to use Best-Fit/Worst-Fit algorithm - all suitable free</span></div><div class="line"><a name="l06591"></a><span class="lineno"> 6591</span>&#160;<span class="comment">  suballocations will be analized and best one will be chosen.</span></div><div class="line"><a name="l06592"></a><span class="lineno"> 6592</span>&#160;<span class="comment">- Any other value is also acceptable.</span></div><div class="line"><a name="l06593"></a><span class="lineno"> 6593</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l06594"></a><span class="lineno"> 6594</span>&#160;<span class="comment">//static const uint32_t MAX_SUITABLE_SUBALLOCATIONS_TO_CHECK = 8;</span></div><div class="line"><a name="l06595"></a><span class="lineno"> 6595</span>&#160;</div><div class="line"><a name="l06596"></a><span class="lineno"> 6596</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Generic::CreateAllocationRequest(</div><div class="line"><a name="l06597"></a><span class="lineno"> 6597</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l06598"></a><span class="lineno"> 6598</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l06599"></a><span class="lineno"> 6599</span>&#160;    VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l06600"></a><span class="lineno"> 6600</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l06601"></a><span class="lineno"> 6601</span>&#160;    VkDeviceSize allocAlignment,</div><div class="line"><a name="l06602"></a><span class="lineno"> 6602</span>&#160;    <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l06603"></a><span class="lineno"> 6603</span>&#160;    VmaSuballocationType allocType,</div><div class="line"><a name="l06604"></a><span class="lineno"> 6604</span>&#160;    <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l06605"></a><span class="lineno"> 6605</span>&#160;    VmaAllocationRequest* pAllocationRequest)</div><div class="line"><a name="l06606"></a><span class="lineno"> 6606</span>&#160;{</div><div class="line"><a name="l06607"></a><span class="lineno"> 6607</span>&#160;    VMA_ASSERT(allocSize &gt; 0);</div><div class="line"><a name="l06608"></a><span class="lineno"> 6608</span>&#160;    VMA_ASSERT(!upperAddress);</div><div class="line"><a name="l06609"></a><span class="lineno"> 6609</span>&#160;    VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06610"></a><span class="lineno"> 6610</span>&#160;    VMA_ASSERT(pAllocationRequest != VMA_NULL);</div><div class="line"><a name="l06611"></a><span class="lineno"> 6611</span>&#160;    VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l06612"></a><span class="lineno"> 6612</span>&#160;</div><div class="line"><a name="l06613"></a><span class="lineno"> 6613</span>&#160;    <span class="comment">// There is not enough total free space in this block to fullfill the request: Early return.</span></div><div class="line"><a name="l06614"></a><span class="lineno"> 6614</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost == <span class="keyword">false</span> &amp;&amp; m_SumFreeSize &lt; allocSize + 2 * VMA_DEBUG_MARGIN)</div><div class="line"><a name="l06615"></a><span class="lineno"> 6615</span>&#160;    {</div><div class="line"><a name="l06616"></a><span class="lineno"> 6616</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06617"></a><span class="lineno"> 6617</span>&#160;    }</div><div class="line"><a name="l06618"></a><span class="lineno"> 6618</span>&#160;</div><div class="line"><a name="l06619"></a><span class="lineno"> 6619</span>&#160;    <span class="comment">// New algorithm, efficiently searching freeSuballocationsBySize.</span></div><div class="line"><a name="l06620"></a><span class="lineno"> 6620</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> freeSuballocCount = m_FreeSuballocationsBySize.size();</div><div class="line"><a name="l06621"></a><span class="lineno"> 6621</span>&#160;    <span class="keywordflow">if</span>(freeSuballocCount &gt; 0)</div><div class="line"><a name="l06622"></a><span class="lineno"> 6622</span>&#160;    {</div><div class="line"><a name="l06623"></a><span class="lineno"> 6623</span>&#160;        <span class="keywordflow">if</span>(VMA_BEST_FIT)</div><div class="line"><a name="l06624"></a><span class="lineno"> 6624</span>&#160;        {</div><div class="line"><a name="l06625"></a><span class="lineno"> 6625</span>&#160;            <span class="comment">// Find first free suballocation with size not less than allocSize + 2 * VMA_DEBUG_MARGIN.</span></div><div class="line"><a name="l06626"></a><span class="lineno"> 6626</span>&#160;            VmaSuballocationList::iterator* <span class="keyword">const</span> it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l06627"></a><span class="lineno"> 6627</span>&#160;                m_FreeSuballocationsBySize.data(),</div><div class="line"><a name="l06628"></a><span class="lineno"> 6628</span>&#160;                m_FreeSuballocationsBySize.data() + freeSuballocCount,</div><div class="line"><a name="l06629"></a><span class="lineno"> 6629</span>&#160;                allocSize + 2 * VMA_DEBUG_MARGIN,</div><div class="line"><a name="l06630"></a><span class="lineno"> 6630</span>&#160;                VmaSuballocationItemSizeLess());</div><div class="line"><a name="l06631"></a><span class="lineno"> 6631</span>&#160;            <span class="keywordtype">size_t</span> index = it - m_FreeSuballocationsBySize.data();</div><div class="line"><a name="l06632"></a><span class="lineno"> 6632</span>&#160;            <span class="keywordflow">for</span>(; index &lt; freeSuballocCount; ++index)</div><div class="line"><a name="l06633"></a><span class="lineno"> 6633</span>&#160;            {</div><div class="line"><a name="l06634"></a><span class="lineno"> 6634</span>&#160;                <span class="keywordflow">if</span>(CheckAllocation(</div><div class="line"><a name="l06635"></a><span class="lineno"> 6635</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l06636"></a><span class="lineno"> 6636</span>&#160;                    frameInUseCount,</div><div class="line"><a name="l06637"></a><span class="lineno"> 6637</span>&#160;                    bufferImageGranularity,</div><div class="line"><a name="l06638"></a><span class="lineno"> 6638</span>&#160;                    allocSize,</div><div class="line"><a name="l06639"></a><span class="lineno"> 6639</span>&#160;                    allocAlignment,</div><div class="line"><a name="l06640"></a><span class="lineno"> 6640</span>&#160;                    allocType,</div><div class="line"><a name="l06641"></a><span class="lineno"> 6641</span>&#160;                    m_FreeSuballocationsBySize[index],</div><div class="line"><a name="l06642"></a><span class="lineno"> 6642</span>&#160;                    <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l06643"></a><span class="lineno"> 6643</span>&#160;                    &amp;pAllocationRequest-&gt;offset,</div><div class="line"><a name="l06644"></a><span class="lineno"> 6644</span>&#160;                    &amp;pAllocationRequest-&gt;itemsToMakeLostCount,</div><div class="line"><a name="l06645"></a><span class="lineno"> 6645</span>&#160;                    &amp;pAllocationRequest-&gt;sumFreeSize,</div><div class="line"><a name="l06646"></a><span class="lineno"> 6646</span>&#160;                    &amp;pAllocationRequest-&gt;sumItemSize))</div><div class="line"><a name="l06647"></a><span class="lineno"> 6647</span>&#160;                {</div><div class="line"><a name="l06648"></a><span class="lineno"> 6648</span>&#160;                    pAllocationRequest-&gt;item = m_FreeSuballocationsBySize[index];</div><div class="line"><a name="l06649"></a><span class="lineno"> 6649</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06650"></a><span class="lineno"> 6650</span>&#160;                }</div><div class="line"><a name="l06651"></a><span class="lineno"> 6651</span>&#160;            }</div><div class="line"><a name="l06652"></a><span class="lineno"> 6652</span>&#160;        }</div><div class="line"><a name="l06653"></a><span class="lineno"> 6653</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06654"></a><span class="lineno"> 6654</span>&#160;        {</div><div class="line"><a name="l06655"></a><span class="lineno"> 6655</span>&#160;            <span class="comment">// Search staring from biggest suballocations.</span></div><div class="line"><a name="l06656"></a><span class="lineno"> 6656</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> index = freeSuballocCount; index--; )</div><div class="line"><a name="l06657"></a><span class="lineno"> 6657</span>&#160;            {</div><div class="line"><a name="l06658"></a><span class="lineno"> 6658</span>&#160;                <span class="keywordflow">if</span>(CheckAllocation(</div><div class="line"><a name="l06659"></a><span class="lineno"> 6659</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l06660"></a><span class="lineno"> 6660</span>&#160;                    frameInUseCount,</div><div class="line"><a name="l06661"></a><span class="lineno"> 6661</span>&#160;                    bufferImageGranularity,</div><div class="line"><a name="l06662"></a><span class="lineno"> 6662</span>&#160;                    allocSize,</div><div class="line"><a name="l06663"></a><span class="lineno"> 6663</span>&#160;                    allocAlignment,</div><div class="line"><a name="l06664"></a><span class="lineno"> 6664</span>&#160;                    allocType,</div><div class="line"><a name="l06665"></a><span class="lineno"> 6665</span>&#160;                    m_FreeSuballocationsBySize[index],</div><div class="line"><a name="l06666"></a><span class="lineno"> 6666</span>&#160;                    <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l06667"></a><span class="lineno"> 6667</span>&#160;                    &amp;pAllocationRequest-&gt;offset,</div><div class="line"><a name="l06668"></a><span class="lineno"> 6668</span>&#160;                    &amp;pAllocationRequest-&gt;itemsToMakeLostCount,</div><div class="line"><a name="l06669"></a><span class="lineno"> 6669</span>&#160;                    &amp;pAllocationRequest-&gt;sumFreeSize,</div><div class="line"><a name="l06670"></a><span class="lineno"> 6670</span>&#160;                    &amp;pAllocationRequest-&gt;sumItemSize))</div><div class="line"><a name="l06671"></a><span class="lineno"> 6671</span>&#160;                {</div><div class="line"><a name="l06672"></a><span class="lineno"> 6672</span>&#160;                    pAllocationRequest-&gt;item = m_FreeSuballocationsBySize[index];</div><div class="line"><a name="l06673"></a><span class="lineno"> 6673</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06674"></a><span class="lineno"> 6674</span>&#160;                }</div><div class="line"><a name="l06675"></a><span class="lineno"> 6675</span>&#160;            }</div><div class="line"><a name="l06676"></a><span class="lineno"> 6676</span>&#160;        }</div><div class="line"><a name="l06677"></a><span class="lineno"> 6677</span>&#160;    }</div><div class="line"><a name="l06678"></a><span class="lineno"> 6678</span>&#160;</div><div class="line"><a name="l06679"></a><span class="lineno"> 6679</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost)</div><div class="line"><a name="l06680"></a><span class="lineno"> 6680</span>&#160;    {</div><div class="line"><a name="l06681"></a><span class="lineno"> 6681</span>&#160;        <span class="comment">// Brute-force algorithm. TODO: Come up with something better.</span></div><div class="line"><a name="l06682"></a><span class="lineno"> 6682</span>&#160;</div><div class="line"><a name="l06683"></a><span class="lineno"> 6683</span>&#160;        pAllocationRequest-&gt;sumFreeSize = VK_WHOLE_SIZE;</div><div class="line"><a name="l06684"></a><span class="lineno"> 6684</span>&#160;        pAllocationRequest-&gt;sumItemSize = VK_WHOLE_SIZE;</div><div class="line"><a name="l06685"></a><span class="lineno"> 6685</span>&#160;</div><div class="line"><a name="l06686"></a><span class="lineno"> 6686</span>&#160;        VmaAllocationRequest tmpAllocRequest = {};</div><div class="line"><a name="l06687"></a><span class="lineno"> 6687</span>&#160;        <span class="keywordflow">for</span>(VmaSuballocationList::iterator suballocIt = m_Suballocations.begin();</div><div class="line"><a name="l06688"></a><span class="lineno"> 6688</span>&#160;            suballocIt != m_Suballocations.end();</div><div class="line"><a name="l06689"></a><span class="lineno"> 6689</span>&#160;            ++suballocIt)</div><div class="line"><a name="l06690"></a><span class="lineno"> 6690</span>&#160;        {</div><div class="line"><a name="l06691"></a><span class="lineno"> 6691</span>&#160;            <span class="keywordflow">if</span>(suballocIt-&gt;type == VMA_SUBALLOCATION_TYPE_FREE ||</div><div class="line"><a name="l06692"></a><span class="lineno"> 6692</span>&#160;                suballocIt-&gt;hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l06693"></a><span class="lineno"> 6693</span>&#160;            {</div><div class="line"><a name="l06694"></a><span class="lineno"> 6694</span>&#160;                <span class="keywordflow">if</span>(CheckAllocation(</div><div class="line"><a name="l06695"></a><span class="lineno"> 6695</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l06696"></a><span class="lineno"> 6696</span>&#160;                    frameInUseCount,</div><div class="line"><a name="l06697"></a><span class="lineno"> 6697</span>&#160;                    bufferImageGranularity,</div><div class="line"><a name="l06698"></a><span class="lineno"> 6698</span>&#160;                    allocSize,</div><div class="line"><a name="l06699"></a><span class="lineno"> 6699</span>&#160;                    allocAlignment,</div><div class="line"><a name="l06700"></a><span class="lineno"> 6700</span>&#160;                    allocType,</div><div class="line"><a name="l06701"></a><span class="lineno"> 6701</span>&#160;                    suballocIt,</div><div class="line"><a name="l06702"></a><span class="lineno"> 6702</span>&#160;                    canMakeOtherLost,</div><div class="line"><a name="l06703"></a><span class="lineno"> 6703</span>&#160;                    &amp;tmpAllocRequest.offset,</div><div class="line"><a name="l06704"></a><span class="lineno"> 6704</span>&#160;                    &amp;tmpAllocRequest.itemsToMakeLostCount,</div><div class="line"><a name="l06705"></a><span class="lineno"> 6705</span>&#160;                    &amp;tmpAllocRequest.sumFreeSize,</div><div class="line"><a name="l06706"></a><span class="lineno"> 6706</span>&#160;                    &amp;tmpAllocRequest.sumItemSize))</div><div class="line"><a name="l06707"></a><span class="lineno"> 6707</span>&#160;                {</div><div class="line"><a name="l06708"></a><span class="lineno"> 6708</span>&#160;                    tmpAllocRequest.item = suballocIt;</div><div class="line"><a name="l06709"></a><span class="lineno"> 6709</span>&#160;</div><div class="line"><a name="l06710"></a><span class="lineno"> 6710</span>&#160;                    <span class="keywordflow">if</span>(tmpAllocRequest.CalcCost() &lt; pAllocationRequest-&gt;CalcCost())</div><div class="line"><a name="l06711"></a><span class="lineno"> 6711</span>&#160;                    {</div><div class="line"><a name="l06712"></a><span class="lineno"> 6712</span>&#160;                        *pAllocationRequest = tmpAllocRequest;</div><div class="line"><a name="l06713"></a><span class="lineno"> 6713</span>&#160;                    }</div><div class="line"><a name="l06714"></a><span class="lineno"> 6714</span>&#160;                }</div><div class="line"><a name="l06715"></a><span class="lineno"> 6715</span>&#160;            }</div><div class="line"><a name="l06716"></a><span class="lineno"> 6716</span>&#160;        }</div><div class="line"><a name="l06717"></a><span class="lineno"> 6717</span>&#160;</div><div class="line"><a name="l06718"></a><span class="lineno"> 6718</span>&#160;        <span class="keywordflow">if</span>(pAllocationRequest-&gt;sumItemSize != VK_WHOLE_SIZE)</div><div class="line"><a name="l06719"></a><span class="lineno"> 6719</span>&#160;        {</div><div class="line"><a name="l06720"></a><span class="lineno"> 6720</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06721"></a><span class="lineno"> 6721</span>&#160;        }</div><div class="line"><a name="l06722"></a><span class="lineno"> 6722</span>&#160;    }</div><div class="line"><a name="l06723"></a><span class="lineno"> 6723</span>&#160;</div><div class="line"><a name="l06724"></a><span class="lineno"> 6724</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06725"></a><span class="lineno"> 6725</span>&#160;}</div><div class="line"><a name="l06726"></a><span class="lineno"> 6726</span>&#160;</div><div class="line"><a name="l06727"></a><span class="lineno"> 6727</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Generic::MakeRequestedAllocationsLost(</div><div class="line"><a name="l06728"></a><span class="lineno"> 6728</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l06729"></a><span class="lineno"> 6729</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l06730"></a><span class="lineno"> 6730</span>&#160;    VmaAllocationRequest* pAllocationRequest)</div><div class="line"><a name="l06731"></a><span class="lineno"> 6731</span>&#160;{</div><div class="line"><a name="l06732"></a><span class="lineno"> 6732</span>&#160;    <span class="keywordflow">while</span>(pAllocationRequest-&gt;itemsToMakeLostCount &gt; 0)</div><div class="line"><a name="l06733"></a><span class="lineno"> 6733</span>&#160;    {</div><div class="line"><a name="l06734"></a><span class="lineno"> 6734</span>&#160;        <span class="keywordflow">if</span>(pAllocationRequest-&gt;item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06735"></a><span class="lineno"> 6735</span>&#160;        {</div><div class="line"><a name="l06736"></a><span class="lineno"> 6736</span>&#160;            ++pAllocationRequest-&gt;item;</div><div class="line"><a name="l06737"></a><span class="lineno"> 6737</span>&#160;        }</div><div class="line"><a name="l06738"></a><span class="lineno"> 6738</span>&#160;        VMA_ASSERT(pAllocationRequest-&gt;item != m_Suballocations.end());</div><div class="line"><a name="l06739"></a><span class="lineno"> 6739</span>&#160;        VMA_ASSERT(pAllocationRequest-&gt;item-&gt;hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l06740"></a><span class="lineno"> 6740</span>&#160;        VMA_ASSERT(pAllocationRequest-&gt;item-&gt;hAllocation-&gt;CanBecomeLost());</div><div class="line"><a name="l06741"></a><span class="lineno"> 6741</span>&#160;        <span class="keywordflow">if</span>(pAllocationRequest-&gt;item-&gt;hAllocation-&gt;MakeLost(currentFrameIndex, frameInUseCount))</div><div class="line"><a name="l06742"></a><span class="lineno"> 6742</span>&#160;        {</div><div class="line"><a name="l06743"></a><span class="lineno"> 6743</span>&#160;            pAllocationRequest-&gt;item = FreeSuballocation(pAllocationRequest-&gt;item);</div><div class="line"><a name="l06744"></a><span class="lineno"> 6744</span>&#160;            --pAllocationRequest-&gt;itemsToMakeLostCount;</div><div class="line"><a name="l06745"></a><span class="lineno"> 6745</span>&#160;        }</div><div class="line"><a name="l06746"></a><span class="lineno"> 6746</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06747"></a><span class="lineno"> 6747</span>&#160;        {</div><div class="line"><a name="l06748"></a><span class="lineno"> 6748</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06749"></a><span class="lineno"> 6749</span>&#160;        }</div><div class="line"><a name="l06750"></a><span class="lineno"> 6750</span>&#160;    }</div><div class="line"><a name="l06751"></a><span class="lineno"> 6751</span>&#160;</div><div class="line"><a name="l06752"></a><span class="lineno"> 6752</span>&#160;    VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l06753"></a><span class="lineno"> 6753</span>&#160;    VMA_ASSERT(pAllocationRequest-&gt;item != m_Suballocations.end());</div><div class="line"><a name="l06754"></a><span class="lineno"> 6754</span>&#160;    VMA_ASSERT(pAllocationRequest-&gt;item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06755"></a><span class="lineno"> 6755</span>&#160;    </div><div class="line"><a name="l06756"></a><span class="lineno"> 6756</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06757"></a><span class="lineno"> 6757</span>&#160;}</div><div class="line"><a name="l06758"></a><span class="lineno"> 6758</span>&#160;</div><div class="line"><a name="l06759"></a><span class="lineno"> 6759</span>&#160;uint32_t VmaBlockMetadata_Generic::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)</div><div class="line"><a name="l06760"></a><span class="lineno"> 6760</span>&#160;{</div><div class="line"><a name="l06761"></a><span class="lineno"> 6761</span>&#160;    uint32_t lostAllocationCount = 0;</div><div class="line"><a name="l06762"></a><span class="lineno"> 6762</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::iterator it = m_Suballocations.begin();</div><div class="line"><a name="l06763"></a><span class="lineno"> 6763</span>&#160;        it != m_Suballocations.end();</div><div class="line"><a name="l06764"></a><span class="lineno"> 6764</span>&#160;        ++it)</div><div class="line"><a name="l06765"></a><span class="lineno"> 6765</span>&#160;    {</div><div class="line"><a name="l06766"></a><span class="lineno"> 6766</span>&#160;        <span class="keywordflow">if</span>(it-&gt;type != VMA_SUBALLOCATION_TYPE_FREE &amp;&amp;</div><div class="line"><a name="l06767"></a><span class="lineno"> 6767</span>&#160;            it-&gt;hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l06768"></a><span class="lineno"> 6768</span>&#160;            it-&gt;hAllocation-&gt;MakeLost(currentFrameIndex, frameInUseCount))</div><div class="line"><a name="l06769"></a><span class="lineno"> 6769</span>&#160;        {</div><div class="line"><a name="l06770"></a><span class="lineno"> 6770</span>&#160;            it = FreeSuballocation(it);</div><div class="line"><a name="l06771"></a><span class="lineno"> 6771</span>&#160;            ++lostAllocationCount;</div><div class="line"><a name="l06772"></a><span class="lineno"> 6772</span>&#160;        }</div><div class="line"><a name="l06773"></a><span class="lineno"> 6773</span>&#160;    }</div><div class="line"><a name="l06774"></a><span class="lineno"> 6774</span>&#160;    <span class="keywordflow">return</span> lostAllocationCount;</div><div class="line"><a name="l06775"></a><span class="lineno"> 6775</span>&#160;}</div><div class="line"><a name="l06776"></a><span class="lineno"> 6776</span>&#160;</div><div class="line"><a name="l06777"></a><span class="lineno"> 6777</span>&#160;VkResult VmaBlockMetadata_Generic::CheckCorruption(<span class="keyword">const</span> <span class="keywordtype">void</span>* pBlockData)</div><div class="line"><a name="l06778"></a><span class="lineno"> 6778</span>&#160;{</div><div class="line"><a name="l06779"></a><span class="lineno"> 6779</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::iterator it = m_Suballocations.begin();</div><div class="line"><a name="l06780"></a><span class="lineno"> 6780</span>&#160;        it != m_Suballocations.end();</div><div class="line"><a name="l06781"></a><span class="lineno"> 6781</span>&#160;        ++it)</div><div class="line"><a name="l06782"></a><span class="lineno"> 6782</span>&#160;    {</div><div class="line"><a name="l06783"></a><span class="lineno"> 6783</span>&#160;        <span class="keywordflow">if</span>(it-&gt;type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06784"></a><span class="lineno"> 6784</span>&#160;        {</div><div class="line"><a name="l06785"></a><span class="lineno"> 6785</span>&#160;            <span class="keywordflow">if</span>(!VmaValidateMagicValue(pBlockData, it-&gt;offset - VMA_DEBUG_MARGIN))</div><div class="line"><a name="l06786"></a><span class="lineno"> 6786</span>&#160;            {</div><div class="line"><a name="l06787"></a><span class="lineno"> 6787</span>&#160;                VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l06788"></a><span class="lineno"> 6788</span>&#160;                <span class="keywordflow">return</span> VK_ERROR_VALIDATION_FAILED_EXT;</div><div class="line"><a name="l06789"></a><span class="lineno"> 6789</span>&#160;            }</div><div class="line"><a name="l06790"></a><span class="lineno"> 6790</span>&#160;            <span class="keywordflow">if</span>(!VmaValidateMagicValue(pBlockData, it-&gt;offset + it-&gt;size))</div><div class="line"><a name="l06791"></a><span class="lineno"> 6791</span>&#160;            {</div><div class="line"><a name="l06792"></a><span class="lineno"> 6792</span>&#160;                VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l06793"></a><span class="lineno"> 6793</span>&#160;                <span class="keywordflow">return</span> VK_ERROR_VALIDATION_FAILED_EXT;</div><div class="line"><a name="l06794"></a><span class="lineno"> 6794</span>&#160;            }</div><div class="line"><a name="l06795"></a><span class="lineno"> 6795</span>&#160;        }</div><div class="line"><a name="l06796"></a><span class="lineno"> 6796</span>&#160;    }</div><div class="line"><a name="l06797"></a><span class="lineno"> 6797</span>&#160;</div><div class="line"><a name="l06798"></a><span class="lineno"> 6798</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l06799"></a><span class="lineno"> 6799</span>&#160;}</div><div class="line"><a name="l06800"></a><span class="lineno"> 6800</span>&#160;</div><div class="line"><a name="l06801"></a><span class="lineno"> 6801</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::Alloc(</div><div class="line"><a name="l06802"></a><span class="lineno"> 6802</span>&#160;    <span class="keyword">const</span> VmaAllocationRequest&amp; request,</div><div class="line"><a name="l06803"></a><span class="lineno"> 6803</span>&#160;    VmaSuballocationType type,</div><div class="line"><a name="l06804"></a><span class="lineno"> 6804</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l06805"></a><span class="lineno"> 6805</span>&#160;    <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l06806"></a><span class="lineno"> 6806</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l06807"></a><span class="lineno"> 6807</span>&#160;{</div><div class="line"><a name="l06808"></a><span class="lineno"> 6808</span>&#160;    VMA_ASSERT(!upperAddress);</div><div class="line"><a name="l06809"></a><span class="lineno"> 6809</span>&#160;    VMA_ASSERT(request.item != m_Suballocations.end());</div><div class="line"><a name="l06810"></a><span class="lineno"> 6810</span>&#160;    VmaSuballocation&amp; suballoc = *request.item;</div><div class="line"><a name="l06811"></a><span class="lineno"> 6811</span>&#160;    <span class="comment">// Given suballocation is a free block.</span></div><div class="line"><a name="l06812"></a><span class="lineno"> 6812</span>&#160;    VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06813"></a><span class="lineno"> 6813</span>&#160;    <span class="comment">// Given offset is inside this suballocation.</span></div><div class="line"><a name="l06814"></a><span class="lineno"> 6814</span>&#160;    VMA_ASSERT(request.offset &gt;= suballoc.offset);</div><div class="line"><a name="l06815"></a><span class="lineno"> 6815</span>&#160;    <span class="keyword">const</span> VkDeviceSize paddingBegin = request.offset - suballoc.offset;</div><div class="line"><a name="l06816"></a><span class="lineno"> 6816</span>&#160;    VMA_ASSERT(suballoc.size &gt;= paddingBegin + allocSize);</div><div class="line"><a name="l06817"></a><span class="lineno"> 6817</span>&#160;    <span class="keyword">const</span> VkDeviceSize paddingEnd = suballoc.size - paddingBegin - allocSize;</div><div class="line"><a name="l06818"></a><span class="lineno"> 6818</span>&#160;</div><div class="line"><a name="l06819"></a><span class="lineno"> 6819</span>&#160;    <span class="comment">// Unregister this free suballocation from m_FreeSuballocationsBySize and update</span></div><div class="line"><a name="l06820"></a><span class="lineno"> 6820</span>&#160;    <span class="comment">// it to become used.</span></div><div class="line"><a name="l06821"></a><span class="lineno"> 6821</span>&#160;    UnregisterFreeSuballocation(request.item);</div><div class="line"><a name="l06822"></a><span class="lineno"> 6822</span>&#160;</div><div class="line"><a name="l06823"></a><span class="lineno"> 6823</span>&#160;    suballoc.offset = request.offset;</div><div class="line"><a name="l06824"></a><span class="lineno"> 6824</span>&#160;    suballoc.size = allocSize;</div><div class="line"><a name="l06825"></a><span class="lineno"> 6825</span>&#160;    suballoc.type = type;</div><div class="line"><a name="l06826"></a><span class="lineno"> 6826</span>&#160;    suballoc.hAllocation = hAllocation;</div><div class="line"><a name="l06827"></a><span class="lineno"> 6827</span>&#160;</div><div class="line"><a name="l06828"></a><span class="lineno"> 6828</span>&#160;    <span class="comment">// If there are any free bytes remaining at the end, insert new free suballocation after current one.</span></div><div class="line"><a name="l06829"></a><span class="lineno"> 6829</span>&#160;    <span class="keywordflow">if</span>(paddingEnd)</div><div class="line"><a name="l06830"></a><span class="lineno"> 6830</span>&#160;    {</div><div class="line"><a name="l06831"></a><span class="lineno"> 6831</span>&#160;        VmaSuballocation paddingSuballoc = {};</div><div class="line"><a name="l06832"></a><span class="lineno"> 6832</span>&#160;        paddingSuballoc.offset = request.offset + allocSize;</div><div class="line"><a name="l06833"></a><span class="lineno"> 6833</span>&#160;        paddingSuballoc.size = paddingEnd;</div><div class="line"><a name="l06834"></a><span class="lineno"> 6834</span>&#160;        paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l06835"></a><span class="lineno"> 6835</span>&#160;        VmaSuballocationList::iterator next = request.item;</div><div class="line"><a name="l06836"></a><span class="lineno"> 6836</span>&#160;        ++next;</div><div class="line"><a name="l06837"></a><span class="lineno"> 6837</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator paddingEndItem =</div><div class="line"><a name="l06838"></a><span class="lineno"> 6838</span>&#160;            m_Suballocations.insert(next, paddingSuballoc);</div><div class="line"><a name="l06839"></a><span class="lineno"> 6839</span>&#160;        RegisterFreeSuballocation(paddingEndItem);</div><div class="line"><a name="l06840"></a><span class="lineno"> 6840</span>&#160;    }</div><div class="line"><a name="l06841"></a><span class="lineno"> 6841</span>&#160;</div><div class="line"><a name="l06842"></a><span class="lineno"> 6842</span>&#160;    <span class="comment">// If there are any free bytes remaining at the beginning, insert new free suballocation before current one.</span></div><div class="line"><a name="l06843"></a><span class="lineno"> 6843</span>&#160;    <span class="keywordflow">if</span>(paddingBegin)</div><div class="line"><a name="l06844"></a><span class="lineno"> 6844</span>&#160;    {</div><div class="line"><a name="l06845"></a><span class="lineno"> 6845</span>&#160;        VmaSuballocation paddingSuballoc = {};</div><div class="line"><a name="l06846"></a><span class="lineno"> 6846</span>&#160;        paddingSuballoc.offset = request.offset - paddingBegin;</div><div class="line"><a name="l06847"></a><span class="lineno"> 6847</span>&#160;        paddingSuballoc.size = paddingBegin;</div><div class="line"><a name="l06848"></a><span class="lineno"> 6848</span>&#160;        paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l06849"></a><span class="lineno"> 6849</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator paddingBeginItem =</div><div class="line"><a name="l06850"></a><span class="lineno"> 6850</span>&#160;            m_Suballocations.insert(request.item, paddingSuballoc);</div><div class="line"><a name="l06851"></a><span class="lineno"> 6851</span>&#160;        RegisterFreeSuballocation(paddingBeginItem);</div><div class="line"><a name="l06852"></a><span class="lineno"> 6852</span>&#160;    }</div><div class="line"><a name="l06853"></a><span class="lineno"> 6853</span>&#160;</div><div class="line"><a name="l06854"></a><span class="lineno"> 6854</span>&#160;    <span class="comment">// Update totals.</span></div><div class="line"><a name="l06855"></a><span class="lineno"> 6855</span>&#160;    m_FreeCount = m_FreeCount - 1;</div><div class="line"><a name="l06856"></a><span class="lineno"> 6856</span>&#160;    <span class="keywordflow">if</span>(paddingBegin &gt; 0)</div><div class="line"><a name="l06857"></a><span class="lineno"> 6857</span>&#160;    {</div><div class="line"><a name="l06858"></a><span class="lineno"> 6858</span>&#160;        ++m_FreeCount;</div><div class="line"><a name="l06859"></a><span class="lineno"> 6859</span>&#160;    }</div><div class="line"><a name="l06860"></a><span class="lineno"> 6860</span>&#160;    <span class="keywordflow">if</span>(paddingEnd &gt; 0)</div><div class="line"><a name="l06861"></a><span class="lineno"> 6861</span>&#160;    {</div><div class="line"><a name="l06862"></a><span class="lineno"> 6862</span>&#160;        ++m_FreeCount;</div><div class="line"><a name="l06863"></a><span class="lineno"> 6863</span>&#160;    }</div><div class="line"><a name="l06864"></a><span class="lineno"> 6864</span>&#160;    m_SumFreeSize -= allocSize;</div><div class="line"><a name="l06865"></a><span class="lineno"> 6865</span>&#160;}</div><div class="line"><a name="l06866"></a><span class="lineno"> 6866</span>&#160;</div><div class="line"><a name="l06867"></a><span class="lineno"> 6867</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::Free(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l06868"></a><span class="lineno"> 6868</span>&#160;{</div><div class="line"><a name="l06869"></a><span class="lineno"> 6869</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();</div><div class="line"><a name="l06870"></a><span class="lineno"> 6870</span>&#160;        suballocItem != m_Suballocations.end();</div><div class="line"><a name="l06871"></a><span class="lineno"> 6871</span>&#160;        ++suballocItem)</div><div class="line"><a name="l06872"></a><span class="lineno"> 6872</span>&#160;    {</div><div class="line"><a name="l06873"></a><span class="lineno"> 6873</span>&#160;        VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l06874"></a><span class="lineno"> 6874</span>&#160;        <span class="keywordflow">if</span>(suballoc.hAllocation == allocation)</div><div class="line"><a name="l06875"></a><span class="lineno"> 6875</span>&#160;        {</div><div class="line"><a name="l06876"></a><span class="lineno"> 6876</span>&#160;            FreeSuballocation(suballocItem);</div><div class="line"><a name="l06877"></a><span class="lineno"> 6877</span>&#160;            VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l06878"></a><span class="lineno"> 6878</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l06879"></a><span class="lineno"> 6879</span>&#160;        }</div><div class="line"><a name="l06880"></a><span class="lineno"> 6880</span>&#160;    }</div><div class="line"><a name="l06881"></a><span class="lineno"> 6881</span>&#160;    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Not found!&quot;</span>);</div><div class="line"><a name="l06882"></a><span class="lineno"> 6882</span>&#160;}</div><div class="line"><a name="l06883"></a><span class="lineno"> 6883</span>&#160;</div><div class="line"><a name="l06884"></a><span class="lineno"> 6884</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::FreeAtOffset(VkDeviceSize offset)</div><div class="line"><a name="l06885"></a><span class="lineno"> 6885</span>&#160;{</div><div class="line"><a name="l06886"></a><span class="lineno"> 6886</span>&#160;    <span class="keywordflow">for</span>(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();</div><div class="line"><a name="l06887"></a><span class="lineno"> 6887</span>&#160;        suballocItem != m_Suballocations.end();</div><div class="line"><a name="l06888"></a><span class="lineno"> 6888</span>&#160;        ++suballocItem)</div><div class="line"><a name="l06889"></a><span class="lineno"> 6889</span>&#160;    {</div><div class="line"><a name="l06890"></a><span class="lineno"> 6890</span>&#160;        VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l06891"></a><span class="lineno"> 6891</span>&#160;        <span class="keywordflow">if</span>(suballoc.offset == offset)</div><div class="line"><a name="l06892"></a><span class="lineno"> 6892</span>&#160;        {</div><div class="line"><a name="l06893"></a><span class="lineno"> 6893</span>&#160;            FreeSuballocation(suballocItem);</div><div class="line"><a name="l06894"></a><span class="lineno"> 6894</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l06895"></a><span class="lineno"> 6895</span>&#160;        }</div><div class="line"><a name="l06896"></a><span class="lineno"> 6896</span>&#160;    }</div><div class="line"><a name="l06897"></a><span class="lineno"> 6897</span>&#160;    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Not found!&quot;</span>);</div><div class="line"><a name="l06898"></a><span class="lineno"> 6898</span>&#160;}</div><div class="line"><a name="l06899"></a><span class="lineno"> 6899</span>&#160;</div><div class="line"><a name="l06900"></a><span class="lineno"> 6900</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Generic::ValidateFreeSuballocationList()<span class="keyword"> const</span></div><div class="line"><a name="l06901"></a><span class="lineno"> 6901</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06902"></a><span class="lineno"> 6902</span>&#160;    VkDeviceSize lastSize = 0;</div><div class="line"><a name="l06903"></a><span class="lineno"> 6903</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0, count = m_FreeSuballocationsBySize.size(); i &lt; count; ++i)</div><div class="line"><a name="l06904"></a><span class="lineno"> 6904</span>&#160;    {</div><div class="line"><a name="l06905"></a><span class="lineno"> 6905</span>&#160;        <span class="keyword">const</span> VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i];</div><div class="line"><a name="l06906"></a><span class="lineno"> 6906</span>&#160;</div><div class="line"><a name="l06907"></a><span class="lineno"> 6907</span>&#160;        <span class="keywordflow">if</span>(it-&gt;type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06908"></a><span class="lineno"> 6908</span>&#160;        {</div><div class="line"><a name="l06909"></a><span class="lineno"> 6909</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l06910"></a><span class="lineno"> 6910</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06911"></a><span class="lineno"> 6911</span>&#160;        }</div><div class="line"><a name="l06912"></a><span class="lineno"> 6912</span>&#160;        <span class="keywordflow">if</span>(it-&gt;size &lt; VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l06913"></a><span class="lineno"> 6913</span>&#160;        {</div><div class="line"><a name="l06914"></a><span class="lineno"> 6914</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l06915"></a><span class="lineno"> 6915</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06916"></a><span class="lineno"> 6916</span>&#160;        }</div><div class="line"><a name="l06917"></a><span class="lineno"> 6917</span>&#160;        <span class="keywordflow">if</span>(it-&gt;size &lt; lastSize)</div><div class="line"><a name="l06918"></a><span class="lineno"> 6918</span>&#160;        {</div><div class="line"><a name="l06919"></a><span class="lineno"> 6919</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l06920"></a><span class="lineno"> 6920</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06921"></a><span class="lineno"> 6921</span>&#160;        }</div><div class="line"><a name="l06922"></a><span class="lineno"> 6922</span>&#160;</div><div class="line"><a name="l06923"></a><span class="lineno"> 6923</span>&#160;        lastSize = it-&gt;size;</div><div class="line"><a name="l06924"></a><span class="lineno"> 6924</span>&#160;    }</div><div class="line"><a name="l06925"></a><span class="lineno"> 6925</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l06926"></a><span class="lineno"> 6926</span>&#160;}</div><div class="line"><a name="l06927"></a><span class="lineno"> 6927</span>&#160;</div><div class="line"><a name="l06928"></a><span class="lineno"> 6928</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Generic::CheckAllocation(</div><div class="line"><a name="l06929"></a><span class="lineno"> 6929</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l06930"></a><span class="lineno"> 6930</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l06931"></a><span class="lineno"> 6931</span>&#160;    VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l06932"></a><span class="lineno"> 6932</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l06933"></a><span class="lineno"> 6933</span>&#160;    VkDeviceSize allocAlignment,</div><div class="line"><a name="l06934"></a><span class="lineno"> 6934</span>&#160;    VmaSuballocationType allocType,</div><div class="line"><a name="l06935"></a><span class="lineno"> 6935</span>&#160;    VmaSuballocationList::const_iterator suballocItem,</div><div class="line"><a name="l06936"></a><span class="lineno"> 6936</span>&#160;    <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l06937"></a><span class="lineno"> 6937</span>&#160;    VkDeviceSize* pOffset,</div><div class="line"><a name="l06938"></a><span class="lineno"> 6938</span>&#160;    <span class="keywordtype">size_t</span>* itemsToMakeLostCount,</div><div class="line"><a name="l06939"></a><span class="lineno"> 6939</span>&#160;    VkDeviceSize* pSumFreeSize,</div><div class="line"><a name="l06940"></a><span class="lineno"> 6940</span>&#160;    VkDeviceSize* pSumItemSize)<span class="keyword"> const</span></div><div class="line"><a name="l06941"></a><span class="lineno"> 6941</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l06942"></a><span class="lineno"> 6942</span>&#160;    VMA_ASSERT(allocSize &gt; 0);</div><div class="line"><a name="l06943"></a><span class="lineno"> 6943</span>&#160;    VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l06944"></a><span class="lineno"> 6944</span>&#160;    VMA_ASSERT(suballocItem != m_Suballocations.cend());</div><div class="line"><a name="l06945"></a><span class="lineno"> 6945</span>&#160;    VMA_ASSERT(pOffset != VMA_NULL);</div><div class="line"><a name="l06946"></a><span class="lineno"> 6946</span>&#160;    </div><div class="line"><a name="l06947"></a><span class="lineno"> 6947</span>&#160;    *itemsToMakeLostCount = 0;</div><div class="line"><a name="l06948"></a><span class="lineno"> 6948</span>&#160;    *pSumFreeSize = 0;</div><div class="line"><a name="l06949"></a><span class="lineno"> 6949</span>&#160;    *pSumItemSize = 0;</div><div class="line"><a name="l06950"></a><span class="lineno"> 6950</span>&#160;</div><div class="line"><a name="l06951"></a><span class="lineno"> 6951</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost)</div><div class="line"><a name="l06952"></a><span class="lineno"> 6952</span>&#160;    {</div><div class="line"><a name="l06953"></a><span class="lineno"> 6953</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l06954"></a><span class="lineno"> 6954</span>&#160;        {</div><div class="line"><a name="l06955"></a><span class="lineno"> 6955</span>&#160;            *pSumFreeSize = suballocItem-&gt;size;</div><div class="line"><a name="l06956"></a><span class="lineno"> 6956</span>&#160;        }</div><div class="line"><a name="l06957"></a><span class="lineno"> 6957</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l06958"></a><span class="lineno"> 6958</span>&#160;        {</div><div class="line"><a name="l06959"></a><span class="lineno"> 6959</span>&#160;            <span class="keywordflow">if</span>(suballocItem-&gt;hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l06960"></a><span class="lineno"> 6960</span>&#160;                suballocItem-&gt;hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l06961"></a><span class="lineno"> 6961</span>&#160;            {</div><div class="line"><a name="l06962"></a><span class="lineno"> 6962</span>&#160;                ++*itemsToMakeLostCount;</div><div class="line"><a name="l06963"></a><span class="lineno"> 6963</span>&#160;                *pSumItemSize = suballocItem-&gt;size;</div><div class="line"><a name="l06964"></a><span class="lineno"> 6964</span>&#160;            }</div><div class="line"><a name="l06965"></a><span class="lineno"> 6965</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l06966"></a><span class="lineno"> 6966</span>&#160;            {</div><div class="line"><a name="l06967"></a><span class="lineno"> 6967</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06968"></a><span class="lineno"> 6968</span>&#160;            }</div><div class="line"><a name="l06969"></a><span class="lineno"> 6969</span>&#160;        }</div><div class="line"><a name="l06970"></a><span class="lineno"> 6970</span>&#160;</div><div class="line"><a name="l06971"></a><span class="lineno"> 6971</span>&#160;        <span class="comment">// Remaining size is too small for this request: Early return.</span></div><div class="line"><a name="l06972"></a><span class="lineno"> 6972</span>&#160;        <span class="keywordflow">if</span>(GetSize() - suballocItem-&gt;offset &lt; allocSize)</div><div class="line"><a name="l06973"></a><span class="lineno"> 6973</span>&#160;        {</div><div class="line"><a name="l06974"></a><span class="lineno"> 6974</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l06975"></a><span class="lineno"> 6975</span>&#160;        }</div><div class="line"><a name="l06976"></a><span class="lineno"> 6976</span>&#160;</div><div class="line"><a name="l06977"></a><span class="lineno"> 6977</span>&#160;        <span class="comment">// Start from offset equal to beginning of this suballocation.</span></div><div class="line"><a name="l06978"></a><span class="lineno"> 6978</span>&#160;        *pOffset = suballocItem-&gt;offset;</div><div class="line"><a name="l06979"></a><span class="lineno"> 6979</span>&#160;    </div><div class="line"><a name="l06980"></a><span class="lineno"> 6980</span>&#160;        <span class="comment">// Apply VMA_DEBUG_MARGIN at the beginning.</span></div><div class="line"><a name="l06981"></a><span class="lineno"> 6981</span>&#160;        <span class="keywordflow">if</span>(VMA_DEBUG_MARGIN &gt; 0)</div><div class="line"><a name="l06982"></a><span class="lineno"> 6982</span>&#160;        {</div><div class="line"><a name="l06983"></a><span class="lineno"> 6983</span>&#160;            *pOffset += VMA_DEBUG_MARGIN;</div><div class="line"><a name="l06984"></a><span class="lineno"> 6984</span>&#160;        }</div><div class="line"><a name="l06985"></a><span class="lineno"> 6985</span>&#160;    </div><div class="line"><a name="l06986"></a><span class="lineno"> 6986</span>&#160;        <span class="comment">// Apply alignment.</span></div><div class="line"><a name="l06987"></a><span class="lineno"> 6987</span>&#160;        *pOffset = VmaAlignUp(*pOffset, allocAlignment);</div><div class="line"><a name="l06988"></a><span class="lineno"> 6988</span>&#160;</div><div class="line"><a name="l06989"></a><span class="lineno"> 6989</span>&#160;        <span class="comment">// Check previous suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l06990"></a><span class="lineno"> 6990</span>&#160;        <span class="comment">// Make bigger alignment if necessary.</span></div><div class="line"><a name="l06991"></a><span class="lineno"> 6991</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l06992"></a><span class="lineno"> 6992</span>&#160;        {</div><div class="line"><a name="l06993"></a><span class="lineno"> 6993</span>&#160;            <span class="keywordtype">bool</span> bufferImageGranularityConflict = <span class="keyword">false</span>;</div><div class="line"><a name="l06994"></a><span class="lineno"> 6994</span>&#160;            VmaSuballocationList::const_iterator prevSuballocItem = suballocItem;</div><div class="line"><a name="l06995"></a><span class="lineno"> 6995</span>&#160;            <span class="keywordflow">while</span>(prevSuballocItem != m_Suballocations.cbegin())</div><div class="line"><a name="l06996"></a><span class="lineno"> 6996</span>&#160;            {</div><div class="line"><a name="l06997"></a><span class="lineno"> 6997</span>&#160;                --prevSuballocItem;</div><div class="line"><a name="l06998"></a><span class="lineno"> 6998</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; prevSuballoc = *prevSuballocItem;</div><div class="line"><a name="l06999"></a><span class="lineno"> 6999</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, *pOffset, bufferImageGranularity))</div><div class="line"><a name="l07000"></a><span class="lineno"> 7000</span>&#160;                {</div><div class="line"><a name="l07001"></a><span class="lineno"> 7001</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))</div><div class="line"><a name="l07002"></a><span class="lineno"> 7002</span>&#160;                    {</div><div class="line"><a name="l07003"></a><span class="lineno"> 7003</span>&#160;                        bufferImageGranularityConflict = <span class="keyword">true</span>;</div><div class="line"><a name="l07004"></a><span class="lineno"> 7004</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l07005"></a><span class="lineno"> 7005</span>&#160;                    }</div><div class="line"><a name="l07006"></a><span class="lineno"> 7006</span>&#160;                }</div><div class="line"><a name="l07007"></a><span class="lineno"> 7007</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l07008"></a><span class="lineno"> 7008</span>&#160;                    <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l07009"></a><span class="lineno"> 7009</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l07010"></a><span class="lineno"> 7010</span>&#160;            }</div><div class="line"><a name="l07011"></a><span class="lineno"> 7011</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularityConflict)</div><div class="line"><a name="l07012"></a><span class="lineno"> 7012</span>&#160;            {</div><div class="line"><a name="l07013"></a><span class="lineno"> 7013</span>&#160;                *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity);</div><div class="line"><a name="l07014"></a><span class="lineno"> 7014</span>&#160;            }</div><div class="line"><a name="l07015"></a><span class="lineno"> 7015</span>&#160;        }</div><div class="line"><a name="l07016"></a><span class="lineno"> 7016</span>&#160;    </div><div class="line"><a name="l07017"></a><span class="lineno"> 7017</span>&#160;        <span class="comment">// Now that we have final *pOffset, check if we are past suballocItem.</span></div><div class="line"><a name="l07018"></a><span class="lineno"> 7018</span>&#160;        <span class="comment">// If yes, return false - this function should be called for another suballocItem as starting point.</span></div><div class="line"><a name="l07019"></a><span class="lineno"> 7019</span>&#160;        <span class="keywordflow">if</span>(*pOffset &gt;= suballocItem-&gt;offset + suballocItem-&gt;size)</div><div class="line"><a name="l07020"></a><span class="lineno"> 7020</span>&#160;        {</div><div class="line"><a name="l07021"></a><span class="lineno"> 7021</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07022"></a><span class="lineno"> 7022</span>&#160;        }</div><div class="line"><a name="l07023"></a><span class="lineno"> 7023</span>&#160;    </div><div class="line"><a name="l07024"></a><span class="lineno"> 7024</span>&#160;        <span class="comment">// Calculate padding at the beginning based on current offset.</span></div><div class="line"><a name="l07025"></a><span class="lineno"> 7025</span>&#160;        <span class="keyword">const</span> VkDeviceSize paddingBegin = *pOffset - suballocItem-&gt;offset;</div><div class="line"><a name="l07026"></a><span class="lineno"> 7026</span>&#160;</div><div class="line"><a name="l07027"></a><span class="lineno"> 7027</span>&#160;        <span class="comment">// Calculate required margin at the end.</span></div><div class="line"><a name="l07028"></a><span class="lineno"> 7028</span>&#160;        <span class="keyword">const</span> VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN;</div><div class="line"><a name="l07029"></a><span class="lineno"> 7029</span>&#160;</div><div class="line"><a name="l07030"></a><span class="lineno"> 7030</span>&#160;        <span class="keyword">const</span> VkDeviceSize totalSize = paddingBegin + allocSize + requiredEndMargin;</div><div class="line"><a name="l07031"></a><span class="lineno"> 7031</span>&#160;        <span class="comment">// Another early return check.</span></div><div class="line"><a name="l07032"></a><span class="lineno"> 7032</span>&#160;        <span class="keywordflow">if</span>(suballocItem-&gt;offset + totalSize &gt; GetSize())</div><div class="line"><a name="l07033"></a><span class="lineno"> 7033</span>&#160;        {</div><div class="line"><a name="l07034"></a><span class="lineno"> 7034</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07035"></a><span class="lineno"> 7035</span>&#160;        }</div><div class="line"><a name="l07036"></a><span class="lineno"> 7036</span>&#160;</div><div class="line"><a name="l07037"></a><span class="lineno"> 7037</span>&#160;        <span class="comment">// Advance lastSuballocItem until desired size is reached.</span></div><div class="line"><a name="l07038"></a><span class="lineno"> 7038</span>&#160;        <span class="comment">// Update itemsToMakeLostCount.</span></div><div class="line"><a name="l07039"></a><span class="lineno"> 7039</span>&#160;        VmaSuballocationList::const_iterator lastSuballocItem = suballocItem;</div><div class="line"><a name="l07040"></a><span class="lineno"> 7040</span>&#160;        <span class="keywordflow">if</span>(totalSize &gt; suballocItem-&gt;size)</div><div class="line"><a name="l07041"></a><span class="lineno"> 7041</span>&#160;        {</div><div class="line"><a name="l07042"></a><span class="lineno"> 7042</span>&#160;            VkDeviceSize remainingSize = totalSize - suballocItem-&gt;size;</div><div class="line"><a name="l07043"></a><span class="lineno"> 7043</span>&#160;            <span class="keywordflow">while</span>(remainingSize &gt; 0)</div><div class="line"><a name="l07044"></a><span class="lineno"> 7044</span>&#160;            {</div><div class="line"><a name="l07045"></a><span class="lineno"> 7045</span>&#160;                ++lastSuballocItem;</div><div class="line"><a name="l07046"></a><span class="lineno"> 7046</span>&#160;                <span class="keywordflow">if</span>(lastSuballocItem == m_Suballocations.cend())</div><div class="line"><a name="l07047"></a><span class="lineno"> 7047</span>&#160;                {</div><div class="line"><a name="l07048"></a><span class="lineno"> 7048</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07049"></a><span class="lineno"> 7049</span>&#160;                }</div><div class="line"><a name="l07050"></a><span class="lineno"> 7050</span>&#160;                <span class="keywordflow">if</span>(lastSuballocItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l07051"></a><span class="lineno"> 7051</span>&#160;                {</div><div class="line"><a name="l07052"></a><span class="lineno"> 7052</span>&#160;                    *pSumFreeSize += lastSuballocItem-&gt;size;</div><div class="line"><a name="l07053"></a><span class="lineno"> 7053</span>&#160;                }</div><div class="line"><a name="l07054"></a><span class="lineno"> 7054</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l07055"></a><span class="lineno"> 7055</span>&#160;                {</div><div class="line"><a name="l07056"></a><span class="lineno"> 7056</span>&#160;                    VMA_ASSERT(lastSuballocItem-&gt;hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l07057"></a><span class="lineno"> 7057</span>&#160;                    <span class="keywordflow">if</span>(lastSuballocItem-&gt;hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l07058"></a><span class="lineno"> 7058</span>&#160;                        lastSuballocItem-&gt;hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l07059"></a><span class="lineno"> 7059</span>&#160;                    {</div><div class="line"><a name="l07060"></a><span class="lineno"> 7060</span>&#160;                        ++*itemsToMakeLostCount;</div><div class="line"><a name="l07061"></a><span class="lineno"> 7061</span>&#160;                        *pSumItemSize += lastSuballocItem-&gt;size;</div><div class="line"><a name="l07062"></a><span class="lineno"> 7062</span>&#160;                    }</div><div class="line"><a name="l07063"></a><span class="lineno"> 7063</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l07064"></a><span class="lineno"> 7064</span>&#160;                    {</div><div class="line"><a name="l07065"></a><span class="lineno"> 7065</span>&#160;                        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07066"></a><span class="lineno"> 7066</span>&#160;                    }</div><div class="line"><a name="l07067"></a><span class="lineno"> 7067</span>&#160;                }</div><div class="line"><a name="l07068"></a><span class="lineno"> 7068</span>&#160;                remainingSize = (lastSuballocItem-&gt;size &lt; remainingSize) ?</div><div class="line"><a name="l07069"></a><span class="lineno"> 7069</span>&#160;                    remainingSize - lastSuballocItem-&gt;size : 0;</div><div class="line"><a name="l07070"></a><span class="lineno"> 7070</span>&#160;            }</div><div class="line"><a name="l07071"></a><span class="lineno"> 7071</span>&#160;        }</div><div class="line"><a name="l07072"></a><span class="lineno"> 7072</span>&#160;</div><div class="line"><a name="l07073"></a><span class="lineno"> 7073</span>&#160;        <span class="comment">// Check next suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l07074"></a><span class="lineno"> 7074</span>&#160;        <span class="comment">// If conflict exists, we must mark more allocations lost or fail.</span></div><div class="line"><a name="l07075"></a><span class="lineno"> 7075</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l07076"></a><span class="lineno"> 7076</span>&#160;        {</div><div class="line"><a name="l07077"></a><span class="lineno"> 7077</span>&#160;            VmaSuballocationList::const_iterator nextSuballocItem = lastSuballocItem;</div><div class="line"><a name="l07078"></a><span class="lineno"> 7078</span>&#160;            ++nextSuballocItem;</div><div class="line"><a name="l07079"></a><span class="lineno"> 7079</span>&#160;            <span class="keywordflow">while</span>(nextSuballocItem != m_Suballocations.cend())</div><div class="line"><a name="l07080"></a><span class="lineno"> 7080</span>&#160;            {</div><div class="line"><a name="l07081"></a><span class="lineno"> 7081</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; nextSuballoc = *nextSuballocItem;</div><div class="line"><a name="l07082"></a><span class="lineno"> 7082</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(*pOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l07083"></a><span class="lineno"> 7083</span>&#160;                {</div><div class="line"><a name="l07084"></a><span class="lineno"> 7084</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))</div><div class="line"><a name="l07085"></a><span class="lineno"> 7085</span>&#160;                    {</div><div class="line"><a name="l07086"></a><span class="lineno"> 7086</span>&#160;                        VMA_ASSERT(nextSuballoc.hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l07087"></a><span class="lineno"> 7087</span>&#160;                        <span class="keywordflow">if</span>(nextSuballoc.hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l07088"></a><span class="lineno"> 7088</span>&#160;                            nextSuballoc.hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l07089"></a><span class="lineno"> 7089</span>&#160;                        {</div><div class="line"><a name="l07090"></a><span class="lineno"> 7090</span>&#160;                            ++*itemsToMakeLostCount;</div><div class="line"><a name="l07091"></a><span class="lineno"> 7091</span>&#160;                        }</div><div class="line"><a name="l07092"></a><span class="lineno"> 7092</span>&#160;                        <span class="keywordflow">else</span></div><div class="line"><a name="l07093"></a><span class="lineno"> 7093</span>&#160;                        {</div><div class="line"><a name="l07094"></a><span class="lineno"> 7094</span>&#160;                            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07095"></a><span class="lineno"> 7095</span>&#160;                        }</div><div class="line"><a name="l07096"></a><span class="lineno"> 7096</span>&#160;                    }</div><div class="line"><a name="l07097"></a><span class="lineno"> 7097</span>&#160;                }</div><div class="line"><a name="l07098"></a><span class="lineno"> 7098</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l07099"></a><span class="lineno"> 7099</span>&#160;                {</div><div class="line"><a name="l07100"></a><span class="lineno"> 7100</span>&#160;                    <span class="comment">// Already on next page.</span></div><div class="line"><a name="l07101"></a><span class="lineno"> 7101</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l07102"></a><span class="lineno"> 7102</span>&#160;                }</div><div class="line"><a name="l07103"></a><span class="lineno"> 7103</span>&#160;                ++nextSuballocItem;</div><div class="line"><a name="l07104"></a><span class="lineno"> 7104</span>&#160;            }</div><div class="line"><a name="l07105"></a><span class="lineno"> 7105</span>&#160;        }</div><div class="line"><a name="l07106"></a><span class="lineno"> 7106</span>&#160;    }</div><div class="line"><a name="l07107"></a><span class="lineno"> 7107</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l07108"></a><span class="lineno"> 7108</span>&#160;    {</div><div class="line"><a name="l07109"></a><span class="lineno"> 7109</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l07110"></a><span class="lineno"> 7110</span>&#160;        VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07111"></a><span class="lineno"> 7111</span>&#160;</div><div class="line"><a name="l07112"></a><span class="lineno"> 7112</span>&#160;        *pSumFreeSize = suballoc.size;</div><div class="line"><a name="l07113"></a><span class="lineno"> 7113</span>&#160;</div><div class="line"><a name="l07114"></a><span class="lineno"> 7114</span>&#160;        <span class="comment">// Size of this suballocation is too small for this request: Early return.</span></div><div class="line"><a name="l07115"></a><span class="lineno"> 7115</span>&#160;        <span class="keywordflow">if</span>(suballoc.size &lt; allocSize)</div><div class="line"><a name="l07116"></a><span class="lineno"> 7116</span>&#160;        {</div><div class="line"><a name="l07117"></a><span class="lineno"> 7117</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07118"></a><span class="lineno"> 7118</span>&#160;        }</div><div class="line"><a name="l07119"></a><span class="lineno"> 7119</span>&#160;</div><div class="line"><a name="l07120"></a><span class="lineno"> 7120</span>&#160;        <span class="comment">// Start from offset equal to beginning of this suballocation.</span></div><div class="line"><a name="l07121"></a><span class="lineno"> 7121</span>&#160;        *pOffset = suballoc.offset;</div><div class="line"><a name="l07122"></a><span class="lineno"> 7122</span>&#160;    </div><div class="line"><a name="l07123"></a><span class="lineno"> 7123</span>&#160;        <span class="comment">// Apply VMA_DEBUG_MARGIN at the beginning.</span></div><div class="line"><a name="l07124"></a><span class="lineno"> 7124</span>&#160;        <span class="keywordflow">if</span>(VMA_DEBUG_MARGIN &gt; 0)</div><div class="line"><a name="l07125"></a><span class="lineno"> 7125</span>&#160;        {</div><div class="line"><a name="l07126"></a><span class="lineno"> 7126</span>&#160;            *pOffset += VMA_DEBUG_MARGIN;</div><div class="line"><a name="l07127"></a><span class="lineno"> 7127</span>&#160;        }</div><div class="line"><a name="l07128"></a><span class="lineno"> 7128</span>&#160;    </div><div class="line"><a name="l07129"></a><span class="lineno"> 7129</span>&#160;        <span class="comment">// Apply alignment.</span></div><div class="line"><a name="l07130"></a><span class="lineno"> 7130</span>&#160;        *pOffset = VmaAlignUp(*pOffset, allocAlignment);</div><div class="line"><a name="l07131"></a><span class="lineno"> 7131</span>&#160;    </div><div class="line"><a name="l07132"></a><span class="lineno"> 7132</span>&#160;        <span class="comment">// Check previous suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l07133"></a><span class="lineno"> 7133</span>&#160;        <span class="comment">// Make bigger alignment if necessary.</span></div><div class="line"><a name="l07134"></a><span class="lineno"> 7134</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l07135"></a><span class="lineno"> 7135</span>&#160;        {</div><div class="line"><a name="l07136"></a><span class="lineno"> 7136</span>&#160;            <span class="keywordtype">bool</span> bufferImageGranularityConflict = <span class="keyword">false</span>;</div><div class="line"><a name="l07137"></a><span class="lineno"> 7137</span>&#160;            VmaSuballocationList::const_iterator prevSuballocItem = suballocItem;</div><div class="line"><a name="l07138"></a><span class="lineno"> 7138</span>&#160;            <span class="keywordflow">while</span>(prevSuballocItem != m_Suballocations.cbegin())</div><div class="line"><a name="l07139"></a><span class="lineno"> 7139</span>&#160;            {</div><div class="line"><a name="l07140"></a><span class="lineno"> 7140</span>&#160;                --prevSuballocItem;</div><div class="line"><a name="l07141"></a><span class="lineno"> 7141</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; prevSuballoc = *prevSuballocItem;</div><div class="line"><a name="l07142"></a><span class="lineno"> 7142</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, *pOffset, bufferImageGranularity))</div><div class="line"><a name="l07143"></a><span class="lineno"> 7143</span>&#160;                {</div><div class="line"><a name="l07144"></a><span class="lineno"> 7144</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))</div><div class="line"><a name="l07145"></a><span class="lineno"> 7145</span>&#160;                    {</div><div class="line"><a name="l07146"></a><span class="lineno"> 7146</span>&#160;                        bufferImageGranularityConflict = <span class="keyword">true</span>;</div><div class="line"><a name="l07147"></a><span class="lineno"> 7147</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l07148"></a><span class="lineno"> 7148</span>&#160;                    }</div><div class="line"><a name="l07149"></a><span class="lineno"> 7149</span>&#160;                }</div><div class="line"><a name="l07150"></a><span class="lineno"> 7150</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l07151"></a><span class="lineno"> 7151</span>&#160;                    <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l07152"></a><span class="lineno"> 7152</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l07153"></a><span class="lineno"> 7153</span>&#160;            }</div><div class="line"><a name="l07154"></a><span class="lineno"> 7154</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularityConflict)</div><div class="line"><a name="l07155"></a><span class="lineno"> 7155</span>&#160;            {</div><div class="line"><a name="l07156"></a><span class="lineno"> 7156</span>&#160;                *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity);</div><div class="line"><a name="l07157"></a><span class="lineno"> 7157</span>&#160;            }</div><div class="line"><a name="l07158"></a><span class="lineno"> 7158</span>&#160;        }</div><div class="line"><a name="l07159"></a><span class="lineno"> 7159</span>&#160;    </div><div class="line"><a name="l07160"></a><span class="lineno"> 7160</span>&#160;        <span class="comment">// Calculate padding at the beginning based on current offset.</span></div><div class="line"><a name="l07161"></a><span class="lineno"> 7161</span>&#160;        <span class="keyword">const</span> VkDeviceSize paddingBegin = *pOffset - suballoc.offset;</div><div class="line"><a name="l07162"></a><span class="lineno"> 7162</span>&#160;</div><div class="line"><a name="l07163"></a><span class="lineno"> 7163</span>&#160;        <span class="comment">// Calculate required margin at the end.</span></div><div class="line"><a name="l07164"></a><span class="lineno"> 7164</span>&#160;        <span class="keyword">const</span> VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN;</div><div class="line"><a name="l07165"></a><span class="lineno"> 7165</span>&#160;</div><div class="line"><a name="l07166"></a><span class="lineno"> 7166</span>&#160;        <span class="comment">// Fail if requested size plus margin before and after is bigger than size of this suballocation.</span></div><div class="line"><a name="l07167"></a><span class="lineno"> 7167</span>&#160;        <span class="keywordflow">if</span>(paddingBegin + allocSize + requiredEndMargin &gt; suballoc.size)</div><div class="line"><a name="l07168"></a><span class="lineno"> 7168</span>&#160;        {</div><div class="line"><a name="l07169"></a><span class="lineno"> 7169</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07170"></a><span class="lineno"> 7170</span>&#160;        }</div><div class="line"><a name="l07171"></a><span class="lineno"> 7171</span>&#160;</div><div class="line"><a name="l07172"></a><span class="lineno"> 7172</span>&#160;        <span class="comment">// Check next suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l07173"></a><span class="lineno"> 7173</span>&#160;        <span class="comment">// If conflict exists, allocation cannot be made here.</span></div><div class="line"><a name="l07174"></a><span class="lineno"> 7174</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l07175"></a><span class="lineno"> 7175</span>&#160;        {</div><div class="line"><a name="l07176"></a><span class="lineno"> 7176</span>&#160;            VmaSuballocationList::const_iterator nextSuballocItem = suballocItem;</div><div class="line"><a name="l07177"></a><span class="lineno"> 7177</span>&#160;            ++nextSuballocItem;</div><div class="line"><a name="l07178"></a><span class="lineno"> 7178</span>&#160;            <span class="keywordflow">while</span>(nextSuballocItem != m_Suballocations.cend())</div><div class="line"><a name="l07179"></a><span class="lineno"> 7179</span>&#160;            {</div><div class="line"><a name="l07180"></a><span class="lineno"> 7180</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; nextSuballoc = *nextSuballocItem;</div><div class="line"><a name="l07181"></a><span class="lineno"> 7181</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(*pOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l07182"></a><span class="lineno"> 7182</span>&#160;                {</div><div class="line"><a name="l07183"></a><span class="lineno"> 7183</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))</div><div class="line"><a name="l07184"></a><span class="lineno"> 7184</span>&#160;                    {</div><div class="line"><a name="l07185"></a><span class="lineno"> 7185</span>&#160;                        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07186"></a><span class="lineno"> 7186</span>&#160;                    }</div><div class="line"><a name="l07187"></a><span class="lineno"> 7187</span>&#160;                }</div><div class="line"><a name="l07188"></a><span class="lineno"> 7188</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l07189"></a><span class="lineno"> 7189</span>&#160;                {</div><div class="line"><a name="l07190"></a><span class="lineno"> 7190</span>&#160;                    <span class="comment">// Already on next page.</span></div><div class="line"><a name="l07191"></a><span class="lineno"> 7191</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l07192"></a><span class="lineno"> 7192</span>&#160;                }</div><div class="line"><a name="l07193"></a><span class="lineno"> 7193</span>&#160;                ++nextSuballocItem;</div><div class="line"><a name="l07194"></a><span class="lineno"> 7194</span>&#160;            }</div><div class="line"><a name="l07195"></a><span class="lineno"> 7195</span>&#160;        }</div><div class="line"><a name="l07196"></a><span class="lineno"> 7196</span>&#160;    }</div><div class="line"><a name="l07197"></a><span class="lineno"> 7197</span>&#160;</div><div class="line"><a name="l07198"></a><span class="lineno"> 7198</span>&#160;    <span class="comment">// All tests passed: Success. pOffset is already filled.</span></div><div class="line"><a name="l07199"></a><span class="lineno"> 7199</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l07200"></a><span class="lineno"> 7200</span>&#160;}</div><div class="line"><a name="l07201"></a><span class="lineno"> 7201</span>&#160;</div><div class="line"><a name="l07202"></a><span class="lineno"> 7202</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::MergeFreeWithNext(VmaSuballocationList::iterator item)</div><div class="line"><a name="l07203"></a><span class="lineno"> 7203</span>&#160;{</div><div class="line"><a name="l07204"></a><span class="lineno"> 7204</span>&#160;    VMA_ASSERT(item != m_Suballocations.end());</div><div class="line"><a name="l07205"></a><span class="lineno"> 7205</span>&#160;    VMA_ASSERT(item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07206"></a><span class="lineno"> 7206</span>&#160;    </div><div class="line"><a name="l07207"></a><span class="lineno"> 7207</span>&#160;    VmaSuballocationList::iterator nextItem = item;</div><div class="line"><a name="l07208"></a><span class="lineno"> 7208</span>&#160;    ++nextItem;</div><div class="line"><a name="l07209"></a><span class="lineno"> 7209</span>&#160;    VMA_ASSERT(nextItem != m_Suballocations.end());</div><div class="line"><a name="l07210"></a><span class="lineno"> 7210</span>&#160;    VMA_ASSERT(nextItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07211"></a><span class="lineno"> 7211</span>&#160;</div><div class="line"><a name="l07212"></a><span class="lineno"> 7212</span>&#160;    item-&gt;size += nextItem-&gt;size;</div><div class="line"><a name="l07213"></a><span class="lineno"> 7213</span>&#160;    --m_FreeCount;</div><div class="line"><a name="l07214"></a><span class="lineno"> 7214</span>&#160;    m_Suballocations.erase(nextItem);</div><div class="line"><a name="l07215"></a><span class="lineno"> 7215</span>&#160;}</div><div class="line"><a name="l07216"></a><span class="lineno"> 7216</span>&#160;</div><div class="line"><a name="l07217"></a><span class="lineno"> 7217</span>&#160;VmaSuballocationList::iterator VmaBlockMetadata_Generic::FreeSuballocation(VmaSuballocationList::iterator suballocItem)</div><div class="line"><a name="l07218"></a><span class="lineno"> 7218</span>&#160;{</div><div class="line"><a name="l07219"></a><span class="lineno"> 7219</span>&#160;    <span class="comment">// Change this suballocation to be marked as free.</span></div><div class="line"><a name="l07220"></a><span class="lineno"> 7220</span>&#160;    VmaSuballocation&amp; suballoc = *suballocItem;</div><div class="line"><a name="l07221"></a><span class="lineno"> 7221</span>&#160;    suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l07222"></a><span class="lineno"> 7222</span>&#160;    suballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l07223"></a><span class="lineno"> 7223</span>&#160;    </div><div class="line"><a name="l07224"></a><span class="lineno"> 7224</span>&#160;    <span class="comment">// Update totals.</span></div><div class="line"><a name="l07225"></a><span class="lineno"> 7225</span>&#160;    ++m_FreeCount;</div><div class="line"><a name="l07226"></a><span class="lineno"> 7226</span>&#160;    m_SumFreeSize += suballoc.size;</div><div class="line"><a name="l07227"></a><span class="lineno"> 7227</span>&#160;</div><div class="line"><a name="l07228"></a><span class="lineno"> 7228</span>&#160;    <span class="comment">// Merge with previous and/or next suballocation if it&#39;s also free.</span></div><div class="line"><a name="l07229"></a><span class="lineno"> 7229</span>&#160;    <span class="keywordtype">bool</span> mergeWithNext = <span class="keyword">false</span>;</div><div class="line"><a name="l07230"></a><span class="lineno"> 7230</span>&#160;    <span class="keywordtype">bool</span> mergeWithPrev = <span class="keyword">false</span>;</div><div class="line"><a name="l07231"></a><span class="lineno"> 7231</span>&#160;    </div><div class="line"><a name="l07232"></a><span class="lineno"> 7232</span>&#160;    VmaSuballocationList::iterator nextItem = suballocItem;</div><div class="line"><a name="l07233"></a><span class="lineno"> 7233</span>&#160;    ++nextItem;</div><div class="line"><a name="l07234"></a><span class="lineno"> 7234</span>&#160;    <span class="keywordflow">if</span>((nextItem != m_Suballocations.end()) &amp;&amp; (nextItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE))</div><div class="line"><a name="l07235"></a><span class="lineno"> 7235</span>&#160;    {</div><div class="line"><a name="l07236"></a><span class="lineno"> 7236</span>&#160;        mergeWithNext = <span class="keyword">true</span>;</div><div class="line"><a name="l07237"></a><span class="lineno"> 7237</span>&#160;    }</div><div class="line"><a name="l07238"></a><span class="lineno"> 7238</span>&#160;</div><div class="line"><a name="l07239"></a><span class="lineno"> 7239</span>&#160;    VmaSuballocationList::iterator prevItem = suballocItem;</div><div class="line"><a name="l07240"></a><span class="lineno"> 7240</span>&#160;    <span class="keywordflow">if</span>(suballocItem != m_Suballocations.begin())</div><div class="line"><a name="l07241"></a><span class="lineno"> 7241</span>&#160;    {</div><div class="line"><a name="l07242"></a><span class="lineno"> 7242</span>&#160;        --prevItem;</div><div class="line"><a name="l07243"></a><span class="lineno"> 7243</span>&#160;        <span class="keywordflow">if</span>(prevItem-&gt;type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l07244"></a><span class="lineno"> 7244</span>&#160;        {</div><div class="line"><a name="l07245"></a><span class="lineno"> 7245</span>&#160;            mergeWithPrev = <span class="keyword">true</span>;</div><div class="line"><a name="l07246"></a><span class="lineno"> 7246</span>&#160;        }</div><div class="line"><a name="l07247"></a><span class="lineno"> 7247</span>&#160;    }</div><div class="line"><a name="l07248"></a><span class="lineno"> 7248</span>&#160;</div><div class="line"><a name="l07249"></a><span class="lineno"> 7249</span>&#160;    <span class="keywordflow">if</span>(mergeWithNext)</div><div class="line"><a name="l07250"></a><span class="lineno"> 7250</span>&#160;    {</div><div class="line"><a name="l07251"></a><span class="lineno"> 7251</span>&#160;        UnregisterFreeSuballocation(nextItem);</div><div class="line"><a name="l07252"></a><span class="lineno"> 7252</span>&#160;        MergeFreeWithNext(suballocItem);</div><div class="line"><a name="l07253"></a><span class="lineno"> 7253</span>&#160;    }</div><div class="line"><a name="l07254"></a><span class="lineno"> 7254</span>&#160;</div><div class="line"><a name="l07255"></a><span class="lineno"> 7255</span>&#160;    <span class="keywordflow">if</span>(mergeWithPrev)</div><div class="line"><a name="l07256"></a><span class="lineno"> 7256</span>&#160;    {</div><div class="line"><a name="l07257"></a><span class="lineno"> 7257</span>&#160;        UnregisterFreeSuballocation(prevItem);</div><div class="line"><a name="l07258"></a><span class="lineno"> 7258</span>&#160;        MergeFreeWithNext(prevItem);</div><div class="line"><a name="l07259"></a><span class="lineno"> 7259</span>&#160;        RegisterFreeSuballocation(prevItem);</div><div class="line"><a name="l07260"></a><span class="lineno"> 7260</span>&#160;        <span class="keywordflow">return</span> prevItem;</div><div class="line"><a name="l07261"></a><span class="lineno"> 7261</span>&#160;    }</div><div class="line"><a name="l07262"></a><span class="lineno"> 7262</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l07263"></a><span class="lineno"> 7263</span>&#160;    {</div><div class="line"><a name="l07264"></a><span class="lineno"> 7264</span>&#160;        RegisterFreeSuballocation(suballocItem);</div><div class="line"><a name="l07265"></a><span class="lineno"> 7265</span>&#160;        <span class="keywordflow">return</span> suballocItem;</div><div class="line"><a name="l07266"></a><span class="lineno"> 7266</span>&#160;    }</div><div class="line"><a name="l07267"></a><span class="lineno"> 7267</span>&#160;}</div><div class="line"><a name="l07268"></a><span class="lineno"> 7268</span>&#160;</div><div class="line"><a name="l07269"></a><span class="lineno"> 7269</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::RegisterFreeSuballocation(VmaSuballocationList::iterator item)</div><div class="line"><a name="l07270"></a><span class="lineno"> 7270</span>&#160;{</div><div class="line"><a name="l07271"></a><span class="lineno"> 7271</span>&#160;    VMA_ASSERT(item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07272"></a><span class="lineno"> 7272</span>&#160;    VMA_ASSERT(item-&gt;size &gt; 0);</div><div class="line"><a name="l07273"></a><span class="lineno"> 7273</span>&#160;</div><div class="line"><a name="l07274"></a><span class="lineno"> 7274</span>&#160;    <span class="comment">// You may want to enable this validation at the beginning or at the end of</span></div><div class="line"><a name="l07275"></a><span class="lineno"> 7275</span>&#160;    <span class="comment">// this function, depending on what do you want to check.</span></div><div class="line"><a name="l07276"></a><span class="lineno"> 7276</span>&#160;    VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</div><div class="line"><a name="l07277"></a><span class="lineno"> 7277</span>&#160;</div><div class="line"><a name="l07278"></a><span class="lineno"> 7278</span>&#160;    <span class="keywordflow">if</span>(item-&gt;size &gt;= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l07279"></a><span class="lineno"> 7279</span>&#160;    {</div><div class="line"><a name="l07280"></a><span class="lineno"> 7280</span>&#160;        <span class="keywordflow">if</span>(m_FreeSuballocationsBySize.empty())</div><div class="line"><a name="l07281"></a><span class="lineno"> 7281</span>&#160;        {</div><div class="line"><a name="l07282"></a><span class="lineno"> 7282</span>&#160;            m_FreeSuballocationsBySize.push_back(item);</div><div class="line"><a name="l07283"></a><span class="lineno"> 7283</span>&#160;        }</div><div class="line"><a name="l07284"></a><span class="lineno"> 7284</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07285"></a><span class="lineno"> 7285</span>&#160;        {</div><div class="line"><a name="l07286"></a><span class="lineno"> 7286</span>&#160;            VmaVectorInsertSorted&lt;VmaSuballocationItemSizeLess&gt;(m_FreeSuballocationsBySize, item);</div><div class="line"><a name="l07287"></a><span class="lineno"> 7287</span>&#160;        }</div><div class="line"><a name="l07288"></a><span class="lineno"> 7288</span>&#160;    }</div><div class="line"><a name="l07289"></a><span class="lineno"> 7289</span>&#160;</div><div class="line"><a name="l07290"></a><span class="lineno"> 7290</span>&#160;    <span class="comment">//VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</span></div><div class="line"><a name="l07291"></a><span class="lineno"> 7291</span>&#160;}</div><div class="line"><a name="l07292"></a><span class="lineno"> 7292</span>&#160;</div><div class="line"><a name="l07293"></a><span class="lineno"> 7293</span>&#160;</div><div class="line"><a name="l07294"></a><span class="lineno"> 7294</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Generic::UnregisterFreeSuballocation(VmaSuballocationList::iterator item)</div><div class="line"><a name="l07295"></a><span class="lineno"> 7295</span>&#160;{</div><div class="line"><a name="l07296"></a><span class="lineno"> 7296</span>&#160;    VMA_ASSERT(item-&gt;type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07297"></a><span class="lineno"> 7297</span>&#160;    VMA_ASSERT(item-&gt;size &gt; 0);</div><div class="line"><a name="l07298"></a><span class="lineno"> 7298</span>&#160;</div><div class="line"><a name="l07299"></a><span class="lineno"> 7299</span>&#160;    <span class="comment">// You may want to enable this validation at the beginning or at the end of</span></div><div class="line"><a name="l07300"></a><span class="lineno"> 7300</span>&#160;    <span class="comment">// this function, depending on what do you want to check.</span></div><div class="line"><a name="l07301"></a><span class="lineno"> 7301</span>&#160;    VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</div><div class="line"><a name="l07302"></a><span class="lineno"> 7302</span>&#160;</div><div class="line"><a name="l07303"></a><span class="lineno"> 7303</span>&#160;    <span class="keywordflow">if</span>(item-&gt;size &gt;= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)</div><div class="line"><a name="l07304"></a><span class="lineno"> 7304</span>&#160;    {</div><div class="line"><a name="l07305"></a><span class="lineno"> 7305</span>&#160;        VmaSuballocationList::iterator* <span class="keyword">const</span> it = VmaBinaryFindFirstNotLess(</div><div class="line"><a name="l07306"></a><span class="lineno"> 7306</span>&#160;            m_FreeSuballocationsBySize.data(),</div><div class="line"><a name="l07307"></a><span class="lineno"> 7307</span>&#160;            m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(),</div><div class="line"><a name="l07308"></a><span class="lineno"> 7308</span>&#160;            item,</div><div class="line"><a name="l07309"></a><span class="lineno"> 7309</span>&#160;            VmaSuballocationItemSizeLess());</div><div class="line"><a name="l07310"></a><span class="lineno"> 7310</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> index = it - m_FreeSuballocationsBySize.data();</div><div class="line"><a name="l07311"></a><span class="lineno"> 7311</span>&#160;            index &lt; m_FreeSuballocationsBySize.size();</div><div class="line"><a name="l07312"></a><span class="lineno"> 7312</span>&#160;            ++index)</div><div class="line"><a name="l07313"></a><span class="lineno"> 7313</span>&#160;        {</div><div class="line"><a name="l07314"></a><span class="lineno"> 7314</span>&#160;            <span class="keywordflow">if</span>(m_FreeSuballocationsBySize[index] == item)</div><div class="line"><a name="l07315"></a><span class="lineno"> 7315</span>&#160;            {</div><div class="line"><a name="l07316"></a><span class="lineno"> 7316</span>&#160;                VmaVectorRemove(m_FreeSuballocationsBySize, index);</div><div class="line"><a name="l07317"></a><span class="lineno"> 7317</span>&#160;                <span class="keywordflow">return</span>;</div><div class="line"><a name="l07318"></a><span class="lineno"> 7318</span>&#160;            }</div><div class="line"><a name="l07319"></a><span class="lineno"> 7319</span>&#160;            VMA_ASSERT((m_FreeSuballocationsBySize[index]-&gt;size == item-&gt;size) &amp;&amp; <span class="stringliteral">&quot;Not found.&quot;</span>);</div><div class="line"><a name="l07320"></a><span class="lineno"> 7320</span>&#160;        }</div><div class="line"><a name="l07321"></a><span class="lineno"> 7321</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Not found.&quot;</span>);</div><div class="line"><a name="l07322"></a><span class="lineno"> 7322</span>&#160;    }</div><div class="line"><a name="l07323"></a><span class="lineno"> 7323</span>&#160;</div><div class="line"><a name="l07324"></a><span class="lineno"> 7324</span>&#160;    <span class="comment">//VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());</span></div><div class="line"><a name="l07325"></a><span class="lineno"> 7325</span>&#160;}</div><div class="line"><a name="l07326"></a><span class="lineno"> 7326</span>&#160;</div><div class="line"><a name="l07328"></a><span class="lineno"> 7328</span>&#160;<span class="comment">// class VmaBlockMetadata_Linear</span></div><div class="line"><a name="l07329"></a><span class="lineno"> 7329</span>&#160;</div><div class="line"><a name="l07330"></a><span class="lineno"> 7330</span>&#160;VmaBlockMetadata_Linear::VmaBlockMetadata_Linear(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator) :</div><div class="line"><a name="l07331"></a><span class="lineno"> 7331</span>&#160;    m_SumFreeSize(0),</div><div class="line"><a name="l07332"></a><span class="lineno"> 7332</span>&#160;    m_Suballocations0(VmaStlAllocator&lt;VmaSuballocation&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l07333"></a><span class="lineno"> 7333</span>&#160;    m_Suballocations1(VmaStlAllocator&lt;VmaSuballocation&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l07334"></a><span class="lineno"> 7334</span>&#160;    m_1stVectorIndex(0),</div><div class="line"><a name="l07335"></a><span class="lineno"> 7335</span>&#160;    m_2ndVectorMode(SECOND_VECTOR_EMPTY),</div><div class="line"><a name="l07336"></a><span class="lineno"> 7336</span>&#160;    m_1stNullItemsBeginCount(0),</div><div class="line"><a name="l07337"></a><span class="lineno"> 7337</span>&#160;    m_1stNullItemsMiddleCount(0),</div><div class="line"><a name="l07338"></a><span class="lineno"> 7338</span>&#160;    m_2ndNullItemsCount(0)</div><div class="line"><a name="l07339"></a><span class="lineno"> 7339</span>&#160;{</div><div class="line"><a name="l07340"></a><span class="lineno"> 7340</span>&#160;}</div><div class="line"><a name="l07341"></a><span class="lineno"> 7341</span>&#160;</div><div class="line"><a name="l07342"></a><span class="lineno"> 7342</span>&#160;VmaBlockMetadata_Linear::~VmaBlockMetadata_Linear()</div><div class="line"><a name="l07343"></a><span class="lineno"> 7343</span>&#160;{</div><div class="line"><a name="l07344"></a><span class="lineno"> 7344</span>&#160;}</div><div class="line"><a name="l07345"></a><span class="lineno"> 7345</span>&#160;</div><div class="line"><a name="l07346"></a><span class="lineno"> 7346</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::Init(VkDeviceSize size)</div><div class="line"><a name="l07347"></a><span class="lineno"> 7347</span>&#160;{</div><div class="line"><a name="l07348"></a><span class="lineno"> 7348</span>&#160;    VmaBlockMetadata::Init(size);</div><div class="line"><a name="l07349"></a><span class="lineno"> 7349</span>&#160;    m_SumFreeSize = size;</div><div class="line"><a name="l07350"></a><span class="lineno"> 7350</span>&#160;}</div><div class="line"><a name="l07351"></a><span class="lineno"> 7351</span>&#160;</div><div class="line"><a name="l07352"></a><span class="lineno"> 7352</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Linear::Validate()<span class="keyword"> const</span></div><div class="line"><a name="l07353"></a><span class="lineno"> 7353</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07354"></a><span class="lineno"> 7354</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l07355"></a><span class="lineno"> 7355</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l07356"></a><span class="lineno"> 7356</span>&#160;</div><div class="line"><a name="l07357"></a><span class="lineno"> 7357</span>&#160;    <span class="keywordflow">if</span>(suballocations2nd.empty() != (m_2ndVectorMode == SECOND_VECTOR_EMPTY))</div><div class="line"><a name="l07358"></a><span class="lineno"> 7358</span>&#160;    {</div><div class="line"><a name="l07359"></a><span class="lineno"> 7359</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07360"></a><span class="lineno"> 7360</span>&#160;    }</div><div class="line"><a name="l07361"></a><span class="lineno"> 7361</span>&#160;    <span class="keywordflow">if</span>(suballocations1st.empty() &amp;&amp; !suballocations2nd.empty() &amp;&amp;</div><div class="line"><a name="l07362"></a><span class="lineno"> 7362</span>&#160;        m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l07363"></a><span class="lineno"> 7363</span>&#160;    {</div><div class="line"><a name="l07364"></a><span class="lineno"> 7364</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07365"></a><span class="lineno"> 7365</span>&#160;    }</div><div class="line"><a name="l07366"></a><span class="lineno"> 7366</span>&#160;    <span class="keywordflow">if</span>(!suballocations1st.empty())</div><div class="line"><a name="l07367"></a><span class="lineno"> 7367</span>&#160;    {</div><div class="line"><a name="l07368"></a><span class="lineno"> 7368</span>&#160;        <span class="comment">// Null item at the beginning should be accounted into m_1stNullItemsBeginCount.</span></div><div class="line"><a name="l07369"></a><span class="lineno"> 7369</span>&#160;        <span class="keywordflow">if</span>(suballocations1st[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07370"></a><span class="lineno"> 7370</span>&#160;        {</div><div class="line"><a name="l07371"></a><span class="lineno"> 7371</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07372"></a><span class="lineno"> 7372</span>&#160;        }</div><div class="line"><a name="l07373"></a><span class="lineno"> 7373</span>&#160;        <span class="comment">// Null item at the end should be just pop_back().</span></div><div class="line"><a name="l07374"></a><span class="lineno"> 7374</span>&#160;        <span class="keywordflow">if</span>(suballocations1st.back().hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07375"></a><span class="lineno"> 7375</span>&#160;        {</div><div class="line"><a name="l07376"></a><span class="lineno"> 7376</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07377"></a><span class="lineno"> 7377</span>&#160;        }</div><div class="line"><a name="l07378"></a><span class="lineno"> 7378</span>&#160;    }</div><div class="line"><a name="l07379"></a><span class="lineno"> 7379</span>&#160;    <span class="keywordflow">if</span>(!suballocations2nd.empty())</div><div class="line"><a name="l07380"></a><span class="lineno"> 7380</span>&#160;    {</div><div class="line"><a name="l07381"></a><span class="lineno"> 7381</span>&#160;        <span class="comment">// Null item at the end should be just pop_back().</span></div><div class="line"><a name="l07382"></a><span class="lineno"> 7382</span>&#160;        <span class="keywordflow">if</span>(suballocations2nd.back().hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07383"></a><span class="lineno"> 7383</span>&#160;        {</div><div class="line"><a name="l07384"></a><span class="lineno"> 7384</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07385"></a><span class="lineno"> 7385</span>&#160;        }</div><div class="line"><a name="l07386"></a><span class="lineno"> 7386</span>&#160;    }</div><div class="line"><a name="l07387"></a><span class="lineno"> 7387</span>&#160;</div><div class="line"><a name="l07388"></a><span class="lineno"> 7388</span>&#160;    <span class="keywordflow">if</span>(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount &gt; suballocations1st.size())</div><div class="line"><a name="l07389"></a><span class="lineno"> 7389</span>&#160;    {</div><div class="line"><a name="l07390"></a><span class="lineno"> 7390</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07391"></a><span class="lineno"> 7391</span>&#160;    }</div><div class="line"><a name="l07392"></a><span class="lineno"> 7392</span>&#160;    <span class="keywordflow">if</span>(m_2ndNullItemsCount &gt; suballocations2nd.size())</div><div class="line"><a name="l07393"></a><span class="lineno"> 7393</span>&#160;    {</div><div class="line"><a name="l07394"></a><span class="lineno"> 7394</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07395"></a><span class="lineno"> 7395</span>&#160;    }</div><div class="line"><a name="l07396"></a><span class="lineno"> 7396</span>&#160;</div><div class="line"><a name="l07397"></a><span class="lineno"> 7397</span>&#160;    VkDeviceSize sumUsedSize = 0;</div><div class="line"><a name="l07398"></a><span class="lineno"> 7398</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc1stCount = suballocations1st.size();</div><div class="line"><a name="l07399"></a><span class="lineno"> 7399</span>&#160;    VkDeviceSize offset = VMA_DEBUG_MARGIN;</div><div class="line"><a name="l07400"></a><span class="lineno"> 7400</span>&#160;</div><div class="line"><a name="l07401"></a><span class="lineno"> 7401</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l07402"></a><span class="lineno"> 7402</span>&#160;    {</div><div class="line"><a name="l07403"></a><span class="lineno"> 7403</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc2ndCount = suballocations2nd.size();</div><div class="line"><a name="l07404"></a><span class="lineno"> 7404</span>&#160;        <span class="keywordtype">size_t</span> nullItem2ndCount = 0;</div><div class="line"><a name="l07405"></a><span class="lineno"> 7405</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; suballoc2ndCount; ++i)</div><div class="line"><a name="l07406"></a><span class="lineno"> 7406</span>&#160;        {</div><div class="line"><a name="l07407"></a><span class="lineno"> 7407</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[i];</div><div class="line"><a name="l07408"></a><span class="lineno"> 7408</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">bool</span> currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07409"></a><span class="lineno"> 7409</span>&#160;</div><div class="line"><a name="l07410"></a><span class="lineno"> 7410</span>&#160;            <span class="keywordflow">if</span>(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))</div><div class="line"><a name="l07411"></a><span class="lineno"> 7411</span>&#160;            {</div><div class="line"><a name="l07412"></a><span class="lineno"> 7412</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07413"></a><span class="lineno"> 7413</span>&#160;            }</div><div class="line"><a name="l07414"></a><span class="lineno"> 7414</span>&#160;            <span class="keywordflow">if</span>(suballoc.offset &lt; offset)</div><div class="line"><a name="l07415"></a><span class="lineno"> 7415</span>&#160;            {</div><div class="line"><a name="l07416"></a><span class="lineno"> 7416</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07417"></a><span class="lineno"> 7417</span>&#160;            }</div><div class="line"><a name="l07418"></a><span class="lineno"> 7418</span>&#160;</div><div class="line"><a name="l07419"></a><span class="lineno"> 7419</span>&#160;            <span class="keywordflow">if</span>(!currFree)</div><div class="line"><a name="l07420"></a><span class="lineno"> 7420</span>&#160;            {</div><div class="line"><a name="l07421"></a><span class="lineno"> 7421</span>&#160;                <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;GetOffset() != suballoc.offset)</div><div class="line"><a name="l07422"></a><span class="lineno"> 7422</span>&#160;                {</div><div class="line"><a name="l07423"></a><span class="lineno"> 7423</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07424"></a><span class="lineno"> 7424</span>&#160;                }</div><div class="line"><a name="l07425"></a><span class="lineno"> 7425</span>&#160;                <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;GetSize() != suballoc.size)</div><div class="line"><a name="l07426"></a><span class="lineno"> 7426</span>&#160;                {</div><div class="line"><a name="l07427"></a><span class="lineno"> 7427</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07428"></a><span class="lineno"> 7428</span>&#160;                }</div><div class="line"><a name="l07429"></a><span class="lineno"> 7429</span>&#160;                sumUsedSize += suballoc.size;</div><div class="line"><a name="l07430"></a><span class="lineno"> 7430</span>&#160;            }</div><div class="line"><a name="l07431"></a><span class="lineno"> 7431</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07432"></a><span class="lineno"> 7432</span>&#160;            {</div><div class="line"><a name="l07433"></a><span class="lineno"> 7433</span>&#160;                ++nullItem2ndCount;</div><div class="line"><a name="l07434"></a><span class="lineno"> 7434</span>&#160;            }</div><div class="line"><a name="l07435"></a><span class="lineno"> 7435</span>&#160;</div><div class="line"><a name="l07436"></a><span class="lineno"> 7436</span>&#160;            offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;</div><div class="line"><a name="l07437"></a><span class="lineno"> 7437</span>&#160;        }</div><div class="line"><a name="l07438"></a><span class="lineno"> 7438</span>&#160;</div><div class="line"><a name="l07439"></a><span class="lineno"> 7439</span>&#160;        <span class="keywordflow">if</span>(nullItem2ndCount != m_2ndNullItemsCount)</div><div class="line"><a name="l07440"></a><span class="lineno"> 7440</span>&#160;        {</div><div class="line"><a name="l07441"></a><span class="lineno"> 7441</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07442"></a><span class="lineno"> 7442</span>&#160;        }</div><div class="line"><a name="l07443"></a><span class="lineno"> 7443</span>&#160;    }</div><div class="line"><a name="l07444"></a><span class="lineno"> 7444</span>&#160;</div><div class="line"><a name="l07445"></a><span class="lineno"> 7445</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_1stNullItemsBeginCount; ++i)</div><div class="line"><a name="l07446"></a><span class="lineno"> 7446</span>&#160;    {</div><div class="line"><a name="l07447"></a><span class="lineno"> 7447</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[i];</div><div class="line"><a name="l07448"></a><span class="lineno"> 7448</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE ||</div><div class="line"><a name="l07449"></a><span class="lineno"> 7449</span>&#160;            suballoc.hAllocation != VK_NULL_HANDLE)</div><div class="line"><a name="l07450"></a><span class="lineno"> 7450</span>&#160;        {</div><div class="line"><a name="l07451"></a><span class="lineno"> 7451</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07452"></a><span class="lineno"> 7452</span>&#160;        }</div><div class="line"><a name="l07453"></a><span class="lineno"> 7453</span>&#160;    }</div><div class="line"><a name="l07454"></a><span class="lineno"> 7454</span>&#160;</div><div class="line"><a name="l07455"></a><span class="lineno"> 7455</span>&#160;    <span class="keywordtype">size_t</span> nullItem1stCount = m_1stNullItemsBeginCount;</div><div class="line"><a name="l07456"></a><span class="lineno"> 7456</span>&#160;</div><div class="line"><a name="l07457"></a><span class="lineno"> 7457</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_1stNullItemsBeginCount; i &lt; suballoc1stCount; ++i)</div><div class="line"><a name="l07458"></a><span class="lineno"> 7458</span>&#160;    {</div><div class="line"><a name="l07459"></a><span class="lineno"> 7459</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[i];</div><div class="line"><a name="l07460"></a><span class="lineno"> 7460</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">bool</span> currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07461"></a><span class="lineno"> 7461</span>&#160;</div><div class="line"><a name="l07462"></a><span class="lineno"> 7462</span>&#160;        <span class="keywordflow">if</span>(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))</div><div class="line"><a name="l07463"></a><span class="lineno"> 7463</span>&#160;        {</div><div class="line"><a name="l07464"></a><span class="lineno"> 7464</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07465"></a><span class="lineno"> 7465</span>&#160;        }</div><div class="line"><a name="l07466"></a><span class="lineno"> 7466</span>&#160;        <span class="keywordflow">if</span>(suballoc.offset &lt; offset)</div><div class="line"><a name="l07467"></a><span class="lineno"> 7467</span>&#160;        {</div><div class="line"><a name="l07468"></a><span class="lineno"> 7468</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07469"></a><span class="lineno"> 7469</span>&#160;        }</div><div class="line"><a name="l07470"></a><span class="lineno"> 7470</span>&#160;        <span class="keywordflow">if</span>(i &lt; m_1stNullItemsBeginCount &amp;&amp; !currFree)</div><div class="line"><a name="l07471"></a><span class="lineno"> 7471</span>&#160;        {</div><div class="line"><a name="l07472"></a><span class="lineno"> 7472</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07473"></a><span class="lineno"> 7473</span>&#160;        }</div><div class="line"><a name="l07474"></a><span class="lineno"> 7474</span>&#160;</div><div class="line"><a name="l07475"></a><span class="lineno"> 7475</span>&#160;        <span class="keywordflow">if</span>(!currFree)</div><div class="line"><a name="l07476"></a><span class="lineno"> 7476</span>&#160;        {</div><div class="line"><a name="l07477"></a><span class="lineno"> 7477</span>&#160;            <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;GetOffset() != suballoc.offset)</div><div class="line"><a name="l07478"></a><span class="lineno"> 7478</span>&#160;            {</div><div class="line"><a name="l07479"></a><span class="lineno"> 7479</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07480"></a><span class="lineno"> 7480</span>&#160;            }</div><div class="line"><a name="l07481"></a><span class="lineno"> 7481</span>&#160;            <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;GetSize() != suballoc.size)</div><div class="line"><a name="l07482"></a><span class="lineno"> 7482</span>&#160;            {</div><div class="line"><a name="l07483"></a><span class="lineno"> 7483</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07484"></a><span class="lineno"> 7484</span>&#160;            }</div><div class="line"><a name="l07485"></a><span class="lineno"> 7485</span>&#160;            sumUsedSize += suballoc.size;</div><div class="line"><a name="l07486"></a><span class="lineno"> 7486</span>&#160;        }</div><div class="line"><a name="l07487"></a><span class="lineno"> 7487</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07488"></a><span class="lineno"> 7488</span>&#160;        {</div><div class="line"><a name="l07489"></a><span class="lineno"> 7489</span>&#160;            ++nullItem1stCount;</div><div class="line"><a name="l07490"></a><span class="lineno"> 7490</span>&#160;        }</div><div class="line"><a name="l07491"></a><span class="lineno"> 7491</span>&#160;</div><div class="line"><a name="l07492"></a><span class="lineno"> 7492</span>&#160;        offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;</div><div class="line"><a name="l07493"></a><span class="lineno"> 7493</span>&#160;    }</div><div class="line"><a name="l07494"></a><span class="lineno"> 7494</span>&#160;    <span class="keywordflow">if</span>(nullItem1stCount != m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount)</div><div class="line"><a name="l07495"></a><span class="lineno"> 7495</span>&#160;    {</div><div class="line"><a name="l07496"></a><span class="lineno"> 7496</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07497"></a><span class="lineno"> 7497</span>&#160;    }</div><div class="line"><a name="l07498"></a><span class="lineno"> 7498</span>&#160;</div><div class="line"><a name="l07499"></a><span class="lineno"> 7499</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l07500"></a><span class="lineno"> 7500</span>&#160;    {</div><div class="line"><a name="l07501"></a><span class="lineno"> 7501</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc2ndCount = suballocations2nd.size();</div><div class="line"><a name="l07502"></a><span class="lineno"> 7502</span>&#160;        <span class="keywordtype">size_t</span> nullItem2ndCount = 0;</div><div class="line"><a name="l07503"></a><span class="lineno"> 7503</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = suballoc2ndCount; i--; )</div><div class="line"><a name="l07504"></a><span class="lineno"> 7504</span>&#160;        {</div><div class="line"><a name="l07505"></a><span class="lineno"> 7505</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[i];</div><div class="line"><a name="l07506"></a><span class="lineno"> 7506</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">bool</span> currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l07507"></a><span class="lineno"> 7507</span>&#160;</div><div class="line"><a name="l07508"></a><span class="lineno"> 7508</span>&#160;            <span class="keywordflow">if</span>(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))</div><div class="line"><a name="l07509"></a><span class="lineno"> 7509</span>&#160;            {</div><div class="line"><a name="l07510"></a><span class="lineno"> 7510</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07511"></a><span class="lineno"> 7511</span>&#160;            }</div><div class="line"><a name="l07512"></a><span class="lineno"> 7512</span>&#160;            <span class="keywordflow">if</span>(suballoc.offset &lt; offset)</div><div class="line"><a name="l07513"></a><span class="lineno"> 7513</span>&#160;            {</div><div class="line"><a name="l07514"></a><span class="lineno"> 7514</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07515"></a><span class="lineno"> 7515</span>&#160;            }</div><div class="line"><a name="l07516"></a><span class="lineno"> 7516</span>&#160;</div><div class="line"><a name="l07517"></a><span class="lineno"> 7517</span>&#160;            <span class="keywordflow">if</span>(!currFree)</div><div class="line"><a name="l07518"></a><span class="lineno"> 7518</span>&#160;            {</div><div class="line"><a name="l07519"></a><span class="lineno"> 7519</span>&#160;                <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;GetOffset() != suballoc.offset)</div><div class="line"><a name="l07520"></a><span class="lineno"> 7520</span>&#160;                {</div><div class="line"><a name="l07521"></a><span class="lineno"> 7521</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07522"></a><span class="lineno"> 7522</span>&#160;                }</div><div class="line"><a name="l07523"></a><span class="lineno"> 7523</span>&#160;                <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;GetSize() != suballoc.size)</div><div class="line"><a name="l07524"></a><span class="lineno"> 7524</span>&#160;                {</div><div class="line"><a name="l07525"></a><span class="lineno"> 7525</span>&#160;                    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07526"></a><span class="lineno"> 7526</span>&#160;                }</div><div class="line"><a name="l07527"></a><span class="lineno"> 7527</span>&#160;                sumUsedSize += suballoc.size;</div><div class="line"><a name="l07528"></a><span class="lineno"> 7528</span>&#160;            }</div><div class="line"><a name="l07529"></a><span class="lineno"> 7529</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07530"></a><span class="lineno"> 7530</span>&#160;            {</div><div class="line"><a name="l07531"></a><span class="lineno"> 7531</span>&#160;                ++nullItem2ndCount;</div><div class="line"><a name="l07532"></a><span class="lineno"> 7532</span>&#160;            }</div><div class="line"><a name="l07533"></a><span class="lineno"> 7533</span>&#160;</div><div class="line"><a name="l07534"></a><span class="lineno"> 7534</span>&#160;            offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;</div><div class="line"><a name="l07535"></a><span class="lineno"> 7535</span>&#160;        }</div><div class="line"><a name="l07536"></a><span class="lineno"> 7536</span>&#160;</div><div class="line"><a name="l07537"></a><span class="lineno"> 7537</span>&#160;        <span class="keywordflow">if</span>(nullItem2ndCount != m_2ndNullItemsCount)</div><div class="line"><a name="l07538"></a><span class="lineno"> 7538</span>&#160;        {</div><div class="line"><a name="l07539"></a><span class="lineno"> 7539</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07540"></a><span class="lineno"> 7540</span>&#160;        }</div><div class="line"><a name="l07541"></a><span class="lineno"> 7541</span>&#160;    }</div><div class="line"><a name="l07542"></a><span class="lineno"> 7542</span>&#160;</div><div class="line"><a name="l07543"></a><span class="lineno"> 7543</span>&#160;    <span class="keywordflow">if</span>(offset &gt; GetSize())</div><div class="line"><a name="l07544"></a><span class="lineno"> 7544</span>&#160;    {</div><div class="line"><a name="l07545"></a><span class="lineno"> 7545</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07546"></a><span class="lineno"> 7546</span>&#160;    }</div><div class="line"><a name="l07547"></a><span class="lineno"> 7547</span>&#160;    <span class="keywordflow">if</span>(m_SumFreeSize != GetSize() - sumUsedSize)</div><div class="line"><a name="l07548"></a><span class="lineno"> 7548</span>&#160;    {</div><div class="line"><a name="l07549"></a><span class="lineno"> 7549</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l07550"></a><span class="lineno"> 7550</span>&#160;    }</div><div class="line"><a name="l07551"></a><span class="lineno"> 7551</span>&#160;</div><div class="line"><a name="l07552"></a><span class="lineno"> 7552</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l07553"></a><span class="lineno"> 7553</span>&#160;}</div><div class="line"><a name="l07554"></a><span class="lineno"> 7554</span>&#160;</div><div class="line"><a name="l07555"></a><span class="lineno"> 7555</span>&#160;<span class="keywordtype">size_t</span> VmaBlockMetadata_Linear::GetAllocationCount()<span class="keyword"> const</span></div><div class="line"><a name="l07556"></a><span class="lineno"> 7556</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07557"></a><span class="lineno"> 7557</span>&#160;    <span class="keywordflow">return</span> AccessSuballocations1st().size() - (m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount) +</div><div class="line"><a name="l07558"></a><span class="lineno"> 7558</span>&#160;        AccessSuballocations2nd().size() - m_2ndNullItemsCount;</div><div class="line"><a name="l07559"></a><span class="lineno"> 7559</span>&#160;}</div><div class="line"><a name="l07560"></a><span class="lineno"> 7560</span>&#160;</div><div class="line"><a name="l07561"></a><span class="lineno"> 7561</span>&#160;VkDeviceSize VmaBlockMetadata_Linear::GetUnusedRangeSizeMax()<span class="keyword"> const</span></div><div class="line"><a name="l07562"></a><span class="lineno"> 7562</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07563"></a><span class="lineno"> 7563</span>&#160;    <span class="keyword">const</span> VkDeviceSize size = GetSize();</div><div class="line"><a name="l07564"></a><span class="lineno"> 7564</span>&#160;</div><div class="line"><a name="l07565"></a><span class="lineno"> 7565</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l07566"></a><span class="lineno"> 7566</span>&#160;<span class="comment">    We don&#39;t consider gaps inside allocation vectors with freed allocations because</span></div><div class="line"><a name="l07567"></a><span class="lineno"> 7567</span>&#160;<span class="comment">    they are not suitable for reuse in linear allocator. We consider only space that</span></div><div class="line"><a name="l07568"></a><span class="lineno"> 7568</span>&#160;<span class="comment">    is available for new allocations.</span></div><div class="line"><a name="l07569"></a><span class="lineno"> 7569</span>&#160;<span class="comment">    */</span></div><div class="line"><a name="l07570"></a><span class="lineno"> 7570</span>&#160;    <span class="keywordflow">if</span>(IsEmpty())</div><div class="line"><a name="l07571"></a><span class="lineno"> 7571</span>&#160;    {</div><div class="line"><a name="l07572"></a><span class="lineno"> 7572</span>&#160;        <span class="keywordflow">return</span> size;</div><div class="line"><a name="l07573"></a><span class="lineno"> 7573</span>&#160;    }</div><div class="line"><a name="l07574"></a><span class="lineno"> 7574</span>&#160;    </div><div class="line"><a name="l07575"></a><span class="lineno"> 7575</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l07576"></a><span class="lineno"> 7576</span>&#160;</div><div class="line"><a name="l07577"></a><span class="lineno"> 7577</span>&#160;    <span class="keywordflow">switch</span>(m_2ndVectorMode)</div><div class="line"><a name="l07578"></a><span class="lineno"> 7578</span>&#160;    {</div><div class="line"><a name="l07579"></a><span class="lineno"> 7579</span>&#160;    <span class="keywordflow">case</span> SECOND_VECTOR_EMPTY:</div><div class="line"><a name="l07580"></a><span class="lineno"> 7580</span>&#160;        <span class="comment">/*</span></div><div class="line"><a name="l07581"></a><span class="lineno"> 7581</span>&#160;<span class="comment">        Available space is after end of 1st, as well as before beginning of 1st (which</span></div><div class="line"><a name="l07582"></a><span class="lineno"> 7582</span>&#160;<span class="comment">        whould make it a ring buffer).</span></div><div class="line"><a name="l07583"></a><span class="lineno"> 7583</span>&#160;<span class="comment">        */</span></div><div class="line"><a name="l07584"></a><span class="lineno"> 7584</span>&#160;        {</div><div class="line"><a name="l07585"></a><span class="lineno"> 7585</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballocations1stCount = suballocations1st.size();</div><div class="line"><a name="l07586"></a><span class="lineno"> 7586</span>&#160;            VMA_ASSERT(suballocations1stCount &gt; m_1stNullItemsBeginCount);</div><div class="line"><a name="l07587"></a><span class="lineno"> 7587</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; firstSuballoc = suballocations1st[m_1stNullItemsBeginCount];</div><div class="line"><a name="l07588"></a><span class="lineno"> 7588</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; lastSuballoc  = suballocations1st[suballocations1stCount - 1];</div><div class="line"><a name="l07589"></a><span class="lineno"> 7589</span>&#160;            <span class="keywordflow">return</span> VMA_MAX(</div><div class="line"><a name="l07590"></a><span class="lineno"> 7590</span>&#160;                firstSuballoc.offset,</div><div class="line"><a name="l07591"></a><span class="lineno"> 7591</span>&#160;                size - (lastSuballoc.offset + lastSuballoc.size));</div><div class="line"><a name="l07592"></a><span class="lineno"> 7592</span>&#160;        }</div><div class="line"><a name="l07593"></a><span class="lineno"> 7593</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l07594"></a><span class="lineno"> 7594</span>&#160;</div><div class="line"><a name="l07595"></a><span class="lineno"> 7595</span>&#160;    <span class="keywordflow">case</span> SECOND_VECTOR_RING_BUFFER:</div><div class="line"><a name="l07596"></a><span class="lineno"> 7596</span>&#160;        <span class="comment">/*</span></div><div class="line"><a name="l07597"></a><span class="lineno"> 7597</span>&#160;<span class="comment">        Available space is only between end of 2nd and beginning of 1st.</span></div><div class="line"><a name="l07598"></a><span class="lineno"> 7598</span>&#160;<span class="comment">        */</span></div><div class="line"><a name="l07599"></a><span class="lineno"> 7599</span>&#160;        {</div><div class="line"><a name="l07600"></a><span class="lineno"> 7600</span>&#160;            <span class="keyword">const</span> SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l07601"></a><span class="lineno"> 7601</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; lastSuballoc2nd = suballocations2nd.back();</div><div class="line"><a name="l07602"></a><span class="lineno"> 7602</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; firstSuballoc1st = suballocations1st[m_1stNullItemsBeginCount];</div><div class="line"><a name="l07603"></a><span class="lineno"> 7603</span>&#160;            <span class="keywordflow">return</span> firstSuballoc1st.offset - (lastSuballoc2nd.offset + lastSuballoc2nd.size);</div><div class="line"><a name="l07604"></a><span class="lineno"> 7604</span>&#160;        }</div><div class="line"><a name="l07605"></a><span class="lineno"> 7605</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l07606"></a><span class="lineno"> 7606</span>&#160;</div><div class="line"><a name="l07607"></a><span class="lineno"> 7607</span>&#160;    <span class="keywordflow">case</span> SECOND_VECTOR_DOUBLE_STACK:</div><div class="line"><a name="l07608"></a><span class="lineno"> 7608</span>&#160;        <span class="comment">/*</span></div><div class="line"><a name="l07609"></a><span class="lineno"> 7609</span>&#160;<span class="comment">        Available space is only between end of 1st and top of 2nd.</span></div><div class="line"><a name="l07610"></a><span class="lineno"> 7610</span>&#160;<span class="comment">        */</span></div><div class="line"><a name="l07611"></a><span class="lineno"> 7611</span>&#160;        {</div><div class="line"><a name="l07612"></a><span class="lineno"> 7612</span>&#160;            <span class="keyword">const</span> SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l07613"></a><span class="lineno"> 7613</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; topSuballoc2nd = suballocations2nd.back();</div><div class="line"><a name="l07614"></a><span class="lineno"> 7614</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; lastSuballoc1st = suballocations1st.back();</div><div class="line"><a name="l07615"></a><span class="lineno"> 7615</span>&#160;            <span class="keywordflow">return</span> topSuballoc2nd.offset - (lastSuballoc1st.offset + lastSuballoc1st.size);</div><div class="line"><a name="l07616"></a><span class="lineno"> 7616</span>&#160;        }</div><div class="line"><a name="l07617"></a><span class="lineno"> 7617</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l07618"></a><span class="lineno"> 7618</span>&#160;</div><div class="line"><a name="l07619"></a><span class="lineno"> 7619</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l07620"></a><span class="lineno"> 7620</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l07621"></a><span class="lineno"> 7621</span>&#160;        <span class="keywordflow">return</span> 0;</div><div class="line"><a name="l07622"></a><span class="lineno"> 7622</span>&#160;    }</div><div class="line"><a name="l07623"></a><span class="lineno"> 7623</span>&#160;}</div><div class="line"><a name="l07624"></a><span class="lineno"> 7624</span>&#160;</div><div class="line"><a name="l07625"></a><span class="lineno"> 7625</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::CalcAllocationStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo)<span class="keyword"> const</span></div><div class="line"><a name="l07626"></a><span class="lineno"> 7626</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07627"></a><span class="lineno"> 7627</span>&#160;    <span class="keyword">const</span> VkDeviceSize size = GetSize();</div><div class="line"><a name="l07628"></a><span class="lineno"> 7628</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l07629"></a><span class="lineno"> 7629</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l07630"></a><span class="lineno"> 7630</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc1stCount = suballocations1st.size();</div><div class="line"><a name="l07631"></a><span class="lineno"> 7631</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc2ndCount = suballocations2nd.size();</div><div class="line"><a name="l07632"></a><span class="lineno"> 7632</span>&#160;</div><div class="line"><a name="l07633"></a><span class="lineno"> 7633</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> = 1;</div><div class="line"><a name="l07634"></a><span class="lineno"> 7634</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> = (uint32_t)GetAllocationCount();</div><div class="line"><a name="l07635"></a><span class="lineno"> 7635</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> = 0;</div><div class="line"><a name="l07636"></a><span class="lineno"> 7636</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> = 0;</div><div class="line"><a name="l07637"></a><span class="lineno"> 7637</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l07638"></a><span class="lineno"> 7638</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = 0;</div><div class="line"><a name="l07639"></a><span class="lineno"> 7639</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l07640"></a><span class="lineno"> 7640</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = 0;</div><div class="line"><a name="l07641"></a><span class="lineno"> 7641</span>&#160;</div><div class="line"><a name="l07642"></a><span class="lineno"> 7642</span>&#160;    VkDeviceSize lastOffset = 0;</div><div class="line"><a name="l07643"></a><span class="lineno"> 7643</span>&#160;</div><div class="line"><a name="l07644"></a><span class="lineno"> 7644</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l07645"></a><span class="lineno"> 7645</span>&#160;    {</div><div class="line"><a name="l07646"></a><span class="lineno"> 7646</span>&#160;        <span class="keyword">const</span> VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;</div><div class="line"><a name="l07647"></a><span class="lineno"> 7647</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = 0;</div><div class="line"><a name="l07648"></a><span class="lineno"> 7648</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l07649"></a><span class="lineno"> 7649</span>&#160;        {</div><div class="line"><a name="l07650"></a><span class="lineno"> 7650</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAllocIndex to the end.</span></div><div class="line"><a name="l07651"></a><span class="lineno"> 7651</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex &lt; suballoc2ndCount &amp;&amp;</div><div class="line"><a name="l07652"></a><span class="lineno"> 7652</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07653"></a><span class="lineno"> 7653</span>&#160;            {</div><div class="line"><a name="l07654"></a><span class="lineno"> 7654</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l07655"></a><span class="lineno"> 7655</span>&#160;            }</div><div class="line"><a name="l07656"></a><span class="lineno"> 7656</span>&#160;</div><div class="line"><a name="l07657"></a><span class="lineno"> 7657</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l07658"></a><span class="lineno"> 7658</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex &lt; suballoc2ndCount)</div><div class="line"><a name="l07659"></a><span class="lineno"> 7659</span>&#160;            {</div><div class="line"><a name="l07660"></a><span class="lineno"> 7660</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l07661"></a><span class="lineno"> 7661</span>&#160;            </div><div class="line"><a name="l07662"></a><span class="lineno"> 7662</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l07663"></a><span class="lineno"> 7663</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l07664"></a><span class="lineno"> 7664</span>&#160;                {</div><div class="line"><a name="l07665"></a><span class="lineno"> 7665</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l07666"></a><span class="lineno"> 7666</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l07667"></a><span class="lineno"> 7667</span>&#160;                    ++outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l07668"></a><span class="lineno"> 7668</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += unusedRangeSize;</div><div class="line"><a name="l07669"></a><span class="lineno"> 7669</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSize);</div><div class="line"><a name="l07670"></a><span class="lineno"> 7670</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07671"></a><span class="lineno"> 7671</span>&#160;                }</div><div class="line"><a name="l07672"></a><span class="lineno"> 7672</span>&#160;            </div><div class="line"><a name="l07673"></a><span class="lineno"> 7673</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l07674"></a><span class="lineno"> 7674</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l07675"></a><span class="lineno"> 7675</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> += suballoc.size;</div><div class="line"><a name="l07676"></a><span class="lineno"> 7676</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, suballoc.size);</div><div class="line"><a name="l07677"></a><span class="lineno"> 7677</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>, suballoc.size);</div><div class="line"><a name="l07678"></a><span class="lineno"> 7678</span>&#160;            </div><div class="line"><a name="l07679"></a><span class="lineno"> 7679</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l07680"></a><span class="lineno"> 7680</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l07681"></a><span class="lineno"> 7681</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l07682"></a><span class="lineno"> 7682</span>&#160;            }</div><div class="line"><a name="l07683"></a><span class="lineno"> 7683</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l07684"></a><span class="lineno"> 7684</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07685"></a><span class="lineno"> 7685</span>&#160;            {</div><div class="line"><a name="l07686"></a><span class="lineno"> 7686</span>&#160;                <span class="comment">// There is free space from lastOffset to freeSpace2ndTo1stEnd.</span></div><div class="line"><a name="l07687"></a><span class="lineno"> 7687</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l07688"></a><span class="lineno"> 7688</span>&#160;                {</div><div class="line"><a name="l07689"></a><span class="lineno"> 7689</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;</div><div class="line"><a name="l07690"></a><span class="lineno"> 7690</span>&#160;                    ++outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l07691"></a><span class="lineno"> 7691</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += unusedRangeSize;</div><div class="line"><a name="l07692"></a><span class="lineno"> 7692</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSize);</div><div class="line"><a name="l07693"></a><span class="lineno"> 7693</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07694"></a><span class="lineno"> 7694</span>&#160;               }</div><div class="line"><a name="l07695"></a><span class="lineno"> 7695</span>&#160;</div><div class="line"><a name="l07696"></a><span class="lineno"> 7696</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l07697"></a><span class="lineno"> 7697</span>&#160;                lastOffset = freeSpace2ndTo1stEnd;</div><div class="line"><a name="l07698"></a><span class="lineno"> 7698</span>&#160;            }</div><div class="line"><a name="l07699"></a><span class="lineno"> 7699</span>&#160;        }</div><div class="line"><a name="l07700"></a><span class="lineno"> 7700</span>&#160;    }</div><div class="line"><a name="l07701"></a><span class="lineno"> 7701</span>&#160;</div><div class="line"><a name="l07702"></a><span class="lineno"> 7702</span>&#160;    <span class="keywordtype">size_t</span> nextAlloc1stIndex = m_1stNullItemsBeginCount;</div><div class="line"><a name="l07703"></a><span class="lineno"> 7703</span>&#160;    <span class="keyword">const</span> VkDeviceSize freeSpace1stTo2ndEnd =</div><div class="line"><a name="l07704"></a><span class="lineno"> 7704</span>&#160;        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;</div><div class="line"><a name="l07705"></a><span class="lineno"> 7705</span>&#160;    <span class="keywordflow">while</span>(lastOffset &lt; freeSpace1stTo2ndEnd)</div><div class="line"><a name="l07706"></a><span class="lineno"> 7706</span>&#160;    {</div><div class="line"><a name="l07707"></a><span class="lineno"> 7707</span>&#160;        <span class="comment">// Find next non-null allocation or move nextAllocIndex to the end.</span></div><div class="line"><a name="l07708"></a><span class="lineno"> 7708</span>&#160;        <span class="keywordflow">while</span>(nextAlloc1stIndex &lt; suballoc1stCount &amp;&amp;</div><div class="line"><a name="l07709"></a><span class="lineno"> 7709</span>&#160;            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07710"></a><span class="lineno"> 7710</span>&#160;        {</div><div class="line"><a name="l07711"></a><span class="lineno"> 7711</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l07712"></a><span class="lineno"> 7712</span>&#160;        }</div><div class="line"><a name="l07713"></a><span class="lineno"> 7713</span>&#160;</div><div class="line"><a name="l07714"></a><span class="lineno"> 7714</span>&#160;        <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l07715"></a><span class="lineno"> 7715</span>&#160;        <span class="keywordflow">if</span>(nextAlloc1stIndex &lt; suballoc1stCount)</div><div class="line"><a name="l07716"></a><span class="lineno"> 7716</span>&#160;        {</div><div class="line"><a name="l07717"></a><span class="lineno"> 7717</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[nextAlloc1stIndex];</div><div class="line"><a name="l07718"></a><span class="lineno"> 7718</span>&#160;            </div><div class="line"><a name="l07719"></a><span class="lineno"> 7719</span>&#160;            <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l07720"></a><span class="lineno"> 7720</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l07721"></a><span class="lineno"> 7721</span>&#160;            {</div><div class="line"><a name="l07722"></a><span class="lineno"> 7722</span>&#160;                <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l07723"></a><span class="lineno"> 7723</span>&#160;                <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l07724"></a><span class="lineno"> 7724</span>&#160;                ++outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l07725"></a><span class="lineno"> 7725</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += unusedRangeSize;</div><div class="line"><a name="l07726"></a><span class="lineno"> 7726</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSize);</div><div class="line"><a name="l07727"></a><span class="lineno"> 7727</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07728"></a><span class="lineno"> 7728</span>&#160;            }</div><div class="line"><a name="l07729"></a><span class="lineno"> 7729</span>&#160;            </div><div class="line"><a name="l07730"></a><span class="lineno"> 7730</span>&#160;            <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l07731"></a><span class="lineno"> 7731</span>&#160;            <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l07732"></a><span class="lineno"> 7732</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> += suballoc.size;</div><div class="line"><a name="l07733"></a><span class="lineno"> 7733</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, suballoc.size);</div><div class="line"><a name="l07734"></a><span class="lineno"> 7734</span>&#160;            outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>, suballoc.size);</div><div class="line"><a name="l07735"></a><span class="lineno"> 7735</span>&#160;            </div><div class="line"><a name="l07736"></a><span class="lineno"> 7736</span>&#160;            <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l07737"></a><span class="lineno"> 7737</span>&#160;            lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l07738"></a><span class="lineno"> 7738</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l07739"></a><span class="lineno"> 7739</span>&#160;        }</div><div class="line"><a name="l07740"></a><span class="lineno"> 7740</span>&#160;        <span class="comment">// We are at the end.</span></div><div class="line"><a name="l07741"></a><span class="lineno"> 7741</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07742"></a><span class="lineno"> 7742</span>&#160;        {</div><div class="line"><a name="l07743"></a><span class="lineno"> 7743</span>&#160;            <span class="comment">// There is free space from lastOffset to freeSpace1stTo2ndEnd.</span></div><div class="line"><a name="l07744"></a><span class="lineno"> 7744</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; freeSpace1stTo2ndEnd)</div><div class="line"><a name="l07745"></a><span class="lineno"> 7745</span>&#160;            {</div><div class="line"><a name="l07746"></a><span class="lineno"> 7746</span>&#160;                <span class="keyword">const</span> VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;</div><div class="line"><a name="l07747"></a><span class="lineno"> 7747</span>&#160;                ++outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l07748"></a><span class="lineno"> 7748</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += unusedRangeSize;</div><div class="line"><a name="l07749"></a><span class="lineno"> 7749</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSize);</div><div class="line"><a name="l07750"></a><span class="lineno"> 7750</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07751"></a><span class="lineno"> 7751</span>&#160;           }</div><div class="line"><a name="l07752"></a><span class="lineno"> 7752</span>&#160;</div><div class="line"><a name="l07753"></a><span class="lineno"> 7753</span>&#160;            <span class="comment">// End of loop.</span></div><div class="line"><a name="l07754"></a><span class="lineno"> 7754</span>&#160;            lastOffset = freeSpace1stTo2ndEnd;</div><div class="line"><a name="l07755"></a><span class="lineno"> 7755</span>&#160;        }</div><div class="line"><a name="l07756"></a><span class="lineno"> 7756</span>&#160;    }</div><div class="line"><a name="l07757"></a><span class="lineno"> 7757</span>&#160;</div><div class="line"><a name="l07758"></a><span class="lineno"> 7758</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l07759"></a><span class="lineno"> 7759</span>&#160;    {</div><div class="line"><a name="l07760"></a><span class="lineno"> 7760</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = suballocations2nd.size() - 1;</div><div class="line"><a name="l07761"></a><span class="lineno"> 7761</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; size)</div><div class="line"><a name="l07762"></a><span class="lineno"> 7762</span>&#160;        {</div><div class="line"><a name="l07763"></a><span class="lineno"> 7763</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAllocIndex to the end.</span></div><div class="line"><a name="l07764"></a><span class="lineno"> 7764</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex != SIZE_MAX &amp;&amp;</div><div class="line"><a name="l07765"></a><span class="lineno"> 7765</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07766"></a><span class="lineno"> 7766</span>&#160;            {</div><div class="line"><a name="l07767"></a><span class="lineno"> 7767</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l07768"></a><span class="lineno"> 7768</span>&#160;            }</div><div class="line"><a name="l07769"></a><span class="lineno"> 7769</span>&#160;</div><div class="line"><a name="l07770"></a><span class="lineno"> 7770</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l07771"></a><span class="lineno"> 7771</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex != SIZE_MAX)</div><div class="line"><a name="l07772"></a><span class="lineno"> 7772</span>&#160;            {</div><div class="line"><a name="l07773"></a><span class="lineno"> 7773</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l07774"></a><span class="lineno"> 7774</span>&#160;            </div><div class="line"><a name="l07775"></a><span class="lineno"> 7775</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l07776"></a><span class="lineno"> 7776</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l07777"></a><span class="lineno"> 7777</span>&#160;                {</div><div class="line"><a name="l07778"></a><span class="lineno"> 7778</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l07779"></a><span class="lineno"> 7779</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l07780"></a><span class="lineno"> 7780</span>&#160;                    ++outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l07781"></a><span class="lineno"> 7781</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += unusedRangeSize;</div><div class="line"><a name="l07782"></a><span class="lineno"> 7782</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSize);</div><div class="line"><a name="l07783"></a><span class="lineno"> 7783</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07784"></a><span class="lineno"> 7784</span>&#160;                }</div><div class="line"><a name="l07785"></a><span class="lineno"> 7785</span>&#160;            </div><div class="line"><a name="l07786"></a><span class="lineno"> 7786</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l07787"></a><span class="lineno"> 7787</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l07788"></a><span class="lineno"> 7788</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> += suballoc.size;</div><div class="line"><a name="l07789"></a><span class="lineno"> 7789</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, suballoc.size);</div><div class="line"><a name="l07790"></a><span class="lineno"> 7790</span>&#160;                outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>, suballoc.size);</div><div class="line"><a name="l07791"></a><span class="lineno"> 7791</span>&#160;            </div><div class="line"><a name="l07792"></a><span class="lineno"> 7792</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l07793"></a><span class="lineno"> 7793</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l07794"></a><span class="lineno"> 7794</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l07795"></a><span class="lineno"> 7795</span>&#160;            }</div><div class="line"><a name="l07796"></a><span class="lineno"> 7796</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l07797"></a><span class="lineno"> 7797</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07798"></a><span class="lineno"> 7798</span>&#160;            {</div><div class="line"><a name="l07799"></a><span class="lineno"> 7799</span>&#160;                <span class="comment">// There is free space from lastOffset to size.</span></div><div class="line"><a name="l07800"></a><span class="lineno"> 7800</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; size)</div><div class="line"><a name="l07801"></a><span class="lineno"> 7801</span>&#160;                {</div><div class="line"><a name="l07802"></a><span class="lineno"> 7802</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = size - lastOffset;</div><div class="line"><a name="l07803"></a><span class="lineno"> 7803</span>&#160;                    ++outInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l07804"></a><span class="lineno"> 7804</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += unusedRangeSize;</div><div class="line"><a name="l07805"></a><span class="lineno"> 7805</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, unusedRangeSize);</div><div class="line"><a name="l07806"></a><span class="lineno"> 7806</span>&#160;                    outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MIN(outInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07807"></a><span class="lineno"> 7807</span>&#160;               }</div><div class="line"><a name="l07808"></a><span class="lineno"> 7808</span>&#160;</div><div class="line"><a name="l07809"></a><span class="lineno"> 7809</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l07810"></a><span class="lineno"> 7810</span>&#160;                lastOffset = size;</div><div class="line"><a name="l07811"></a><span class="lineno"> 7811</span>&#160;            }</div><div class="line"><a name="l07812"></a><span class="lineno"> 7812</span>&#160;        }</div><div class="line"><a name="l07813"></a><span class="lineno"> 7813</span>&#160;    }</div><div class="line"><a name="l07814"></a><span class="lineno"> 7814</span>&#160;</div><div class="line"><a name="l07815"></a><span class="lineno"> 7815</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> = size - outInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>;</div><div class="line"><a name="l07816"></a><span class="lineno"> 7816</span>&#160;}</div><div class="line"><a name="l07817"></a><span class="lineno"> 7817</span>&#160;</div><div class="line"><a name="l07818"></a><span class="lineno"> 7818</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::AddPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>&amp; inoutStats)<span class="keyword"> const</span></div><div class="line"><a name="l07819"></a><span class="lineno"> 7819</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07820"></a><span class="lineno"> 7820</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l07821"></a><span class="lineno"> 7821</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l07822"></a><span class="lineno"> 7822</span>&#160;    <span class="keyword">const</span> VkDeviceSize size = GetSize();</div><div class="line"><a name="l07823"></a><span class="lineno"> 7823</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc1stCount = suballocations1st.size();</div><div class="line"><a name="l07824"></a><span class="lineno"> 7824</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc2ndCount = suballocations2nd.size();</div><div class="line"><a name="l07825"></a><span class="lineno"> 7825</span>&#160;</div><div class="line"><a name="l07826"></a><span class="lineno"> 7826</span>&#160;    inoutStats.<a class="code" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a> += size;</div><div class="line"><a name="l07827"></a><span class="lineno"> 7827</span>&#160;</div><div class="line"><a name="l07828"></a><span class="lineno"> 7828</span>&#160;    VkDeviceSize lastOffset = 0;</div><div class="line"><a name="l07829"></a><span class="lineno"> 7829</span>&#160;</div><div class="line"><a name="l07830"></a><span class="lineno"> 7830</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l07831"></a><span class="lineno"> 7831</span>&#160;    {</div><div class="line"><a name="l07832"></a><span class="lineno"> 7832</span>&#160;        <span class="keyword">const</span> VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;</div><div class="line"><a name="l07833"></a><span class="lineno"> 7833</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = m_1stNullItemsBeginCount;</div><div class="line"><a name="l07834"></a><span class="lineno"> 7834</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l07835"></a><span class="lineno"> 7835</span>&#160;        {</div><div class="line"><a name="l07836"></a><span class="lineno"> 7836</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAlloc2ndIndex to the end.</span></div><div class="line"><a name="l07837"></a><span class="lineno"> 7837</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex &lt; suballoc2ndCount &amp;&amp;</div><div class="line"><a name="l07838"></a><span class="lineno"> 7838</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07839"></a><span class="lineno"> 7839</span>&#160;            {</div><div class="line"><a name="l07840"></a><span class="lineno"> 7840</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l07841"></a><span class="lineno"> 7841</span>&#160;            }</div><div class="line"><a name="l07842"></a><span class="lineno"> 7842</span>&#160;</div><div class="line"><a name="l07843"></a><span class="lineno"> 7843</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l07844"></a><span class="lineno"> 7844</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex &lt; suballoc2ndCount)</div><div class="line"><a name="l07845"></a><span class="lineno"> 7845</span>&#160;            {</div><div class="line"><a name="l07846"></a><span class="lineno"> 7846</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l07847"></a><span class="lineno"> 7847</span>&#160;            </div><div class="line"><a name="l07848"></a><span class="lineno"> 7848</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l07849"></a><span class="lineno"> 7849</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l07850"></a><span class="lineno"> 7850</span>&#160;                {</div><div class="line"><a name="l07851"></a><span class="lineno"> 7851</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l07852"></a><span class="lineno"> 7852</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l07853"></a><span class="lineno"> 7853</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += unusedRangeSize;</div><div class="line"><a name="l07854"></a><span class="lineno"> 7854</span>&#160;                    ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l07855"></a><span class="lineno"> 7855</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07856"></a><span class="lineno"> 7856</span>&#160;                }</div><div class="line"><a name="l07857"></a><span class="lineno"> 7857</span>&#160;            </div><div class="line"><a name="l07858"></a><span class="lineno"> 7858</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l07859"></a><span class="lineno"> 7859</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l07860"></a><span class="lineno"> 7860</span>&#160;                ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a>;</div><div class="line"><a name="l07861"></a><span class="lineno"> 7861</span>&#160;            </div><div class="line"><a name="l07862"></a><span class="lineno"> 7862</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l07863"></a><span class="lineno"> 7863</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l07864"></a><span class="lineno"> 7864</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l07865"></a><span class="lineno"> 7865</span>&#160;            }</div><div class="line"><a name="l07866"></a><span class="lineno"> 7866</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l07867"></a><span class="lineno"> 7867</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07868"></a><span class="lineno"> 7868</span>&#160;            {</div><div class="line"><a name="l07869"></a><span class="lineno"> 7869</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l07870"></a><span class="lineno"> 7870</span>&#160;                {</div><div class="line"><a name="l07871"></a><span class="lineno"> 7871</span>&#160;                    <span class="comment">// There is free space from lastOffset to freeSpace2ndTo1stEnd.</span></div><div class="line"><a name="l07872"></a><span class="lineno"> 7872</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;</div><div class="line"><a name="l07873"></a><span class="lineno"> 7873</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += unusedRangeSize;</div><div class="line"><a name="l07874"></a><span class="lineno"> 7874</span>&#160;                    ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l07875"></a><span class="lineno"> 7875</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07876"></a><span class="lineno"> 7876</span>&#160;                }</div><div class="line"><a name="l07877"></a><span class="lineno"> 7877</span>&#160;</div><div class="line"><a name="l07878"></a><span class="lineno"> 7878</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l07879"></a><span class="lineno"> 7879</span>&#160;                lastOffset = freeSpace2ndTo1stEnd;</div><div class="line"><a name="l07880"></a><span class="lineno"> 7880</span>&#160;            }</div><div class="line"><a name="l07881"></a><span class="lineno"> 7881</span>&#160;        }</div><div class="line"><a name="l07882"></a><span class="lineno"> 7882</span>&#160;    }</div><div class="line"><a name="l07883"></a><span class="lineno"> 7883</span>&#160;</div><div class="line"><a name="l07884"></a><span class="lineno"> 7884</span>&#160;    <span class="keywordtype">size_t</span> nextAlloc1stIndex = m_1stNullItemsBeginCount;</div><div class="line"><a name="l07885"></a><span class="lineno"> 7885</span>&#160;    <span class="keyword">const</span> VkDeviceSize freeSpace1stTo2ndEnd =</div><div class="line"><a name="l07886"></a><span class="lineno"> 7886</span>&#160;        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;</div><div class="line"><a name="l07887"></a><span class="lineno"> 7887</span>&#160;    <span class="keywordflow">while</span>(lastOffset &lt; freeSpace1stTo2ndEnd)</div><div class="line"><a name="l07888"></a><span class="lineno"> 7888</span>&#160;    {</div><div class="line"><a name="l07889"></a><span class="lineno"> 7889</span>&#160;        <span class="comment">// Find next non-null allocation or move nextAllocIndex to the end.</span></div><div class="line"><a name="l07890"></a><span class="lineno"> 7890</span>&#160;        <span class="keywordflow">while</span>(nextAlloc1stIndex &lt; suballoc1stCount &amp;&amp;</div><div class="line"><a name="l07891"></a><span class="lineno"> 7891</span>&#160;            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07892"></a><span class="lineno"> 7892</span>&#160;        {</div><div class="line"><a name="l07893"></a><span class="lineno"> 7893</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l07894"></a><span class="lineno"> 7894</span>&#160;        }</div><div class="line"><a name="l07895"></a><span class="lineno"> 7895</span>&#160;</div><div class="line"><a name="l07896"></a><span class="lineno"> 7896</span>&#160;        <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l07897"></a><span class="lineno"> 7897</span>&#160;        <span class="keywordflow">if</span>(nextAlloc1stIndex &lt; suballoc1stCount)</div><div class="line"><a name="l07898"></a><span class="lineno"> 7898</span>&#160;        {</div><div class="line"><a name="l07899"></a><span class="lineno"> 7899</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[nextAlloc1stIndex];</div><div class="line"><a name="l07900"></a><span class="lineno"> 7900</span>&#160;            </div><div class="line"><a name="l07901"></a><span class="lineno"> 7901</span>&#160;            <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l07902"></a><span class="lineno"> 7902</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l07903"></a><span class="lineno"> 7903</span>&#160;            {</div><div class="line"><a name="l07904"></a><span class="lineno"> 7904</span>&#160;                <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l07905"></a><span class="lineno"> 7905</span>&#160;                <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l07906"></a><span class="lineno"> 7906</span>&#160;                inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += unusedRangeSize;</div><div class="line"><a name="l07907"></a><span class="lineno"> 7907</span>&#160;                ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l07908"></a><span class="lineno"> 7908</span>&#160;                inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07909"></a><span class="lineno"> 7909</span>&#160;            }</div><div class="line"><a name="l07910"></a><span class="lineno"> 7910</span>&#160;            </div><div class="line"><a name="l07911"></a><span class="lineno"> 7911</span>&#160;            <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l07912"></a><span class="lineno"> 7912</span>&#160;            <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l07913"></a><span class="lineno"> 7913</span>&#160;            ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a>;</div><div class="line"><a name="l07914"></a><span class="lineno"> 7914</span>&#160;            </div><div class="line"><a name="l07915"></a><span class="lineno"> 7915</span>&#160;            <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l07916"></a><span class="lineno"> 7916</span>&#160;            lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l07917"></a><span class="lineno"> 7917</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l07918"></a><span class="lineno"> 7918</span>&#160;        }</div><div class="line"><a name="l07919"></a><span class="lineno"> 7919</span>&#160;        <span class="comment">// We are at the end.</span></div><div class="line"><a name="l07920"></a><span class="lineno"> 7920</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l07921"></a><span class="lineno"> 7921</span>&#160;        {</div><div class="line"><a name="l07922"></a><span class="lineno"> 7922</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; freeSpace1stTo2ndEnd)</div><div class="line"><a name="l07923"></a><span class="lineno"> 7923</span>&#160;            {</div><div class="line"><a name="l07924"></a><span class="lineno"> 7924</span>&#160;                <span class="comment">// There is free space from lastOffset to freeSpace1stTo2ndEnd.</span></div><div class="line"><a name="l07925"></a><span class="lineno"> 7925</span>&#160;                <span class="keyword">const</span> VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;</div><div class="line"><a name="l07926"></a><span class="lineno"> 7926</span>&#160;                inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += unusedRangeSize;</div><div class="line"><a name="l07927"></a><span class="lineno"> 7927</span>&#160;                ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l07928"></a><span class="lineno"> 7928</span>&#160;                inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07929"></a><span class="lineno"> 7929</span>&#160;            }</div><div class="line"><a name="l07930"></a><span class="lineno"> 7930</span>&#160;</div><div class="line"><a name="l07931"></a><span class="lineno"> 7931</span>&#160;            <span class="comment">// End of loop.</span></div><div class="line"><a name="l07932"></a><span class="lineno"> 7932</span>&#160;            lastOffset = freeSpace1stTo2ndEnd;</div><div class="line"><a name="l07933"></a><span class="lineno"> 7933</span>&#160;        }</div><div class="line"><a name="l07934"></a><span class="lineno"> 7934</span>&#160;    }</div><div class="line"><a name="l07935"></a><span class="lineno"> 7935</span>&#160;</div><div class="line"><a name="l07936"></a><span class="lineno"> 7936</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l07937"></a><span class="lineno"> 7937</span>&#160;    {</div><div class="line"><a name="l07938"></a><span class="lineno"> 7938</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = suballocations2nd.size() - 1;</div><div class="line"><a name="l07939"></a><span class="lineno"> 7939</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; size)</div><div class="line"><a name="l07940"></a><span class="lineno"> 7940</span>&#160;        {</div><div class="line"><a name="l07941"></a><span class="lineno"> 7941</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAlloc2ndIndex to the end.</span></div><div class="line"><a name="l07942"></a><span class="lineno"> 7942</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex != SIZE_MAX &amp;&amp;</div><div class="line"><a name="l07943"></a><span class="lineno"> 7943</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l07944"></a><span class="lineno"> 7944</span>&#160;            {</div><div class="line"><a name="l07945"></a><span class="lineno"> 7945</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l07946"></a><span class="lineno"> 7946</span>&#160;            }</div><div class="line"><a name="l07947"></a><span class="lineno"> 7947</span>&#160;</div><div class="line"><a name="l07948"></a><span class="lineno"> 7948</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l07949"></a><span class="lineno"> 7949</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex != SIZE_MAX)</div><div class="line"><a name="l07950"></a><span class="lineno"> 7950</span>&#160;            {</div><div class="line"><a name="l07951"></a><span class="lineno"> 7951</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l07952"></a><span class="lineno"> 7952</span>&#160;            </div><div class="line"><a name="l07953"></a><span class="lineno"> 7953</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l07954"></a><span class="lineno"> 7954</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l07955"></a><span class="lineno"> 7955</span>&#160;                {</div><div class="line"><a name="l07956"></a><span class="lineno"> 7956</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l07957"></a><span class="lineno"> 7957</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l07958"></a><span class="lineno"> 7958</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += unusedRangeSize;</div><div class="line"><a name="l07959"></a><span class="lineno"> 7959</span>&#160;                    ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l07960"></a><span class="lineno"> 7960</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07961"></a><span class="lineno"> 7961</span>&#160;                }</div><div class="line"><a name="l07962"></a><span class="lineno"> 7962</span>&#160;            </div><div class="line"><a name="l07963"></a><span class="lineno"> 7963</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l07964"></a><span class="lineno"> 7964</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l07965"></a><span class="lineno"> 7965</span>&#160;                ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a>;</div><div class="line"><a name="l07966"></a><span class="lineno"> 7966</span>&#160;            </div><div class="line"><a name="l07967"></a><span class="lineno"> 7967</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l07968"></a><span class="lineno"> 7968</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l07969"></a><span class="lineno"> 7969</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l07970"></a><span class="lineno"> 7970</span>&#160;            }</div><div class="line"><a name="l07971"></a><span class="lineno"> 7971</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l07972"></a><span class="lineno"> 7972</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l07973"></a><span class="lineno"> 7973</span>&#160;            {</div><div class="line"><a name="l07974"></a><span class="lineno"> 7974</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; size)</div><div class="line"><a name="l07975"></a><span class="lineno"> 7975</span>&#160;                {</div><div class="line"><a name="l07976"></a><span class="lineno"> 7976</span>&#160;                    <span class="comment">// There is free space from lastOffset to size.</span></div><div class="line"><a name="l07977"></a><span class="lineno"> 7977</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = size - lastOffset;</div><div class="line"><a name="l07978"></a><span class="lineno"> 7978</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> += unusedRangeSize;</div><div class="line"><a name="l07979"></a><span class="lineno"> 7979</span>&#160;                    ++inoutStats.<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a>;</div><div class="line"><a name="l07980"></a><span class="lineno"> 7980</span>&#160;                    inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = VMA_MAX(inoutStats.<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a>, unusedRangeSize);</div><div class="line"><a name="l07981"></a><span class="lineno"> 7981</span>&#160;                }</div><div class="line"><a name="l07982"></a><span class="lineno"> 7982</span>&#160;</div><div class="line"><a name="l07983"></a><span class="lineno"> 7983</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l07984"></a><span class="lineno"> 7984</span>&#160;                lastOffset = size;</div><div class="line"><a name="l07985"></a><span class="lineno"> 7985</span>&#160;            }</div><div class="line"><a name="l07986"></a><span class="lineno"> 7986</span>&#160;        }</div><div class="line"><a name="l07987"></a><span class="lineno"> 7987</span>&#160;    }</div><div class="line"><a name="l07988"></a><span class="lineno"> 7988</span>&#160;}</div><div class="line"><a name="l07989"></a><span class="lineno"> 7989</span>&#160;</div><div class="line"><a name="l07990"></a><span class="lineno"> 7990</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l07991"></a><span class="lineno"> 7991</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json)<span class="keyword"> const</span></div><div class="line"><a name="l07992"></a><span class="lineno"> 7992</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l07993"></a><span class="lineno"> 7993</span>&#160;    <span class="keyword">const</span> VkDeviceSize size = GetSize();</div><div class="line"><a name="l07994"></a><span class="lineno"> 7994</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l07995"></a><span class="lineno"> 7995</span>&#160;    <span class="keyword">const</span> SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l07996"></a><span class="lineno"> 7996</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc1stCount = suballocations1st.size();</div><div class="line"><a name="l07997"></a><span class="lineno"> 7997</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc2ndCount = suballocations2nd.size();</div><div class="line"><a name="l07998"></a><span class="lineno"> 7998</span>&#160;</div><div class="line"><a name="l07999"></a><span class="lineno"> 7999</span>&#160;    <span class="comment">// FIRST PASS</span></div><div class="line"><a name="l08000"></a><span class="lineno"> 8000</span>&#160;</div><div class="line"><a name="l08001"></a><span class="lineno"> 8001</span>&#160;    <span class="keywordtype">size_t</span> unusedRangeCount = 0;</div><div class="line"><a name="l08002"></a><span class="lineno"> 8002</span>&#160;    VkDeviceSize usedBytes = 0;</div><div class="line"><a name="l08003"></a><span class="lineno"> 8003</span>&#160;</div><div class="line"><a name="l08004"></a><span class="lineno"> 8004</span>&#160;    VkDeviceSize lastOffset = 0;</div><div class="line"><a name="l08005"></a><span class="lineno"> 8005</span>&#160;</div><div class="line"><a name="l08006"></a><span class="lineno"> 8006</span>&#160;    <span class="keywordtype">size_t</span> alloc2ndCount = 0;</div><div class="line"><a name="l08007"></a><span class="lineno"> 8007</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l08008"></a><span class="lineno"> 8008</span>&#160;    {</div><div class="line"><a name="l08009"></a><span class="lineno"> 8009</span>&#160;        <span class="keyword">const</span> VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;</div><div class="line"><a name="l08010"></a><span class="lineno"> 8010</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = 0;</div><div class="line"><a name="l08011"></a><span class="lineno"> 8011</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l08012"></a><span class="lineno"> 8012</span>&#160;        {</div><div class="line"><a name="l08013"></a><span class="lineno"> 8013</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAlloc2ndIndex to the end.</span></div><div class="line"><a name="l08014"></a><span class="lineno"> 8014</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex &lt; suballoc2ndCount &amp;&amp;</div><div class="line"><a name="l08015"></a><span class="lineno"> 8015</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l08016"></a><span class="lineno"> 8016</span>&#160;            {</div><div class="line"><a name="l08017"></a><span class="lineno"> 8017</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l08018"></a><span class="lineno"> 8018</span>&#160;            }</div><div class="line"><a name="l08019"></a><span class="lineno"> 8019</span>&#160;</div><div class="line"><a name="l08020"></a><span class="lineno"> 8020</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l08021"></a><span class="lineno"> 8021</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex &lt; suballoc2ndCount)</div><div class="line"><a name="l08022"></a><span class="lineno"> 8022</span>&#160;            {</div><div class="line"><a name="l08023"></a><span class="lineno"> 8023</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l08024"></a><span class="lineno"> 8024</span>&#160;            </div><div class="line"><a name="l08025"></a><span class="lineno"> 8025</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l08026"></a><span class="lineno"> 8026</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l08027"></a><span class="lineno"> 8027</span>&#160;                {</div><div class="line"><a name="l08028"></a><span class="lineno"> 8028</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l08029"></a><span class="lineno"> 8029</span>&#160;                    ++unusedRangeCount;</div><div class="line"><a name="l08030"></a><span class="lineno"> 8030</span>&#160;                }</div><div class="line"><a name="l08031"></a><span class="lineno"> 8031</span>&#160;            </div><div class="line"><a name="l08032"></a><span class="lineno"> 8032</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l08033"></a><span class="lineno"> 8033</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l08034"></a><span class="lineno"> 8034</span>&#160;                ++alloc2ndCount;</div><div class="line"><a name="l08035"></a><span class="lineno"> 8035</span>&#160;                usedBytes += suballoc.size;</div><div class="line"><a name="l08036"></a><span class="lineno"> 8036</span>&#160;            </div><div class="line"><a name="l08037"></a><span class="lineno"> 8037</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l08038"></a><span class="lineno"> 8038</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l08039"></a><span class="lineno"> 8039</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l08040"></a><span class="lineno"> 8040</span>&#160;            }</div><div class="line"><a name="l08041"></a><span class="lineno"> 8041</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l08042"></a><span class="lineno"> 8042</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l08043"></a><span class="lineno"> 8043</span>&#160;            {</div><div class="line"><a name="l08044"></a><span class="lineno"> 8044</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l08045"></a><span class="lineno"> 8045</span>&#160;                {</div><div class="line"><a name="l08046"></a><span class="lineno"> 8046</span>&#160;                    <span class="comment">// There is free space from lastOffset to freeSpace2ndTo1stEnd.</span></div><div class="line"><a name="l08047"></a><span class="lineno"> 8047</span>&#160;                    ++unusedRangeCount;</div><div class="line"><a name="l08048"></a><span class="lineno"> 8048</span>&#160;                }</div><div class="line"><a name="l08049"></a><span class="lineno"> 8049</span>&#160;</div><div class="line"><a name="l08050"></a><span class="lineno"> 8050</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l08051"></a><span class="lineno"> 8051</span>&#160;                lastOffset = freeSpace2ndTo1stEnd;</div><div class="line"><a name="l08052"></a><span class="lineno"> 8052</span>&#160;            }</div><div class="line"><a name="l08053"></a><span class="lineno"> 8053</span>&#160;        }</div><div class="line"><a name="l08054"></a><span class="lineno"> 8054</span>&#160;    }</div><div class="line"><a name="l08055"></a><span class="lineno"> 8055</span>&#160;</div><div class="line"><a name="l08056"></a><span class="lineno"> 8056</span>&#160;    <span class="keywordtype">size_t</span> nextAlloc1stIndex = m_1stNullItemsBeginCount;</div><div class="line"><a name="l08057"></a><span class="lineno"> 8057</span>&#160;    <span class="keywordtype">size_t</span> alloc1stCount = 0;</div><div class="line"><a name="l08058"></a><span class="lineno"> 8058</span>&#160;    <span class="keyword">const</span> VkDeviceSize freeSpace1stTo2ndEnd =</div><div class="line"><a name="l08059"></a><span class="lineno"> 8059</span>&#160;        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;</div><div class="line"><a name="l08060"></a><span class="lineno"> 8060</span>&#160;    <span class="keywordflow">while</span>(lastOffset &lt; freeSpace1stTo2ndEnd)</div><div class="line"><a name="l08061"></a><span class="lineno"> 8061</span>&#160;    {</div><div class="line"><a name="l08062"></a><span class="lineno"> 8062</span>&#160;        <span class="comment">// Find next non-null allocation or move nextAllocIndex to the end.</span></div><div class="line"><a name="l08063"></a><span class="lineno"> 8063</span>&#160;        <span class="keywordflow">while</span>(nextAlloc1stIndex &lt; suballoc1stCount &amp;&amp;</div><div class="line"><a name="l08064"></a><span class="lineno"> 8064</span>&#160;            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l08065"></a><span class="lineno"> 8065</span>&#160;        {</div><div class="line"><a name="l08066"></a><span class="lineno"> 8066</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l08067"></a><span class="lineno"> 8067</span>&#160;        }</div><div class="line"><a name="l08068"></a><span class="lineno"> 8068</span>&#160;</div><div class="line"><a name="l08069"></a><span class="lineno"> 8069</span>&#160;        <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l08070"></a><span class="lineno"> 8070</span>&#160;        <span class="keywordflow">if</span>(nextAlloc1stIndex &lt; suballoc1stCount)</div><div class="line"><a name="l08071"></a><span class="lineno"> 8071</span>&#160;        {</div><div class="line"><a name="l08072"></a><span class="lineno"> 8072</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[nextAlloc1stIndex];</div><div class="line"><a name="l08073"></a><span class="lineno"> 8073</span>&#160;            </div><div class="line"><a name="l08074"></a><span class="lineno"> 8074</span>&#160;            <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l08075"></a><span class="lineno"> 8075</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l08076"></a><span class="lineno"> 8076</span>&#160;            {</div><div class="line"><a name="l08077"></a><span class="lineno"> 8077</span>&#160;                <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l08078"></a><span class="lineno"> 8078</span>&#160;                ++unusedRangeCount;</div><div class="line"><a name="l08079"></a><span class="lineno"> 8079</span>&#160;            }</div><div class="line"><a name="l08080"></a><span class="lineno"> 8080</span>&#160;            </div><div class="line"><a name="l08081"></a><span class="lineno"> 8081</span>&#160;            <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l08082"></a><span class="lineno"> 8082</span>&#160;            <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l08083"></a><span class="lineno"> 8083</span>&#160;            ++alloc1stCount;</div><div class="line"><a name="l08084"></a><span class="lineno"> 8084</span>&#160;            usedBytes += suballoc.size;</div><div class="line"><a name="l08085"></a><span class="lineno"> 8085</span>&#160;            </div><div class="line"><a name="l08086"></a><span class="lineno"> 8086</span>&#160;            <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l08087"></a><span class="lineno"> 8087</span>&#160;            lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l08088"></a><span class="lineno"> 8088</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l08089"></a><span class="lineno"> 8089</span>&#160;        }</div><div class="line"><a name="l08090"></a><span class="lineno"> 8090</span>&#160;        <span class="comment">// We are at the end.</span></div><div class="line"><a name="l08091"></a><span class="lineno"> 8091</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l08092"></a><span class="lineno"> 8092</span>&#160;        {</div><div class="line"><a name="l08093"></a><span class="lineno"> 8093</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; size)</div><div class="line"><a name="l08094"></a><span class="lineno"> 8094</span>&#160;            {</div><div class="line"><a name="l08095"></a><span class="lineno"> 8095</span>&#160;                <span class="comment">// There is free space from lastOffset to freeSpace1stTo2ndEnd.</span></div><div class="line"><a name="l08096"></a><span class="lineno"> 8096</span>&#160;                ++unusedRangeCount;</div><div class="line"><a name="l08097"></a><span class="lineno"> 8097</span>&#160;            }</div><div class="line"><a name="l08098"></a><span class="lineno"> 8098</span>&#160;</div><div class="line"><a name="l08099"></a><span class="lineno"> 8099</span>&#160;            <span class="comment">// End of loop.</span></div><div class="line"><a name="l08100"></a><span class="lineno"> 8100</span>&#160;            lastOffset = freeSpace1stTo2ndEnd;</div><div class="line"><a name="l08101"></a><span class="lineno"> 8101</span>&#160;        }</div><div class="line"><a name="l08102"></a><span class="lineno"> 8102</span>&#160;    }</div><div class="line"><a name="l08103"></a><span class="lineno"> 8103</span>&#160;</div><div class="line"><a name="l08104"></a><span class="lineno"> 8104</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l08105"></a><span class="lineno"> 8105</span>&#160;    {</div><div class="line"><a name="l08106"></a><span class="lineno"> 8106</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = suballocations2nd.size() - 1;</div><div class="line"><a name="l08107"></a><span class="lineno"> 8107</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; size)</div><div class="line"><a name="l08108"></a><span class="lineno"> 8108</span>&#160;        {</div><div class="line"><a name="l08109"></a><span class="lineno"> 8109</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAlloc2ndIndex to the end.</span></div><div class="line"><a name="l08110"></a><span class="lineno"> 8110</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex != SIZE_MAX &amp;&amp;</div><div class="line"><a name="l08111"></a><span class="lineno"> 8111</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l08112"></a><span class="lineno"> 8112</span>&#160;            {</div><div class="line"><a name="l08113"></a><span class="lineno"> 8113</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l08114"></a><span class="lineno"> 8114</span>&#160;            }</div><div class="line"><a name="l08115"></a><span class="lineno"> 8115</span>&#160;</div><div class="line"><a name="l08116"></a><span class="lineno"> 8116</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l08117"></a><span class="lineno"> 8117</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex != SIZE_MAX)</div><div class="line"><a name="l08118"></a><span class="lineno"> 8118</span>&#160;            {</div><div class="line"><a name="l08119"></a><span class="lineno"> 8119</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l08120"></a><span class="lineno"> 8120</span>&#160;            </div><div class="line"><a name="l08121"></a><span class="lineno"> 8121</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l08122"></a><span class="lineno"> 8122</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l08123"></a><span class="lineno"> 8123</span>&#160;                {</div><div class="line"><a name="l08124"></a><span class="lineno"> 8124</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l08125"></a><span class="lineno"> 8125</span>&#160;                    ++unusedRangeCount;</div><div class="line"><a name="l08126"></a><span class="lineno"> 8126</span>&#160;                }</div><div class="line"><a name="l08127"></a><span class="lineno"> 8127</span>&#160;            </div><div class="line"><a name="l08128"></a><span class="lineno"> 8128</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l08129"></a><span class="lineno"> 8129</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l08130"></a><span class="lineno"> 8130</span>&#160;                ++alloc2ndCount;</div><div class="line"><a name="l08131"></a><span class="lineno"> 8131</span>&#160;                usedBytes += suballoc.size;</div><div class="line"><a name="l08132"></a><span class="lineno"> 8132</span>&#160;            </div><div class="line"><a name="l08133"></a><span class="lineno"> 8133</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l08134"></a><span class="lineno"> 8134</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l08135"></a><span class="lineno"> 8135</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l08136"></a><span class="lineno"> 8136</span>&#160;            }</div><div class="line"><a name="l08137"></a><span class="lineno"> 8137</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l08138"></a><span class="lineno"> 8138</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l08139"></a><span class="lineno"> 8139</span>&#160;            {</div><div class="line"><a name="l08140"></a><span class="lineno"> 8140</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; size)</div><div class="line"><a name="l08141"></a><span class="lineno"> 8141</span>&#160;                {</div><div class="line"><a name="l08142"></a><span class="lineno"> 8142</span>&#160;                    <span class="comment">// There is free space from lastOffset to size.</span></div><div class="line"><a name="l08143"></a><span class="lineno"> 8143</span>&#160;                    ++unusedRangeCount;</div><div class="line"><a name="l08144"></a><span class="lineno"> 8144</span>&#160;                }</div><div class="line"><a name="l08145"></a><span class="lineno"> 8145</span>&#160;</div><div class="line"><a name="l08146"></a><span class="lineno"> 8146</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l08147"></a><span class="lineno"> 8147</span>&#160;                lastOffset = size;</div><div class="line"><a name="l08148"></a><span class="lineno"> 8148</span>&#160;            }</div><div class="line"><a name="l08149"></a><span class="lineno"> 8149</span>&#160;        }</div><div class="line"><a name="l08150"></a><span class="lineno"> 8150</span>&#160;    }</div><div class="line"><a name="l08151"></a><span class="lineno"> 8151</span>&#160;</div><div class="line"><a name="l08152"></a><span class="lineno"> 8152</span>&#160;    <span class="keyword">const</span> VkDeviceSize unusedBytes = size - usedBytes;</div><div class="line"><a name="l08153"></a><span class="lineno"> 8153</span>&#160;    PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount);</div><div class="line"><a name="l08154"></a><span class="lineno"> 8154</span>&#160;</div><div class="line"><a name="l08155"></a><span class="lineno"> 8155</span>&#160;    <span class="comment">// SECOND PASS</span></div><div class="line"><a name="l08156"></a><span class="lineno"> 8156</span>&#160;    lastOffset = 0;</div><div class="line"><a name="l08157"></a><span class="lineno"> 8157</span>&#160;</div><div class="line"><a name="l08158"></a><span class="lineno"> 8158</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l08159"></a><span class="lineno"> 8159</span>&#160;    {</div><div class="line"><a name="l08160"></a><span class="lineno"> 8160</span>&#160;        <span class="keyword">const</span> VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;</div><div class="line"><a name="l08161"></a><span class="lineno"> 8161</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = 0;</div><div class="line"><a name="l08162"></a><span class="lineno"> 8162</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l08163"></a><span class="lineno"> 8163</span>&#160;        {</div><div class="line"><a name="l08164"></a><span class="lineno"> 8164</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAlloc2ndIndex to the end.</span></div><div class="line"><a name="l08165"></a><span class="lineno"> 8165</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex &lt; suballoc2ndCount &amp;&amp;</div><div class="line"><a name="l08166"></a><span class="lineno"> 8166</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l08167"></a><span class="lineno"> 8167</span>&#160;            {</div><div class="line"><a name="l08168"></a><span class="lineno"> 8168</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l08169"></a><span class="lineno"> 8169</span>&#160;            }</div><div class="line"><a name="l08170"></a><span class="lineno"> 8170</span>&#160;</div><div class="line"><a name="l08171"></a><span class="lineno"> 8171</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l08172"></a><span class="lineno"> 8172</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex &lt; suballoc2ndCount)</div><div class="line"><a name="l08173"></a><span class="lineno"> 8173</span>&#160;            {</div><div class="line"><a name="l08174"></a><span class="lineno"> 8174</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l08175"></a><span class="lineno"> 8175</span>&#160;            </div><div class="line"><a name="l08176"></a><span class="lineno"> 8176</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l08177"></a><span class="lineno"> 8177</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l08178"></a><span class="lineno"> 8178</span>&#160;                {</div><div class="line"><a name="l08179"></a><span class="lineno"> 8179</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l08180"></a><span class="lineno"> 8180</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l08181"></a><span class="lineno"> 8181</span>&#160;                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);</div><div class="line"><a name="l08182"></a><span class="lineno"> 8182</span>&#160;                }</div><div class="line"><a name="l08183"></a><span class="lineno"> 8183</span>&#160;            </div><div class="line"><a name="l08184"></a><span class="lineno"> 8184</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l08185"></a><span class="lineno"> 8185</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l08186"></a><span class="lineno"> 8186</span>&#160;                PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation);</div><div class="line"><a name="l08187"></a><span class="lineno"> 8187</span>&#160;            </div><div class="line"><a name="l08188"></a><span class="lineno"> 8188</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l08189"></a><span class="lineno"> 8189</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l08190"></a><span class="lineno"> 8190</span>&#160;                ++nextAlloc2ndIndex;</div><div class="line"><a name="l08191"></a><span class="lineno"> 8191</span>&#160;            }</div><div class="line"><a name="l08192"></a><span class="lineno"> 8192</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l08193"></a><span class="lineno"> 8193</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l08194"></a><span class="lineno"> 8194</span>&#160;            {</div><div class="line"><a name="l08195"></a><span class="lineno"> 8195</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; freeSpace2ndTo1stEnd)</div><div class="line"><a name="l08196"></a><span class="lineno"> 8196</span>&#160;                {</div><div class="line"><a name="l08197"></a><span class="lineno"> 8197</span>&#160;                    <span class="comment">// There is free space from lastOffset to freeSpace2ndTo1stEnd.</span></div><div class="line"><a name="l08198"></a><span class="lineno"> 8198</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;</div><div class="line"><a name="l08199"></a><span class="lineno"> 8199</span>&#160;                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);</div><div class="line"><a name="l08200"></a><span class="lineno"> 8200</span>&#160;                }</div><div class="line"><a name="l08201"></a><span class="lineno"> 8201</span>&#160;</div><div class="line"><a name="l08202"></a><span class="lineno"> 8202</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l08203"></a><span class="lineno"> 8203</span>&#160;                lastOffset = freeSpace2ndTo1stEnd;</div><div class="line"><a name="l08204"></a><span class="lineno"> 8204</span>&#160;            }</div><div class="line"><a name="l08205"></a><span class="lineno"> 8205</span>&#160;        }</div><div class="line"><a name="l08206"></a><span class="lineno"> 8206</span>&#160;    }</div><div class="line"><a name="l08207"></a><span class="lineno"> 8207</span>&#160;</div><div class="line"><a name="l08208"></a><span class="lineno"> 8208</span>&#160;    nextAlloc1stIndex = m_1stNullItemsBeginCount;</div><div class="line"><a name="l08209"></a><span class="lineno"> 8209</span>&#160;    <span class="keywordflow">while</span>(lastOffset &lt; freeSpace1stTo2ndEnd)</div><div class="line"><a name="l08210"></a><span class="lineno"> 8210</span>&#160;    {</div><div class="line"><a name="l08211"></a><span class="lineno"> 8211</span>&#160;        <span class="comment">// Find next non-null allocation or move nextAllocIndex to the end.</span></div><div class="line"><a name="l08212"></a><span class="lineno"> 8212</span>&#160;        <span class="keywordflow">while</span>(nextAlloc1stIndex &lt; suballoc1stCount &amp;&amp;</div><div class="line"><a name="l08213"></a><span class="lineno"> 8213</span>&#160;            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l08214"></a><span class="lineno"> 8214</span>&#160;        {</div><div class="line"><a name="l08215"></a><span class="lineno"> 8215</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l08216"></a><span class="lineno"> 8216</span>&#160;        }</div><div class="line"><a name="l08217"></a><span class="lineno"> 8217</span>&#160;</div><div class="line"><a name="l08218"></a><span class="lineno"> 8218</span>&#160;        <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l08219"></a><span class="lineno"> 8219</span>&#160;        <span class="keywordflow">if</span>(nextAlloc1stIndex &lt; suballoc1stCount)</div><div class="line"><a name="l08220"></a><span class="lineno"> 8220</span>&#160;        {</div><div class="line"><a name="l08221"></a><span class="lineno"> 8221</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[nextAlloc1stIndex];</div><div class="line"><a name="l08222"></a><span class="lineno"> 8222</span>&#160;            </div><div class="line"><a name="l08223"></a><span class="lineno"> 8223</span>&#160;            <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l08224"></a><span class="lineno"> 8224</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l08225"></a><span class="lineno"> 8225</span>&#160;            {</div><div class="line"><a name="l08226"></a><span class="lineno"> 8226</span>&#160;                <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l08227"></a><span class="lineno"> 8227</span>&#160;                <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l08228"></a><span class="lineno"> 8228</span>&#160;                PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);</div><div class="line"><a name="l08229"></a><span class="lineno"> 8229</span>&#160;            }</div><div class="line"><a name="l08230"></a><span class="lineno"> 8230</span>&#160;            </div><div class="line"><a name="l08231"></a><span class="lineno"> 8231</span>&#160;            <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l08232"></a><span class="lineno"> 8232</span>&#160;            <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l08233"></a><span class="lineno"> 8233</span>&#160;            PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation);</div><div class="line"><a name="l08234"></a><span class="lineno"> 8234</span>&#160;            </div><div class="line"><a name="l08235"></a><span class="lineno"> 8235</span>&#160;            <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l08236"></a><span class="lineno"> 8236</span>&#160;            lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l08237"></a><span class="lineno"> 8237</span>&#160;            ++nextAlloc1stIndex;</div><div class="line"><a name="l08238"></a><span class="lineno"> 8238</span>&#160;        }</div><div class="line"><a name="l08239"></a><span class="lineno"> 8239</span>&#160;        <span class="comment">// We are at the end.</span></div><div class="line"><a name="l08240"></a><span class="lineno"> 8240</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l08241"></a><span class="lineno"> 8241</span>&#160;        {</div><div class="line"><a name="l08242"></a><span class="lineno"> 8242</span>&#160;            <span class="keywordflow">if</span>(lastOffset &lt; freeSpace1stTo2ndEnd)</div><div class="line"><a name="l08243"></a><span class="lineno"> 8243</span>&#160;            {</div><div class="line"><a name="l08244"></a><span class="lineno"> 8244</span>&#160;                <span class="comment">// There is free space from lastOffset to freeSpace1stTo2ndEnd.</span></div><div class="line"><a name="l08245"></a><span class="lineno"> 8245</span>&#160;                <span class="keyword">const</span> VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;</div><div class="line"><a name="l08246"></a><span class="lineno"> 8246</span>&#160;                PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);</div><div class="line"><a name="l08247"></a><span class="lineno"> 8247</span>&#160;            }</div><div class="line"><a name="l08248"></a><span class="lineno"> 8248</span>&#160;</div><div class="line"><a name="l08249"></a><span class="lineno"> 8249</span>&#160;            <span class="comment">// End of loop.</span></div><div class="line"><a name="l08250"></a><span class="lineno"> 8250</span>&#160;            lastOffset = freeSpace1stTo2ndEnd;</div><div class="line"><a name="l08251"></a><span class="lineno"> 8251</span>&#160;        }</div><div class="line"><a name="l08252"></a><span class="lineno"> 8252</span>&#160;    }</div><div class="line"><a name="l08253"></a><span class="lineno"> 8253</span>&#160;</div><div class="line"><a name="l08254"></a><span class="lineno"> 8254</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l08255"></a><span class="lineno"> 8255</span>&#160;    {</div><div class="line"><a name="l08256"></a><span class="lineno"> 8256</span>&#160;        <span class="keywordtype">size_t</span> nextAlloc2ndIndex = suballocations2nd.size() - 1;</div><div class="line"><a name="l08257"></a><span class="lineno"> 8257</span>&#160;        <span class="keywordflow">while</span>(lastOffset &lt; size)</div><div class="line"><a name="l08258"></a><span class="lineno"> 8258</span>&#160;        {</div><div class="line"><a name="l08259"></a><span class="lineno"> 8259</span>&#160;            <span class="comment">// Find next non-null allocation or move nextAlloc2ndIndex to the end.</span></div><div class="line"><a name="l08260"></a><span class="lineno"> 8260</span>&#160;            <span class="keywordflow">while</span>(nextAlloc2ndIndex != SIZE_MAX &amp;&amp;</div><div class="line"><a name="l08261"></a><span class="lineno"> 8261</span>&#160;                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l08262"></a><span class="lineno"> 8262</span>&#160;            {</div><div class="line"><a name="l08263"></a><span class="lineno"> 8263</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l08264"></a><span class="lineno"> 8264</span>&#160;            }</div><div class="line"><a name="l08265"></a><span class="lineno"> 8265</span>&#160;</div><div class="line"><a name="l08266"></a><span class="lineno"> 8266</span>&#160;            <span class="comment">// Found non-null allocation.</span></div><div class="line"><a name="l08267"></a><span class="lineno"> 8267</span>&#160;            <span class="keywordflow">if</span>(nextAlloc2ndIndex != SIZE_MAX)</div><div class="line"><a name="l08268"></a><span class="lineno"> 8268</span>&#160;            {</div><div class="line"><a name="l08269"></a><span class="lineno"> 8269</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[nextAlloc2ndIndex];</div><div class="line"><a name="l08270"></a><span class="lineno"> 8270</span>&#160;            </div><div class="line"><a name="l08271"></a><span class="lineno"> 8271</span>&#160;                <span class="comment">// 1. Process free space before this allocation.</span></div><div class="line"><a name="l08272"></a><span class="lineno"> 8272</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; suballoc.offset)</div><div class="line"><a name="l08273"></a><span class="lineno"> 8273</span>&#160;                {</div><div class="line"><a name="l08274"></a><span class="lineno"> 8274</span>&#160;                    <span class="comment">// There is free space from lastOffset to suballoc.offset.</span></div><div class="line"><a name="l08275"></a><span class="lineno"> 8275</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;</div><div class="line"><a name="l08276"></a><span class="lineno"> 8276</span>&#160;                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);</div><div class="line"><a name="l08277"></a><span class="lineno"> 8277</span>&#160;                }</div><div class="line"><a name="l08278"></a><span class="lineno"> 8278</span>&#160;            </div><div class="line"><a name="l08279"></a><span class="lineno"> 8279</span>&#160;                <span class="comment">// 2. Process this allocation.</span></div><div class="line"><a name="l08280"></a><span class="lineno"> 8280</span>&#160;                <span class="comment">// There is allocation with suballoc.offset, suballoc.size.</span></div><div class="line"><a name="l08281"></a><span class="lineno"> 8281</span>&#160;                PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation);</div><div class="line"><a name="l08282"></a><span class="lineno"> 8282</span>&#160;            </div><div class="line"><a name="l08283"></a><span class="lineno"> 8283</span>&#160;                <span class="comment">// 3. Prepare for next iteration.</span></div><div class="line"><a name="l08284"></a><span class="lineno"> 8284</span>&#160;                lastOffset = suballoc.offset + suballoc.size;</div><div class="line"><a name="l08285"></a><span class="lineno"> 8285</span>&#160;                --nextAlloc2ndIndex;</div><div class="line"><a name="l08286"></a><span class="lineno"> 8286</span>&#160;            }</div><div class="line"><a name="l08287"></a><span class="lineno"> 8287</span>&#160;            <span class="comment">// We are at the end.</span></div><div class="line"><a name="l08288"></a><span class="lineno"> 8288</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l08289"></a><span class="lineno"> 8289</span>&#160;            {</div><div class="line"><a name="l08290"></a><span class="lineno"> 8290</span>&#160;                <span class="keywordflow">if</span>(lastOffset &lt; size)</div><div class="line"><a name="l08291"></a><span class="lineno"> 8291</span>&#160;                {</div><div class="line"><a name="l08292"></a><span class="lineno"> 8292</span>&#160;                    <span class="comment">// There is free space from lastOffset to size.</span></div><div class="line"><a name="l08293"></a><span class="lineno"> 8293</span>&#160;                    <span class="keyword">const</span> VkDeviceSize unusedRangeSize = size - lastOffset;</div><div class="line"><a name="l08294"></a><span class="lineno"> 8294</span>&#160;                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);</div><div class="line"><a name="l08295"></a><span class="lineno"> 8295</span>&#160;                }</div><div class="line"><a name="l08296"></a><span class="lineno"> 8296</span>&#160;</div><div class="line"><a name="l08297"></a><span class="lineno"> 8297</span>&#160;                <span class="comment">// End of loop.</span></div><div class="line"><a name="l08298"></a><span class="lineno"> 8298</span>&#160;                lastOffset = size;</div><div class="line"><a name="l08299"></a><span class="lineno"> 8299</span>&#160;            }</div><div class="line"><a name="l08300"></a><span class="lineno"> 8300</span>&#160;        }</div><div class="line"><a name="l08301"></a><span class="lineno"> 8301</span>&#160;    }</div><div class="line"><a name="l08302"></a><span class="lineno"> 8302</span>&#160;</div><div class="line"><a name="l08303"></a><span class="lineno"> 8303</span>&#160;    PrintDetailedMap_End(json);</div><div class="line"><a name="l08304"></a><span class="lineno"> 8304</span>&#160;}</div><div class="line"><a name="l08305"></a><span class="lineno"> 8305</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l08306"></a><span class="lineno"> 8306</span>&#160;</div><div class="line"><a name="l08307"></a><span class="lineno"> 8307</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Linear::CreateAllocationRequest(</div><div class="line"><a name="l08308"></a><span class="lineno"> 8308</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l08309"></a><span class="lineno"> 8309</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l08310"></a><span class="lineno"> 8310</span>&#160;    VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l08311"></a><span class="lineno"> 8311</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l08312"></a><span class="lineno"> 8312</span>&#160;    VkDeviceSize allocAlignment,</div><div class="line"><a name="l08313"></a><span class="lineno"> 8313</span>&#160;    <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l08314"></a><span class="lineno"> 8314</span>&#160;    VmaSuballocationType allocType,</div><div class="line"><a name="l08315"></a><span class="lineno"> 8315</span>&#160;    <span class="keywordtype">bool</span> canMakeOtherLost,</div><div class="line"><a name="l08316"></a><span class="lineno"> 8316</span>&#160;    VmaAllocationRequest* pAllocationRequest)</div><div class="line"><a name="l08317"></a><span class="lineno"> 8317</span>&#160;{</div><div class="line"><a name="l08318"></a><span class="lineno"> 8318</span>&#160;    VMA_ASSERT(allocSize &gt; 0);</div><div class="line"><a name="l08319"></a><span class="lineno"> 8319</span>&#160;    VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);</div><div class="line"><a name="l08320"></a><span class="lineno"> 8320</span>&#160;    VMA_ASSERT(pAllocationRequest != VMA_NULL);</div><div class="line"><a name="l08321"></a><span class="lineno"> 8321</span>&#160;    VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l08322"></a><span class="lineno"> 8322</span>&#160;</div><div class="line"><a name="l08323"></a><span class="lineno"> 8323</span>&#160;    <span class="keyword">const</span> VkDeviceSize size = GetSize();</div><div class="line"><a name="l08324"></a><span class="lineno"> 8324</span>&#160;    SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l08325"></a><span class="lineno"> 8325</span>&#160;    SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l08326"></a><span class="lineno"> 8326</span>&#160;</div><div class="line"><a name="l08327"></a><span class="lineno"> 8327</span>&#160;    <span class="keywordflow">if</span>(upperAddress)</div><div class="line"><a name="l08328"></a><span class="lineno"> 8328</span>&#160;    {</div><div class="line"><a name="l08329"></a><span class="lineno"> 8329</span>&#160;        <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l08330"></a><span class="lineno"> 8330</span>&#160;        {</div><div class="line"><a name="l08331"></a><span class="lineno"> 8331</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Trying to use pool with linear algorithm as double stack, while it is already being used as ring buffer.&quot;</span>);</div><div class="line"><a name="l08332"></a><span class="lineno"> 8332</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08333"></a><span class="lineno"> 8333</span>&#160;        }</div><div class="line"><a name="l08334"></a><span class="lineno"> 8334</span>&#160;</div><div class="line"><a name="l08335"></a><span class="lineno"> 8335</span>&#160;        <span class="comment">// Try to allocate before 2nd.back(), or end of block if 2nd.empty().</span></div><div class="line"><a name="l08336"></a><span class="lineno"> 8336</span>&#160;        <span class="keywordflow">if</span>(allocSize &gt; size)</div><div class="line"><a name="l08337"></a><span class="lineno"> 8337</span>&#160;        {</div><div class="line"><a name="l08338"></a><span class="lineno"> 8338</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08339"></a><span class="lineno"> 8339</span>&#160;        }</div><div class="line"><a name="l08340"></a><span class="lineno"> 8340</span>&#160;        VkDeviceSize resultBaseOffset = size - allocSize;</div><div class="line"><a name="l08341"></a><span class="lineno"> 8341</span>&#160;        <span class="keywordflow">if</span>(!suballocations2nd.empty())</div><div class="line"><a name="l08342"></a><span class="lineno"> 8342</span>&#160;        {</div><div class="line"><a name="l08343"></a><span class="lineno"> 8343</span>&#160;            <span class="keyword">const</span> VmaSuballocation&amp; lastSuballoc = suballocations2nd.back();</div><div class="line"><a name="l08344"></a><span class="lineno"> 8344</span>&#160;            resultBaseOffset = lastSuballoc.offset - allocSize;</div><div class="line"><a name="l08345"></a><span class="lineno"> 8345</span>&#160;            <span class="keywordflow">if</span>(allocSize &gt; lastSuballoc.offset)</div><div class="line"><a name="l08346"></a><span class="lineno"> 8346</span>&#160;            {</div><div class="line"><a name="l08347"></a><span class="lineno"> 8347</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08348"></a><span class="lineno"> 8348</span>&#160;            }</div><div class="line"><a name="l08349"></a><span class="lineno"> 8349</span>&#160;        }</div><div class="line"><a name="l08350"></a><span class="lineno"> 8350</span>&#160;</div><div class="line"><a name="l08351"></a><span class="lineno"> 8351</span>&#160;        <span class="comment">// Start from offset equal to end of free space.</span></div><div class="line"><a name="l08352"></a><span class="lineno"> 8352</span>&#160;        VkDeviceSize resultOffset = resultBaseOffset;</div><div class="line"><a name="l08353"></a><span class="lineno"> 8353</span>&#160;</div><div class="line"><a name="l08354"></a><span class="lineno"> 8354</span>&#160;        <span class="comment">// Apply VMA_DEBUG_MARGIN at the end.</span></div><div class="line"><a name="l08355"></a><span class="lineno"> 8355</span>&#160;        <span class="keywordflow">if</span>(VMA_DEBUG_MARGIN &gt; 0)</div><div class="line"><a name="l08356"></a><span class="lineno"> 8356</span>&#160;        {</div><div class="line"><a name="l08357"></a><span class="lineno"> 8357</span>&#160;            <span class="keywordflow">if</span>(resultOffset &lt; VMA_DEBUG_MARGIN)</div><div class="line"><a name="l08358"></a><span class="lineno"> 8358</span>&#160;            {</div><div class="line"><a name="l08359"></a><span class="lineno"> 8359</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08360"></a><span class="lineno"> 8360</span>&#160;            }</div><div class="line"><a name="l08361"></a><span class="lineno"> 8361</span>&#160;            resultOffset -= VMA_DEBUG_MARGIN;</div><div class="line"><a name="l08362"></a><span class="lineno"> 8362</span>&#160;        }</div><div class="line"><a name="l08363"></a><span class="lineno"> 8363</span>&#160;</div><div class="line"><a name="l08364"></a><span class="lineno"> 8364</span>&#160;        <span class="comment">// Apply alignment.</span></div><div class="line"><a name="l08365"></a><span class="lineno"> 8365</span>&#160;        resultOffset = VmaAlignDown(resultOffset, allocAlignment);</div><div class="line"><a name="l08366"></a><span class="lineno"> 8366</span>&#160;</div><div class="line"><a name="l08367"></a><span class="lineno"> 8367</span>&#160;        <span class="comment">// Check next suballocations from 2nd for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l08368"></a><span class="lineno"> 8368</span>&#160;        <span class="comment">// Make bigger alignment if necessary.</span></div><div class="line"><a name="l08369"></a><span class="lineno"> 8369</span>&#160;        <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1 &amp;&amp; !suballocations2nd.empty())</div><div class="line"><a name="l08370"></a><span class="lineno"> 8370</span>&#160;        {</div><div class="line"><a name="l08371"></a><span class="lineno"> 8371</span>&#160;            <span class="keywordtype">bool</span> bufferImageGranularityConflict = <span class="keyword">false</span>;</div><div class="line"><a name="l08372"></a><span class="lineno"> 8372</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; )</div><div class="line"><a name="l08373"></a><span class="lineno"> 8373</span>&#160;            {</div><div class="line"><a name="l08374"></a><span class="lineno"> 8374</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; nextSuballoc = suballocations2nd[nextSuballocIndex];</div><div class="line"><a name="l08375"></a><span class="lineno"> 8375</span>&#160;                <span class="keywordflow">if</span>(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l08376"></a><span class="lineno"> 8376</span>&#160;                {</div><div class="line"><a name="l08377"></a><span class="lineno"> 8377</span>&#160;                    <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(nextSuballoc.type, allocType))</div><div class="line"><a name="l08378"></a><span class="lineno"> 8378</span>&#160;                    {</div><div class="line"><a name="l08379"></a><span class="lineno"> 8379</span>&#160;                        bufferImageGranularityConflict = <span class="keyword">true</span>;</div><div class="line"><a name="l08380"></a><span class="lineno"> 8380</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08381"></a><span class="lineno"> 8381</span>&#160;                    }</div><div class="line"><a name="l08382"></a><span class="lineno"> 8382</span>&#160;                }</div><div class="line"><a name="l08383"></a><span class="lineno"> 8383</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l08384"></a><span class="lineno"> 8384</span>&#160;                    <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l08385"></a><span class="lineno"> 8385</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l08386"></a><span class="lineno"> 8386</span>&#160;            }</div><div class="line"><a name="l08387"></a><span class="lineno"> 8387</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularityConflict)</div><div class="line"><a name="l08388"></a><span class="lineno"> 8388</span>&#160;            {</div><div class="line"><a name="l08389"></a><span class="lineno"> 8389</span>&#160;                resultOffset = VmaAlignDown(resultOffset, bufferImageGranularity);</div><div class="line"><a name="l08390"></a><span class="lineno"> 8390</span>&#160;            }</div><div class="line"><a name="l08391"></a><span class="lineno"> 8391</span>&#160;        }</div><div class="line"><a name="l08392"></a><span class="lineno"> 8392</span>&#160;</div><div class="line"><a name="l08393"></a><span class="lineno"> 8393</span>&#160;        <span class="comment">// There is enough free space.</span></div><div class="line"><a name="l08394"></a><span class="lineno"> 8394</span>&#160;        <span class="keyword">const</span> VkDeviceSize endOf1st = !suballocations1st.empty() ?</div><div class="line"><a name="l08395"></a><span class="lineno"> 8395</span>&#160;            suballocations1st.back().offset + suballocations1st.back().size :</div><div class="line"><a name="l08396"></a><span class="lineno"> 8396</span>&#160;            0;</div><div class="line"><a name="l08397"></a><span class="lineno"> 8397</span>&#160;        <span class="keywordflow">if</span>(endOf1st + VMA_DEBUG_MARGIN &lt;= resultOffset)</div><div class="line"><a name="l08398"></a><span class="lineno"> 8398</span>&#160;        {</div><div class="line"><a name="l08399"></a><span class="lineno"> 8399</span>&#160;            <span class="comment">// Check previous suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l08400"></a><span class="lineno"> 8400</span>&#160;            <span class="comment">// If conflict exists, allocation cannot be made here.</span></div><div class="line"><a name="l08401"></a><span class="lineno"> 8401</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l08402"></a><span class="lineno"> 8402</span>&#160;            {</div><div class="line"><a name="l08403"></a><span class="lineno"> 8403</span>&#160;                <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; )</div><div class="line"><a name="l08404"></a><span class="lineno"> 8404</span>&#160;                {</div><div class="line"><a name="l08405"></a><span class="lineno"> 8405</span>&#160;                    <span class="keyword">const</span> VmaSuballocation&amp; prevSuballoc = suballocations1st[prevSuballocIndex];</div><div class="line"><a name="l08406"></a><span class="lineno"> 8406</span>&#160;                    <span class="keywordflow">if</span>(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))</div><div class="line"><a name="l08407"></a><span class="lineno"> 8407</span>&#160;                    {</div><div class="line"><a name="l08408"></a><span class="lineno"> 8408</span>&#160;                        <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(allocType, prevSuballoc.type))</div><div class="line"><a name="l08409"></a><span class="lineno"> 8409</span>&#160;                        {</div><div class="line"><a name="l08410"></a><span class="lineno"> 8410</span>&#160;                            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08411"></a><span class="lineno"> 8411</span>&#160;                        }</div><div class="line"><a name="l08412"></a><span class="lineno"> 8412</span>&#160;                    }</div><div class="line"><a name="l08413"></a><span class="lineno"> 8413</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l08414"></a><span class="lineno"> 8414</span>&#160;                    {</div><div class="line"><a name="l08415"></a><span class="lineno"> 8415</span>&#160;                        <span class="comment">// Already on next page.</span></div><div class="line"><a name="l08416"></a><span class="lineno"> 8416</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08417"></a><span class="lineno"> 8417</span>&#160;                    }</div><div class="line"><a name="l08418"></a><span class="lineno"> 8418</span>&#160;                }</div><div class="line"><a name="l08419"></a><span class="lineno"> 8419</span>&#160;            }</div><div class="line"><a name="l08420"></a><span class="lineno"> 8420</span>&#160;</div><div class="line"><a name="l08421"></a><span class="lineno"> 8421</span>&#160;            <span class="comment">// All tests passed: Success.</span></div><div class="line"><a name="l08422"></a><span class="lineno"> 8422</span>&#160;            pAllocationRequest-&gt;offset = resultOffset;</div><div class="line"><a name="l08423"></a><span class="lineno"> 8423</span>&#160;            pAllocationRequest-&gt;sumFreeSize = resultBaseOffset + allocSize - endOf1st;</div><div class="line"><a name="l08424"></a><span class="lineno"> 8424</span>&#160;            pAllocationRequest-&gt;sumItemSize = 0;</div><div class="line"><a name="l08425"></a><span class="lineno"> 8425</span>&#160;            <span class="comment">// pAllocationRequest-&gt;item unused.</span></div><div class="line"><a name="l08426"></a><span class="lineno"> 8426</span>&#160;            pAllocationRequest-&gt;itemsToMakeLostCount = 0;</div><div class="line"><a name="l08427"></a><span class="lineno"> 8427</span>&#160;            <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l08428"></a><span class="lineno"> 8428</span>&#160;        }</div><div class="line"><a name="l08429"></a><span class="lineno"> 8429</span>&#160;    }</div><div class="line"><a name="l08430"></a><span class="lineno"> 8430</span>&#160;    <span class="keywordflow">else</span> <span class="comment">// !upperAddress</span></div><div class="line"><a name="l08431"></a><span class="lineno"> 8431</span>&#160;    {</div><div class="line"><a name="l08432"></a><span class="lineno"> 8432</span>&#160;        <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l08433"></a><span class="lineno"> 8433</span>&#160;        {</div><div class="line"><a name="l08434"></a><span class="lineno"> 8434</span>&#160;            <span class="comment">// Try to allocate at the end of 1st vector.</span></div><div class="line"><a name="l08435"></a><span class="lineno"> 8435</span>&#160;</div><div class="line"><a name="l08436"></a><span class="lineno"> 8436</span>&#160;            VkDeviceSize resultBaseOffset = 0;</div><div class="line"><a name="l08437"></a><span class="lineno"> 8437</span>&#160;            <span class="keywordflow">if</span>(!suballocations1st.empty())</div><div class="line"><a name="l08438"></a><span class="lineno"> 8438</span>&#160;            {</div><div class="line"><a name="l08439"></a><span class="lineno"> 8439</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; lastSuballoc = suballocations1st.back();</div><div class="line"><a name="l08440"></a><span class="lineno"> 8440</span>&#160;                resultBaseOffset = lastSuballoc.offset + lastSuballoc.size;</div><div class="line"><a name="l08441"></a><span class="lineno"> 8441</span>&#160;            }</div><div class="line"><a name="l08442"></a><span class="lineno"> 8442</span>&#160;</div><div class="line"><a name="l08443"></a><span class="lineno"> 8443</span>&#160;            <span class="comment">// Start from offset equal to beginning of free space.</span></div><div class="line"><a name="l08444"></a><span class="lineno"> 8444</span>&#160;            VkDeviceSize resultOffset = resultBaseOffset;</div><div class="line"><a name="l08445"></a><span class="lineno"> 8445</span>&#160;</div><div class="line"><a name="l08446"></a><span class="lineno"> 8446</span>&#160;            <span class="comment">// Apply VMA_DEBUG_MARGIN at the beginning.</span></div><div class="line"><a name="l08447"></a><span class="lineno"> 8447</span>&#160;            <span class="keywordflow">if</span>(VMA_DEBUG_MARGIN &gt; 0)</div><div class="line"><a name="l08448"></a><span class="lineno"> 8448</span>&#160;            {</div><div class="line"><a name="l08449"></a><span class="lineno"> 8449</span>&#160;                resultOffset += VMA_DEBUG_MARGIN;</div><div class="line"><a name="l08450"></a><span class="lineno"> 8450</span>&#160;            }</div><div class="line"><a name="l08451"></a><span class="lineno"> 8451</span>&#160;</div><div class="line"><a name="l08452"></a><span class="lineno"> 8452</span>&#160;            <span class="comment">// Apply alignment.</span></div><div class="line"><a name="l08453"></a><span class="lineno"> 8453</span>&#160;            resultOffset = VmaAlignUp(resultOffset, allocAlignment);</div><div class="line"><a name="l08454"></a><span class="lineno"> 8454</span>&#160;</div><div class="line"><a name="l08455"></a><span class="lineno"> 8455</span>&#160;            <span class="comment">// Check previous suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l08456"></a><span class="lineno"> 8456</span>&#160;            <span class="comment">// Make bigger alignment if necessary.</span></div><div class="line"><a name="l08457"></a><span class="lineno"> 8457</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1 &amp;&amp; !suballocations1st.empty())</div><div class="line"><a name="l08458"></a><span class="lineno"> 8458</span>&#160;            {</div><div class="line"><a name="l08459"></a><span class="lineno"> 8459</span>&#160;                <span class="keywordtype">bool</span> bufferImageGranularityConflict = <span class="keyword">false</span>;</div><div class="line"><a name="l08460"></a><span class="lineno"> 8460</span>&#160;                <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; )</div><div class="line"><a name="l08461"></a><span class="lineno"> 8461</span>&#160;                {</div><div class="line"><a name="l08462"></a><span class="lineno"> 8462</span>&#160;                    <span class="keyword">const</span> VmaSuballocation&amp; prevSuballoc = suballocations1st[prevSuballocIndex];</div><div class="line"><a name="l08463"></a><span class="lineno"> 8463</span>&#160;                    <span class="keywordflow">if</span>(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))</div><div class="line"><a name="l08464"></a><span class="lineno"> 8464</span>&#160;                    {</div><div class="line"><a name="l08465"></a><span class="lineno"> 8465</span>&#160;                        <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))</div><div class="line"><a name="l08466"></a><span class="lineno"> 8466</span>&#160;                        {</div><div class="line"><a name="l08467"></a><span class="lineno"> 8467</span>&#160;                            bufferImageGranularityConflict = <span class="keyword">true</span>;</div><div class="line"><a name="l08468"></a><span class="lineno"> 8468</span>&#160;                            <span class="keywordflow">break</span>;</div><div class="line"><a name="l08469"></a><span class="lineno"> 8469</span>&#160;                        }</div><div class="line"><a name="l08470"></a><span class="lineno"> 8470</span>&#160;                    }</div><div class="line"><a name="l08471"></a><span class="lineno"> 8471</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l08472"></a><span class="lineno"> 8472</span>&#160;                        <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l08473"></a><span class="lineno"> 8473</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08474"></a><span class="lineno"> 8474</span>&#160;                }</div><div class="line"><a name="l08475"></a><span class="lineno"> 8475</span>&#160;                <span class="keywordflow">if</span>(bufferImageGranularityConflict)</div><div class="line"><a name="l08476"></a><span class="lineno"> 8476</span>&#160;                {</div><div class="line"><a name="l08477"></a><span class="lineno"> 8477</span>&#160;                    resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity);</div><div class="line"><a name="l08478"></a><span class="lineno"> 8478</span>&#160;                }</div><div class="line"><a name="l08479"></a><span class="lineno"> 8479</span>&#160;            }</div><div class="line"><a name="l08480"></a><span class="lineno"> 8480</span>&#160;</div><div class="line"><a name="l08481"></a><span class="lineno"> 8481</span>&#160;            <span class="keyword">const</span> VkDeviceSize freeSpaceEnd = m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ?</div><div class="line"><a name="l08482"></a><span class="lineno"> 8482</span>&#160;                suballocations2nd.back().offset : size;</div><div class="line"><a name="l08483"></a><span class="lineno"> 8483</span>&#160;</div><div class="line"><a name="l08484"></a><span class="lineno"> 8484</span>&#160;            <span class="comment">// There is enough free space at the end after alignment.</span></div><div class="line"><a name="l08485"></a><span class="lineno"> 8485</span>&#160;            <span class="keywordflow">if</span>(resultOffset + allocSize + VMA_DEBUG_MARGIN &lt;= freeSpaceEnd)</div><div class="line"><a name="l08486"></a><span class="lineno"> 8486</span>&#160;            {</div><div class="line"><a name="l08487"></a><span class="lineno"> 8487</span>&#160;                <span class="comment">// Check next suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l08488"></a><span class="lineno"> 8488</span>&#160;                <span class="comment">// If conflict exists, allocation cannot be made here.</span></div><div class="line"><a name="l08489"></a><span class="lineno"> 8489</span>&#160;                <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1 &amp;&amp; m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l08490"></a><span class="lineno"> 8490</span>&#160;                {</div><div class="line"><a name="l08491"></a><span class="lineno"> 8491</span>&#160;                    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; )</div><div class="line"><a name="l08492"></a><span class="lineno"> 8492</span>&#160;                    {</div><div class="line"><a name="l08493"></a><span class="lineno"> 8493</span>&#160;                        <span class="keyword">const</span> VmaSuballocation&amp; nextSuballoc = suballocations2nd[nextSuballocIndex];</div><div class="line"><a name="l08494"></a><span class="lineno"> 8494</span>&#160;                        <span class="keywordflow">if</span>(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l08495"></a><span class="lineno"> 8495</span>&#160;                        {</div><div class="line"><a name="l08496"></a><span class="lineno"> 8496</span>&#160;                            <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))</div><div class="line"><a name="l08497"></a><span class="lineno"> 8497</span>&#160;                            {</div><div class="line"><a name="l08498"></a><span class="lineno"> 8498</span>&#160;                                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08499"></a><span class="lineno"> 8499</span>&#160;                            }</div><div class="line"><a name="l08500"></a><span class="lineno"> 8500</span>&#160;                        }</div><div class="line"><a name="l08501"></a><span class="lineno"> 8501</span>&#160;                        <span class="keywordflow">else</span></div><div class="line"><a name="l08502"></a><span class="lineno"> 8502</span>&#160;                        {</div><div class="line"><a name="l08503"></a><span class="lineno"> 8503</span>&#160;                            <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l08504"></a><span class="lineno"> 8504</span>&#160;                            <span class="keywordflow">break</span>;</div><div class="line"><a name="l08505"></a><span class="lineno"> 8505</span>&#160;                        }</div><div class="line"><a name="l08506"></a><span class="lineno"> 8506</span>&#160;                    }</div><div class="line"><a name="l08507"></a><span class="lineno"> 8507</span>&#160;                }</div><div class="line"><a name="l08508"></a><span class="lineno"> 8508</span>&#160;</div><div class="line"><a name="l08509"></a><span class="lineno"> 8509</span>&#160;                <span class="comment">// All tests passed: Success.</span></div><div class="line"><a name="l08510"></a><span class="lineno"> 8510</span>&#160;                pAllocationRequest-&gt;offset = resultOffset;</div><div class="line"><a name="l08511"></a><span class="lineno"> 8511</span>&#160;                pAllocationRequest-&gt;sumFreeSize = freeSpaceEnd - resultBaseOffset;</div><div class="line"><a name="l08512"></a><span class="lineno"> 8512</span>&#160;                pAllocationRequest-&gt;sumItemSize = 0;</div><div class="line"><a name="l08513"></a><span class="lineno"> 8513</span>&#160;                <span class="comment">// pAllocationRequest-&gt;item unused.</span></div><div class="line"><a name="l08514"></a><span class="lineno"> 8514</span>&#160;                pAllocationRequest-&gt;itemsToMakeLostCount = 0;</div><div class="line"><a name="l08515"></a><span class="lineno"> 8515</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l08516"></a><span class="lineno"> 8516</span>&#160;            }</div><div class="line"><a name="l08517"></a><span class="lineno"> 8517</span>&#160;        }</div><div class="line"><a name="l08518"></a><span class="lineno"> 8518</span>&#160;</div><div class="line"><a name="l08519"></a><span class="lineno"> 8519</span>&#160;        <span class="comment">// Wrap-around to end of 2nd vector. Try to allocate there, watching for the</span></div><div class="line"><a name="l08520"></a><span class="lineno"> 8520</span>&#160;        <span class="comment">// beginning of 1st vector as the end of free space.</span></div><div class="line"><a name="l08521"></a><span class="lineno"> 8521</span>&#160;        <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l08522"></a><span class="lineno"> 8522</span>&#160;        {</div><div class="line"><a name="l08523"></a><span class="lineno"> 8523</span>&#160;            VMA_ASSERT(!suballocations1st.empty());</div><div class="line"><a name="l08524"></a><span class="lineno"> 8524</span>&#160;</div><div class="line"><a name="l08525"></a><span class="lineno"> 8525</span>&#160;            VkDeviceSize resultBaseOffset = 0;</div><div class="line"><a name="l08526"></a><span class="lineno"> 8526</span>&#160;            <span class="keywordflow">if</span>(!suballocations2nd.empty())</div><div class="line"><a name="l08527"></a><span class="lineno"> 8527</span>&#160;            {</div><div class="line"><a name="l08528"></a><span class="lineno"> 8528</span>&#160;                <span class="keyword">const</span> VmaSuballocation&amp; lastSuballoc = suballocations2nd.back();</div><div class="line"><a name="l08529"></a><span class="lineno"> 8529</span>&#160;                resultBaseOffset = lastSuballoc.offset + lastSuballoc.size;</div><div class="line"><a name="l08530"></a><span class="lineno"> 8530</span>&#160;            }</div><div class="line"><a name="l08531"></a><span class="lineno"> 8531</span>&#160;</div><div class="line"><a name="l08532"></a><span class="lineno"> 8532</span>&#160;            <span class="comment">// Start from offset equal to beginning of free space.</span></div><div class="line"><a name="l08533"></a><span class="lineno"> 8533</span>&#160;            VkDeviceSize resultOffset = resultBaseOffset;</div><div class="line"><a name="l08534"></a><span class="lineno"> 8534</span>&#160;</div><div class="line"><a name="l08535"></a><span class="lineno"> 8535</span>&#160;            <span class="comment">// Apply VMA_DEBUG_MARGIN at the beginning.</span></div><div class="line"><a name="l08536"></a><span class="lineno"> 8536</span>&#160;            <span class="keywordflow">if</span>(VMA_DEBUG_MARGIN &gt; 0)</div><div class="line"><a name="l08537"></a><span class="lineno"> 8537</span>&#160;            {</div><div class="line"><a name="l08538"></a><span class="lineno"> 8538</span>&#160;                resultOffset += VMA_DEBUG_MARGIN;</div><div class="line"><a name="l08539"></a><span class="lineno"> 8539</span>&#160;            }</div><div class="line"><a name="l08540"></a><span class="lineno"> 8540</span>&#160;</div><div class="line"><a name="l08541"></a><span class="lineno"> 8541</span>&#160;            <span class="comment">// Apply alignment.</span></div><div class="line"><a name="l08542"></a><span class="lineno"> 8542</span>&#160;            resultOffset = VmaAlignUp(resultOffset, allocAlignment);</div><div class="line"><a name="l08543"></a><span class="lineno"> 8543</span>&#160;</div><div class="line"><a name="l08544"></a><span class="lineno"> 8544</span>&#160;            <span class="comment">// Check previous suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l08545"></a><span class="lineno"> 8545</span>&#160;            <span class="comment">// Make bigger alignment if necessary.</span></div><div class="line"><a name="l08546"></a><span class="lineno"> 8546</span>&#160;            <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1 &amp;&amp; !suballocations2nd.empty())</div><div class="line"><a name="l08547"></a><span class="lineno"> 8547</span>&#160;            {</div><div class="line"><a name="l08548"></a><span class="lineno"> 8548</span>&#160;                <span class="keywordtype">bool</span> bufferImageGranularityConflict = <span class="keyword">false</span>;</div><div class="line"><a name="l08549"></a><span class="lineno"> 8549</span>&#160;                <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> prevSuballocIndex = suballocations2nd.size(); prevSuballocIndex--; )</div><div class="line"><a name="l08550"></a><span class="lineno"> 8550</span>&#160;                {</div><div class="line"><a name="l08551"></a><span class="lineno"> 8551</span>&#160;                    <span class="keyword">const</span> VmaSuballocation&amp; prevSuballoc = suballocations2nd[prevSuballocIndex];</div><div class="line"><a name="l08552"></a><span class="lineno"> 8552</span>&#160;                    <span class="keywordflow">if</span>(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))</div><div class="line"><a name="l08553"></a><span class="lineno"> 8553</span>&#160;                    {</div><div class="line"><a name="l08554"></a><span class="lineno"> 8554</span>&#160;                        <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))</div><div class="line"><a name="l08555"></a><span class="lineno"> 8555</span>&#160;                        {</div><div class="line"><a name="l08556"></a><span class="lineno"> 8556</span>&#160;                            bufferImageGranularityConflict = <span class="keyword">true</span>;</div><div class="line"><a name="l08557"></a><span class="lineno"> 8557</span>&#160;                            <span class="keywordflow">break</span>;</div><div class="line"><a name="l08558"></a><span class="lineno"> 8558</span>&#160;                        }</div><div class="line"><a name="l08559"></a><span class="lineno"> 8559</span>&#160;                    }</div><div class="line"><a name="l08560"></a><span class="lineno"> 8560</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l08561"></a><span class="lineno"> 8561</span>&#160;                        <span class="comment">// Already on previous page.</span></div><div class="line"><a name="l08562"></a><span class="lineno"> 8562</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l08563"></a><span class="lineno"> 8563</span>&#160;                }</div><div class="line"><a name="l08564"></a><span class="lineno"> 8564</span>&#160;                <span class="keywordflow">if</span>(bufferImageGranularityConflict)</div><div class="line"><a name="l08565"></a><span class="lineno"> 8565</span>&#160;                {</div><div class="line"><a name="l08566"></a><span class="lineno"> 8566</span>&#160;                    resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity);</div><div class="line"><a name="l08567"></a><span class="lineno"> 8567</span>&#160;                }</div><div class="line"><a name="l08568"></a><span class="lineno"> 8568</span>&#160;            }</div><div class="line"><a name="l08569"></a><span class="lineno"> 8569</span>&#160;</div><div class="line"><a name="l08570"></a><span class="lineno"> 8570</span>&#160;            pAllocationRequest-&gt;itemsToMakeLostCount = 0;</div><div class="line"><a name="l08571"></a><span class="lineno"> 8571</span>&#160;            pAllocationRequest-&gt;sumItemSize = 0;</div><div class="line"><a name="l08572"></a><span class="lineno"> 8572</span>&#160;            <span class="keywordtype">size_t</span> index1st = m_1stNullItemsBeginCount;</div><div class="line"><a name="l08573"></a><span class="lineno"> 8573</span>&#160;</div><div class="line"><a name="l08574"></a><span class="lineno"> 8574</span>&#160;            <span class="keywordflow">if</span>(canMakeOtherLost)</div><div class="line"><a name="l08575"></a><span class="lineno"> 8575</span>&#160;            {</div><div class="line"><a name="l08576"></a><span class="lineno"> 8576</span>&#160;                <span class="keywordflow">while</span>(index1st &lt; suballocations1st.size() &amp;&amp;</div><div class="line"><a name="l08577"></a><span class="lineno"> 8577</span>&#160;                    resultOffset + allocSize + VMA_DEBUG_MARGIN &gt; suballocations1st[index1st].offset)</div><div class="line"><a name="l08578"></a><span class="lineno"> 8578</span>&#160;                {</div><div class="line"><a name="l08579"></a><span class="lineno"> 8579</span>&#160;                    <span class="comment">// Next colliding allocation at the beginning of 1st vector found. Try to make it lost.</span></div><div class="line"><a name="l08580"></a><span class="lineno"> 8580</span>&#160;                    <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[index1st];</div><div class="line"><a name="l08581"></a><span class="lineno"> 8581</span>&#160;                    <span class="keywordflow">if</span>(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l08582"></a><span class="lineno"> 8582</span>&#160;                    {</div><div class="line"><a name="l08583"></a><span class="lineno"> 8583</span>&#160;                        <span class="comment">// No problem.</span></div><div class="line"><a name="l08584"></a><span class="lineno"> 8584</span>&#160;                    }</div><div class="line"><a name="l08585"></a><span class="lineno"> 8585</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l08586"></a><span class="lineno"> 8586</span>&#160;                    {</div><div class="line"><a name="l08587"></a><span class="lineno"> 8587</span>&#160;                        VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l08588"></a><span class="lineno"> 8588</span>&#160;                        <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l08589"></a><span class="lineno"> 8589</span>&#160;                            suballoc.hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l08590"></a><span class="lineno"> 8590</span>&#160;                        {</div><div class="line"><a name="l08591"></a><span class="lineno"> 8591</span>&#160;                            ++pAllocationRequest-&gt;itemsToMakeLostCount;</div><div class="line"><a name="l08592"></a><span class="lineno"> 8592</span>&#160;                            pAllocationRequest-&gt;sumItemSize += suballoc.size;</div><div class="line"><a name="l08593"></a><span class="lineno"> 8593</span>&#160;                        }</div><div class="line"><a name="l08594"></a><span class="lineno"> 8594</span>&#160;                        <span class="keywordflow">else</span></div><div class="line"><a name="l08595"></a><span class="lineno"> 8595</span>&#160;                        {</div><div class="line"><a name="l08596"></a><span class="lineno"> 8596</span>&#160;                            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08597"></a><span class="lineno"> 8597</span>&#160;                        }</div><div class="line"><a name="l08598"></a><span class="lineno"> 8598</span>&#160;                    }</div><div class="line"><a name="l08599"></a><span class="lineno"> 8599</span>&#160;                    ++index1st;</div><div class="line"><a name="l08600"></a><span class="lineno"> 8600</span>&#160;                }</div><div class="line"><a name="l08601"></a><span class="lineno"> 8601</span>&#160;</div><div class="line"><a name="l08602"></a><span class="lineno"> 8602</span>&#160;                <span class="comment">// Check next suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l08603"></a><span class="lineno"> 8603</span>&#160;                <span class="comment">// If conflict exists, we must mark more allocations lost or fail.</span></div><div class="line"><a name="l08604"></a><span class="lineno"> 8604</span>&#160;                <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l08605"></a><span class="lineno"> 8605</span>&#160;                {</div><div class="line"><a name="l08606"></a><span class="lineno"> 8606</span>&#160;                    <span class="keywordflow">while</span>(index1st &lt; suballocations1st.size())</div><div class="line"><a name="l08607"></a><span class="lineno"> 8607</span>&#160;                    {</div><div class="line"><a name="l08608"></a><span class="lineno"> 8608</span>&#160;                        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[index1st];</div><div class="line"><a name="l08609"></a><span class="lineno"> 8609</span>&#160;                        <span class="keywordflow">if</span>(VmaBlocksOnSamePage(resultOffset, allocSize, suballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l08610"></a><span class="lineno"> 8610</span>&#160;                        {</div><div class="line"><a name="l08611"></a><span class="lineno"> 8611</span>&#160;                            <span class="keywordflow">if</span>(suballoc.hAllocation != VK_NULL_HANDLE)</div><div class="line"><a name="l08612"></a><span class="lineno"> 8612</span>&#160;                            {</div><div class="line"><a name="l08613"></a><span class="lineno"> 8613</span>&#160;                                <span class="comment">// Not checking actual VmaIsBufferImageGranularityConflict(allocType, suballoc.type).</span></div><div class="line"><a name="l08614"></a><span class="lineno"> 8614</span>&#160;                                <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l08615"></a><span class="lineno"> 8615</span>&#160;                                    suballoc.hAllocation-&gt;GetLastUseFrameIndex() + frameInUseCount &lt; currentFrameIndex)</div><div class="line"><a name="l08616"></a><span class="lineno"> 8616</span>&#160;                                {</div><div class="line"><a name="l08617"></a><span class="lineno"> 8617</span>&#160;                                    ++pAllocationRequest-&gt;itemsToMakeLostCount;</div><div class="line"><a name="l08618"></a><span class="lineno"> 8618</span>&#160;                                    pAllocationRequest-&gt;sumItemSize += suballoc.size;</div><div class="line"><a name="l08619"></a><span class="lineno"> 8619</span>&#160;                                }</div><div class="line"><a name="l08620"></a><span class="lineno"> 8620</span>&#160;                                <span class="keywordflow">else</span></div><div class="line"><a name="l08621"></a><span class="lineno"> 8621</span>&#160;                                {</div><div class="line"><a name="l08622"></a><span class="lineno"> 8622</span>&#160;                                    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08623"></a><span class="lineno"> 8623</span>&#160;                                }</div><div class="line"><a name="l08624"></a><span class="lineno"> 8624</span>&#160;                            }</div><div class="line"><a name="l08625"></a><span class="lineno"> 8625</span>&#160;                        }</div><div class="line"><a name="l08626"></a><span class="lineno"> 8626</span>&#160;                        <span class="keywordflow">else</span></div><div class="line"><a name="l08627"></a><span class="lineno"> 8627</span>&#160;                        {</div><div class="line"><a name="l08628"></a><span class="lineno"> 8628</span>&#160;                            <span class="comment">// Already on next page.</span></div><div class="line"><a name="l08629"></a><span class="lineno"> 8629</span>&#160;                            <span class="keywordflow">break</span>;</div><div class="line"><a name="l08630"></a><span class="lineno"> 8630</span>&#160;                        }</div><div class="line"><a name="l08631"></a><span class="lineno"> 8631</span>&#160;                        ++index1st;</div><div class="line"><a name="l08632"></a><span class="lineno"> 8632</span>&#160;                    }</div><div class="line"><a name="l08633"></a><span class="lineno"> 8633</span>&#160;                }</div><div class="line"><a name="l08634"></a><span class="lineno"> 8634</span>&#160;            }</div><div class="line"><a name="l08635"></a><span class="lineno"> 8635</span>&#160;</div><div class="line"><a name="l08636"></a><span class="lineno"> 8636</span>&#160;            <span class="comment">// There is enough free space at the end after alignment.</span></div><div class="line"><a name="l08637"></a><span class="lineno"> 8637</span>&#160;            <span class="keywordflow">if</span>(index1st == suballocations1st.size() &amp;&amp; resultOffset + allocSize + VMA_DEBUG_MARGIN &lt; size ||</div><div class="line"><a name="l08638"></a><span class="lineno"> 8638</span>&#160;                index1st &lt; suballocations1st.size() &amp;&amp; resultOffset + allocSize + VMA_DEBUG_MARGIN &lt;= suballocations1st[index1st].offset)</div><div class="line"><a name="l08639"></a><span class="lineno"> 8639</span>&#160;            {</div><div class="line"><a name="l08640"></a><span class="lineno"> 8640</span>&#160;                <span class="comment">// Check next suballocations for BufferImageGranularity conflicts.</span></div><div class="line"><a name="l08641"></a><span class="lineno"> 8641</span>&#160;                <span class="comment">// If conflict exists, allocation cannot be made here.</span></div><div class="line"><a name="l08642"></a><span class="lineno"> 8642</span>&#160;                <span class="keywordflow">if</span>(bufferImageGranularity &gt; 1)</div><div class="line"><a name="l08643"></a><span class="lineno"> 8643</span>&#160;                {</div><div class="line"><a name="l08644"></a><span class="lineno"> 8644</span>&#160;                    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> nextSuballocIndex = index1st;</div><div class="line"><a name="l08645"></a><span class="lineno"> 8645</span>&#160;                        nextSuballocIndex &lt; suballocations1st.size();</div><div class="line"><a name="l08646"></a><span class="lineno"> 8646</span>&#160;                        nextSuballocIndex++)</div><div class="line"><a name="l08647"></a><span class="lineno"> 8647</span>&#160;                    {</div><div class="line"><a name="l08648"></a><span class="lineno"> 8648</span>&#160;                        <span class="keyword">const</span> VmaSuballocation&amp; nextSuballoc = suballocations1st[nextSuballocIndex];</div><div class="line"><a name="l08649"></a><span class="lineno"> 8649</span>&#160;                        <span class="keywordflow">if</span>(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))</div><div class="line"><a name="l08650"></a><span class="lineno"> 8650</span>&#160;                        {</div><div class="line"><a name="l08651"></a><span class="lineno"> 8651</span>&#160;                            <span class="keywordflow">if</span>(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))</div><div class="line"><a name="l08652"></a><span class="lineno"> 8652</span>&#160;                            {</div><div class="line"><a name="l08653"></a><span class="lineno"> 8653</span>&#160;                                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08654"></a><span class="lineno"> 8654</span>&#160;                            }</div><div class="line"><a name="l08655"></a><span class="lineno"> 8655</span>&#160;                        }</div><div class="line"><a name="l08656"></a><span class="lineno"> 8656</span>&#160;                        <span class="keywordflow">else</span></div><div class="line"><a name="l08657"></a><span class="lineno"> 8657</span>&#160;                        {</div><div class="line"><a name="l08658"></a><span class="lineno"> 8658</span>&#160;                            <span class="comment">// Already on next page.</span></div><div class="line"><a name="l08659"></a><span class="lineno"> 8659</span>&#160;                            <span class="keywordflow">break</span>;</div><div class="line"><a name="l08660"></a><span class="lineno"> 8660</span>&#160;                        }</div><div class="line"><a name="l08661"></a><span class="lineno"> 8661</span>&#160;                    }</div><div class="line"><a name="l08662"></a><span class="lineno"> 8662</span>&#160;                }</div><div class="line"><a name="l08663"></a><span class="lineno"> 8663</span>&#160;</div><div class="line"><a name="l08664"></a><span class="lineno"> 8664</span>&#160;                <span class="comment">// All tests passed: Success.</span></div><div class="line"><a name="l08665"></a><span class="lineno"> 8665</span>&#160;                pAllocationRequest-&gt;offset = resultOffset;</div><div class="line"><a name="l08666"></a><span class="lineno"> 8666</span>&#160;                pAllocationRequest-&gt;sumFreeSize =</div><div class="line"><a name="l08667"></a><span class="lineno"> 8667</span>&#160;                    (index1st &lt; suballocations1st.size() ? suballocations1st[index1st].offset : size)</div><div class="line"><a name="l08668"></a><span class="lineno"> 8668</span>&#160;                    - resultBaseOffset</div><div class="line"><a name="l08669"></a><span class="lineno"> 8669</span>&#160;                    - pAllocationRequest-&gt;sumItemSize;</div><div class="line"><a name="l08670"></a><span class="lineno"> 8670</span>&#160;                <span class="comment">// pAllocationRequest-&gt;item unused.</span></div><div class="line"><a name="l08671"></a><span class="lineno"> 8671</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l08672"></a><span class="lineno"> 8672</span>&#160;            }</div><div class="line"><a name="l08673"></a><span class="lineno"> 8673</span>&#160;        }</div><div class="line"><a name="l08674"></a><span class="lineno"> 8674</span>&#160;    }</div><div class="line"><a name="l08675"></a><span class="lineno"> 8675</span>&#160;</div><div class="line"><a name="l08676"></a><span class="lineno"> 8676</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08677"></a><span class="lineno"> 8677</span>&#160;}</div><div class="line"><a name="l08678"></a><span class="lineno"> 8678</span>&#160;</div><div class="line"><a name="l08679"></a><span class="lineno"> 8679</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Linear::MakeRequestedAllocationsLost(</div><div class="line"><a name="l08680"></a><span class="lineno"> 8680</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l08681"></a><span class="lineno"> 8681</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l08682"></a><span class="lineno"> 8682</span>&#160;    VmaAllocationRequest* pAllocationRequest)</div><div class="line"><a name="l08683"></a><span class="lineno"> 8683</span>&#160;{</div><div class="line"><a name="l08684"></a><span class="lineno"> 8684</span>&#160;    <span class="keywordflow">if</span>(pAllocationRequest-&gt;itemsToMakeLostCount == 0)</div><div class="line"><a name="l08685"></a><span class="lineno"> 8685</span>&#160;    {</div><div class="line"><a name="l08686"></a><span class="lineno"> 8686</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l08687"></a><span class="lineno"> 8687</span>&#160;    }</div><div class="line"><a name="l08688"></a><span class="lineno"> 8688</span>&#160;</div><div class="line"><a name="l08689"></a><span class="lineno"> 8689</span>&#160;    VMA_ASSERT(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER);</div><div class="line"><a name="l08690"></a><span class="lineno"> 8690</span>&#160;    </div><div class="line"><a name="l08691"></a><span class="lineno"> 8691</span>&#160;    SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l08692"></a><span class="lineno"> 8692</span>&#160;    <span class="keywordtype">size_t</span> index1st = m_1stNullItemsBeginCount;</div><div class="line"><a name="l08693"></a><span class="lineno"> 8693</span>&#160;    <span class="keywordtype">size_t</span> madeLostCount = 0;</div><div class="line"><a name="l08694"></a><span class="lineno"> 8694</span>&#160;    <span class="keywordflow">while</span>(madeLostCount &lt; pAllocationRequest-&gt;itemsToMakeLostCount)</div><div class="line"><a name="l08695"></a><span class="lineno"> 8695</span>&#160;    {</div><div class="line"><a name="l08696"></a><span class="lineno"> 8696</span>&#160;        VMA_ASSERT(index1st &lt; suballocations1st.size());</div><div class="line"><a name="l08697"></a><span class="lineno"> 8697</span>&#160;        VmaSuballocation&amp; suballoc = suballocations1st[index1st];</div><div class="line"><a name="l08698"></a><span class="lineno"> 8698</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l08699"></a><span class="lineno"> 8699</span>&#160;        {</div><div class="line"><a name="l08700"></a><span class="lineno"> 8700</span>&#160;            VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE);</div><div class="line"><a name="l08701"></a><span class="lineno"> 8701</span>&#160;            VMA_ASSERT(suballoc.hAllocation-&gt;CanBecomeLost());</div><div class="line"><a name="l08702"></a><span class="lineno"> 8702</span>&#160;            <span class="keywordflow">if</span>(suballoc.hAllocation-&gt;MakeLost(currentFrameIndex, frameInUseCount))</div><div class="line"><a name="l08703"></a><span class="lineno"> 8703</span>&#160;            {</div><div class="line"><a name="l08704"></a><span class="lineno"> 8704</span>&#160;                suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l08705"></a><span class="lineno"> 8705</span>&#160;                suballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l08706"></a><span class="lineno"> 8706</span>&#160;                m_SumFreeSize += suballoc.size;</div><div class="line"><a name="l08707"></a><span class="lineno"> 8707</span>&#160;                ++m_1stNullItemsMiddleCount;</div><div class="line"><a name="l08708"></a><span class="lineno"> 8708</span>&#160;                ++madeLostCount;</div><div class="line"><a name="l08709"></a><span class="lineno"> 8709</span>&#160;            }</div><div class="line"><a name="l08710"></a><span class="lineno"> 8710</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l08711"></a><span class="lineno"> 8711</span>&#160;            {</div><div class="line"><a name="l08712"></a><span class="lineno"> 8712</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l08713"></a><span class="lineno"> 8713</span>&#160;            }</div><div class="line"><a name="l08714"></a><span class="lineno"> 8714</span>&#160;        }</div><div class="line"><a name="l08715"></a><span class="lineno"> 8715</span>&#160;        ++index1st;</div><div class="line"><a name="l08716"></a><span class="lineno"> 8716</span>&#160;    }</div><div class="line"><a name="l08717"></a><span class="lineno"> 8717</span>&#160;</div><div class="line"><a name="l08718"></a><span class="lineno"> 8718</span>&#160;    CleanupAfterFree();</div><div class="line"><a name="l08719"></a><span class="lineno"> 8719</span>&#160;    <span class="comment">//VMA_HEAVY_ASSERT(Validate()); // Already called by ClanupAfterFree().</span></div><div class="line"><a name="l08720"></a><span class="lineno"> 8720</span>&#160;    </div><div class="line"><a name="l08721"></a><span class="lineno"> 8721</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l08722"></a><span class="lineno"> 8722</span>&#160;}</div><div class="line"><a name="l08723"></a><span class="lineno"> 8723</span>&#160;</div><div class="line"><a name="l08724"></a><span class="lineno"> 8724</span>&#160;uint32_t VmaBlockMetadata_Linear::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)</div><div class="line"><a name="l08725"></a><span class="lineno"> 8725</span>&#160;{</div><div class="line"><a name="l08726"></a><span class="lineno"> 8726</span>&#160;    uint32_t lostAllocationCount = 0;</div><div class="line"><a name="l08727"></a><span class="lineno"> 8727</span>&#160;    </div><div class="line"><a name="l08728"></a><span class="lineno"> 8728</span>&#160;    SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l08729"></a><span class="lineno"> 8729</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i &lt; count; ++i)</div><div class="line"><a name="l08730"></a><span class="lineno"> 8730</span>&#160;    {</div><div class="line"><a name="l08731"></a><span class="lineno"> 8731</span>&#160;        VmaSuballocation&amp; suballoc = suballocations1st[i];</div><div class="line"><a name="l08732"></a><span class="lineno"> 8732</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE &amp;&amp;</div><div class="line"><a name="l08733"></a><span class="lineno"> 8733</span>&#160;            suballoc.hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l08734"></a><span class="lineno"> 8734</span>&#160;            suballoc.hAllocation-&gt;MakeLost(currentFrameIndex, frameInUseCount))</div><div class="line"><a name="l08735"></a><span class="lineno"> 8735</span>&#160;        {</div><div class="line"><a name="l08736"></a><span class="lineno"> 8736</span>&#160;            suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l08737"></a><span class="lineno"> 8737</span>&#160;            suballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l08738"></a><span class="lineno"> 8738</span>&#160;            ++m_1stNullItemsMiddleCount;</div><div class="line"><a name="l08739"></a><span class="lineno"> 8739</span>&#160;            m_SumFreeSize += suballoc.size;</div><div class="line"><a name="l08740"></a><span class="lineno"> 8740</span>&#160;            ++lostAllocationCount;</div><div class="line"><a name="l08741"></a><span class="lineno"> 8741</span>&#160;        }</div><div class="line"><a name="l08742"></a><span class="lineno"> 8742</span>&#160;    }</div><div class="line"><a name="l08743"></a><span class="lineno"> 8743</span>&#160;</div><div class="line"><a name="l08744"></a><span class="lineno"> 8744</span>&#160;    SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l08745"></a><span class="lineno"> 8745</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0, count = suballocations2nd.size(); i &lt; count; ++i)</div><div class="line"><a name="l08746"></a><span class="lineno"> 8746</span>&#160;    {</div><div class="line"><a name="l08747"></a><span class="lineno"> 8747</span>&#160;        VmaSuballocation&amp; suballoc = suballocations2nd[i];</div><div class="line"><a name="l08748"></a><span class="lineno"> 8748</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE &amp;&amp;</div><div class="line"><a name="l08749"></a><span class="lineno"> 8749</span>&#160;            suballoc.hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l08750"></a><span class="lineno"> 8750</span>&#160;            suballoc.hAllocation-&gt;MakeLost(currentFrameIndex, frameInUseCount))</div><div class="line"><a name="l08751"></a><span class="lineno"> 8751</span>&#160;        {</div><div class="line"><a name="l08752"></a><span class="lineno"> 8752</span>&#160;            suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l08753"></a><span class="lineno"> 8753</span>&#160;            suballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l08754"></a><span class="lineno"> 8754</span>&#160;            ++m_2ndNullItemsCount;</div><div class="line"><a name="l08755"></a><span class="lineno"> 8755</span>&#160;            ++lostAllocationCount;</div><div class="line"><a name="l08756"></a><span class="lineno"> 8756</span>&#160;        }</div><div class="line"><a name="l08757"></a><span class="lineno"> 8757</span>&#160;    }</div><div class="line"><a name="l08758"></a><span class="lineno"> 8758</span>&#160;</div><div class="line"><a name="l08759"></a><span class="lineno"> 8759</span>&#160;    <span class="keywordflow">if</span>(lostAllocationCount)</div><div class="line"><a name="l08760"></a><span class="lineno"> 8760</span>&#160;    {</div><div class="line"><a name="l08761"></a><span class="lineno"> 8761</span>&#160;        CleanupAfterFree();</div><div class="line"><a name="l08762"></a><span class="lineno"> 8762</span>&#160;    }</div><div class="line"><a name="l08763"></a><span class="lineno"> 8763</span>&#160;</div><div class="line"><a name="l08764"></a><span class="lineno"> 8764</span>&#160;    <span class="keywordflow">return</span> lostAllocationCount;</div><div class="line"><a name="l08765"></a><span class="lineno"> 8765</span>&#160;}</div><div class="line"><a name="l08766"></a><span class="lineno"> 8766</span>&#160;</div><div class="line"><a name="l08767"></a><span class="lineno"> 8767</span>&#160;VkResult VmaBlockMetadata_Linear::CheckCorruption(<span class="keyword">const</span> <span class="keywordtype">void</span>* pBlockData)</div><div class="line"><a name="l08768"></a><span class="lineno"> 8768</span>&#160;{</div><div class="line"><a name="l08769"></a><span class="lineno"> 8769</span>&#160;    SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l08770"></a><span class="lineno"> 8770</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i &lt; count; ++i)</div><div class="line"><a name="l08771"></a><span class="lineno"> 8771</span>&#160;    {</div><div class="line"><a name="l08772"></a><span class="lineno"> 8772</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations1st[i];</div><div class="line"><a name="l08773"></a><span class="lineno"> 8773</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l08774"></a><span class="lineno"> 8774</span>&#160;        {</div><div class="line"><a name="l08775"></a><span class="lineno"> 8775</span>&#160;            <span class="keywordflow">if</span>(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN))</div><div class="line"><a name="l08776"></a><span class="lineno"> 8776</span>&#160;            {</div><div class="line"><a name="l08777"></a><span class="lineno"> 8777</span>&#160;                VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l08778"></a><span class="lineno"> 8778</span>&#160;                <span class="keywordflow">return</span> VK_ERROR_VALIDATION_FAILED_EXT;</div><div class="line"><a name="l08779"></a><span class="lineno"> 8779</span>&#160;            }</div><div class="line"><a name="l08780"></a><span class="lineno"> 8780</span>&#160;            <span class="keywordflow">if</span>(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size))</div><div class="line"><a name="l08781"></a><span class="lineno"> 8781</span>&#160;            {</div><div class="line"><a name="l08782"></a><span class="lineno"> 8782</span>&#160;                VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l08783"></a><span class="lineno"> 8783</span>&#160;                <span class="keywordflow">return</span> VK_ERROR_VALIDATION_FAILED_EXT;</div><div class="line"><a name="l08784"></a><span class="lineno"> 8784</span>&#160;            }</div><div class="line"><a name="l08785"></a><span class="lineno"> 8785</span>&#160;        }</div><div class="line"><a name="l08786"></a><span class="lineno"> 8786</span>&#160;    }</div><div class="line"><a name="l08787"></a><span class="lineno"> 8787</span>&#160;</div><div class="line"><a name="l08788"></a><span class="lineno"> 8788</span>&#160;    SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l08789"></a><span class="lineno"> 8789</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0, count = suballocations2nd.size(); i &lt; count; ++i)</div><div class="line"><a name="l08790"></a><span class="lineno"> 8790</span>&#160;    {</div><div class="line"><a name="l08791"></a><span class="lineno"> 8791</span>&#160;        <span class="keyword">const</span> VmaSuballocation&amp; suballoc = suballocations2nd[i];</div><div class="line"><a name="l08792"></a><span class="lineno"> 8792</span>&#160;        <span class="keywordflow">if</span>(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)</div><div class="line"><a name="l08793"></a><span class="lineno"> 8793</span>&#160;        {</div><div class="line"><a name="l08794"></a><span class="lineno"> 8794</span>&#160;            <span class="keywordflow">if</span>(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN))</div><div class="line"><a name="l08795"></a><span class="lineno"> 8795</span>&#160;            {</div><div class="line"><a name="l08796"></a><span class="lineno"> 8796</span>&#160;                VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l08797"></a><span class="lineno"> 8797</span>&#160;                <span class="keywordflow">return</span> VK_ERROR_VALIDATION_FAILED_EXT;</div><div class="line"><a name="l08798"></a><span class="lineno"> 8798</span>&#160;            }</div><div class="line"><a name="l08799"></a><span class="lineno"> 8799</span>&#160;            <span class="keywordflow">if</span>(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size))</div><div class="line"><a name="l08800"></a><span class="lineno"> 8800</span>&#160;            {</div><div class="line"><a name="l08801"></a><span class="lineno"> 8801</span>&#160;                VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l08802"></a><span class="lineno"> 8802</span>&#160;                <span class="keywordflow">return</span> VK_ERROR_VALIDATION_FAILED_EXT;</div><div class="line"><a name="l08803"></a><span class="lineno"> 8803</span>&#160;            }</div><div class="line"><a name="l08804"></a><span class="lineno"> 8804</span>&#160;        }</div><div class="line"><a name="l08805"></a><span class="lineno"> 8805</span>&#160;    }</div><div class="line"><a name="l08806"></a><span class="lineno"> 8806</span>&#160;</div><div class="line"><a name="l08807"></a><span class="lineno"> 8807</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l08808"></a><span class="lineno"> 8808</span>&#160;}</div><div class="line"><a name="l08809"></a><span class="lineno"> 8809</span>&#160;</div><div class="line"><a name="l08810"></a><span class="lineno"> 8810</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::Alloc(</div><div class="line"><a name="l08811"></a><span class="lineno"> 8811</span>&#160;    <span class="keyword">const</span> VmaAllocationRequest&amp; request,</div><div class="line"><a name="l08812"></a><span class="lineno"> 8812</span>&#160;    VmaSuballocationType type,</div><div class="line"><a name="l08813"></a><span class="lineno"> 8813</span>&#160;    VkDeviceSize allocSize,</div><div class="line"><a name="l08814"></a><span class="lineno"> 8814</span>&#160;    <span class="keywordtype">bool</span> upperAddress,</div><div class="line"><a name="l08815"></a><span class="lineno"> 8815</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l08816"></a><span class="lineno"> 8816</span>&#160;{</div><div class="line"><a name="l08817"></a><span class="lineno"> 8817</span>&#160;    <span class="keyword">const</span> VmaSuballocation newSuballoc = { request.offset, allocSize, hAllocation, type };</div><div class="line"><a name="l08818"></a><span class="lineno"> 8818</span>&#160;</div><div class="line"><a name="l08819"></a><span class="lineno"> 8819</span>&#160;    <span class="keywordflow">if</span>(upperAddress)</div><div class="line"><a name="l08820"></a><span class="lineno"> 8820</span>&#160;    {</div><div class="line"><a name="l08821"></a><span class="lineno"> 8821</span>&#160;        VMA_ASSERT(m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER &amp;&amp;</div><div class="line"><a name="l08822"></a><span class="lineno"> 8822</span>&#160;            <span class="stringliteral">&quot;CRITICAL ERROR: Trying to use linear allocator as double stack while it was already used as ring buffer.&quot;</span>);</div><div class="line"><a name="l08823"></a><span class="lineno"> 8823</span>&#160;        SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l08824"></a><span class="lineno"> 8824</span>&#160;        suballocations2nd.push_back(newSuballoc);</div><div class="line"><a name="l08825"></a><span class="lineno"> 8825</span>&#160;        m_2ndVectorMode = SECOND_VECTOR_DOUBLE_STACK;</div><div class="line"><a name="l08826"></a><span class="lineno"> 8826</span>&#160;    }</div><div class="line"><a name="l08827"></a><span class="lineno"> 8827</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l08828"></a><span class="lineno"> 8828</span>&#160;    {</div><div class="line"><a name="l08829"></a><span class="lineno"> 8829</span>&#160;        SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l08830"></a><span class="lineno"> 8830</span>&#160;</div><div class="line"><a name="l08831"></a><span class="lineno"> 8831</span>&#160;        <span class="comment">// First allocation.</span></div><div class="line"><a name="l08832"></a><span class="lineno"> 8832</span>&#160;        <span class="keywordflow">if</span>(suballocations1st.empty())</div><div class="line"><a name="l08833"></a><span class="lineno"> 8833</span>&#160;        {</div><div class="line"><a name="l08834"></a><span class="lineno"> 8834</span>&#160;            suballocations1st.push_back(newSuballoc);</div><div class="line"><a name="l08835"></a><span class="lineno"> 8835</span>&#160;        }</div><div class="line"><a name="l08836"></a><span class="lineno"> 8836</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l08837"></a><span class="lineno"> 8837</span>&#160;        {</div><div class="line"><a name="l08838"></a><span class="lineno"> 8838</span>&#160;            <span class="comment">// New allocation at the end of 1st vector.</span></div><div class="line"><a name="l08839"></a><span class="lineno"> 8839</span>&#160;            <span class="keywordflow">if</span>(request.offset &gt;= suballocations1st.back().offset + suballocations1st.back().size)</div><div class="line"><a name="l08840"></a><span class="lineno"> 8840</span>&#160;            {</div><div class="line"><a name="l08841"></a><span class="lineno"> 8841</span>&#160;                <span class="comment">// Check if it fits before the end of the block.</span></div><div class="line"><a name="l08842"></a><span class="lineno"> 8842</span>&#160;                VMA_ASSERT(request.offset + allocSize &lt;= GetSize());</div><div class="line"><a name="l08843"></a><span class="lineno"> 8843</span>&#160;                suballocations1st.push_back(newSuballoc);</div><div class="line"><a name="l08844"></a><span class="lineno"> 8844</span>&#160;            }</div><div class="line"><a name="l08845"></a><span class="lineno"> 8845</span>&#160;            <span class="comment">// New allocation at the end of 2-part ring buffer, so before first allocation from 1st vector.</span></div><div class="line"><a name="l08846"></a><span class="lineno"> 8846</span>&#160;            <span class="keywordflow">else</span> <span class="keywordflow">if</span>(request.offset + allocSize &lt;= suballocations1st[m_1stNullItemsBeginCount].offset)</div><div class="line"><a name="l08847"></a><span class="lineno"> 8847</span>&#160;            {</div><div class="line"><a name="l08848"></a><span class="lineno"> 8848</span>&#160;                SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l08849"></a><span class="lineno"> 8849</span>&#160;</div><div class="line"><a name="l08850"></a><span class="lineno"> 8850</span>&#160;                <span class="keywordflow">switch</span>(m_2ndVectorMode)</div><div class="line"><a name="l08851"></a><span class="lineno"> 8851</span>&#160;                {</div><div class="line"><a name="l08852"></a><span class="lineno"> 8852</span>&#160;                <span class="keywordflow">case</span> SECOND_VECTOR_EMPTY:</div><div class="line"><a name="l08853"></a><span class="lineno"> 8853</span>&#160;                    <span class="comment">// First allocation from second part ring buffer.</span></div><div class="line"><a name="l08854"></a><span class="lineno"> 8854</span>&#160;                    VMA_ASSERT(suballocations2nd.empty());</div><div class="line"><a name="l08855"></a><span class="lineno"> 8855</span>&#160;                    m_2ndVectorMode = SECOND_VECTOR_RING_BUFFER;</div><div class="line"><a name="l08856"></a><span class="lineno"> 8856</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l08857"></a><span class="lineno"> 8857</span>&#160;                <span class="keywordflow">case</span> SECOND_VECTOR_RING_BUFFER:</div><div class="line"><a name="l08858"></a><span class="lineno"> 8858</span>&#160;                    <span class="comment">// 2-part ring buffer is already started.</span></div><div class="line"><a name="l08859"></a><span class="lineno"> 8859</span>&#160;                    VMA_ASSERT(!suballocations2nd.empty());</div><div class="line"><a name="l08860"></a><span class="lineno"> 8860</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l08861"></a><span class="lineno"> 8861</span>&#160;                <span class="keywordflow">case</span> SECOND_VECTOR_DOUBLE_STACK:</div><div class="line"><a name="l08862"></a><span class="lineno"> 8862</span>&#160;                    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;CRITICAL ERROR: Trying to use linear allocator as ring buffer while it was already used as double stack.&quot;</span>);</div><div class="line"><a name="l08863"></a><span class="lineno"> 8863</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l08864"></a><span class="lineno"> 8864</span>&#160;                <span class="keywordflow">default</span>:</div><div class="line"><a name="l08865"></a><span class="lineno"> 8865</span>&#160;                    VMA_ASSERT(0);</div><div class="line"><a name="l08866"></a><span class="lineno"> 8866</span>&#160;                }</div><div class="line"><a name="l08867"></a><span class="lineno"> 8867</span>&#160;</div><div class="line"><a name="l08868"></a><span class="lineno"> 8868</span>&#160;                suballocations2nd.push_back(newSuballoc);</div><div class="line"><a name="l08869"></a><span class="lineno"> 8869</span>&#160;            }</div><div class="line"><a name="l08870"></a><span class="lineno"> 8870</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l08871"></a><span class="lineno"> 8871</span>&#160;            {</div><div class="line"><a name="l08872"></a><span class="lineno"> 8872</span>&#160;                VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;CRITICAL INTERNAL ERROR.&quot;</span>);</div><div class="line"><a name="l08873"></a><span class="lineno"> 8873</span>&#160;            }</div><div class="line"><a name="l08874"></a><span class="lineno"> 8874</span>&#160;        }</div><div class="line"><a name="l08875"></a><span class="lineno"> 8875</span>&#160;    }</div><div class="line"><a name="l08876"></a><span class="lineno"> 8876</span>&#160;</div><div class="line"><a name="l08877"></a><span class="lineno"> 8877</span>&#160;    m_SumFreeSize -= newSuballoc.size;</div><div class="line"><a name="l08878"></a><span class="lineno"> 8878</span>&#160;}</div><div class="line"><a name="l08879"></a><span class="lineno"> 8879</span>&#160;</div><div class="line"><a name="l08880"></a><span class="lineno"> 8880</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::Free(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l08881"></a><span class="lineno"> 8881</span>&#160;{</div><div class="line"><a name="l08882"></a><span class="lineno"> 8882</span>&#160;    FreeAtOffset(allocation-&gt;GetOffset());</div><div class="line"><a name="l08883"></a><span class="lineno"> 8883</span>&#160;}</div><div class="line"><a name="l08884"></a><span class="lineno"> 8884</span>&#160;</div><div class="line"><a name="l08885"></a><span class="lineno"> 8885</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::FreeAtOffset(VkDeviceSize offset)</div><div class="line"><a name="l08886"></a><span class="lineno"> 8886</span>&#160;{</div><div class="line"><a name="l08887"></a><span class="lineno"> 8887</span>&#160;    SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l08888"></a><span class="lineno"> 8888</span>&#160;    SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l08889"></a><span class="lineno"> 8889</span>&#160;</div><div class="line"><a name="l08890"></a><span class="lineno"> 8890</span>&#160;    <span class="keywordflow">if</span>(!suballocations1st.empty())</div><div class="line"><a name="l08891"></a><span class="lineno"> 8891</span>&#160;    {</div><div class="line"><a name="l08892"></a><span class="lineno"> 8892</span>&#160;        <span class="comment">// First allocation: Mark it as next empty at the beginning.</span></div><div class="line"><a name="l08893"></a><span class="lineno"> 8893</span>&#160;        VmaSuballocation&amp; firstSuballoc = suballocations1st[m_1stNullItemsBeginCount];</div><div class="line"><a name="l08894"></a><span class="lineno"> 8894</span>&#160;        <span class="keywordflow">if</span>(firstSuballoc.offset == offset)</div><div class="line"><a name="l08895"></a><span class="lineno"> 8895</span>&#160;        {</div><div class="line"><a name="l08896"></a><span class="lineno"> 8896</span>&#160;            firstSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l08897"></a><span class="lineno"> 8897</span>&#160;            firstSuballoc.hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l08898"></a><span class="lineno"> 8898</span>&#160;            m_SumFreeSize += firstSuballoc.size;</div><div class="line"><a name="l08899"></a><span class="lineno"> 8899</span>&#160;            ++m_1stNullItemsBeginCount;</div><div class="line"><a name="l08900"></a><span class="lineno"> 8900</span>&#160;            CleanupAfterFree();</div><div class="line"><a name="l08901"></a><span class="lineno"> 8901</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l08902"></a><span class="lineno"> 8902</span>&#160;        }</div><div class="line"><a name="l08903"></a><span class="lineno"> 8903</span>&#160;    }</div><div class="line"><a name="l08904"></a><span class="lineno"> 8904</span>&#160;</div><div class="line"><a name="l08905"></a><span class="lineno"> 8905</span>&#160;    <span class="comment">// Last allocation in 2-part ring buffer or top of upper stack (same logic).</span></div><div class="line"><a name="l08906"></a><span class="lineno"> 8906</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ||</div><div class="line"><a name="l08907"></a><span class="lineno"> 8907</span>&#160;        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)</div><div class="line"><a name="l08908"></a><span class="lineno"> 8908</span>&#160;    {</div><div class="line"><a name="l08909"></a><span class="lineno"> 8909</span>&#160;        VmaSuballocation&amp; lastSuballoc = suballocations2nd.back();</div><div class="line"><a name="l08910"></a><span class="lineno"> 8910</span>&#160;        <span class="keywordflow">if</span>(lastSuballoc.offset == offset)</div><div class="line"><a name="l08911"></a><span class="lineno"> 8911</span>&#160;        {</div><div class="line"><a name="l08912"></a><span class="lineno"> 8912</span>&#160;            m_SumFreeSize += lastSuballoc.size;</div><div class="line"><a name="l08913"></a><span class="lineno"> 8913</span>&#160;            suballocations2nd.pop_back();</div><div class="line"><a name="l08914"></a><span class="lineno"> 8914</span>&#160;            CleanupAfterFree();</div><div class="line"><a name="l08915"></a><span class="lineno"> 8915</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l08916"></a><span class="lineno"> 8916</span>&#160;        }</div><div class="line"><a name="l08917"></a><span class="lineno"> 8917</span>&#160;    }</div><div class="line"><a name="l08918"></a><span class="lineno"> 8918</span>&#160;    <span class="comment">// Last allocation in 1st vector.</span></div><div class="line"><a name="l08919"></a><span class="lineno"> 8919</span>&#160;    <span class="keywordflow">else</span> <span class="keywordflow">if</span>(m_2ndVectorMode == SECOND_VECTOR_EMPTY)</div><div class="line"><a name="l08920"></a><span class="lineno"> 8920</span>&#160;    {</div><div class="line"><a name="l08921"></a><span class="lineno"> 8921</span>&#160;        VmaSuballocation&amp; lastSuballoc = suballocations1st.back();</div><div class="line"><a name="l08922"></a><span class="lineno"> 8922</span>&#160;        <span class="keywordflow">if</span>(lastSuballoc.offset == offset)</div><div class="line"><a name="l08923"></a><span class="lineno"> 8923</span>&#160;        {</div><div class="line"><a name="l08924"></a><span class="lineno"> 8924</span>&#160;            m_SumFreeSize += lastSuballoc.size;</div><div class="line"><a name="l08925"></a><span class="lineno"> 8925</span>&#160;            suballocations1st.pop_back();</div><div class="line"><a name="l08926"></a><span class="lineno"> 8926</span>&#160;            CleanupAfterFree();</div><div class="line"><a name="l08927"></a><span class="lineno"> 8927</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l08928"></a><span class="lineno"> 8928</span>&#160;        }</div><div class="line"><a name="l08929"></a><span class="lineno"> 8929</span>&#160;    }</div><div class="line"><a name="l08930"></a><span class="lineno"> 8930</span>&#160;</div><div class="line"><a name="l08931"></a><span class="lineno"> 8931</span>&#160;    <span class="comment">// Item from the middle of 1st vector.</span></div><div class="line"><a name="l08932"></a><span class="lineno"> 8932</span>&#160;    {</div><div class="line"><a name="l08933"></a><span class="lineno"> 8933</span>&#160;        VmaSuballocation refSuballoc;</div><div class="line"><a name="l08934"></a><span class="lineno"> 8934</span>&#160;        refSuballoc.offset = offset;</div><div class="line"><a name="l08935"></a><span class="lineno"> 8935</span>&#160;        <span class="comment">// Rest of members stays uninitialized intentionally for better performance.</span></div><div class="line"><a name="l08936"></a><span class="lineno"> 8936</span>&#160;        SuballocationVectorType::iterator it = VmaVectorFindSorted&lt;VmaSuballocationOffsetLess&gt;(</div><div class="line"><a name="l08937"></a><span class="lineno"> 8937</span>&#160;            suballocations1st.begin() + m_1stNullItemsBeginCount,</div><div class="line"><a name="l08938"></a><span class="lineno"> 8938</span>&#160;            suballocations1st.end(),</div><div class="line"><a name="l08939"></a><span class="lineno"> 8939</span>&#160;            refSuballoc);</div><div class="line"><a name="l08940"></a><span class="lineno"> 8940</span>&#160;        <span class="keywordflow">if</span>(it != suballocations1st.end())</div><div class="line"><a name="l08941"></a><span class="lineno"> 8941</span>&#160;        {</div><div class="line"><a name="l08942"></a><span class="lineno"> 8942</span>&#160;            it-&gt;type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l08943"></a><span class="lineno"> 8943</span>&#160;            it-&gt;hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l08944"></a><span class="lineno"> 8944</span>&#160;            ++m_1stNullItemsMiddleCount;</div><div class="line"><a name="l08945"></a><span class="lineno"> 8945</span>&#160;            m_SumFreeSize += it-&gt;size;</div><div class="line"><a name="l08946"></a><span class="lineno"> 8946</span>&#160;            CleanupAfterFree();</div><div class="line"><a name="l08947"></a><span class="lineno"> 8947</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l08948"></a><span class="lineno"> 8948</span>&#160;        }</div><div class="line"><a name="l08949"></a><span class="lineno"> 8949</span>&#160;    }</div><div class="line"><a name="l08950"></a><span class="lineno"> 8950</span>&#160;</div><div class="line"><a name="l08951"></a><span class="lineno"> 8951</span>&#160;    <span class="keywordflow">if</span>(m_2ndVectorMode != SECOND_VECTOR_EMPTY)</div><div class="line"><a name="l08952"></a><span class="lineno"> 8952</span>&#160;    {</div><div class="line"><a name="l08953"></a><span class="lineno"> 8953</span>&#160;        <span class="comment">// Item from the middle of 2nd vector.</span></div><div class="line"><a name="l08954"></a><span class="lineno"> 8954</span>&#160;        VmaSuballocation refSuballoc;</div><div class="line"><a name="l08955"></a><span class="lineno"> 8955</span>&#160;        refSuballoc.offset = offset;</div><div class="line"><a name="l08956"></a><span class="lineno"> 8956</span>&#160;        <span class="comment">// Rest of members stays uninitialized intentionally for better performance.</span></div><div class="line"><a name="l08957"></a><span class="lineno"> 8957</span>&#160;        SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ?</div><div class="line"><a name="l08958"></a><span class="lineno"> 8958</span>&#160;            VmaVectorFindSorted&lt;VmaSuballocationOffsetLess&gt;(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc) :</div><div class="line"><a name="l08959"></a><span class="lineno"> 8959</span>&#160;            VmaVectorFindSorted&lt;VmaSuballocationOffsetGreater&gt;(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc);</div><div class="line"><a name="l08960"></a><span class="lineno"> 8960</span>&#160;        <span class="keywordflow">if</span>(it != suballocations2nd.end())</div><div class="line"><a name="l08961"></a><span class="lineno"> 8961</span>&#160;        {</div><div class="line"><a name="l08962"></a><span class="lineno"> 8962</span>&#160;            it-&gt;type = VMA_SUBALLOCATION_TYPE_FREE;</div><div class="line"><a name="l08963"></a><span class="lineno"> 8963</span>&#160;            it-&gt;hAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l08964"></a><span class="lineno"> 8964</span>&#160;            ++m_2ndNullItemsCount;</div><div class="line"><a name="l08965"></a><span class="lineno"> 8965</span>&#160;            m_SumFreeSize += it-&gt;size;</div><div class="line"><a name="l08966"></a><span class="lineno"> 8966</span>&#160;            CleanupAfterFree();</div><div class="line"><a name="l08967"></a><span class="lineno"> 8967</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l08968"></a><span class="lineno"> 8968</span>&#160;        }</div><div class="line"><a name="l08969"></a><span class="lineno"> 8969</span>&#160;    }</div><div class="line"><a name="l08970"></a><span class="lineno"> 8970</span>&#160;</div><div class="line"><a name="l08971"></a><span class="lineno"> 8971</span>&#160;    VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Allocation to free not found in linear allocator!&quot;</span>);</div><div class="line"><a name="l08972"></a><span class="lineno"> 8972</span>&#160;}</div><div class="line"><a name="l08973"></a><span class="lineno"> 8973</span>&#160;</div><div class="line"><a name="l08974"></a><span class="lineno"> 8974</span>&#160;<span class="keywordtype">bool</span> VmaBlockMetadata_Linear::ShouldCompact1st()<span class="keyword"> const</span></div><div class="line"><a name="l08975"></a><span class="lineno"> 8975</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l08976"></a><span class="lineno"> 8976</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> nullItemCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount;</div><div class="line"><a name="l08977"></a><span class="lineno"> 8977</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballocCount = AccessSuballocations1st().size();</div><div class="line"><a name="l08978"></a><span class="lineno"> 8978</span>&#160;    <span class="keywordflow">return</span> suballocCount &gt; 32 &amp;&amp; nullItemCount * 2 &gt;= (suballocCount - nullItemCount) * 3;</div><div class="line"><a name="l08979"></a><span class="lineno"> 8979</span>&#160;}</div><div class="line"><a name="l08980"></a><span class="lineno"> 8980</span>&#160;</div><div class="line"><a name="l08981"></a><span class="lineno"> 8981</span>&#160;<span class="keywordtype">void</span> VmaBlockMetadata_Linear::CleanupAfterFree()</div><div class="line"><a name="l08982"></a><span class="lineno"> 8982</span>&#160;{</div><div class="line"><a name="l08983"></a><span class="lineno"> 8983</span>&#160;    SuballocationVectorType&amp; suballocations1st = AccessSuballocations1st();</div><div class="line"><a name="l08984"></a><span class="lineno"> 8984</span>&#160;    SuballocationVectorType&amp; suballocations2nd = AccessSuballocations2nd();</div><div class="line"><a name="l08985"></a><span class="lineno"> 8985</span>&#160;</div><div class="line"><a name="l08986"></a><span class="lineno"> 8986</span>&#160;    <span class="keywordflow">if</span>(IsEmpty())</div><div class="line"><a name="l08987"></a><span class="lineno"> 8987</span>&#160;    {</div><div class="line"><a name="l08988"></a><span class="lineno"> 8988</span>&#160;        suballocations1st.clear();</div><div class="line"><a name="l08989"></a><span class="lineno"> 8989</span>&#160;        suballocations2nd.clear();</div><div class="line"><a name="l08990"></a><span class="lineno"> 8990</span>&#160;        m_1stNullItemsBeginCount = 0;</div><div class="line"><a name="l08991"></a><span class="lineno"> 8991</span>&#160;        m_1stNullItemsMiddleCount = 0;</div><div class="line"><a name="l08992"></a><span class="lineno"> 8992</span>&#160;        m_2ndNullItemsCount = 0;</div><div class="line"><a name="l08993"></a><span class="lineno"> 8993</span>&#160;        m_2ndVectorMode = SECOND_VECTOR_EMPTY;</div><div class="line"><a name="l08994"></a><span class="lineno"> 8994</span>&#160;    }</div><div class="line"><a name="l08995"></a><span class="lineno"> 8995</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l08996"></a><span class="lineno"> 8996</span>&#160;    {</div><div class="line"><a name="l08997"></a><span class="lineno"> 8997</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> suballoc1stCount = suballocations1st.size();</div><div class="line"><a name="l08998"></a><span class="lineno"> 8998</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> nullItem1stCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount;</div><div class="line"><a name="l08999"></a><span class="lineno"> 8999</span>&#160;        VMA_ASSERT(nullItem1stCount &lt;= suballoc1stCount);</div><div class="line"><a name="l09000"></a><span class="lineno"> 9000</span>&#160;</div><div class="line"><a name="l09001"></a><span class="lineno"> 9001</span>&#160;        <span class="comment">// Find more null items at the beginning of 1st vector.</span></div><div class="line"><a name="l09002"></a><span class="lineno"> 9002</span>&#160;        <span class="keywordflow">while</span>(m_1stNullItemsBeginCount &lt; suballoc1stCount &amp;&amp;</div><div class="line"><a name="l09003"></a><span class="lineno"> 9003</span>&#160;            suballocations1st[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l09004"></a><span class="lineno"> 9004</span>&#160;        {</div><div class="line"><a name="l09005"></a><span class="lineno"> 9005</span>&#160;            ++m_1stNullItemsBeginCount;</div><div class="line"><a name="l09006"></a><span class="lineno"> 9006</span>&#160;            --m_1stNullItemsMiddleCount;</div><div class="line"><a name="l09007"></a><span class="lineno"> 9007</span>&#160;        }</div><div class="line"><a name="l09008"></a><span class="lineno"> 9008</span>&#160;</div><div class="line"><a name="l09009"></a><span class="lineno"> 9009</span>&#160;        <span class="comment">// Find more null items at the end of 1st vector.</span></div><div class="line"><a name="l09010"></a><span class="lineno"> 9010</span>&#160;        <span class="keywordflow">while</span>(m_1stNullItemsMiddleCount &gt; 0 &amp;&amp;</div><div class="line"><a name="l09011"></a><span class="lineno"> 9011</span>&#160;            suballocations1st.back().hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l09012"></a><span class="lineno"> 9012</span>&#160;        {</div><div class="line"><a name="l09013"></a><span class="lineno"> 9013</span>&#160;            --m_1stNullItemsMiddleCount;</div><div class="line"><a name="l09014"></a><span class="lineno"> 9014</span>&#160;            suballocations1st.pop_back();</div><div class="line"><a name="l09015"></a><span class="lineno"> 9015</span>&#160;        }</div><div class="line"><a name="l09016"></a><span class="lineno"> 9016</span>&#160;</div><div class="line"><a name="l09017"></a><span class="lineno"> 9017</span>&#160;        <span class="comment">// Find more null items at the end of 2nd vector.</span></div><div class="line"><a name="l09018"></a><span class="lineno"> 9018</span>&#160;        <span class="keywordflow">while</span>(m_2ndNullItemsCount &gt; 0 &amp;&amp;</div><div class="line"><a name="l09019"></a><span class="lineno"> 9019</span>&#160;            suballocations2nd.back().hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l09020"></a><span class="lineno"> 9020</span>&#160;        {</div><div class="line"><a name="l09021"></a><span class="lineno"> 9021</span>&#160;            --m_2ndNullItemsCount;</div><div class="line"><a name="l09022"></a><span class="lineno"> 9022</span>&#160;            suballocations2nd.pop_back();</div><div class="line"><a name="l09023"></a><span class="lineno"> 9023</span>&#160;        }</div><div class="line"><a name="l09024"></a><span class="lineno"> 9024</span>&#160;</div><div class="line"><a name="l09025"></a><span class="lineno"> 9025</span>&#160;        <span class="keywordflow">if</span>(ShouldCompact1st())</div><div class="line"><a name="l09026"></a><span class="lineno"> 9026</span>&#160;        {</div><div class="line"><a name="l09027"></a><span class="lineno"> 9027</span>&#160;            <span class="keyword">const</span> <span class="keywordtype">size_t</span> nonNullItemCount = suballoc1stCount - nullItem1stCount;</div><div class="line"><a name="l09028"></a><span class="lineno"> 9028</span>&#160;            <span class="keywordtype">size_t</span> srcIndex = m_1stNullItemsBeginCount;</div><div class="line"><a name="l09029"></a><span class="lineno"> 9029</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> dstIndex = 0; dstIndex &lt; nonNullItemCount; ++dstIndex)</div><div class="line"><a name="l09030"></a><span class="lineno"> 9030</span>&#160;            {</div><div class="line"><a name="l09031"></a><span class="lineno"> 9031</span>&#160;                <span class="keywordflow">while</span>(suballocations1st[srcIndex].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l09032"></a><span class="lineno"> 9032</span>&#160;                {</div><div class="line"><a name="l09033"></a><span class="lineno"> 9033</span>&#160;                    ++srcIndex;</div><div class="line"><a name="l09034"></a><span class="lineno"> 9034</span>&#160;                }</div><div class="line"><a name="l09035"></a><span class="lineno"> 9035</span>&#160;                <span class="keywordflow">if</span>(dstIndex != srcIndex)</div><div class="line"><a name="l09036"></a><span class="lineno"> 9036</span>&#160;                {</div><div class="line"><a name="l09037"></a><span class="lineno"> 9037</span>&#160;                    suballocations1st[dstIndex] = suballocations1st[srcIndex];</div><div class="line"><a name="l09038"></a><span class="lineno"> 9038</span>&#160;                }</div><div class="line"><a name="l09039"></a><span class="lineno"> 9039</span>&#160;                ++srcIndex;</div><div class="line"><a name="l09040"></a><span class="lineno"> 9040</span>&#160;            }</div><div class="line"><a name="l09041"></a><span class="lineno"> 9041</span>&#160;            suballocations1st.resize(nonNullItemCount);</div><div class="line"><a name="l09042"></a><span class="lineno"> 9042</span>&#160;            m_1stNullItemsBeginCount = 0;</div><div class="line"><a name="l09043"></a><span class="lineno"> 9043</span>&#160;            m_1stNullItemsMiddleCount = 0;</div><div class="line"><a name="l09044"></a><span class="lineno"> 9044</span>&#160;        }</div><div class="line"><a name="l09045"></a><span class="lineno"> 9045</span>&#160;</div><div class="line"><a name="l09046"></a><span class="lineno"> 9046</span>&#160;        <span class="comment">// 2nd vector became empty.</span></div><div class="line"><a name="l09047"></a><span class="lineno"> 9047</span>&#160;        <span class="keywordflow">if</span>(suballocations2nd.empty())</div><div class="line"><a name="l09048"></a><span class="lineno"> 9048</span>&#160;        {</div><div class="line"><a name="l09049"></a><span class="lineno"> 9049</span>&#160;            m_2ndVectorMode = SECOND_VECTOR_EMPTY;</div><div class="line"><a name="l09050"></a><span class="lineno"> 9050</span>&#160;        }</div><div class="line"><a name="l09051"></a><span class="lineno"> 9051</span>&#160;</div><div class="line"><a name="l09052"></a><span class="lineno"> 9052</span>&#160;        <span class="comment">// 1st vector became empty.</span></div><div class="line"><a name="l09053"></a><span class="lineno"> 9053</span>&#160;        <span class="keywordflow">if</span>(suballocations1st.size() - m_1stNullItemsBeginCount == 0)</div><div class="line"><a name="l09054"></a><span class="lineno"> 9054</span>&#160;        {</div><div class="line"><a name="l09055"></a><span class="lineno"> 9055</span>&#160;            suballocations1st.clear();</div><div class="line"><a name="l09056"></a><span class="lineno"> 9056</span>&#160;            m_1stNullItemsBeginCount = 0;</div><div class="line"><a name="l09057"></a><span class="lineno"> 9057</span>&#160;</div><div class="line"><a name="l09058"></a><span class="lineno"> 9058</span>&#160;            <span class="keywordflow">if</span>(!suballocations2nd.empty() &amp;&amp; m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)</div><div class="line"><a name="l09059"></a><span class="lineno"> 9059</span>&#160;            {</div><div class="line"><a name="l09060"></a><span class="lineno"> 9060</span>&#160;                <span class="comment">// Swap 1st with 2nd. Now 2nd is empty.</span></div><div class="line"><a name="l09061"></a><span class="lineno"> 9061</span>&#160;                m_2ndVectorMode = SECOND_VECTOR_EMPTY;</div><div class="line"><a name="l09062"></a><span class="lineno"> 9062</span>&#160;                m_1stNullItemsMiddleCount = m_2ndNullItemsCount;</div><div class="line"><a name="l09063"></a><span class="lineno"> 9063</span>&#160;                <span class="keywordflow">while</span>(m_1stNullItemsBeginCount &lt; suballocations2nd.size() &amp;&amp;</div><div class="line"><a name="l09064"></a><span class="lineno"> 9064</span>&#160;                    suballocations2nd[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE)</div><div class="line"><a name="l09065"></a><span class="lineno"> 9065</span>&#160;                {</div><div class="line"><a name="l09066"></a><span class="lineno"> 9066</span>&#160;                    ++m_1stNullItemsBeginCount;</div><div class="line"><a name="l09067"></a><span class="lineno"> 9067</span>&#160;                    --m_1stNullItemsMiddleCount;</div><div class="line"><a name="l09068"></a><span class="lineno"> 9068</span>&#160;                }</div><div class="line"><a name="l09069"></a><span class="lineno"> 9069</span>&#160;                m_2ndNullItemsCount = 0;</div><div class="line"><a name="l09070"></a><span class="lineno"> 9070</span>&#160;                m_1stVectorIndex ^= 1;</div><div class="line"><a name="l09071"></a><span class="lineno"> 9071</span>&#160;            }</div><div class="line"><a name="l09072"></a><span class="lineno"> 9072</span>&#160;        }</div><div class="line"><a name="l09073"></a><span class="lineno"> 9073</span>&#160;    }</div><div class="line"><a name="l09074"></a><span class="lineno"> 9074</span>&#160;</div><div class="line"><a name="l09075"></a><span class="lineno"> 9075</span>&#160;    VMA_HEAVY_ASSERT(Validate());</div><div class="line"><a name="l09076"></a><span class="lineno"> 9076</span>&#160;}</div><div class="line"><a name="l09077"></a><span class="lineno"> 9077</span>&#160;</div><div class="line"><a name="l09078"></a><span class="lineno"> 9078</span>&#160;</div><div class="line"><a name="l09080"></a><span class="lineno"> 9080</span>&#160;<span class="comment">// class VmaDeviceMemoryBlock</span></div><div class="line"><a name="l09081"></a><span class="lineno"> 9081</span>&#160;</div><div class="line"><a name="l09082"></a><span class="lineno"> 9082</span>&#160;VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator) :</div><div class="line"><a name="l09083"></a><span class="lineno"> 9083</span>&#160;    m_pMetadata(VMA_NULL),</div><div class="line"><a name="l09084"></a><span class="lineno"> 9084</span>&#160;    m_MemoryTypeIndex(UINT32_MAX),</div><div class="line"><a name="l09085"></a><span class="lineno"> 9085</span>&#160;    m_Id(0),</div><div class="line"><a name="l09086"></a><span class="lineno"> 9086</span>&#160;    m_hMemory(VK_NULL_HANDLE),</div><div class="line"><a name="l09087"></a><span class="lineno"> 9087</span>&#160;    m_MapCount(0),</div><div class="line"><a name="l09088"></a><span class="lineno"> 9088</span>&#160;    m_pMappedData(VMA_NULL)</div><div class="line"><a name="l09089"></a><span class="lineno"> 9089</span>&#160;{</div><div class="line"><a name="l09090"></a><span class="lineno"> 9090</span>&#160;}</div><div class="line"><a name="l09091"></a><span class="lineno"> 9091</span>&#160;</div><div class="line"><a name="l09092"></a><span class="lineno"> 9092</span>&#160;<span class="keywordtype">void</span> VmaDeviceMemoryBlock::Init(</div><div class="line"><a name="l09093"></a><span class="lineno"> 9093</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l09094"></a><span class="lineno"> 9094</span>&#160;    uint32_t newMemoryTypeIndex,</div><div class="line"><a name="l09095"></a><span class="lineno"> 9095</span>&#160;    VkDeviceMemory newMemory,</div><div class="line"><a name="l09096"></a><span class="lineno"> 9096</span>&#160;    VkDeviceSize newSize,</div><div class="line"><a name="l09097"></a><span class="lineno"> 9097</span>&#160;    uint32_t <span class="keywordtype">id</span>,</div><div class="line"><a name="l09098"></a><span class="lineno"> 9098</span>&#160;    <span class="keywordtype">bool</span> linearAlgorithm)</div><div class="line"><a name="l09099"></a><span class="lineno"> 9099</span>&#160;{</div><div class="line"><a name="l09100"></a><span class="lineno"> 9100</span>&#160;    VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);</div><div class="line"><a name="l09101"></a><span class="lineno"> 9101</span>&#160;</div><div class="line"><a name="l09102"></a><span class="lineno"> 9102</span>&#160;    m_MemoryTypeIndex = newMemoryTypeIndex;</div><div class="line"><a name="l09103"></a><span class="lineno"> 9103</span>&#160;    m_Id = id;</div><div class="line"><a name="l09104"></a><span class="lineno"> 9104</span>&#160;    m_hMemory = newMemory;</div><div class="line"><a name="l09105"></a><span class="lineno"> 9105</span>&#160;</div><div class="line"><a name="l09106"></a><span class="lineno"> 9106</span>&#160;    <span class="keywordflow">if</span>(linearAlgorithm)</div><div class="line"><a name="l09107"></a><span class="lineno"> 9107</span>&#160;    {</div><div class="line"><a name="l09108"></a><span class="lineno"> 9108</span>&#160;        m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Linear)(hAllocator);</div><div class="line"><a name="l09109"></a><span class="lineno"> 9109</span>&#160;    }</div><div class="line"><a name="l09110"></a><span class="lineno"> 9110</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l09111"></a><span class="lineno"> 9111</span>&#160;    {</div><div class="line"><a name="l09112"></a><span class="lineno"> 9112</span>&#160;        m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Generic)(hAllocator);</div><div class="line"><a name="l09113"></a><span class="lineno"> 9113</span>&#160;    }</div><div class="line"><a name="l09114"></a><span class="lineno"> 9114</span>&#160;    m_pMetadata-&gt;Init(newSize);</div><div class="line"><a name="l09115"></a><span class="lineno"> 9115</span>&#160;}</div><div class="line"><a name="l09116"></a><span class="lineno"> 9116</span>&#160;</div><div class="line"><a name="l09117"></a><span class="lineno"> 9117</span>&#160;<span class="keywordtype">void</span> VmaDeviceMemoryBlock::Destroy(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator)</div><div class="line"><a name="l09118"></a><span class="lineno"> 9118</span>&#160;{</div><div class="line"><a name="l09119"></a><span class="lineno"> 9119</span>&#160;    <span class="comment">// This is the most important assert in the entire library.</span></div><div class="line"><a name="l09120"></a><span class="lineno"> 9120</span>&#160;    <span class="comment">// Hitting it means you have some memory leak - unreleased VmaAllocation objects.</span></div><div class="line"><a name="l09121"></a><span class="lineno"> 9121</span>&#160;    VMA_ASSERT(m_pMetadata-&gt;IsEmpty() &amp;&amp; <span class="stringliteral">&quot;Some allocations were not freed before destruction of this memory block!&quot;</span>);</div><div class="line"><a name="l09122"></a><span class="lineno"> 9122</span>&#160;</div><div class="line"><a name="l09123"></a><span class="lineno"> 9123</span>&#160;    VMA_ASSERT(m_hMemory != VK_NULL_HANDLE);</div><div class="line"><a name="l09124"></a><span class="lineno"> 9124</span>&#160;    allocator-&gt;FreeVulkanMemory(m_MemoryTypeIndex, m_pMetadata-&gt;GetSize(), m_hMemory);</div><div class="line"><a name="l09125"></a><span class="lineno"> 9125</span>&#160;    m_hMemory = VK_NULL_HANDLE;</div><div class="line"><a name="l09126"></a><span class="lineno"> 9126</span>&#160;</div><div class="line"><a name="l09127"></a><span class="lineno"> 9127</span>&#160;    vma_delete(allocator, m_pMetadata);</div><div class="line"><a name="l09128"></a><span class="lineno"> 9128</span>&#160;    m_pMetadata = VMA_NULL;</div><div class="line"><a name="l09129"></a><span class="lineno"> 9129</span>&#160;}</div><div class="line"><a name="l09130"></a><span class="lineno"> 9130</span>&#160;</div><div class="line"><a name="l09131"></a><span class="lineno"> 9131</span>&#160;<span class="keywordtype">bool</span> VmaDeviceMemoryBlock::Validate()<span class="keyword"> const</span></div><div class="line"><a name="l09132"></a><span class="lineno"> 9132</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l09133"></a><span class="lineno"> 9133</span>&#160;    <span class="keywordflow">if</span>((m_hMemory == VK_NULL_HANDLE) ||</div><div class="line"><a name="l09134"></a><span class="lineno"> 9134</span>&#160;        (m_pMetadata-&gt;GetSize() == 0))</div><div class="line"><a name="l09135"></a><span class="lineno"> 9135</span>&#160;    {</div><div class="line"><a name="l09136"></a><span class="lineno"> 9136</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l09137"></a><span class="lineno"> 9137</span>&#160;    }</div><div class="line"><a name="l09138"></a><span class="lineno"> 9138</span>&#160;    </div><div class="line"><a name="l09139"></a><span class="lineno"> 9139</span>&#160;    <span class="keywordflow">return</span> m_pMetadata-&gt;Validate();</div><div class="line"><a name="l09140"></a><span class="lineno"> 9140</span>&#160;}</div><div class="line"><a name="l09141"></a><span class="lineno"> 9141</span>&#160;</div><div class="line"><a name="l09142"></a><span class="lineno"> 9142</span>&#160;VkResult VmaDeviceMemoryBlock::CheckCorruption(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l09143"></a><span class="lineno"> 9143</span>&#160;{</div><div class="line"><a name="l09144"></a><span class="lineno"> 9144</span>&#160;    <span class="keywordtype">void</span>* pData = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l09145"></a><span class="lineno"> 9145</span>&#160;    VkResult res = Map(hAllocator, 1, &amp;pData);</div><div class="line"><a name="l09146"></a><span class="lineno"> 9146</span>&#160;    <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l09147"></a><span class="lineno"> 9147</span>&#160;    {</div><div class="line"><a name="l09148"></a><span class="lineno"> 9148</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09149"></a><span class="lineno"> 9149</span>&#160;    }</div><div class="line"><a name="l09150"></a><span class="lineno"> 9150</span>&#160;</div><div class="line"><a name="l09151"></a><span class="lineno"> 9151</span>&#160;    res = m_pMetadata-&gt;CheckCorruption(pData);</div><div class="line"><a name="l09152"></a><span class="lineno"> 9152</span>&#160;</div><div class="line"><a name="l09153"></a><span class="lineno"> 9153</span>&#160;    Unmap(hAllocator, 1);</div><div class="line"><a name="l09154"></a><span class="lineno"> 9154</span>&#160;</div><div class="line"><a name="l09155"></a><span class="lineno"> 9155</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09156"></a><span class="lineno"> 9156</span>&#160;}</div><div class="line"><a name="l09157"></a><span class="lineno"> 9157</span>&#160;</div><div class="line"><a name="l09158"></a><span class="lineno"> 9158</span>&#160;VkResult VmaDeviceMemoryBlock::Map(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count, <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l09159"></a><span class="lineno"> 9159</span>&#160;{</div><div class="line"><a name="l09160"></a><span class="lineno"> 9160</span>&#160;    <span class="keywordflow">if</span>(count == 0)</div><div class="line"><a name="l09161"></a><span class="lineno"> 9161</span>&#160;    {</div><div class="line"><a name="l09162"></a><span class="lineno"> 9162</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09163"></a><span class="lineno"> 9163</span>&#160;    }</div><div class="line"><a name="l09164"></a><span class="lineno"> 9164</span>&#160;</div><div class="line"><a name="l09165"></a><span class="lineno"> 9165</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09166"></a><span class="lineno"> 9166</span>&#160;    <span class="keywordflow">if</span>(m_MapCount != 0)</div><div class="line"><a name="l09167"></a><span class="lineno"> 9167</span>&#160;    {</div><div class="line"><a name="l09168"></a><span class="lineno"> 9168</span>&#160;        m_MapCount += count;</div><div class="line"><a name="l09169"></a><span class="lineno"> 9169</span>&#160;        VMA_ASSERT(m_pMappedData != VMA_NULL);</div><div class="line"><a name="l09170"></a><span class="lineno"> 9170</span>&#160;        <span class="keywordflow">if</span>(ppData != VMA_NULL)</div><div class="line"><a name="l09171"></a><span class="lineno"> 9171</span>&#160;        {</div><div class="line"><a name="l09172"></a><span class="lineno"> 9172</span>&#160;            *ppData = m_pMappedData;</div><div class="line"><a name="l09173"></a><span class="lineno"> 9173</span>&#160;        }</div><div class="line"><a name="l09174"></a><span class="lineno"> 9174</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09175"></a><span class="lineno"> 9175</span>&#160;    }</div><div class="line"><a name="l09176"></a><span class="lineno"> 9176</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l09177"></a><span class="lineno"> 9177</span>&#160;    {</div><div class="line"><a name="l09178"></a><span class="lineno"> 9178</span>&#160;        VkResult result = (*hAllocator-&gt;GetVulkanFunctions().vkMapMemory)(</div><div class="line"><a name="l09179"></a><span class="lineno"> 9179</span>&#160;            hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l09180"></a><span class="lineno"> 9180</span>&#160;            m_hMemory,</div><div class="line"><a name="l09181"></a><span class="lineno"> 9181</span>&#160;            0, <span class="comment">// offset</span></div><div class="line"><a name="l09182"></a><span class="lineno"> 9182</span>&#160;            VK_WHOLE_SIZE,</div><div class="line"><a name="l09183"></a><span class="lineno"> 9183</span>&#160;            0, <span class="comment">// flags</span></div><div class="line"><a name="l09184"></a><span class="lineno"> 9184</span>&#160;            &amp;m_pMappedData);</div><div class="line"><a name="l09185"></a><span class="lineno"> 9185</span>&#160;        <span class="keywordflow">if</span>(result == VK_SUCCESS)</div><div class="line"><a name="l09186"></a><span class="lineno"> 9186</span>&#160;        {</div><div class="line"><a name="l09187"></a><span class="lineno"> 9187</span>&#160;            <span class="keywordflow">if</span>(ppData != VMA_NULL)</div><div class="line"><a name="l09188"></a><span class="lineno"> 9188</span>&#160;            {</div><div class="line"><a name="l09189"></a><span class="lineno"> 9189</span>&#160;                *ppData = m_pMappedData;</div><div class="line"><a name="l09190"></a><span class="lineno"> 9190</span>&#160;            }</div><div class="line"><a name="l09191"></a><span class="lineno"> 9191</span>&#160;            m_MapCount = count;</div><div class="line"><a name="l09192"></a><span class="lineno"> 9192</span>&#160;        }</div><div class="line"><a name="l09193"></a><span class="lineno"> 9193</span>&#160;        <span class="keywordflow">return</span> result;</div><div class="line"><a name="l09194"></a><span class="lineno"> 9194</span>&#160;    }</div><div class="line"><a name="l09195"></a><span class="lineno"> 9195</span>&#160;}</div><div class="line"><a name="l09196"></a><span class="lineno"> 9196</span>&#160;</div><div class="line"><a name="l09197"></a><span class="lineno"> 9197</span>&#160;<span class="keywordtype">void</span> VmaDeviceMemoryBlock::Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, uint32_t count)</div><div class="line"><a name="l09198"></a><span class="lineno"> 9198</span>&#160;{</div><div class="line"><a name="l09199"></a><span class="lineno"> 9199</span>&#160;    <span class="keywordflow">if</span>(count == 0)</div><div class="line"><a name="l09200"></a><span class="lineno"> 9200</span>&#160;    {</div><div class="line"><a name="l09201"></a><span class="lineno"> 9201</span>&#160;        <span class="keywordflow">return</span>;</div><div class="line"><a name="l09202"></a><span class="lineno"> 9202</span>&#160;    }</div><div class="line"><a name="l09203"></a><span class="lineno"> 9203</span>&#160;</div><div class="line"><a name="l09204"></a><span class="lineno"> 9204</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09205"></a><span class="lineno"> 9205</span>&#160;    <span class="keywordflow">if</span>(m_MapCount &gt;= count)</div><div class="line"><a name="l09206"></a><span class="lineno"> 9206</span>&#160;    {</div><div class="line"><a name="l09207"></a><span class="lineno"> 9207</span>&#160;        m_MapCount -= count;</div><div class="line"><a name="l09208"></a><span class="lineno"> 9208</span>&#160;        <span class="keywordflow">if</span>(m_MapCount == 0)</div><div class="line"><a name="l09209"></a><span class="lineno"> 9209</span>&#160;        {</div><div class="line"><a name="l09210"></a><span class="lineno"> 9210</span>&#160;            m_pMappedData = VMA_NULL;</div><div class="line"><a name="l09211"></a><span class="lineno"> 9211</span>&#160;            (*hAllocator-&gt;GetVulkanFunctions().vkUnmapMemory)(hAllocator-&gt;m_hDevice, m_hMemory);</div><div class="line"><a name="l09212"></a><span class="lineno"> 9212</span>&#160;        }</div><div class="line"><a name="l09213"></a><span class="lineno"> 9213</span>&#160;    }</div><div class="line"><a name="l09214"></a><span class="lineno"> 9214</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l09215"></a><span class="lineno"> 9215</span>&#160;    {</div><div class="line"><a name="l09216"></a><span class="lineno"> 9216</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;VkDeviceMemory block is being unmapped while it was not previously mapped.&quot;</span>);</div><div class="line"><a name="l09217"></a><span class="lineno"> 9217</span>&#160;    }</div><div class="line"><a name="l09218"></a><span class="lineno"> 9218</span>&#160;}</div><div class="line"><a name="l09219"></a><span class="lineno"> 9219</span>&#160;</div><div class="line"><a name="l09220"></a><span class="lineno"> 9220</span>&#160;VkResult VmaDeviceMemoryBlock::WriteMagicValueAroundAllocation(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize)</div><div class="line"><a name="l09221"></a><span class="lineno"> 9221</span>&#160;{</div><div class="line"><a name="l09222"></a><span class="lineno"> 9222</span>&#160;    VMA_ASSERT(VMA_DEBUG_MARGIN &gt; 0 &amp;&amp; VMA_DEBUG_MARGIN % 4 == 0 &amp;&amp; VMA_DEBUG_DETECT_CORRUPTION);</div><div class="line"><a name="l09223"></a><span class="lineno"> 9223</span>&#160;    VMA_ASSERT(allocOffset &gt;= VMA_DEBUG_MARGIN);</div><div class="line"><a name="l09224"></a><span class="lineno"> 9224</span>&#160;</div><div class="line"><a name="l09225"></a><span class="lineno"> 9225</span>&#160;    <span class="keywordtype">void</span>* pData;</div><div class="line"><a name="l09226"></a><span class="lineno"> 9226</span>&#160;    VkResult res = Map(hAllocator, 1, &amp;pData);</div><div class="line"><a name="l09227"></a><span class="lineno"> 9227</span>&#160;    <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l09228"></a><span class="lineno"> 9228</span>&#160;    {</div><div class="line"><a name="l09229"></a><span class="lineno"> 9229</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09230"></a><span class="lineno"> 9230</span>&#160;    }</div><div class="line"><a name="l09231"></a><span class="lineno"> 9231</span>&#160;</div><div class="line"><a name="l09232"></a><span class="lineno"> 9232</span>&#160;    VmaWriteMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN);</div><div class="line"><a name="l09233"></a><span class="lineno"> 9233</span>&#160;    VmaWriteMagicValue(pData, allocOffset + allocSize);</div><div class="line"><a name="l09234"></a><span class="lineno"> 9234</span>&#160;</div><div class="line"><a name="l09235"></a><span class="lineno"> 9235</span>&#160;    Unmap(hAllocator, 1);</div><div class="line"><a name="l09236"></a><span class="lineno"> 9236</span>&#160;</div><div class="line"><a name="l09237"></a><span class="lineno"> 9237</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09238"></a><span class="lineno"> 9238</span>&#160;}</div><div class="line"><a name="l09239"></a><span class="lineno"> 9239</span>&#160;</div><div class="line"><a name="l09240"></a><span class="lineno"> 9240</span>&#160;VkResult VmaDeviceMemoryBlock::ValidateMagicValueAroundAllocation(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize)</div><div class="line"><a name="l09241"></a><span class="lineno"> 9241</span>&#160;{</div><div class="line"><a name="l09242"></a><span class="lineno"> 9242</span>&#160;    VMA_ASSERT(VMA_DEBUG_MARGIN &gt; 0 &amp;&amp; VMA_DEBUG_MARGIN % 4 == 0 &amp;&amp; VMA_DEBUG_DETECT_CORRUPTION);</div><div class="line"><a name="l09243"></a><span class="lineno"> 9243</span>&#160;    VMA_ASSERT(allocOffset &gt;= VMA_DEBUG_MARGIN);</div><div class="line"><a name="l09244"></a><span class="lineno"> 9244</span>&#160;</div><div class="line"><a name="l09245"></a><span class="lineno"> 9245</span>&#160;    <span class="keywordtype">void</span>* pData;</div><div class="line"><a name="l09246"></a><span class="lineno"> 9246</span>&#160;    VkResult res = Map(hAllocator, 1, &amp;pData);</div><div class="line"><a name="l09247"></a><span class="lineno"> 9247</span>&#160;    <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l09248"></a><span class="lineno"> 9248</span>&#160;    {</div><div class="line"><a name="l09249"></a><span class="lineno"> 9249</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09250"></a><span class="lineno"> 9250</span>&#160;    }</div><div class="line"><a name="l09251"></a><span class="lineno"> 9251</span>&#160;</div><div class="line"><a name="l09252"></a><span class="lineno"> 9252</span>&#160;    <span class="keywordflow">if</span>(!VmaValidateMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN))</div><div class="line"><a name="l09253"></a><span class="lineno"> 9253</span>&#160;    {</div><div class="line"><a name="l09254"></a><span class="lineno"> 9254</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED BEFORE FREED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l09255"></a><span class="lineno"> 9255</span>&#160;    }</div><div class="line"><a name="l09256"></a><span class="lineno"> 9256</span>&#160;    <span class="keywordflow">else</span> <span class="keywordflow">if</span>(!VmaValidateMagicValue(pData, allocOffset + allocSize))</div><div class="line"><a name="l09257"></a><span class="lineno"> 9257</span>&#160;    {</div><div class="line"><a name="l09258"></a><span class="lineno"> 9258</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;MEMORY CORRUPTION DETECTED AFTER FREED ALLOCATION!&quot;</span>);</div><div class="line"><a name="l09259"></a><span class="lineno"> 9259</span>&#160;    }</div><div class="line"><a name="l09260"></a><span class="lineno"> 9260</span>&#160;</div><div class="line"><a name="l09261"></a><span class="lineno"> 9261</span>&#160;    Unmap(hAllocator, 1);</div><div class="line"><a name="l09262"></a><span class="lineno"> 9262</span>&#160;</div><div class="line"><a name="l09263"></a><span class="lineno"> 9263</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09264"></a><span class="lineno"> 9264</span>&#160;}</div><div class="line"><a name="l09265"></a><span class="lineno"> 9265</span>&#160;</div><div class="line"><a name="l09266"></a><span class="lineno"> 9266</span>&#160;VkResult VmaDeviceMemoryBlock::BindBufferMemory(</div><div class="line"><a name="l09267"></a><span class="lineno"> 9267</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l09268"></a><span class="lineno"> 9268</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l09269"></a><span class="lineno"> 9269</span>&#160;    VkBuffer hBuffer)</div><div class="line"><a name="l09270"></a><span class="lineno"> 9270</span>&#160;{</div><div class="line"><a name="l09271"></a><span class="lineno"> 9271</span>&#160;    VMA_ASSERT(hAllocation-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &amp;&amp;</div><div class="line"><a name="l09272"></a><span class="lineno"> 9272</span>&#160;        hAllocation-&gt;GetBlock() == <span class="keyword">this</span>);</div><div class="line"><a name="l09273"></a><span class="lineno"> 9273</span>&#160;    <span class="comment">// This lock is important so that we don&#39;t call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.</span></div><div class="line"><a name="l09274"></a><span class="lineno"> 9274</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09275"></a><span class="lineno"> 9275</span>&#160;    <span class="keywordflow">return</span> hAllocator-&gt;GetVulkanFunctions().vkBindBufferMemory(</div><div class="line"><a name="l09276"></a><span class="lineno"> 9276</span>&#160;        hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l09277"></a><span class="lineno"> 9277</span>&#160;        hBuffer,</div><div class="line"><a name="l09278"></a><span class="lineno"> 9278</span>&#160;        m_hMemory,</div><div class="line"><a name="l09279"></a><span class="lineno"> 9279</span>&#160;        hAllocation-&gt;GetOffset());</div><div class="line"><a name="l09280"></a><span class="lineno"> 9280</span>&#160;}</div><div class="line"><a name="l09281"></a><span class="lineno"> 9281</span>&#160;</div><div class="line"><a name="l09282"></a><span class="lineno"> 9282</span>&#160;VkResult VmaDeviceMemoryBlock::BindImageMemory(</div><div class="line"><a name="l09283"></a><span class="lineno"> 9283</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l09284"></a><span class="lineno"> 9284</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l09285"></a><span class="lineno"> 9285</span>&#160;    VkImage hImage)</div><div class="line"><a name="l09286"></a><span class="lineno"> 9286</span>&#160;{</div><div class="line"><a name="l09287"></a><span class="lineno"> 9287</span>&#160;    VMA_ASSERT(hAllocation-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &amp;&amp;</div><div class="line"><a name="l09288"></a><span class="lineno"> 9288</span>&#160;        hAllocation-&gt;GetBlock() == <span class="keyword">this</span>);</div><div class="line"><a name="l09289"></a><span class="lineno"> 9289</span>&#160;    <span class="comment">// This lock is important so that we don&#39;t call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.</span></div><div class="line"><a name="l09290"></a><span class="lineno"> 9290</span>&#160;    VmaMutexLock lock(m_Mutex, hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09291"></a><span class="lineno"> 9291</span>&#160;    <span class="keywordflow">return</span> hAllocator-&gt;GetVulkanFunctions().vkBindImageMemory(</div><div class="line"><a name="l09292"></a><span class="lineno"> 9292</span>&#160;        hAllocator-&gt;m_hDevice,</div><div class="line"><a name="l09293"></a><span class="lineno"> 9293</span>&#160;        hImage,</div><div class="line"><a name="l09294"></a><span class="lineno"> 9294</span>&#160;        m_hMemory,</div><div class="line"><a name="l09295"></a><span class="lineno"> 9295</span>&#160;        hAllocation-&gt;GetOffset());</div><div class="line"><a name="l09296"></a><span class="lineno"> 9296</span>&#160;}</div><div class="line"><a name="l09297"></a><span class="lineno"> 9297</span>&#160;</div><div class="line"><a name="l09298"></a><span class="lineno"> 9298</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> InitStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; outInfo)</div><div class="line"><a name="l09299"></a><span class="lineno"> 9299</span>&#160;{</div><div class="line"><a name="l09300"></a><span class="lineno"> 9300</span>&#160;    memset(&amp;outInfo, 0, <span class="keyword">sizeof</span>(outInfo));</div><div class="line"><a name="l09301"></a><span class="lineno"> 9301</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l09302"></a><span class="lineno"> 9302</span>&#160;    outInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = UINT64_MAX;</div><div class="line"><a name="l09303"></a><span class="lineno"> 9303</span>&#160;}</div><div class="line"><a name="l09304"></a><span class="lineno"> 9304</span>&#160;</div><div class="line"><a name="l09305"></a><span class="lineno"> 9305</span>&#160;<span class="comment">// Adds statistics srcInfo into inoutInfo, like: inoutInfo += srcInfo.</span></div><div class="line"><a name="l09306"></a><span class="lineno"> 9306</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaAddStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; inoutInfo, <span class="keyword">const</span> <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; srcInfo)</div><div class="line"><a name="l09307"></a><span class="lineno"> 9307</span>&#160;{</div><div class="line"><a name="l09308"></a><span class="lineno"> 9308</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a>;</div><div class="line"><a name="l09309"></a><span class="lineno"> 9309</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>;</div><div class="line"><a name="l09310"></a><span class="lineno"> 9310</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>;</div><div class="line"><a name="l09311"></a><span class="lineno"> 9311</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>;</div><div class="line"><a name="l09312"></a><span class="lineno"> 9312</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a> += srcInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>;</div><div class="line"><a name="l09313"></a><span class="lineno"> 9313</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a> = VMA_MIN(inoutInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">allocationSizeMin</a>);</div><div class="line"><a name="l09314"></a><span class="lineno"> 9314</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a> = VMA_MAX(inoutInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">allocationSizeMax</a>);</div><div class="line"><a name="l09315"></a><span class="lineno"> 9315</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a> = VMA_MIN(inoutInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">unusedRangeSizeMin</a>);</div><div class="line"><a name="l09316"></a><span class="lineno"> 9316</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a> = VMA_MAX(inoutInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>, srcInfo.<a class="code" href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">unusedRangeSizeMax</a>);</div><div class="line"><a name="l09317"></a><span class="lineno"> 9317</span>&#160;}</div><div class="line"><a name="l09318"></a><span class="lineno"> 9318</span>&#160;</div><div class="line"><a name="l09319"></a><span class="lineno"> 9319</span>&#160;<span class="keyword">static</span> <span class="keywordtype">void</span> VmaPostprocessCalcStatInfo(<a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a>&amp; inoutInfo)</div><div class="line"><a name="l09320"></a><span class="lineno"> 9320</span>&#160;{</div><div class="line"><a name="l09321"></a><span class="lineno"> 9321</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a1081a039964e566c672e7a2347f9e599">allocationSizeAvg</a> = (inoutInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a> &gt; 0) ?</div><div class="line"><a name="l09322"></a><span class="lineno"> 9322</span>&#160;        VmaRoundDiv&lt;VkDeviceSize&gt;(inoutInfo.<a class="code" href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">usedBytes</a>, inoutInfo.<a class="code" href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">allocationCount</a>) : 0;</div><div class="line"><a name="l09323"></a><span class="lineno"> 9323</span>&#160;    inoutInfo.<a class="code" href="struct_vma_stat_info.html#a2f9b3452af90c9768a30b7fb6ae194fc">unusedRangeSizeAvg</a> = (inoutInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a> &gt; 0) ?</div><div class="line"><a name="l09324"></a><span class="lineno"> 9324</span>&#160;        VmaRoundDiv&lt;VkDeviceSize&gt;(inoutInfo.<a class="code" href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">unusedBytes</a>, inoutInfo.<a class="code" href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">unusedRangeCount</a>) : 0;</div><div class="line"><a name="l09325"></a><span class="lineno"> 9325</span>&#160;}</div><div class="line"><a name="l09326"></a><span class="lineno"> 9326</span>&#160;</div><div class="line"><a name="l09327"></a><span class="lineno"> 9327</span>&#160;VmaPool_T::VmaPool_T(</div><div class="line"><a name="l09328"></a><span class="lineno"> 9328</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l09329"></a><span class="lineno"> 9329</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l09330"></a><span class="lineno"> 9330</span>&#160;    VkDeviceSize preferredBlockSize) :</div><div class="line"><a name="l09331"></a><span class="lineno"> 9331</span>&#160;    m_BlockVector(</div><div class="line"><a name="l09332"></a><span class="lineno"> 9332</span>&#160;        hAllocator,</div><div class="line"><a name="l09333"></a><span class="lineno"> 9333</span>&#160;        createInfo.memoryTypeIndex,</div><div class="line"><a name="l09334"></a><span class="lineno"> 9334</span>&#160;        createInfo.blockSize != 0 ? createInfo.blockSize : preferredBlockSize,</div><div class="line"><a name="l09335"></a><span class="lineno"> 9335</span>&#160;        createInfo.minBlockCount,</div><div class="line"><a name="l09336"></a><span class="lineno"> 9336</span>&#160;        createInfo.maxBlockCount,</div><div class="line"><a name="l09337"></a><span class="lineno"> 9337</span>&#160;        (createInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a>) != 0 ? 1 : hAllocator-&gt;GetBufferImageGranularity(),</div><div class="line"><a name="l09338"></a><span class="lineno"> 9338</span>&#160;        createInfo.frameInUseCount,</div><div class="line"><a name="l09339"></a><span class="lineno"> 9339</span>&#160;        true, <span class="comment">// isCustomPool</span></div><div class="line"><a name="l09340"></a><span class="lineno"> 9340</span>&#160;        createInfo.blockSize != 0, <span class="comment">// explicitBlockSize</span></div><div class="line"><a name="l09341"></a><span class="lineno"> 9341</span>&#160;        (createInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a>) != 0), <span class="comment">// linearAlgorithm</span></div><div class="line"><a name="l09342"></a><span class="lineno"> 9342</span>&#160;    m_Id(0)</div><div class="line"><a name="l09343"></a><span class="lineno"> 9343</span>&#160;{</div><div class="line"><a name="l09344"></a><span class="lineno"> 9344</span>&#160;}</div><div class="line"><a name="l09345"></a><span class="lineno"> 9345</span>&#160;</div><div class="line"><a name="l09346"></a><span class="lineno"> 9346</span>&#160;VmaPool_T::~VmaPool_T()</div><div class="line"><a name="l09347"></a><span class="lineno"> 9347</span>&#160;{</div><div class="line"><a name="l09348"></a><span class="lineno"> 9348</span>&#160;}</div><div class="line"><a name="l09349"></a><span class="lineno"> 9349</span>&#160;</div><div class="line"><a name="l09350"></a><span class="lineno"> 9350</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l09351"></a><span class="lineno"> 9351</span>&#160;</div><div class="line"><a name="l09352"></a><span class="lineno"> 9352</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l09353"></a><span class="lineno"> 9353</span>&#160;</div><div class="line"><a name="l09354"></a><span class="lineno"> 9354</span>&#160;VmaBlockVector::VmaBlockVector(</div><div class="line"><a name="l09355"></a><span class="lineno"> 9355</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l09356"></a><span class="lineno"> 9356</span>&#160;    uint32_t memoryTypeIndex,</div><div class="line"><a name="l09357"></a><span class="lineno"> 9357</span>&#160;    VkDeviceSize preferredBlockSize,</div><div class="line"><a name="l09358"></a><span class="lineno"> 9358</span>&#160;    <span class="keywordtype">size_t</span> minBlockCount,</div><div class="line"><a name="l09359"></a><span class="lineno"> 9359</span>&#160;    <span class="keywordtype">size_t</span> maxBlockCount,</div><div class="line"><a name="l09360"></a><span class="lineno"> 9360</span>&#160;    VkDeviceSize bufferImageGranularity,</div><div class="line"><a name="l09361"></a><span class="lineno"> 9361</span>&#160;    uint32_t frameInUseCount,</div><div class="line"><a name="l09362"></a><span class="lineno"> 9362</span>&#160;    <span class="keywordtype">bool</span> isCustomPool,</div><div class="line"><a name="l09363"></a><span class="lineno"> 9363</span>&#160;    <span class="keywordtype">bool</span> explicitBlockSize,</div><div class="line"><a name="l09364"></a><span class="lineno"> 9364</span>&#160;    <span class="keywordtype">bool</span> linearAlgorithm) :</div><div class="line"><a name="l09365"></a><span class="lineno"> 9365</span>&#160;    m_hAllocator(hAllocator),</div><div class="line"><a name="l09366"></a><span class="lineno"> 9366</span>&#160;    m_MemoryTypeIndex(memoryTypeIndex),</div><div class="line"><a name="l09367"></a><span class="lineno"> 9367</span>&#160;    m_PreferredBlockSize(preferredBlockSize),</div><div class="line"><a name="l09368"></a><span class="lineno"> 9368</span>&#160;    m_MinBlockCount(minBlockCount),</div><div class="line"><a name="l09369"></a><span class="lineno"> 9369</span>&#160;    m_MaxBlockCount(maxBlockCount),</div><div class="line"><a name="l09370"></a><span class="lineno"> 9370</span>&#160;    m_BufferImageGranularity(bufferImageGranularity),</div><div class="line"><a name="l09371"></a><span class="lineno"> 9371</span>&#160;    m_FrameInUseCount(frameInUseCount),</div><div class="line"><a name="l09372"></a><span class="lineno"> 9372</span>&#160;    m_IsCustomPool(isCustomPool),</div><div class="line"><a name="l09373"></a><span class="lineno"> 9373</span>&#160;    m_ExplicitBlockSize(explicitBlockSize),</div><div class="line"><a name="l09374"></a><span class="lineno"> 9374</span>&#160;    m_LinearAlgorithm(linearAlgorithm),</div><div class="line"><a name="l09375"></a><span class="lineno"> 9375</span>&#160;    m_Blocks(VmaStlAllocator&lt;VmaDeviceMemoryBlock*&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l09376"></a><span class="lineno"> 9376</span>&#160;    m_HasEmptyBlock(false),</div><div class="line"><a name="l09377"></a><span class="lineno"> 9377</span>&#160;    m_pDefragmentator(VMA_NULL),</div><div class="line"><a name="l09378"></a><span class="lineno"> 9378</span>&#160;    m_NextBlockId(0)</div><div class="line"><a name="l09379"></a><span class="lineno"> 9379</span>&#160;{</div><div class="line"><a name="l09380"></a><span class="lineno"> 9380</span>&#160;}</div><div class="line"><a name="l09381"></a><span class="lineno"> 9381</span>&#160;</div><div class="line"><a name="l09382"></a><span class="lineno"> 9382</span>&#160;VmaBlockVector::~VmaBlockVector()</div><div class="line"><a name="l09383"></a><span class="lineno"> 9383</span>&#160;{</div><div class="line"><a name="l09384"></a><span class="lineno"> 9384</span>&#160;    VMA_ASSERT(m_pDefragmentator == VMA_NULL);</div><div class="line"><a name="l09385"></a><span class="lineno"> 9385</span>&#160;</div><div class="line"><a name="l09386"></a><span class="lineno"> 9386</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_Blocks.size(); i--; )</div><div class="line"><a name="l09387"></a><span class="lineno"> 9387</span>&#160;    {</div><div class="line"><a name="l09388"></a><span class="lineno"> 9388</span>&#160;        m_Blocks[i]-&gt;Destroy(m_hAllocator);</div><div class="line"><a name="l09389"></a><span class="lineno"> 9389</span>&#160;        vma_delete(m_hAllocator, m_Blocks[i]);</div><div class="line"><a name="l09390"></a><span class="lineno"> 9390</span>&#160;    }</div><div class="line"><a name="l09391"></a><span class="lineno"> 9391</span>&#160;}</div><div class="line"><a name="l09392"></a><span class="lineno"> 9392</span>&#160;</div><div class="line"><a name="l09393"></a><span class="lineno"> 9393</span>&#160;VkResult VmaBlockVector::CreateMinBlocks()</div><div class="line"><a name="l09394"></a><span class="lineno"> 9394</span>&#160;{</div><div class="line"><a name="l09395"></a><span class="lineno"> 9395</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_MinBlockCount; ++i)</div><div class="line"><a name="l09396"></a><span class="lineno"> 9396</span>&#160;    {</div><div class="line"><a name="l09397"></a><span class="lineno"> 9397</span>&#160;        VkResult res = CreateBlock(m_PreferredBlockSize, VMA_NULL);</div><div class="line"><a name="l09398"></a><span class="lineno"> 9398</span>&#160;        <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l09399"></a><span class="lineno"> 9399</span>&#160;        {</div><div class="line"><a name="l09400"></a><span class="lineno"> 9400</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09401"></a><span class="lineno"> 9401</span>&#160;        }</div><div class="line"><a name="l09402"></a><span class="lineno"> 9402</span>&#160;    }</div><div class="line"><a name="l09403"></a><span class="lineno"> 9403</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09404"></a><span class="lineno"> 9404</span>&#160;}</div><div class="line"><a name="l09405"></a><span class="lineno"> 9405</span>&#160;</div><div class="line"><a name="l09406"></a><span class="lineno"> 9406</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::GetPoolStats(<a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pStats)</div><div class="line"><a name="l09407"></a><span class="lineno"> 9407</span>&#160;{</div><div class="line"><a name="l09408"></a><span class="lineno"> 9408</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09409"></a><span class="lineno"> 9409</span>&#160;</div><div class="line"><a name="l09410"></a><span class="lineno"> 9410</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> blockCount = m_Blocks.size();</div><div class="line"><a name="l09411"></a><span class="lineno"> 9411</span>&#160;</div><div class="line"><a name="l09412"></a><span class="lineno"> 9412</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">size</a> = 0;</div><div class="line"><a name="l09413"></a><span class="lineno"> 9413</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">unusedSize</a> = 0;</div><div class="line"><a name="l09414"></a><span class="lineno"> 9414</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">allocationCount</a> = 0;</div><div class="line"><a name="l09415"></a><span class="lineno"> 9415</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">unusedRangeCount</a> = 0;</div><div class="line"><a name="l09416"></a><span class="lineno"> 9416</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">unusedRangeSizeMax</a> = 0;</div><div class="line"><a name="l09417"></a><span class="lineno"> 9417</span>&#160;    pStats-&gt;<a class="code" href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7">blockCount</a> = blockCount;</div><div class="line"><a name="l09418"></a><span class="lineno"> 9418</span>&#160;</div><div class="line"><a name="l09419"></a><span class="lineno"> 9419</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; blockCount; ++blockIndex)</div><div class="line"><a name="l09420"></a><span class="lineno"> 9420</span>&#160;    {</div><div class="line"><a name="l09421"></a><span class="lineno"> 9421</span>&#160;        <span class="keyword">const</span> VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l09422"></a><span class="lineno"> 9422</span>&#160;        VMA_ASSERT(pBlock);</div><div class="line"><a name="l09423"></a><span class="lineno"> 9423</span>&#160;        VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l09424"></a><span class="lineno"> 9424</span>&#160;        pBlock-&gt;m_pMetadata-&gt;AddPoolStats(*pStats);</div><div class="line"><a name="l09425"></a><span class="lineno"> 9425</span>&#160;    }</div><div class="line"><a name="l09426"></a><span class="lineno"> 9426</span>&#160;}</div><div class="line"><a name="l09427"></a><span class="lineno"> 9427</span>&#160;</div><div class="line"><a name="l09428"></a><span class="lineno"> 9428</span>&#160;<span class="keywordtype">bool</span> VmaBlockVector::IsCorruptionDetectionEnabled()<span class="keyword"> const</span></div><div class="line"><a name="l09429"></a><span class="lineno"> 9429</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l09430"></a><span class="lineno"> 9430</span>&#160;    <span class="keyword">const</span> uint32_t requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;</div><div class="line"><a name="l09431"></a><span class="lineno"> 9431</span>&#160;    <span class="keywordflow">return</span> (VMA_DEBUG_DETECT_CORRUPTION != 0) &amp;&amp;</div><div class="line"><a name="l09432"></a><span class="lineno"> 9432</span>&#160;        (VMA_DEBUG_MARGIN &gt; 0) &amp;&amp;</div><div class="line"><a name="l09433"></a><span class="lineno"> 9433</span>&#160;        (m_hAllocator-&gt;m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags &amp; requiredMemFlags) == requiredMemFlags;</div><div class="line"><a name="l09434"></a><span class="lineno"> 9434</span>&#160;}</div><div class="line"><a name="l09435"></a><span class="lineno"> 9435</span>&#160;</div><div class="line"><a name="l09436"></a><span class="lineno"> 9436</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint32_t VMA_ALLOCATION_TRY_COUNT = 32;</div><div class="line"><a name="l09437"></a><span class="lineno"> 9437</span>&#160;</div><div class="line"><a name="l09438"></a><span class="lineno"> 9438</span>&#160;VkResult VmaBlockVector::Allocate(</div><div class="line"><a name="l09439"></a><span class="lineno"> 9439</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> hCurrentPool,</div><div class="line"><a name="l09440"></a><span class="lineno"> 9440</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l09441"></a><span class="lineno"> 9441</span>&#160;    VkDeviceSize size,</div><div class="line"><a name="l09442"></a><span class="lineno"> 9442</span>&#160;    VkDeviceSize alignment,</div><div class="line"><a name="l09443"></a><span class="lineno"> 9443</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l09444"></a><span class="lineno"> 9444</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l09445"></a><span class="lineno"> 9445</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l09446"></a><span class="lineno"> 9446</span>&#160;{</div><div class="line"><a name="l09447"></a><span class="lineno"> 9447</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isUpperAddress = (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a>) != 0;</div><div class="line"><a name="l09448"></a><span class="lineno"> 9448</span>&#160;    <span class="keywordtype">bool</span> canMakeOtherLost = (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>) != 0;</div><div class="line"><a name="l09449"></a><span class="lineno"> 9449</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> mapped = (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0;</div><div class="line"><a name="l09450"></a><span class="lineno"> 9450</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isUserDataString = (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0;</div><div class="line"><a name="l09451"></a><span class="lineno"> 9451</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> canCreateNewBlock =</div><div class="line"><a name="l09452"></a><span class="lineno"> 9452</span>&#160;        ((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) == 0) &amp;&amp;</div><div class="line"><a name="l09453"></a><span class="lineno"> 9453</span>&#160;        (m_Blocks.size() &lt; m_MaxBlockCount);</div><div class="line"><a name="l09454"></a><span class="lineno"> 9454</span>&#160;</div><div class="line"><a name="l09455"></a><span class="lineno"> 9455</span>&#160;    <span class="comment">// If linearAlgorithm is used, canMakeOtherLost is available only when used as ring buffer.</span></div><div class="line"><a name="l09456"></a><span class="lineno"> 9456</span>&#160;    <span class="comment">// Which in turn is available only when maxBlockCount = 1.</span></div><div class="line"><a name="l09457"></a><span class="lineno"> 9457</span>&#160;    <span class="keywordflow">if</span>(m_LinearAlgorithm &amp;&amp; m_MaxBlockCount &gt; 1)</div><div class="line"><a name="l09458"></a><span class="lineno"> 9458</span>&#160;    {</div><div class="line"><a name="l09459"></a><span class="lineno"> 9459</span>&#160;        canMakeOtherLost = <span class="keyword">false</span>;</div><div class="line"><a name="l09460"></a><span class="lineno"> 9460</span>&#160;    }</div><div class="line"><a name="l09461"></a><span class="lineno"> 9461</span>&#160;</div><div class="line"><a name="l09462"></a><span class="lineno"> 9462</span>&#160;    <span class="comment">// Upper address can only be used with linear allocator and within single memory block.</span></div><div class="line"><a name="l09463"></a><span class="lineno"> 9463</span>&#160;    <span class="keywordflow">if</span>(isUpperAddress &amp;&amp;</div><div class="line"><a name="l09464"></a><span class="lineno"> 9464</span>&#160;        (!m_LinearAlgorithm || m_MaxBlockCount &gt; 1))</div><div class="line"><a name="l09465"></a><span class="lineno"> 9465</span>&#160;    {</div><div class="line"><a name="l09466"></a><span class="lineno"> 9466</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_FEATURE_NOT_PRESENT;</div><div class="line"><a name="l09467"></a><span class="lineno"> 9467</span>&#160;    }</div><div class="line"><a name="l09468"></a><span class="lineno"> 9468</span>&#160;</div><div class="line"><a name="l09469"></a><span class="lineno"> 9469</span>&#160;    <span class="comment">// Early reject: requested allocation size is larger that maximum block size for this block vector.</span></div><div class="line"><a name="l09470"></a><span class="lineno"> 9470</span>&#160;    <span class="keywordflow">if</span>(size + 2 * VMA_DEBUG_MARGIN &gt; m_PreferredBlockSize)</div><div class="line"><a name="l09471"></a><span class="lineno"> 9471</span>&#160;    {</div><div class="line"><a name="l09472"></a><span class="lineno"> 9472</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l09473"></a><span class="lineno"> 9473</span>&#160;    }</div><div class="line"><a name="l09474"></a><span class="lineno"> 9474</span>&#160;</div><div class="line"><a name="l09475"></a><span class="lineno"> 9475</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09476"></a><span class="lineno"> 9476</span>&#160;</div><div class="line"><a name="l09477"></a><span class="lineno"> 9477</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l09478"></a><span class="lineno"> 9478</span>&#160;<span class="comment">    Under certain condition, this whole section can be skipped for optimization, so</span></div><div class="line"><a name="l09479"></a><span class="lineno"> 9479</span>&#160;<span class="comment">    we move on directly to trying to allocate with canMakeOtherLost. That&#39;s the case</span></div><div class="line"><a name="l09480"></a><span class="lineno"> 9480</span>&#160;<span class="comment">    e.g. for custom pools with linear algorithm.</span></div><div class="line"><a name="l09481"></a><span class="lineno"> 9481</span>&#160;<span class="comment">    */</span></div><div class="line"><a name="l09482"></a><span class="lineno"> 9482</span>&#160;    <span class="keywordflow">if</span>(!canMakeOtherLost || canCreateNewBlock)</div><div class="line"><a name="l09483"></a><span class="lineno"> 9483</span>&#160;    {</div><div class="line"><a name="l09484"></a><span class="lineno"> 9484</span>&#160;        <span class="comment">// 1. Search existing allocations. Try to allocate without making other allocations lost.</span></div><div class="line"><a name="l09485"></a><span class="lineno"> 9485</span>&#160;        <a class="code" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a> allocFlagsCopy = createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>;</div><div class="line"><a name="l09486"></a><span class="lineno"> 9486</span>&#160;        allocFlagsCopy &amp;= ~<a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>;</div><div class="line"><a name="l09487"></a><span class="lineno"> 9487</span>&#160;</div><div class="line"><a name="l09488"></a><span class="lineno"> 9488</span>&#160;        <span class="keywordflow">if</span>(m_LinearAlgorithm)</div><div class="line"><a name="l09489"></a><span class="lineno"> 9489</span>&#160;        {</div><div class="line"><a name="l09490"></a><span class="lineno"> 9490</span>&#160;            <span class="comment">// Use only last block.</span></div><div class="line"><a name="l09491"></a><span class="lineno"> 9491</span>&#160;            <span class="keywordflow">if</span>(!m_Blocks.empty())</div><div class="line"><a name="l09492"></a><span class="lineno"> 9492</span>&#160;            {</div><div class="line"><a name="l09493"></a><span class="lineno"> 9493</span>&#160;                VmaDeviceMemoryBlock* <span class="keyword">const</span> pCurrBlock = m_Blocks.back();</div><div class="line"><a name="l09494"></a><span class="lineno"> 9494</span>&#160;                VMA_ASSERT(pCurrBlock);</div><div class="line"><a name="l09495"></a><span class="lineno"> 9495</span>&#160;                VkResult res = AllocateFromBlock(</div><div class="line"><a name="l09496"></a><span class="lineno"> 9496</span>&#160;                    pCurrBlock,</div><div class="line"><a name="l09497"></a><span class="lineno"> 9497</span>&#160;                    hCurrentPool,</div><div class="line"><a name="l09498"></a><span class="lineno"> 9498</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l09499"></a><span class="lineno"> 9499</span>&#160;                    size,</div><div class="line"><a name="l09500"></a><span class="lineno"> 9500</span>&#160;                    alignment,</div><div class="line"><a name="l09501"></a><span class="lineno"> 9501</span>&#160;                    allocFlagsCopy,</div><div class="line"><a name="l09502"></a><span class="lineno"> 9502</span>&#160;                    createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>,</div><div class="line"><a name="l09503"></a><span class="lineno"> 9503</span>&#160;                    suballocType,</div><div class="line"><a name="l09504"></a><span class="lineno"> 9504</span>&#160;                    pAllocation);</div><div class="line"><a name="l09505"></a><span class="lineno"> 9505</span>&#160;                <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l09506"></a><span class="lineno"> 9506</span>&#160;                {</div><div class="line"><a name="l09507"></a><span class="lineno"> 9507</span>&#160;                    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Returned from last block #%u&quot;</span>, (uint32_t)(m_Blocks.size() - 1));</div><div class="line"><a name="l09508"></a><span class="lineno"> 9508</span>&#160;                    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09509"></a><span class="lineno"> 9509</span>&#160;                }</div><div class="line"><a name="l09510"></a><span class="lineno"> 9510</span>&#160;            }</div><div class="line"><a name="l09511"></a><span class="lineno"> 9511</span>&#160;        }</div><div class="line"><a name="l09512"></a><span class="lineno"> 9512</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l09513"></a><span class="lineno"> 9513</span>&#160;        {</div><div class="line"><a name="l09514"></a><span class="lineno"> 9514</span>&#160;            <span class="comment">// Forward order in m_Blocks - prefer blocks with smallest amount of free space.</span></div><div class="line"><a name="l09515"></a><span class="lineno"> 9515</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex )</div><div class="line"><a name="l09516"></a><span class="lineno"> 9516</span>&#160;            {</div><div class="line"><a name="l09517"></a><span class="lineno"> 9517</span>&#160;                VmaDeviceMemoryBlock* <span class="keyword">const</span> pCurrBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l09518"></a><span class="lineno"> 9518</span>&#160;                VMA_ASSERT(pCurrBlock);</div><div class="line"><a name="l09519"></a><span class="lineno"> 9519</span>&#160;                VkResult res = AllocateFromBlock(</div><div class="line"><a name="l09520"></a><span class="lineno"> 9520</span>&#160;                    pCurrBlock,</div><div class="line"><a name="l09521"></a><span class="lineno"> 9521</span>&#160;                    hCurrentPool,</div><div class="line"><a name="l09522"></a><span class="lineno"> 9522</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l09523"></a><span class="lineno"> 9523</span>&#160;                    size,</div><div class="line"><a name="l09524"></a><span class="lineno"> 9524</span>&#160;                    alignment,</div><div class="line"><a name="l09525"></a><span class="lineno"> 9525</span>&#160;                    allocFlagsCopy,</div><div class="line"><a name="l09526"></a><span class="lineno"> 9526</span>&#160;                    createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>,</div><div class="line"><a name="l09527"></a><span class="lineno"> 9527</span>&#160;                    suballocType,</div><div class="line"><a name="l09528"></a><span class="lineno"> 9528</span>&#160;                    pAllocation);</div><div class="line"><a name="l09529"></a><span class="lineno"> 9529</span>&#160;                <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l09530"></a><span class="lineno"> 9530</span>&#160;                {</div><div class="line"><a name="l09531"></a><span class="lineno"> 9531</span>&#160;                    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Returned from existing block #%u&quot;</span>, (uint32_t)blockIndex);</div><div class="line"><a name="l09532"></a><span class="lineno"> 9532</span>&#160;                    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09533"></a><span class="lineno"> 9533</span>&#160;                }</div><div class="line"><a name="l09534"></a><span class="lineno"> 9534</span>&#160;            }</div><div class="line"><a name="l09535"></a><span class="lineno"> 9535</span>&#160;        }</div><div class="line"><a name="l09536"></a><span class="lineno"> 9536</span>&#160;</div><div class="line"><a name="l09537"></a><span class="lineno"> 9537</span>&#160;        <span class="comment">// 2. Try to create new block.</span></div><div class="line"><a name="l09538"></a><span class="lineno"> 9538</span>&#160;        <span class="keywordflow">if</span>(canCreateNewBlock)</div><div class="line"><a name="l09539"></a><span class="lineno"> 9539</span>&#160;        {</div><div class="line"><a name="l09540"></a><span class="lineno"> 9540</span>&#160;            <span class="comment">// Calculate optimal size for new block.</span></div><div class="line"><a name="l09541"></a><span class="lineno"> 9541</span>&#160;            VkDeviceSize newBlockSize = m_PreferredBlockSize;</div><div class="line"><a name="l09542"></a><span class="lineno"> 9542</span>&#160;            uint32_t newBlockSizeShift = 0;</div><div class="line"><a name="l09543"></a><span class="lineno"> 9543</span>&#160;            <span class="keyword">const</span> uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3;</div><div class="line"><a name="l09544"></a><span class="lineno"> 9544</span>&#160;</div><div class="line"><a name="l09545"></a><span class="lineno"> 9545</span>&#160;            <span class="keywordflow">if</span>(!m_ExplicitBlockSize)</div><div class="line"><a name="l09546"></a><span class="lineno"> 9546</span>&#160;            {</div><div class="line"><a name="l09547"></a><span class="lineno"> 9547</span>&#160;                <span class="comment">// Allocate 1/8, 1/4, 1/2 as first blocks.</span></div><div class="line"><a name="l09548"></a><span class="lineno"> 9548</span>&#160;                <span class="keyword">const</span> VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize();</div><div class="line"><a name="l09549"></a><span class="lineno"> 9549</span>&#160;                <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; NEW_BLOCK_SIZE_SHIFT_MAX; ++i)</div><div class="line"><a name="l09550"></a><span class="lineno"> 9550</span>&#160;                {</div><div class="line"><a name="l09551"></a><span class="lineno"> 9551</span>&#160;                    <span class="keyword">const</span> VkDeviceSize smallerNewBlockSize = newBlockSize / 2;</div><div class="line"><a name="l09552"></a><span class="lineno"> 9552</span>&#160;                    <span class="keywordflow">if</span>(smallerNewBlockSize &gt; maxExistingBlockSize &amp;&amp; smallerNewBlockSize &gt;= size * 2)</div><div class="line"><a name="l09553"></a><span class="lineno"> 9553</span>&#160;                    {</div><div class="line"><a name="l09554"></a><span class="lineno"> 9554</span>&#160;                        newBlockSize = smallerNewBlockSize;</div><div class="line"><a name="l09555"></a><span class="lineno"> 9555</span>&#160;                        ++newBlockSizeShift;</div><div class="line"><a name="l09556"></a><span class="lineno"> 9556</span>&#160;                    }</div><div class="line"><a name="l09557"></a><span class="lineno"> 9557</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l09558"></a><span class="lineno"> 9558</span>&#160;                    {</div><div class="line"><a name="l09559"></a><span class="lineno"> 9559</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l09560"></a><span class="lineno"> 9560</span>&#160;                    }</div><div class="line"><a name="l09561"></a><span class="lineno"> 9561</span>&#160;                }</div><div class="line"><a name="l09562"></a><span class="lineno"> 9562</span>&#160;            }</div><div class="line"><a name="l09563"></a><span class="lineno"> 9563</span>&#160;</div><div class="line"><a name="l09564"></a><span class="lineno"> 9564</span>&#160;            <span class="keywordtype">size_t</span> newBlockIndex = 0;</div><div class="line"><a name="l09565"></a><span class="lineno"> 9565</span>&#160;            VkResult res = CreateBlock(newBlockSize, &amp;newBlockIndex);</div><div class="line"><a name="l09566"></a><span class="lineno"> 9566</span>&#160;            <span class="comment">// Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.</span></div><div class="line"><a name="l09567"></a><span class="lineno"> 9567</span>&#160;            <span class="keywordflow">if</span>(!m_ExplicitBlockSize)</div><div class="line"><a name="l09568"></a><span class="lineno"> 9568</span>&#160;            {</div><div class="line"><a name="l09569"></a><span class="lineno"> 9569</span>&#160;                <span class="keywordflow">while</span>(res &lt; 0 &amp;&amp; newBlockSizeShift &lt; NEW_BLOCK_SIZE_SHIFT_MAX)</div><div class="line"><a name="l09570"></a><span class="lineno"> 9570</span>&#160;                {</div><div class="line"><a name="l09571"></a><span class="lineno"> 9571</span>&#160;                    <span class="keyword">const</span> VkDeviceSize smallerNewBlockSize = newBlockSize / 2;</div><div class="line"><a name="l09572"></a><span class="lineno"> 9572</span>&#160;                    <span class="keywordflow">if</span>(smallerNewBlockSize &gt;= size)</div><div class="line"><a name="l09573"></a><span class="lineno"> 9573</span>&#160;                    {</div><div class="line"><a name="l09574"></a><span class="lineno"> 9574</span>&#160;                        newBlockSize = smallerNewBlockSize;</div><div class="line"><a name="l09575"></a><span class="lineno"> 9575</span>&#160;                        ++newBlockSizeShift;</div><div class="line"><a name="l09576"></a><span class="lineno"> 9576</span>&#160;                        res = CreateBlock(newBlockSize, &amp;newBlockIndex);</div><div class="line"><a name="l09577"></a><span class="lineno"> 9577</span>&#160;                    }</div><div class="line"><a name="l09578"></a><span class="lineno"> 9578</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l09579"></a><span class="lineno"> 9579</span>&#160;                    {</div><div class="line"><a name="l09580"></a><span class="lineno"> 9580</span>&#160;                        <span class="keywordflow">break</span>;</div><div class="line"><a name="l09581"></a><span class="lineno"> 9581</span>&#160;                    }</div><div class="line"><a name="l09582"></a><span class="lineno"> 9582</span>&#160;                }</div><div class="line"><a name="l09583"></a><span class="lineno"> 9583</span>&#160;            }</div><div class="line"><a name="l09584"></a><span class="lineno"> 9584</span>&#160;</div><div class="line"><a name="l09585"></a><span class="lineno"> 9585</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l09586"></a><span class="lineno"> 9586</span>&#160;            {</div><div class="line"><a name="l09587"></a><span class="lineno"> 9587</span>&#160;                VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[newBlockIndex];</div><div class="line"><a name="l09588"></a><span class="lineno"> 9588</span>&#160;                VMA_ASSERT(pBlock-&gt;m_pMetadata-&gt;GetSize() &gt;= size);</div><div class="line"><a name="l09589"></a><span class="lineno"> 9589</span>&#160;</div><div class="line"><a name="l09590"></a><span class="lineno"> 9590</span>&#160;                res = AllocateFromBlock(</div><div class="line"><a name="l09591"></a><span class="lineno"> 9591</span>&#160;                    pBlock,</div><div class="line"><a name="l09592"></a><span class="lineno"> 9592</span>&#160;                    hCurrentPool,</div><div class="line"><a name="l09593"></a><span class="lineno"> 9593</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l09594"></a><span class="lineno"> 9594</span>&#160;                    size,</div><div class="line"><a name="l09595"></a><span class="lineno"> 9595</span>&#160;                    alignment,</div><div class="line"><a name="l09596"></a><span class="lineno"> 9596</span>&#160;                    allocFlagsCopy,</div><div class="line"><a name="l09597"></a><span class="lineno"> 9597</span>&#160;                    createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>,</div><div class="line"><a name="l09598"></a><span class="lineno"> 9598</span>&#160;                    suballocType,</div><div class="line"><a name="l09599"></a><span class="lineno"> 9599</span>&#160;                    pAllocation);</div><div class="line"><a name="l09600"></a><span class="lineno"> 9600</span>&#160;                <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l09601"></a><span class="lineno"> 9601</span>&#160;                {</div><div class="line"><a name="l09602"></a><span class="lineno"> 9602</span>&#160;                    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Created new block Size=%llu&quot;</span>, newBlockSize);</div><div class="line"><a name="l09603"></a><span class="lineno"> 9603</span>&#160;                    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09604"></a><span class="lineno"> 9604</span>&#160;                }</div><div class="line"><a name="l09605"></a><span class="lineno"> 9605</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l09606"></a><span class="lineno"> 9606</span>&#160;                {</div><div class="line"><a name="l09607"></a><span class="lineno"> 9607</span>&#160;                    <span class="comment">// Allocation from new block failed, possibly due to VMA_DEBUG_MARGIN or alignment.</span></div><div class="line"><a name="l09608"></a><span class="lineno"> 9608</span>&#160;                    <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l09609"></a><span class="lineno"> 9609</span>&#160;                }</div><div class="line"><a name="l09610"></a><span class="lineno"> 9610</span>&#160;            }</div><div class="line"><a name="l09611"></a><span class="lineno"> 9611</span>&#160;        }</div><div class="line"><a name="l09612"></a><span class="lineno"> 9612</span>&#160;    }</div><div class="line"><a name="l09613"></a><span class="lineno"> 9613</span>&#160;</div><div class="line"><a name="l09614"></a><span class="lineno"> 9614</span>&#160;    <span class="comment">// 3. Try to allocate from existing blocks with making other allocations lost.</span></div><div class="line"><a name="l09615"></a><span class="lineno"> 9615</span>&#160;    <span class="keywordflow">if</span>(canMakeOtherLost)</div><div class="line"><a name="l09616"></a><span class="lineno"> 9616</span>&#160;    {</div><div class="line"><a name="l09617"></a><span class="lineno"> 9617</span>&#160;        uint32_t tryIndex = 0;</div><div class="line"><a name="l09618"></a><span class="lineno"> 9618</span>&#160;        <span class="keywordflow">for</span>(; tryIndex &lt; VMA_ALLOCATION_TRY_COUNT; ++tryIndex)</div><div class="line"><a name="l09619"></a><span class="lineno"> 9619</span>&#160;        {</div><div class="line"><a name="l09620"></a><span class="lineno"> 9620</span>&#160;            VmaDeviceMemoryBlock* pBestRequestBlock = VMA_NULL;</div><div class="line"><a name="l09621"></a><span class="lineno"> 9621</span>&#160;            VmaAllocationRequest bestRequest = {};</div><div class="line"><a name="l09622"></a><span class="lineno"> 9622</span>&#160;            VkDeviceSize bestRequestCost = VK_WHOLE_SIZE;</div><div class="line"><a name="l09623"></a><span class="lineno"> 9623</span>&#160;</div><div class="line"><a name="l09624"></a><span class="lineno"> 9624</span>&#160;            <span class="comment">// 1. Search existing allocations.</span></div><div class="line"><a name="l09625"></a><span class="lineno"> 9625</span>&#160;            <span class="comment">// Forward order in m_Blocks - prefer blocks with smallest amount of free space.</span></div><div class="line"><a name="l09626"></a><span class="lineno"> 9626</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex )</div><div class="line"><a name="l09627"></a><span class="lineno"> 9627</span>&#160;            {</div><div class="line"><a name="l09628"></a><span class="lineno"> 9628</span>&#160;                VmaDeviceMemoryBlock* <span class="keyword">const</span> pCurrBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l09629"></a><span class="lineno"> 9629</span>&#160;                VMA_ASSERT(pCurrBlock);</div><div class="line"><a name="l09630"></a><span class="lineno"> 9630</span>&#160;                VmaAllocationRequest currRequest = {};</div><div class="line"><a name="l09631"></a><span class="lineno"> 9631</span>&#160;                <span class="keywordflow">if</span>(pCurrBlock-&gt;m_pMetadata-&gt;CreateAllocationRequest(</div><div class="line"><a name="l09632"></a><span class="lineno"> 9632</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l09633"></a><span class="lineno"> 9633</span>&#160;                    m_FrameInUseCount,</div><div class="line"><a name="l09634"></a><span class="lineno"> 9634</span>&#160;                    m_BufferImageGranularity,</div><div class="line"><a name="l09635"></a><span class="lineno"> 9635</span>&#160;                    size,</div><div class="line"><a name="l09636"></a><span class="lineno"> 9636</span>&#160;                    alignment,</div><div class="line"><a name="l09637"></a><span class="lineno"> 9637</span>&#160;                    (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a>) != 0,</div><div class="line"><a name="l09638"></a><span class="lineno"> 9638</span>&#160;                    suballocType,</div><div class="line"><a name="l09639"></a><span class="lineno"> 9639</span>&#160;                    canMakeOtherLost,</div><div class="line"><a name="l09640"></a><span class="lineno"> 9640</span>&#160;                    &amp;currRequest))</div><div class="line"><a name="l09641"></a><span class="lineno"> 9641</span>&#160;                {</div><div class="line"><a name="l09642"></a><span class="lineno"> 9642</span>&#160;                    <span class="keyword">const</span> VkDeviceSize currRequestCost = currRequest.CalcCost();</div><div class="line"><a name="l09643"></a><span class="lineno"> 9643</span>&#160;                    <span class="keywordflow">if</span>(pBestRequestBlock == VMA_NULL ||</div><div class="line"><a name="l09644"></a><span class="lineno"> 9644</span>&#160;                        currRequestCost &lt; bestRequestCost)</div><div class="line"><a name="l09645"></a><span class="lineno"> 9645</span>&#160;                    {</div><div class="line"><a name="l09646"></a><span class="lineno"> 9646</span>&#160;                        pBestRequestBlock = pCurrBlock;</div><div class="line"><a name="l09647"></a><span class="lineno"> 9647</span>&#160;                        bestRequest = currRequest;</div><div class="line"><a name="l09648"></a><span class="lineno"> 9648</span>&#160;                        bestRequestCost = currRequestCost;</div><div class="line"><a name="l09649"></a><span class="lineno"> 9649</span>&#160;</div><div class="line"><a name="l09650"></a><span class="lineno"> 9650</span>&#160;                        <span class="keywordflow">if</span>(bestRequestCost == 0)</div><div class="line"><a name="l09651"></a><span class="lineno"> 9651</span>&#160;                        {</div><div class="line"><a name="l09652"></a><span class="lineno"> 9652</span>&#160;                            <span class="keywordflow">break</span>;</div><div class="line"><a name="l09653"></a><span class="lineno"> 9653</span>&#160;                        }</div><div class="line"><a name="l09654"></a><span class="lineno"> 9654</span>&#160;                    }</div><div class="line"><a name="l09655"></a><span class="lineno"> 9655</span>&#160;                }</div><div class="line"><a name="l09656"></a><span class="lineno"> 9656</span>&#160;            }</div><div class="line"><a name="l09657"></a><span class="lineno"> 9657</span>&#160;</div><div class="line"><a name="l09658"></a><span class="lineno"> 9658</span>&#160;            <span class="keywordflow">if</span>(pBestRequestBlock != VMA_NULL)</div><div class="line"><a name="l09659"></a><span class="lineno"> 9659</span>&#160;            {</div><div class="line"><a name="l09660"></a><span class="lineno"> 9660</span>&#160;                <span class="keywordflow">if</span>(mapped)</div><div class="line"><a name="l09661"></a><span class="lineno"> 9661</span>&#160;                {</div><div class="line"><a name="l09662"></a><span class="lineno"> 9662</span>&#160;                    VkResult res = pBestRequestBlock-&gt;Map(m_hAllocator, 1, VMA_NULL);</div><div class="line"><a name="l09663"></a><span class="lineno"> 9663</span>&#160;                    <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l09664"></a><span class="lineno"> 9664</span>&#160;                    {</div><div class="line"><a name="l09665"></a><span class="lineno"> 9665</span>&#160;                        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09666"></a><span class="lineno"> 9666</span>&#160;                    }</div><div class="line"><a name="l09667"></a><span class="lineno"> 9667</span>&#160;                }</div><div class="line"><a name="l09668"></a><span class="lineno"> 9668</span>&#160;</div><div class="line"><a name="l09669"></a><span class="lineno"> 9669</span>&#160;                <span class="keywordflow">if</span>(pBestRequestBlock-&gt;m_pMetadata-&gt;MakeRequestedAllocationsLost(</div><div class="line"><a name="l09670"></a><span class="lineno"> 9670</span>&#160;                    currentFrameIndex,</div><div class="line"><a name="l09671"></a><span class="lineno"> 9671</span>&#160;                    m_FrameInUseCount,</div><div class="line"><a name="l09672"></a><span class="lineno"> 9672</span>&#160;                    &amp;bestRequest))</div><div class="line"><a name="l09673"></a><span class="lineno"> 9673</span>&#160;                {</div><div class="line"><a name="l09674"></a><span class="lineno"> 9674</span>&#160;                    <span class="comment">// We no longer have an empty Allocation.</span></div><div class="line"><a name="l09675"></a><span class="lineno"> 9675</span>&#160;                    <span class="keywordflow">if</span>(pBestRequestBlock-&gt;m_pMetadata-&gt;IsEmpty())</div><div class="line"><a name="l09676"></a><span class="lineno"> 9676</span>&#160;                    {</div><div class="line"><a name="l09677"></a><span class="lineno"> 9677</span>&#160;                        m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l09678"></a><span class="lineno"> 9678</span>&#160;                    }</div><div class="line"><a name="l09679"></a><span class="lineno"> 9679</span>&#160;                    <span class="comment">// Allocate from this pBlock.</span></div><div class="line"><a name="l09680"></a><span class="lineno"> 9680</span>&#160;                    *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);</div><div class="line"><a name="l09681"></a><span class="lineno"> 9681</span>&#160;                    pBestRequestBlock-&gt;m_pMetadata-&gt;Alloc(bestRequest, suballocType, size, isUpperAddress, *pAllocation);</div><div class="line"><a name="l09682"></a><span class="lineno"> 9682</span>&#160;                    (*pAllocation)-&gt;InitBlockAllocation(</div><div class="line"><a name="l09683"></a><span class="lineno"> 9683</span>&#160;                        hCurrentPool,</div><div class="line"><a name="l09684"></a><span class="lineno"> 9684</span>&#160;                        pBestRequestBlock,</div><div class="line"><a name="l09685"></a><span class="lineno"> 9685</span>&#160;                        bestRequest.offset,</div><div class="line"><a name="l09686"></a><span class="lineno"> 9686</span>&#160;                        alignment,</div><div class="line"><a name="l09687"></a><span class="lineno"> 9687</span>&#160;                        size,</div><div class="line"><a name="l09688"></a><span class="lineno"> 9688</span>&#160;                        suballocType,</div><div class="line"><a name="l09689"></a><span class="lineno"> 9689</span>&#160;                        mapped,</div><div class="line"><a name="l09690"></a><span class="lineno"> 9690</span>&#160;                        (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a>) != 0);</div><div class="line"><a name="l09691"></a><span class="lineno"> 9691</span>&#160;                    VMA_HEAVY_ASSERT(pBestRequestBlock-&gt;Validate());</div><div class="line"><a name="l09692"></a><span class="lineno"> 9692</span>&#160;                    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Returned from existing allocation #%u&quot;</span>, (uint32_t)blockIndex);</div><div class="line"><a name="l09693"></a><span class="lineno"> 9693</span>&#160;                    (*pAllocation)-&gt;SetUserData(m_hAllocator, createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l09694"></a><span class="lineno"> 9694</span>&#160;                    <span class="keywordflow">if</span>(VMA_DEBUG_INITIALIZE_ALLOCATIONS)</div><div class="line"><a name="l09695"></a><span class="lineno"> 9695</span>&#160;                    {</div><div class="line"><a name="l09696"></a><span class="lineno"> 9696</span>&#160;                        m_hAllocator-&gt;FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);</div><div class="line"><a name="l09697"></a><span class="lineno"> 9697</span>&#160;                    }</div><div class="line"><a name="l09698"></a><span class="lineno"> 9698</span>&#160;                    <span class="keywordflow">if</span>(IsCorruptionDetectionEnabled())</div><div class="line"><a name="l09699"></a><span class="lineno"> 9699</span>&#160;                    {</div><div class="line"><a name="l09700"></a><span class="lineno"> 9700</span>&#160;                        VkResult res = pBestRequestBlock-&gt;WriteMagicValueAroundAllocation(m_hAllocator, bestRequest.offset, size);</div><div class="line"><a name="l09701"></a><span class="lineno"> 9701</span>&#160;                        VMA_ASSERT(res == VK_SUCCESS &amp;&amp; <span class="stringliteral">&quot;Couldn&#39;t map block memory to write magic value.&quot;</span>);</div><div class="line"><a name="l09702"></a><span class="lineno"> 9702</span>&#160;                    }</div><div class="line"><a name="l09703"></a><span class="lineno"> 9703</span>&#160;                    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09704"></a><span class="lineno"> 9704</span>&#160;                }</div><div class="line"><a name="l09705"></a><span class="lineno"> 9705</span>&#160;                <span class="comment">// else: Some allocations must have been touched while we are here. Next try.</span></div><div class="line"><a name="l09706"></a><span class="lineno"> 9706</span>&#160;            }</div><div class="line"><a name="l09707"></a><span class="lineno"> 9707</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l09708"></a><span class="lineno"> 9708</span>&#160;            {</div><div class="line"><a name="l09709"></a><span class="lineno"> 9709</span>&#160;                <span class="comment">// Could not find place in any of the blocks - break outer loop.</span></div><div class="line"><a name="l09710"></a><span class="lineno"> 9710</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l09711"></a><span class="lineno"> 9711</span>&#160;            }</div><div class="line"><a name="l09712"></a><span class="lineno"> 9712</span>&#160;        }</div><div class="line"><a name="l09713"></a><span class="lineno"> 9713</span>&#160;        <span class="comment">/* Maximum number of tries exceeded - a very unlike event when many other</span></div><div class="line"><a name="l09714"></a><span class="lineno"> 9714</span>&#160;<span class="comment">        threads are simultaneously touching allocations making it impossible to make</span></div><div class="line"><a name="l09715"></a><span class="lineno"> 9715</span>&#160;<span class="comment">        lost at the same time as we try to allocate. */</span></div><div class="line"><a name="l09716"></a><span class="lineno"> 9716</span>&#160;        <span class="keywordflow">if</span>(tryIndex == VMA_ALLOCATION_TRY_COUNT)</div><div class="line"><a name="l09717"></a><span class="lineno"> 9717</span>&#160;        {</div><div class="line"><a name="l09718"></a><span class="lineno"> 9718</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_TOO_MANY_OBJECTS;</div><div class="line"><a name="l09719"></a><span class="lineno"> 9719</span>&#160;        }</div><div class="line"><a name="l09720"></a><span class="lineno"> 9720</span>&#160;    }</div><div class="line"><a name="l09721"></a><span class="lineno"> 9721</span>&#160;</div><div class="line"><a name="l09722"></a><span class="lineno"> 9722</span>&#160;    <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l09723"></a><span class="lineno"> 9723</span>&#160;}</div><div class="line"><a name="l09724"></a><span class="lineno"> 9724</span>&#160;</div><div class="line"><a name="l09725"></a><span class="lineno"> 9725</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::Free(</div><div class="line"><a name="l09726"></a><span class="lineno"> 9726</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l09727"></a><span class="lineno"> 9727</span>&#160;{</div><div class="line"><a name="l09728"></a><span class="lineno"> 9728</span>&#160;    VmaDeviceMemoryBlock* pBlockToDelete = VMA_NULL;</div><div class="line"><a name="l09729"></a><span class="lineno"> 9729</span>&#160;</div><div class="line"><a name="l09730"></a><span class="lineno"> 9730</span>&#160;    <span class="comment">// Scope for lock.</span></div><div class="line"><a name="l09731"></a><span class="lineno"> 9731</span>&#160;    {</div><div class="line"><a name="l09732"></a><span class="lineno"> 9732</span>&#160;        VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09733"></a><span class="lineno"> 9733</span>&#160;</div><div class="line"><a name="l09734"></a><span class="lineno"> 9734</span>&#160;        VmaDeviceMemoryBlock* pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l09735"></a><span class="lineno"> 9735</span>&#160;</div><div class="line"><a name="l09736"></a><span class="lineno"> 9736</span>&#160;        <span class="keywordflow">if</span>(IsCorruptionDetectionEnabled())</div><div class="line"><a name="l09737"></a><span class="lineno"> 9737</span>&#160;        {</div><div class="line"><a name="l09738"></a><span class="lineno"> 9738</span>&#160;            VkResult res = pBlock-&gt;ValidateMagicValueAroundAllocation(m_hAllocator, hAllocation-&gt;GetOffset(), hAllocation-&gt;GetSize());</div><div class="line"><a name="l09739"></a><span class="lineno"> 9739</span>&#160;            VMA_ASSERT(res == VK_SUCCESS &amp;&amp; <span class="stringliteral">&quot;Couldn&#39;t map block memory to validate magic value.&quot;</span>);</div><div class="line"><a name="l09740"></a><span class="lineno"> 9740</span>&#160;        }</div><div class="line"><a name="l09741"></a><span class="lineno"> 9741</span>&#160;</div><div class="line"><a name="l09742"></a><span class="lineno"> 9742</span>&#160;        <span class="keywordflow">if</span>(hAllocation-&gt;IsPersistentMap())</div><div class="line"><a name="l09743"></a><span class="lineno"> 9743</span>&#160;        {</div><div class="line"><a name="l09744"></a><span class="lineno"> 9744</span>&#160;            pBlock-&gt;Unmap(m_hAllocator, 1);</div><div class="line"><a name="l09745"></a><span class="lineno"> 9745</span>&#160;        }</div><div class="line"><a name="l09746"></a><span class="lineno"> 9746</span>&#160;</div><div class="line"><a name="l09747"></a><span class="lineno"> 9747</span>&#160;        pBlock-&gt;m_pMetadata-&gt;Free(hAllocation);</div><div class="line"><a name="l09748"></a><span class="lineno"> 9748</span>&#160;        VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l09749"></a><span class="lineno"> 9749</span>&#160;</div><div class="line"><a name="l09750"></a><span class="lineno"> 9750</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;  Freed from MemoryTypeIndex=%u&quot;</span>, memTypeIndex);</div><div class="line"><a name="l09751"></a><span class="lineno"> 9751</span>&#160;</div><div class="line"><a name="l09752"></a><span class="lineno"> 9752</span>&#160;        <span class="comment">// pBlock became empty after this deallocation.</span></div><div class="line"><a name="l09753"></a><span class="lineno"> 9753</span>&#160;        <span class="keywordflow">if</span>(pBlock-&gt;m_pMetadata-&gt;IsEmpty())</div><div class="line"><a name="l09754"></a><span class="lineno"> 9754</span>&#160;        {</div><div class="line"><a name="l09755"></a><span class="lineno"> 9755</span>&#160;            <span class="comment">// Already has empty Allocation. We don&#39;t want to have two, so delete this one.</span></div><div class="line"><a name="l09756"></a><span class="lineno"> 9756</span>&#160;            <span class="keywordflow">if</span>(m_HasEmptyBlock &amp;&amp; m_Blocks.size() &gt; m_MinBlockCount)</div><div class="line"><a name="l09757"></a><span class="lineno"> 9757</span>&#160;            {</div><div class="line"><a name="l09758"></a><span class="lineno"> 9758</span>&#160;                pBlockToDelete = pBlock;</div><div class="line"><a name="l09759"></a><span class="lineno"> 9759</span>&#160;                Remove(pBlock);</div><div class="line"><a name="l09760"></a><span class="lineno"> 9760</span>&#160;            }</div><div class="line"><a name="l09761"></a><span class="lineno"> 9761</span>&#160;            <span class="comment">// We now have first empty block.</span></div><div class="line"><a name="l09762"></a><span class="lineno"> 9762</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l09763"></a><span class="lineno"> 9763</span>&#160;            {</div><div class="line"><a name="l09764"></a><span class="lineno"> 9764</span>&#160;                m_HasEmptyBlock = <span class="keyword">true</span>;</div><div class="line"><a name="l09765"></a><span class="lineno"> 9765</span>&#160;            }</div><div class="line"><a name="l09766"></a><span class="lineno"> 9766</span>&#160;        }</div><div class="line"><a name="l09767"></a><span class="lineno"> 9767</span>&#160;        <span class="comment">// pBlock didn&#39;t become empty, but we have another empty block - find and free that one.</span></div><div class="line"><a name="l09768"></a><span class="lineno"> 9768</span>&#160;        <span class="comment">// (This is optional, heuristics.)</span></div><div class="line"><a name="l09769"></a><span class="lineno"> 9769</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(m_HasEmptyBlock)</div><div class="line"><a name="l09770"></a><span class="lineno"> 9770</span>&#160;        {</div><div class="line"><a name="l09771"></a><span class="lineno"> 9771</span>&#160;            VmaDeviceMemoryBlock* pLastBlock = m_Blocks.back();</div><div class="line"><a name="l09772"></a><span class="lineno"> 9772</span>&#160;            <span class="keywordflow">if</span>(pLastBlock-&gt;m_pMetadata-&gt;IsEmpty() &amp;&amp; m_Blocks.size() &gt; m_MinBlockCount)</div><div class="line"><a name="l09773"></a><span class="lineno"> 9773</span>&#160;            {</div><div class="line"><a name="l09774"></a><span class="lineno"> 9774</span>&#160;                pBlockToDelete = pLastBlock;</div><div class="line"><a name="l09775"></a><span class="lineno"> 9775</span>&#160;                m_Blocks.pop_back();</div><div class="line"><a name="l09776"></a><span class="lineno"> 9776</span>&#160;                m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l09777"></a><span class="lineno"> 9777</span>&#160;            }</div><div class="line"><a name="l09778"></a><span class="lineno"> 9778</span>&#160;        }</div><div class="line"><a name="l09779"></a><span class="lineno"> 9779</span>&#160;</div><div class="line"><a name="l09780"></a><span class="lineno"> 9780</span>&#160;        IncrementallySortBlocks();</div><div class="line"><a name="l09781"></a><span class="lineno"> 9781</span>&#160;    }</div><div class="line"><a name="l09782"></a><span class="lineno"> 9782</span>&#160;</div><div class="line"><a name="l09783"></a><span class="lineno"> 9783</span>&#160;    <span class="comment">// Destruction of a free Allocation. Deferred until this point, outside of mutex</span></div><div class="line"><a name="l09784"></a><span class="lineno"> 9784</span>&#160;    <span class="comment">// lock, for performance reason.</span></div><div class="line"><a name="l09785"></a><span class="lineno"> 9785</span>&#160;    <span class="keywordflow">if</span>(pBlockToDelete != VMA_NULL)</div><div class="line"><a name="l09786"></a><span class="lineno"> 9786</span>&#160;    {</div><div class="line"><a name="l09787"></a><span class="lineno"> 9787</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Deleted empty allocation&quot;</span>);</div><div class="line"><a name="l09788"></a><span class="lineno"> 9788</span>&#160;        pBlockToDelete-&gt;Destroy(m_hAllocator);</div><div class="line"><a name="l09789"></a><span class="lineno"> 9789</span>&#160;        vma_delete(m_hAllocator, pBlockToDelete);</div><div class="line"><a name="l09790"></a><span class="lineno"> 9790</span>&#160;    }</div><div class="line"><a name="l09791"></a><span class="lineno"> 9791</span>&#160;}</div><div class="line"><a name="l09792"></a><span class="lineno"> 9792</span>&#160;</div><div class="line"><a name="l09793"></a><span class="lineno"> 9793</span>&#160;VkDeviceSize VmaBlockVector::CalcMaxBlockSize()<span class="keyword"> const</span></div><div class="line"><a name="l09794"></a><span class="lineno"> 9794</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l09795"></a><span class="lineno"> 9795</span>&#160;    VkDeviceSize result = 0;</div><div class="line"><a name="l09796"></a><span class="lineno"> 9796</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_Blocks.size(); i--; )</div><div class="line"><a name="l09797"></a><span class="lineno"> 9797</span>&#160;    {</div><div class="line"><a name="l09798"></a><span class="lineno"> 9798</span>&#160;        result = VMA_MAX(result, m_Blocks[i]-&gt;m_pMetadata-&gt;GetSize());</div><div class="line"><a name="l09799"></a><span class="lineno"> 9799</span>&#160;        <span class="keywordflow">if</span>(result &gt;= m_PreferredBlockSize)</div><div class="line"><a name="l09800"></a><span class="lineno"> 9800</span>&#160;        {</div><div class="line"><a name="l09801"></a><span class="lineno"> 9801</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l09802"></a><span class="lineno"> 9802</span>&#160;        }</div><div class="line"><a name="l09803"></a><span class="lineno"> 9803</span>&#160;    }</div><div class="line"><a name="l09804"></a><span class="lineno"> 9804</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l09805"></a><span class="lineno"> 9805</span>&#160;}</div><div class="line"><a name="l09806"></a><span class="lineno"> 9806</span>&#160;</div><div class="line"><a name="l09807"></a><span class="lineno"> 9807</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::Remove(VmaDeviceMemoryBlock* pBlock)</div><div class="line"><a name="l09808"></a><span class="lineno"> 9808</span>&#160;{</div><div class="line"><a name="l09809"></a><span class="lineno"> 9809</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l09810"></a><span class="lineno"> 9810</span>&#160;    {</div><div class="line"><a name="l09811"></a><span class="lineno"> 9811</span>&#160;        <span class="keywordflow">if</span>(m_Blocks[blockIndex] == pBlock)</div><div class="line"><a name="l09812"></a><span class="lineno"> 9812</span>&#160;        {</div><div class="line"><a name="l09813"></a><span class="lineno"> 9813</span>&#160;            VmaVectorRemove(m_Blocks, blockIndex);</div><div class="line"><a name="l09814"></a><span class="lineno"> 9814</span>&#160;            <span class="keywordflow">return</span>;</div><div class="line"><a name="l09815"></a><span class="lineno"> 9815</span>&#160;        }</div><div class="line"><a name="l09816"></a><span class="lineno"> 9816</span>&#160;    }</div><div class="line"><a name="l09817"></a><span class="lineno"> 9817</span>&#160;    VMA_ASSERT(0);</div><div class="line"><a name="l09818"></a><span class="lineno"> 9818</span>&#160;}</div><div class="line"><a name="l09819"></a><span class="lineno"> 9819</span>&#160;</div><div class="line"><a name="l09820"></a><span class="lineno"> 9820</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::IncrementallySortBlocks()</div><div class="line"><a name="l09821"></a><span class="lineno"> 9821</span>&#160;{</div><div class="line"><a name="l09822"></a><span class="lineno"> 9822</span>&#160;    <span class="keywordflow">if</span>(!m_LinearAlgorithm)</div><div class="line"><a name="l09823"></a><span class="lineno"> 9823</span>&#160;    {</div><div class="line"><a name="l09824"></a><span class="lineno"> 9824</span>&#160;        <span class="comment">// Bubble sort only until first swap.</span></div><div class="line"><a name="l09825"></a><span class="lineno"> 9825</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 1; i &lt; m_Blocks.size(); ++i)</div><div class="line"><a name="l09826"></a><span class="lineno"> 9826</span>&#160;        {</div><div class="line"><a name="l09827"></a><span class="lineno"> 9827</span>&#160;            <span class="keywordflow">if</span>(m_Blocks[i - 1]-&gt;m_pMetadata-&gt;GetSumFreeSize() &gt; m_Blocks[i]-&gt;m_pMetadata-&gt;GetSumFreeSize())</div><div class="line"><a name="l09828"></a><span class="lineno"> 9828</span>&#160;            {</div><div class="line"><a name="l09829"></a><span class="lineno"> 9829</span>&#160;                VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]);</div><div class="line"><a name="l09830"></a><span class="lineno"> 9830</span>&#160;                <span class="keywordflow">return</span>;</div><div class="line"><a name="l09831"></a><span class="lineno"> 9831</span>&#160;            }</div><div class="line"><a name="l09832"></a><span class="lineno"> 9832</span>&#160;        }</div><div class="line"><a name="l09833"></a><span class="lineno"> 9833</span>&#160;    }</div><div class="line"><a name="l09834"></a><span class="lineno"> 9834</span>&#160;}</div><div class="line"><a name="l09835"></a><span class="lineno"> 9835</span>&#160;</div><div class="line"><a name="l09836"></a><span class="lineno"> 9836</span>&#160;VkResult VmaBlockVector::AllocateFromBlock(</div><div class="line"><a name="l09837"></a><span class="lineno"> 9837</span>&#160;    VmaDeviceMemoryBlock* pBlock,</div><div class="line"><a name="l09838"></a><span class="lineno"> 9838</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> hCurrentPool,</div><div class="line"><a name="l09839"></a><span class="lineno"> 9839</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l09840"></a><span class="lineno"> 9840</span>&#160;    VkDeviceSize size,</div><div class="line"><a name="l09841"></a><span class="lineno"> 9841</span>&#160;    VkDeviceSize alignment,</div><div class="line"><a name="l09842"></a><span class="lineno"> 9842</span>&#160;    <a class="code" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a> allocFlags,</div><div class="line"><a name="l09843"></a><span class="lineno"> 9843</span>&#160;    <span class="keywordtype">void</span>* pUserData,</div><div class="line"><a name="l09844"></a><span class="lineno"> 9844</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l09845"></a><span class="lineno"> 9845</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l09846"></a><span class="lineno"> 9846</span>&#160;{</div><div class="line"><a name="l09847"></a><span class="lineno"> 9847</span>&#160;    VMA_ASSERT((allocFlags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>) == 0);</div><div class="line"><a name="l09848"></a><span class="lineno"> 9848</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isUpperAddress = (allocFlags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a>) != 0;</div><div class="line"><a name="l09849"></a><span class="lineno"> 9849</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> mapped = (allocFlags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0;</div><div class="line"><a name="l09850"></a><span class="lineno"> 9850</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isUserDataString = (allocFlags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0;</div><div class="line"><a name="l09851"></a><span class="lineno"> 9851</span>&#160;</div><div class="line"><a name="l09852"></a><span class="lineno"> 9852</span>&#160;    VmaAllocationRequest currRequest = {};</div><div class="line"><a name="l09853"></a><span class="lineno"> 9853</span>&#160;    <span class="keywordflow">if</span>(pBlock-&gt;m_pMetadata-&gt;CreateAllocationRequest(</div><div class="line"><a name="l09854"></a><span class="lineno"> 9854</span>&#160;        currentFrameIndex,</div><div class="line"><a name="l09855"></a><span class="lineno"> 9855</span>&#160;        m_FrameInUseCount,</div><div class="line"><a name="l09856"></a><span class="lineno"> 9856</span>&#160;        m_BufferImageGranularity,</div><div class="line"><a name="l09857"></a><span class="lineno"> 9857</span>&#160;        size,</div><div class="line"><a name="l09858"></a><span class="lineno"> 9858</span>&#160;        alignment,</div><div class="line"><a name="l09859"></a><span class="lineno"> 9859</span>&#160;        isUpperAddress,</div><div class="line"><a name="l09860"></a><span class="lineno"> 9860</span>&#160;        suballocType,</div><div class="line"><a name="l09861"></a><span class="lineno"> 9861</span>&#160;        <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l09862"></a><span class="lineno"> 9862</span>&#160;        &amp;currRequest))</div><div class="line"><a name="l09863"></a><span class="lineno"> 9863</span>&#160;    {</div><div class="line"><a name="l09864"></a><span class="lineno"> 9864</span>&#160;        <span class="comment">// Allocate from pCurrBlock.</span></div><div class="line"><a name="l09865"></a><span class="lineno"> 9865</span>&#160;        VMA_ASSERT(currRequest.itemsToMakeLostCount == 0);</div><div class="line"><a name="l09866"></a><span class="lineno"> 9866</span>&#160;</div><div class="line"><a name="l09867"></a><span class="lineno"> 9867</span>&#160;        <span class="keywordflow">if</span>(mapped)</div><div class="line"><a name="l09868"></a><span class="lineno"> 9868</span>&#160;        {</div><div class="line"><a name="l09869"></a><span class="lineno"> 9869</span>&#160;            VkResult res = pBlock-&gt;Map(m_hAllocator, 1, VMA_NULL);</div><div class="line"><a name="l09870"></a><span class="lineno"> 9870</span>&#160;            <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l09871"></a><span class="lineno"> 9871</span>&#160;            {</div><div class="line"><a name="l09872"></a><span class="lineno"> 9872</span>&#160;                <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09873"></a><span class="lineno"> 9873</span>&#160;            }</div><div class="line"><a name="l09874"></a><span class="lineno"> 9874</span>&#160;        }</div><div class="line"><a name="l09875"></a><span class="lineno"> 9875</span>&#160;            </div><div class="line"><a name="l09876"></a><span class="lineno"> 9876</span>&#160;        <span class="comment">// We no longer have an empty Allocation.</span></div><div class="line"><a name="l09877"></a><span class="lineno"> 9877</span>&#160;        <span class="keywordflow">if</span>(pBlock-&gt;m_pMetadata-&gt;IsEmpty())</div><div class="line"><a name="l09878"></a><span class="lineno"> 9878</span>&#160;        {</div><div class="line"><a name="l09879"></a><span class="lineno"> 9879</span>&#160;            m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l09880"></a><span class="lineno"> 9880</span>&#160;        }</div><div class="line"><a name="l09881"></a><span class="lineno"> 9881</span>&#160;            </div><div class="line"><a name="l09882"></a><span class="lineno"> 9882</span>&#160;        *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);</div><div class="line"><a name="l09883"></a><span class="lineno"> 9883</span>&#160;        pBlock-&gt;m_pMetadata-&gt;Alloc(currRequest, suballocType, size, isUpperAddress, *pAllocation);</div><div class="line"><a name="l09884"></a><span class="lineno"> 9884</span>&#160;        (*pAllocation)-&gt;InitBlockAllocation(</div><div class="line"><a name="l09885"></a><span class="lineno"> 9885</span>&#160;            hCurrentPool,</div><div class="line"><a name="l09886"></a><span class="lineno"> 9886</span>&#160;            pBlock,</div><div class="line"><a name="l09887"></a><span class="lineno"> 9887</span>&#160;            currRequest.offset,</div><div class="line"><a name="l09888"></a><span class="lineno"> 9888</span>&#160;            alignment,</div><div class="line"><a name="l09889"></a><span class="lineno"> 9889</span>&#160;            size,</div><div class="line"><a name="l09890"></a><span class="lineno"> 9890</span>&#160;            suballocType,</div><div class="line"><a name="l09891"></a><span class="lineno"> 9891</span>&#160;            mapped,</div><div class="line"><a name="l09892"></a><span class="lineno"> 9892</span>&#160;            (allocFlags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a>) != 0);</div><div class="line"><a name="l09893"></a><span class="lineno"> 9893</span>&#160;        VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l09894"></a><span class="lineno"> 9894</span>&#160;        (*pAllocation)-&gt;SetUserData(m_hAllocator, pUserData);</div><div class="line"><a name="l09895"></a><span class="lineno"> 9895</span>&#160;        <span class="keywordflow">if</span>(VMA_DEBUG_INITIALIZE_ALLOCATIONS)</div><div class="line"><a name="l09896"></a><span class="lineno"> 9896</span>&#160;        {</div><div class="line"><a name="l09897"></a><span class="lineno"> 9897</span>&#160;            m_hAllocator-&gt;FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);</div><div class="line"><a name="l09898"></a><span class="lineno"> 9898</span>&#160;        }</div><div class="line"><a name="l09899"></a><span class="lineno"> 9899</span>&#160;        <span class="keywordflow">if</span>(IsCorruptionDetectionEnabled())</div><div class="line"><a name="l09900"></a><span class="lineno"> 9900</span>&#160;        {</div><div class="line"><a name="l09901"></a><span class="lineno"> 9901</span>&#160;            VkResult res = pBlock-&gt;WriteMagicValueAroundAllocation(m_hAllocator, currRequest.offset, size);</div><div class="line"><a name="l09902"></a><span class="lineno"> 9902</span>&#160;            VMA_ASSERT(res == VK_SUCCESS &amp;&amp; <span class="stringliteral">&quot;Couldn&#39;t map block memory to write magic value.&quot;</span>);</div><div class="line"><a name="l09903"></a><span class="lineno"> 9903</span>&#160;        }</div><div class="line"><a name="l09904"></a><span class="lineno"> 9904</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09905"></a><span class="lineno"> 9905</span>&#160;    }</div><div class="line"><a name="l09906"></a><span class="lineno"> 9906</span>&#160;    <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l09907"></a><span class="lineno"> 9907</span>&#160;}</div><div class="line"><a name="l09908"></a><span class="lineno"> 9908</span>&#160;</div><div class="line"><a name="l09909"></a><span class="lineno"> 9909</span>&#160;VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, <span class="keywordtype">size_t</span>* pNewBlockIndex)</div><div class="line"><a name="l09910"></a><span class="lineno"> 9910</span>&#160;{</div><div class="line"><a name="l09911"></a><span class="lineno"> 9911</span>&#160;    VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };</div><div class="line"><a name="l09912"></a><span class="lineno"> 9912</span>&#160;    allocInfo.memoryTypeIndex = m_MemoryTypeIndex;</div><div class="line"><a name="l09913"></a><span class="lineno"> 9913</span>&#160;    allocInfo.allocationSize = blockSize;</div><div class="line"><a name="l09914"></a><span class="lineno"> 9914</span>&#160;    VkDeviceMemory mem = VK_NULL_HANDLE;</div><div class="line"><a name="l09915"></a><span class="lineno"> 9915</span>&#160;    VkResult res = m_hAllocator-&gt;AllocateVulkanMemory(&amp;allocInfo, &amp;mem);</div><div class="line"><a name="l09916"></a><span class="lineno"> 9916</span>&#160;    <span class="keywordflow">if</span>(res &lt; 0)</div><div class="line"><a name="l09917"></a><span class="lineno"> 9917</span>&#160;    {</div><div class="line"><a name="l09918"></a><span class="lineno"> 9918</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l09919"></a><span class="lineno"> 9919</span>&#160;    }</div><div class="line"><a name="l09920"></a><span class="lineno"> 9920</span>&#160;</div><div class="line"><a name="l09921"></a><span class="lineno"> 9921</span>&#160;    <span class="comment">// New VkDeviceMemory successfully created.</span></div><div class="line"><a name="l09922"></a><span class="lineno"> 9922</span>&#160;</div><div class="line"><a name="l09923"></a><span class="lineno"> 9923</span>&#160;    <span class="comment">// Create new Allocation for it.</span></div><div class="line"><a name="l09924"></a><span class="lineno"> 9924</span>&#160;    VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = vma_new(m_hAllocator, VmaDeviceMemoryBlock)(m_hAllocator);</div><div class="line"><a name="l09925"></a><span class="lineno"> 9925</span>&#160;    pBlock-&gt;Init(</div><div class="line"><a name="l09926"></a><span class="lineno"> 9926</span>&#160;        m_hAllocator,</div><div class="line"><a name="l09927"></a><span class="lineno"> 9927</span>&#160;        m_MemoryTypeIndex,</div><div class="line"><a name="l09928"></a><span class="lineno"> 9928</span>&#160;        mem,</div><div class="line"><a name="l09929"></a><span class="lineno"> 9929</span>&#160;        allocInfo.allocationSize,</div><div class="line"><a name="l09930"></a><span class="lineno"> 9930</span>&#160;        m_NextBlockId++,</div><div class="line"><a name="l09931"></a><span class="lineno"> 9931</span>&#160;        m_LinearAlgorithm);</div><div class="line"><a name="l09932"></a><span class="lineno"> 9932</span>&#160;</div><div class="line"><a name="l09933"></a><span class="lineno"> 9933</span>&#160;    m_Blocks.push_back(pBlock);</div><div class="line"><a name="l09934"></a><span class="lineno"> 9934</span>&#160;    <span class="keywordflow">if</span>(pNewBlockIndex != VMA_NULL)</div><div class="line"><a name="l09935"></a><span class="lineno"> 9935</span>&#160;    {</div><div class="line"><a name="l09936"></a><span class="lineno"> 9936</span>&#160;        *pNewBlockIndex = m_Blocks.size() - 1;</div><div class="line"><a name="l09937"></a><span class="lineno"> 9937</span>&#160;    }</div><div class="line"><a name="l09938"></a><span class="lineno"> 9938</span>&#160;</div><div class="line"><a name="l09939"></a><span class="lineno"> 9939</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l09940"></a><span class="lineno"> 9940</span>&#160;}</div><div class="line"><a name="l09941"></a><span class="lineno"> 9941</span>&#160;</div><div class="line"><a name="l09942"></a><span class="lineno"> 9942</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l09943"></a><span class="lineno"> 9943</span>&#160;</div><div class="line"><a name="l09944"></a><span class="lineno"> 9944</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::PrintDetailedMap(<span class="keyword">class</span> VmaJsonWriter&amp; json)</div><div class="line"><a name="l09945"></a><span class="lineno"> 9945</span>&#160;{</div><div class="line"><a name="l09946"></a><span class="lineno"> 9946</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l09947"></a><span class="lineno"> 9947</span>&#160;</div><div class="line"><a name="l09948"></a><span class="lineno"> 9948</span>&#160;    json.BeginObject();</div><div class="line"><a name="l09949"></a><span class="lineno"> 9949</span>&#160;</div><div class="line"><a name="l09950"></a><span class="lineno"> 9950</span>&#160;    <span class="keywordflow">if</span>(m_IsCustomPool)</div><div class="line"><a name="l09951"></a><span class="lineno"> 9951</span>&#160;    {</div><div class="line"><a name="l09952"></a><span class="lineno"> 9952</span>&#160;        json.WriteString(<span class="stringliteral">&quot;MemoryTypeIndex&quot;</span>);</div><div class="line"><a name="l09953"></a><span class="lineno"> 9953</span>&#160;        json.WriteNumber(m_MemoryTypeIndex);</div><div class="line"><a name="l09954"></a><span class="lineno"> 9954</span>&#160;</div><div class="line"><a name="l09955"></a><span class="lineno"> 9955</span>&#160;        json.WriteString(<span class="stringliteral">&quot;BlockSize&quot;</span>);</div><div class="line"><a name="l09956"></a><span class="lineno"> 9956</span>&#160;        json.WriteNumber(m_PreferredBlockSize);</div><div class="line"><a name="l09957"></a><span class="lineno"> 9957</span>&#160;</div><div class="line"><a name="l09958"></a><span class="lineno"> 9958</span>&#160;        json.WriteString(<span class="stringliteral">&quot;BlockCount&quot;</span>);</div><div class="line"><a name="l09959"></a><span class="lineno"> 9959</span>&#160;        json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l09960"></a><span class="lineno"> 9960</span>&#160;        <span class="keywordflow">if</span>(m_MinBlockCount &gt; 0)</div><div class="line"><a name="l09961"></a><span class="lineno"> 9961</span>&#160;        {</div><div class="line"><a name="l09962"></a><span class="lineno"> 9962</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Min&quot;</span>);</div><div class="line"><a name="l09963"></a><span class="lineno"> 9963</span>&#160;            json.WriteNumber((uint64_t)m_MinBlockCount);</div><div class="line"><a name="l09964"></a><span class="lineno"> 9964</span>&#160;        }</div><div class="line"><a name="l09965"></a><span class="lineno"> 9965</span>&#160;        <span class="keywordflow">if</span>(m_MaxBlockCount &lt; SIZE_MAX)</div><div class="line"><a name="l09966"></a><span class="lineno"> 9966</span>&#160;        {</div><div class="line"><a name="l09967"></a><span class="lineno"> 9967</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Max&quot;</span>);</div><div class="line"><a name="l09968"></a><span class="lineno"> 9968</span>&#160;            json.WriteNumber((uint64_t)m_MaxBlockCount);</div><div class="line"><a name="l09969"></a><span class="lineno"> 9969</span>&#160;        }</div><div class="line"><a name="l09970"></a><span class="lineno"> 9970</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Cur&quot;</span>);</div><div class="line"><a name="l09971"></a><span class="lineno"> 9971</span>&#160;        json.WriteNumber((uint64_t)m_Blocks.size());</div><div class="line"><a name="l09972"></a><span class="lineno"> 9972</span>&#160;        json.EndObject();</div><div class="line"><a name="l09973"></a><span class="lineno"> 9973</span>&#160;</div><div class="line"><a name="l09974"></a><span class="lineno"> 9974</span>&#160;        <span class="keywordflow">if</span>(m_FrameInUseCount &gt; 0)</div><div class="line"><a name="l09975"></a><span class="lineno"> 9975</span>&#160;        {</div><div class="line"><a name="l09976"></a><span class="lineno"> 9976</span>&#160;            json.WriteString(<span class="stringliteral">&quot;FrameInUseCount&quot;</span>);</div><div class="line"><a name="l09977"></a><span class="lineno"> 9977</span>&#160;            json.WriteNumber(m_FrameInUseCount);</div><div class="line"><a name="l09978"></a><span class="lineno"> 9978</span>&#160;        }</div><div class="line"><a name="l09979"></a><span class="lineno"> 9979</span>&#160;</div><div class="line"><a name="l09980"></a><span class="lineno"> 9980</span>&#160;        <span class="keywordflow">if</span>(m_LinearAlgorithm)</div><div class="line"><a name="l09981"></a><span class="lineno"> 9981</span>&#160;        {</div><div class="line"><a name="l09982"></a><span class="lineno"> 9982</span>&#160;            json.WriteString(<span class="stringliteral">&quot;LinearAlgorithm&quot;</span>);</div><div class="line"><a name="l09983"></a><span class="lineno"> 9983</span>&#160;            json.WriteBool(<span class="keyword">true</span>);</div><div class="line"><a name="l09984"></a><span class="lineno"> 9984</span>&#160;        }</div><div class="line"><a name="l09985"></a><span class="lineno"> 9985</span>&#160;    }</div><div class="line"><a name="l09986"></a><span class="lineno"> 9986</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l09987"></a><span class="lineno"> 9987</span>&#160;    {</div><div class="line"><a name="l09988"></a><span class="lineno"> 9988</span>&#160;        json.WriteString(<span class="stringliteral">&quot;PreferredBlockSize&quot;</span>);</div><div class="line"><a name="l09989"></a><span class="lineno"> 9989</span>&#160;        json.WriteNumber(m_PreferredBlockSize);</div><div class="line"><a name="l09990"></a><span class="lineno"> 9990</span>&#160;    }</div><div class="line"><a name="l09991"></a><span class="lineno"> 9991</span>&#160;</div><div class="line"><a name="l09992"></a><span class="lineno"> 9992</span>&#160;    json.WriteString(<span class="stringliteral">&quot;Blocks&quot;</span>);</div><div class="line"><a name="l09993"></a><span class="lineno"> 9993</span>&#160;    json.BeginObject();</div><div class="line"><a name="l09994"></a><span class="lineno"> 9994</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; m_Blocks.size(); ++i)</div><div class="line"><a name="l09995"></a><span class="lineno"> 9995</span>&#160;    {</div><div class="line"><a name="l09996"></a><span class="lineno"> 9996</span>&#160;        json.BeginString();</div><div class="line"><a name="l09997"></a><span class="lineno"> 9997</span>&#160;        json.ContinueString(m_Blocks[i]-&gt;GetId());</div><div class="line"><a name="l09998"></a><span class="lineno"> 9998</span>&#160;        json.EndString();</div><div class="line"><a name="l09999"></a><span class="lineno"> 9999</span>&#160;</div><div class="line"><a name="l10000"></a><span class="lineno">10000</span>&#160;        m_Blocks[i]-&gt;m_pMetadata-&gt;PrintDetailedMap(json);</div><div class="line"><a name="l10001"></a><span class="lineno">10001</span>&#160;    }</div><div class="line"><a name="l10002"></a><span class="lineno">10002</span>&#160;    json.EndObject();</div><div class="line"><a name="l10003"></a><span class="lineno">10003</span>&#160;</div><div class="line"><a name="l10004"></a><span class="lineno">10004</span>&#160;    json.EndObject();</div><div class="line"><a name="l10005"></a><span class="lineno">10005</span>&#160;}</div><div class="line"><a name="l10006"></a><span class="lineno">10006</span>&#160;</div><div class="line"><a name="l10007"></a><span class="lineno">10007</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l10008"></a><span class="lineno">10008</span>&#160;</div><div class="line"><a name="l10009"></a><span class="lineno">10009</span>&#160;VmaDefragmentator* VmaBlockVector::EnsureDefragmentator(</div><div class="line"><a name="l10010"></a><span class="lineno">10010</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l10011"></a><span class="lineno">10011</span>&#160;    uint32_t currentFrameIndex)</div><div class="line"><a name="l10012"></a><span class="lineno">10012</span>&#160;{</div><div class="line"><a name="l10013"></a><span class="lineno">10013</span>&#160;    <span class="keywordflow">if</span>(m_pDefragmentator == VMA_NULL)</div><div class="line"><a name="l10014"></a><span class="lineno">10014</span>&#160;    {</div><div class="line"><a name="l10015"></a><span class="lineno">10015</span>&#160;        m_pDefragmentator = vma_new(m_hAllocator, VmaDefragmentator)(</div><div class="line"><a name="l10016"></a><span class="lineno">10016</span>&#160;            hAllocator,</div><div class="line"><a name="l10017"></a><span class="lineno">10017</span>&#160;            <span class="keyword">this</span>,</div><div class="line"><a name="l10018"></a><span class="lineno">10018</span>&#160;            currentFrameIndex);</div><div class="line"><a name="l10019"></a><span class="lineno">10019</span>&#160;    }</div><div class="line"><a name="l10020"></a><span class="lineno">10020</span>&#160;</div><div class="line"><a name="l10021"></a><span class="lineno">10021</span>&#160;    <span class="keywordflow">return</span> m_pDefragmentator;</div><div class="line"><a name="l10022"></a><span class="lineno">10022</span>&#160;}</div><div class="line"><a name="l10023"></a><span class="lineno">10023</span>&#160;</div><div class="line"><a name="l10024"></a><span class="lineno">10024</span>&#160;VkResult VmaBlockVector::Defragment(</div><div class="line"><a name="l10025"></a><span class="lineno">10025</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats,</div><div class="line"><a name="l10026"></a><span class="lineno">10026</span>&#160;    VkDeviceSize&amp; maxBytesToMove,</div><div class="line"><a name="l10027"></a><span class="lineno">10027</span>&#160;    uint32_t&amp; maxAllocationsToMove)</div><div class="line"><a name="l10028"></a><span class="lineno">10028</span>&#160;{</div><div class="line"><a name="l10029"></a><span class="lineno">10029</span>&#160;    <span class="keywordflow">if</span>(m_pDefragmentator == VMA_NULL)</div><div class="line"><a name="l10030"></a><span class="lineno">10030</span>&#160;    {</div><div class="line"><a name="l10031"></a><span class="lineno">10031</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10032"></a><span class="lineno">10032</span>&#160;    }</div><div class="line"><a name="l10033"></a><span class="lineno">10033</span>&#160;</div><div class="line"><a name="l10034"></a><span class="lineno">10034</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l10035"></a><span class="lineno">10035</span>&#160;</div><div class="line"><a name="l10036"></a><span class="lineno">10036</span>&#160;    <span class="comment">// Defragment.</span></div><div class="line"><a name="l10037"></a><span class="lineno">10037</span>&#160;    VkResult result = m_pDefragmentator-&gt;Defragment(maxBytesToMove, maxAllocationsToMove);</div><div class="line"><a name="l10038"></a><span class="lineno">10038</span>&#160;</div><div class="line"><a name="l10039"></a><span class="lineno">10039</span>&#160;    <span class="comment">// Accumulate statistics.</span></div><div class="line"><a name="l10040"></a><span class="lineno">10040</span>&#160;    <span class="keywordflow">if</span>(pDefragmentationStats != VMA_NULL)</div><div class="line"><a name="l10041"></a><span class="lineno">10041</span>&#160;    {</div><div class="line"><a name="l10042"></a><span class="lineno">10042</span>&#160;        <span class="keyword">const</span> VkDeviceSize <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a> = m_pDefragmentator-&gt;GetBytesMoved();</div><div class="line"><a name="l10043"></a><span class="lineno">10043</span>&#160;        <span class="keyword">const</span> uint32_t <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a> = m_pDefragmentator-&gt;GetAllocationsMoved();</div><div class="line"><a name="l10044"></a><span class="lineno">10044</span>&#160;        pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a> += <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a>;</div><div class="line"><a name="l10045"></a><span class="lineno">10045</span>&#160;        pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a> += <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a>;</div><div class="line"><a name="l10046"></a><span class="lineno">10046</span>&#160;        VMA_ASSERT(bytesMoved &lt;= maxBytesToMove);</div><div class="line"><a name="l10047"></a><span class="lineno">10047</span>&#160;        VMA_ASSERT(allocationsMoved &lt;= maxAllocationsToMove);</div><div class="line"><a name="l10048"></a><span class="lineno">10048</span>&#160;        maxBytesToMove -= <a class="code" href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">bytesMoved</a>;</div><div class="line"><a name="l10049"></a><span class="lineno">10049</span>&#160;        maxAllocationsToMove -= <a class="code" href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">allocationsMoved</a>;</div><div class="line"><a name="l10050"></a><span class="lineno">10050</span>&#160;    }</div><div class="line"><a name="l10051"></a><span class="lineno">10051</span>&#160;    </div><div class="line"><a name="l10052"></a><span class="lineno">10052</span>&#160;    <span class="comment">// Free empty blocks.</span></div><div class="line"><a name="l10053"></a><span class="lineno">10053</span>&#160;    m_HasEmptyBlock = <span class="keyword">false</span>;</div><div class="line"><a name="l10054"></a><span class="lineno">10054</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = m_Blocks.size(); blockIndex--; )</div><div class="line"><a name="l10055"></a><span class="lineno">10055</span>&#160;    {</div><div class="line"><a name="l10056"></a><span class="lineno">10056</span>&#160;        VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l10057"></a><span class="lineno">10057</span>&#160;        <span class="keywordflow">if</span>(pBlock-&gt;m_pMetadata-&gt;IsEmpty())</div><div class="line"><a name="l10058"></a><span class="lineno">10058</span>&#160;        {</div><div class="line"><a name="l10059"></a><span class="lineno">10059</span>&#160;            <span class="keywordflow">if</span>(m_Blocks.size() &gt; m_MinBlockCount)</div><div class="line"><a name="l10060"></a><span class="lineno">10060</span>&#160;            {</div><div class="line"><a name="l10061"></a><span class="lineno">10061</span>&#160;                <span class="keywordflow">if</span>(pDefragmentationStats != VMA_NULL)</div><div class="line"><a name="l10062"></a><span class="lineno">10062</span>&#160;                {</div><div class="line"><a name="l10063"></a><span class="lineno">10063</span>&#160;                    ++pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b">deviceMemoryBlocksFreed</a>;</div><div class="line"><a name="l10064"></a><span class="lineno">10064</span>&#160;                    pDefragmentationStats-&gt;<a class="code" href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28">bytesFreed</a> += pBlock-&gt;m_pMetadata-&gt;GetSize();</div><div class="line"><a name="l10065"></a><span class="lineno">10065</span>&#160;                }</div><div class="line"><a name="l10066"></a><span class="lineno">10066</span>&#160;</div><div class="line"><a name="l10067"></a><span class="lineno">10067</span>&#160;                VmaVectorRemove(m_Blocks, blockIndex);</div><div class="line"><a name="l10068"></a><span class="lineno">10068</span>&#160;                pBlock-&gt;Destroy(m_hAllocator);</div><div class="line"><a name="l10069"></a><span class="lineno">10069</span>&#160;                vma_delete(m_hAllocator, pBlock);</div><div class="line"><a name="l10070"></a><span class="lineno">10070</span>&#160;            }</div><div class="line"><a name="l10071"></a><span class="lineno">10071</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l10072"></a><span class="lineno">10072</span>&#160;            {</div><div class="line"><a name="l10073"></a><span class="lineno">10073</span>&#160;                m_HasEmptyBlock = <span class="keyword">true</span>;</div><div class="line"><a name="l10074"></a><span class="lineno">10074</span>&#160;            }</div><div class="line"><a name="l10075"></a><span class="lineno">10075</span>&#160;        }</div><div class="line"><a name="l10076"></a><span class="lineno">10076</span>&#160;    }</div><div class="line"><a name="l10077"></a><span class="lineno">10077</span>&#160;</div><div class="line"><a name="l10078"></a><span class="lineno">10078</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l10079"></a><span class="lineno">10079</span>&#160;}</div><div class="line"><a name="l10080"></a><span class="lineno">10080</span>&#160;</div><div class="line"><a name="l10081"></a><span class="lineno">10081</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::DestroyDefragmentator()</div><div class="line"><a name="l10082"></a><span class="lineno">10082</span>&#160;{</div><div class="line"><a name="l10083"></a><span class="lineno">10083</span>&#160;    <span class="keywordflow">if</span>(m_pDefragmentator != VMA_NULL)</div><div class="line"><a name="l10084"></a><span class="lineno">10084</span>&#160;    {</div><div class="line"><a name="l10085"></a><span class="lineno">10085</span>&#160;        vma_delete(m_hAllocator, m_pDefragmentator);</div><div class="line"><a name="l10086"></a><span class="lineno">10086</span>&#160;        m_pDefragmentator = VMA_NULL;</div><div class="line"><a name="l10087"></a><span class="lineno">10087</span>&#160;    }</div><div class="line"><a name="l10088"></a><span class="lineno">10088</span>&#160;}</div><div class="line"><a name="l10089"></a><span class="lineno">10089</span>&#160;</div><div class="line"><a name="l10090"></a><span class="lineno">10090</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::MakePoolAllocationsLost(</div><div class="line"><a name="l10091"></a><span class="lineno">10091</span>&#160;    uint32_t currentFrameIndex,</div><div class="line"><a name="l10092"></a><span class="lineno">10092</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount)</div><div class="line"><a name="l10093"></a><span class="lineno">10093</span>&#160;{</div><div class="line"><a name="l10094"></a><span class="lineno">10094</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l10095"></a><span class="lineno">10095</span>&#160;    <span class="keywordtype">size_t</span> lostAllocationCount = 0;</div><div class="line"><a name="l10096"></a><span class="lineno">10096</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l10097"></a><span class="lineno">10097</span>&#160;    {</div><div class="line"><a name="l10098"></a><span class="lineno">10098</span>&#160;        VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l10099"></a><span class="lineno">10099</span>&#160;        VMA_ASSERT(pBlock);</div><div class="line"><a name="l10100"></a><span class="lineno">10100</span>&#160;        lostAllocationCount += pBlock-&gt;m_pMetadata-&gt;MakeAllocationsLost(currentFrameIndex, m_FrameInUseCount);</div><div class="line"><a name="l10101"></a><span class="lineno">10101</span>&#160;    }</div><div class="line"><a name="l10102"></a><span class="lineno">10102</span>&#160;    <span class="keywordflow">if</span>(pLostAllocationCount != VMA_NULL)</div><div class="line"><a name="l10103"></a><span class="lineno">10103</span>&#160;    {</div><div class="line"><a name="l10104"></a><span class="lineno">10104</span>&#160;        *pLostAllocationCount = lostAllocationCount;</div><div class="line"><a name="l10105"></a><span class="lineno">10105</span>&#160;    }</div><div class="line"><a name="l10106"></a><span class="lineno">10106</span>&#160;}</div><div class="line"><a name="l10107"></a><span class="lineno">10107</span>&#160;</div><div class="line"><a name="l10108"></a><span class="lineno">10108</span>&#160;VkResult VmaBlockVector::CheckCorruption()</div><div class="line"><a name="l10109"></a><span class="lineno">10109</span>&#160;{</div><div class="line"><a name="l10110"></a><span class="lineno">10110</span>&#160;    <span class="keywordflow">if</span>(!IsCorruptionDetectionEnabled())</div><div class="line"><a name="l10111"></a><span class="lineno">10111</span>&#160;    {</div><div class="line"><a name="l10112"></a><span class="lineno">10112</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_FEATURE_NOT_PRESENT;</div><div class="line"><a name="l10113"></a><span class="lineno">10113</span>&#160;    }</div><div class="line"><a name="l10114"></a><span class="lineno">10114</span>&#160;</div><div class="line"><a name="l10115"></a><span class="lineno">10115</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l10116"></a><span class="lineno">10116</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l10117"></a><span class="lineno">10117</span>&#160;    {</div><div class="line"><a name="l10118"></a><span class="lineno">10118</span>&#160;        VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l10119"></a><span class="lineno">10119</span>&#160;        VMA_ASSERT(pBlock);</div><div class="line"><a name="l10120"></a><span class="lineno">10120</span>&#160;        VkResult res = pBlock-&gt;CheckCorruption(m_hAllocator);</div><div class="line"><a name="l10121"></a><span class="lineno">10121</span>&#160;        <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l10122"></a><span class="lineno">10122</span>&#160;        {</div><div class="line"><a name="l10123"></a><span class="lineno">10123</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l10124"></a><span class="lineno">10124</span>&#160;        }</div><div class="line"><a name="l10125"></a><span class="lineno">10125</span>&#160;    }</div><div class="line"><a name="l10126"></a><span class="lineno">10126</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10127"></a><span class="lineno">10127</span>&#160;}</div><div class="line"><a name="l10128"></a><span class="lineno">10128</span>&#160;</div><div class="line"><a name="l10129"></a><span class="lineno">10129</span>&#160;<span class="keywordtype">void</span> VmaBlockVector::AddStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats)</div><div class="line"><a name="l10130"></a><span class="lineno">10130</span>&#160;{</div><div class="line"><a name="l10131"></a><span class="lineno">10131</span>&#160;    <span class="keyword">const</span> uint32_t memTypeIndex = m_MemoryTypeIndex;</div><div class="line"><a name="l10132"></a><span class="lineno">10132</span>&#160;    <span class="keyword">const</span> uint32_t memHeapIndex = m_hAllocator-&gt;MemoryTypeIndexToHeapIndex(memTypeIndex);</div><div class="line"><a name="l10133"></a><span class="lineno">10133</span>&#160;</div><div class="line"><a name="l10134"></a><span class="lineno">10134</span>&#160;    VmaMutexLock lock(m_Mutex, m_hAllocator-&gt;m_UseMutex);</div><div class="line"><a name="l10135"></a><span class="lineno">10135</span>&#160;</div><div class="line"><a name="l10136"></a><span class="lineno">10136</span>&#160;    <span class="keywordflow">for</span>(uint32_t blockIndex = 0; blockIndex &lt; m_Blocks.size(); ++blockIndex)</div><div class="line"><a name="l10137"></a><span class="lineno">10137</span>&#160;    {</div><div class="line"><a name="l10138"></a><span class="lineno">10138</span>&#160;        <span class="keyword">const</span> VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = m_Blocks[blockIndex];</div><div class="line"><a name="l10139"></a><span class="lineno">10139</span>&#160;        VMA_ASSERT(pBlock);</div><div class="line"><a name="l10140"></a><span class="lineno">10140</span>&#160;        VMA_HEAVY_ASSERT(pBlock-&gt;Validate());</div><div class="line"><a name="l10141"></a><span class="lineno">10141</span>&#160;        <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> allocationStatInfo;</div><div class="line"><a name="l10142"></a><span class="lineno">10142</span>&#160;        pBlock-&gt;m_pMetadata-&gt;CalcAllocationStatInfo(allocationStatInfo);</div><div class="line"><a name="l10143"></a><span class="lineno">10143</span>&#160;        VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>, allocationStatInfo);</div><div class="line"><a name="l10144"></a><span class="lineno">10144</span>&#160;        VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[memTypeIndex], allocationStatInfo);</div><div class="line"><a name="l10145"></a><span class="lineno">10145</span>&#160;        VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[memHeapIndex], allocationStatInfo);</div><div class="line"><a name="l10146"></a><span class="lineno">10146</span>&#160;    }</div><div class="line"><a name="l10147"></a><span class="lineno">10147</span>&#160;}</div><div class="line"><a name="l10148"></a><span class="lineno">10148</span>&#160;</div><div class="line"><a name="l10150"></a><span class="lineno">10150</span>&#160;<span class="comment">// VmaDefragmentator members definition</span></div><div class="line"><a name="l10151"></a><span class="lineno">10151</span>&#160;</div><div class="line"><a name="l10152"></a><span class="lineno">10152</span>&#160;VmaDefragmentator::VmaDefragmentator(</div><div class="line"><a name="l10153"></a><span class="lineno">10153</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator,</div><div class="line"><a name="l10154"></a><span class="lineno">10154</span>&#160;    VmaBlockVector* pBlockVector,</div><div class="line"><a name="l10155"></a><span class="lineno">10155</span>&#160;    uint32_t currentFrameIndex) :</div><div class="line"><a name="l10156"></a><span class="lineno">10156</span>&#160;    m_hAllocator(hAllocator),</div><div class="line"><a name="l10157"></a><span class="lineno">10157</span>&#160;    m_pBlockVector(pBlockVector),</div><div class="line"><a name="l10158"></a><span class="lineno">10158</span>&#160;    m_CurrentFrameIndex(currentFrameIndex),</div><div class="line"><a name="l10159"></a><span class="lineno">10159</span>&#160;    m_BytesMoved(0),</div><div class="line"><a name="l10160"></a><span class="lineno">10160</span>&#160;    m_AllocationsMoved(0),</div><div class="line"><a name="l10161"></a><span class="lineno">10161</span>&#160;    m_Allocations(VmaStlAllocator&lt;AllocationInfo&gt;(hAllocator-&gt;GetAllocationCallbacks())),</div><div class="line"><a name="l10162"></a><span class="lineno">10162</span>&#160;    m_Blocks(VmaStlAllocator&lt;BlockInfo*&gt;(hAllocator-&gt;GetAllocationCallbacks()))</div><div class="line"><a name="l10163"></a><span class="lineno">10163</span>&#160;{</div><div class="line"><a name="l10164"></a><span class="lineno">10164</span>&#160;    VMA_ASSERT(!pBlockVector-&gt;UsesLinearAlgorithm());</div><div class="line"><a name="l10165"></a><span class="lineno">10165</span>&#160;}</div><div class="line"><a name="l10166"></a><span class="lineno">10166</span>&#160;</div><div class="line"><a name="l10167"></a><span class="lineno">10167</span>&#160;VmaDefragmentator::~VmaDefragmentator()</div><div class="line"><a name="l10168"></a><span class="lineno">10168</span>&#160;{</div><div class="line"><a name="l10169"></a><span class="lineno">10169</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = m_Blocks.size(); i--; )</div><div class="line"><a name="l10170"></a><span class="lineno">10170</span>&#160;    {</div><div class="line"><a name="l10171"></a><span class="lineno">10171</span>&#160;        vma_delete(m_hAllocator, m_Blocks[i]);</div><div class="line"><a name="l10172"></a><span class="lineno">10172</span>&#160;    }</div><div class="line"><a name="l10173"></a><span class="lineno">10173</span>&#160;}</div><div class="line"><a name="l10174"></a><span class="lineno">10174</span>&#160;</div><div class="line"><a name="l10175"></a><span class="lineno">10175</span>&#160;<span class="keywordtype">void</span> VmaDefragmentator::AddAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc, VkBool32* pChanged)</div><div class="line"><a name="l10176"></a><span class="lineno">10176</span>&#160;{</div><div class="line"><a name="l10177"></a><span class="lineno">10177</span>&#160;    AllocationInfo allocInfo;</div><div class="line"><a name="l10178"></a><span class="lineno">10178</span>&#160;    allocInfo.m_hAllocation = hAlloc;</div><div class="line"><a name="l10179"></a><span class="lineno">10179</span>&#160;    allocInfo.m_pChanged = pChanged;</div><div class="line"><a name="l10180"></a><span class="lineno">10180</span>&#160;    m_Allocations.push_back(allocInfo);</div><div class="line"><a name="l10181"></a><span class="lineno">10181</span>&#160;}</div><div class="line"><a name="l10182"></a><span class="lineno">10182</span>&#160;</div><div class="line"><a name="l10183"></a><span class="lineno">10183</span>&#160;VkResult VmaDefragmentator::BlockInfo::EnsureMapping(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator, <span class="keywordtype">void</span>** ppMappedData)</div><div class="line"><a name="l10184"></a><span class="lineno">10184</span>&#160;{</div><div class="line"><a name="l10185"></a><span class="lineno">10185</span>&#160;    <span class="comment">// It has already been mapped for defragmentation.</span></div><div class="line"><a name="l10186"></a><span class="lineno">10186</span>&#160;    <span class="keywordflow">if</span>(m_pMappedDataForDefragmentation)</div><div class="line"><a name="l10187"></a><span class="lineno">10187</span>&#160;    {</div><div class="line"><a name="l10188"></a><span class="lineno">10188</span>&#160;        *ppMappedData = m_pMappedDataForDefragmentation;</div><div class="line"><a name="l10189"></a><span class="lineno">10189</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10190"></a><span class="lineno">10190</span>&#160;    }</div><div class="line"><a name="l10191"></a><span class="lineno">10191</span>&#160;            </div><div class="line"><a name="l10192"></a><span class="lineno">10192</span>&#160;    <span class="comment">// It is originally mapped.</span></div><div class="line"><a name="l10193"></a><span class="lineno">10193</span>&#160;    <span class="keywordflow">if</span>(m_pBlock-&gt;GetMappedData())</div><div class="line"><a name="l10194"></a><span class="lineno">10194</span>&#160;    {</div><div class="line"><a name="l10195"></a><span class="lineno">10195</span>&#160;        *ppMappedData = m_pBlock-&gt;GetMappedData();</div><div class="line"><a name="l10196"></a><span class="lineno">10196</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10197"></a><span class="lineno">10197</span>&#160;    }</div><div class="line"><a name="l10198"></a><span class="lineno">10198</span>&#160;            </div><div class="line"><a name="l10199"></a><span class="lineno">10199</span>&#160;    <span class="comment">// Map on first usage.</span></div><div class="line"><a name="l10200"></a><span class="lineno">10200</span>&#160;    VkResult res = m_pBlock-&gt;Map(hAllocator, 1, &amp;m_pMappedDataForDefragmentation);</div><div class="line"><a name="l10201"></a><span class="lineno">10201</span>&#160;    *ppMappedData = m_pMappedDataForDefragmentation;</div><div class="line"><a name="l10202"></a><span class="lineno">10202</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l10203"></a><span class="lineno">10203</span>&#160;}</div><div class="line"><a name="l10204"></a><span class="lineno">10204</span>&#160;</div><div class="line"><a name="l10205"></a><span class="lineno">10205</span>&#160;<span class="keywordtype">void</span> VmaDefragmentator::BlockInfo::Unmap(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> hAllocator)</div><div class="line"><a name="l10206"></a><span class="lineno">10206</span>&#160;{</div><div class="line"><a name="l10207"></a><span class="lineno">10207</span>&#160;    <span class="keywordflow">if</span>(m_pMappedDataForDefragmentation != VMA_NULL)</div><div class="line"><a name="l10208"></a><span class="lineno">10208</span>&#160;    {</div><div class="line"><a name="l10209"></a><span class="lineno">10209</span>&#160;        m_pBlock-&gt;Unmap(hAllocator, 1);</div><div class="line"><a name="l10210"></a><span class="lineno">10210</span>&#160;    }</div><div class="line"><a name="l10211"></a><span class="lineno">10211</span>&#160;}</div><div class="line"><a name="l10212"></a><span class="lineno">10212</span>&#160;</div><div class="line"><a name="l10213"></a><span class="lineno">10213</span>&#160;VkResult VmaDefragmentator::DefragmentRound(</div><div class="line"><a name="l10214"></a><span class="lineno">10214</span>&#160;    VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l10215"></a><span class="lineno">10215</span>&#160;    uint32_t maxAllocationsToMove)</div><div class="line"><a name="l10216"></a><span class="lineno">10216</span>&#160;{</div><div class="line"><a name="l10217"></a><span class="lineno">10217</span>&#160;    <span class="keywordflow">if</span>(m_Blocks.empty())</div><div class="line"><a name="l10218"></a><span class="lineno">10218</span>&#160;    {</div><div class="line"><a name="l10219"></a><span class="lineno">10219</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10220"></a><span class="lineno">10220</span>&#160;    }</div><div class="line"><a name="l10221"></a><span class="lineno">10221</span>&#160;</div><div class="line"><a name="l10222"></a><span class="lineno">10222</span>&#160;    <span class="keywordtype">size_t</span> srcBlockIndex = m_Blocks.size() - 1;</div><div class="line"><a name="l10223"></a><span class="lineno">10223</span>&#160;    <span class="keywordtype">size_t</span> srcAllocIndex = SIZE_MAX;</div><div class="line"><a name="l10224"></a><span class="lineno">10224</span>&#160;    <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l10225"></a><span class="lineno">10225</span>&#160;    {</div><div class="line"><a name="l10226"></a><span class="lineno">10226</span>&#160;        <span class="comment">// 1. Find next allocation to move.</span></div><div class="line"><a name="l10227"></a><span class="lineno">10227</span>&#160;        <span class="comment">// 1.1. Start from last to first m_Blocks - they are sorted from most &quot;destination&quot; to most &quot;source&quot;.</span></div><div class="line"><a name="l10228"></a><span class="lineno">10228</span>&#160;        <span class="comment">// 1.2. Then start from last to first m_Allocations - they are sorted from largest to smallest.</span></div><div class="line"><a name="l10229"></a><span class="lineno">10229</span>&#160;        <span class="keywordflow">while</span>(srcAllocIndex &gt;= m_Blocks[srcBlockIndex]-&gt;m_Allocations.size())</div><div class="line"><a name="l10230"></a><span class="lineno">10230</span>&#160;        {</div><div class="line"><a name="l10231"></a><span class="lineno">10231</span>&#160;            <span class="keywordflow">if</span>(m_Blocks[srcBlockIndex]-&gt;m_Allocations.empty())</div><div class="line"><a name="l10232"></a><span class="lineno">10232</span>&#160;            {</div><div class="line"><a name="l10233"></a><span class="lineno">10233</span>&#160;                <span class="comment">// Finished: no more allocations to process.</span></div><div class="line"><a name="l10234"></a><span class="lineno">10234</span>&#160;                <span class="keywordflow">if</span>(srcBlockIndex == 0)</div><div class="line"><a name="l10235"></a><span class="lineno">10235</span>&#160;                {</div><div class="line"><a name="l10236"></a><span class="lineno">10236</span>&#160;                    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10237"></a><span class="lineno">10237</span>&#160;                }</div><div class="line"><a name="l10238"></a><span class="lineno">10238</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l10239"></a><span class="lineno">10239</span>&#160;                {</div><div class="line"><a name="l10240"></a><span class="lineno">10240</span>&#160;                    --srcBlockIndex;</div><div class="line"><a name="l10241"></a><span class="lineno">10241</span>&#160;                    srcAllocIndex = SIZE_MAX;</div><div class="line"><a name="l10242"></a><span class="lineno">10242</span>&#160;                }</div><div class="line"><a name="l10243"></a><span class="lineno">10243</span>&#160;            }</div><div class="line"><a name="l10244"></a><span class="lineno">10244</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l10245"></a><span class="lineno">10245</span>&#160;            {</div><div class="line"><a name="l10246"></a><span class="lineno">10246</span>&#160;                srcAllocIndex = m_Blocks[srcBlockIndex]-&gt;m_Allocations.size() - 1;</div><div class="line"><a name="l10247"></a><span class="lineno">10247</span>&#160;            }</div><div class="line"><a name="l10248"></a><span class="lineno">10248</span>&#160;        }</div><div class="line"><a name="l10249"></a><span class="lineno">10249</span>&#160;        </div><div class="line"><a name="l10250"></a><span class="lineno">10250</span>&#160;        BlockInfo* pSrcBlockInfo = m_Blocks[srcBlockIndex];</div><div class="line"><a name="l10251"></a><span class="lineno">10251</span>&#160;        AllocationInfo&amp; allocInfo = pSrcBlockInfo-&gt;m_Allocations[srcAllocIndex];</div><div class="line"><a name="l10252"></a><span class="lineno">10252</span>&#160;</div><div class="line"><a name="l10253"></a><span class="lineno">10253</span>&#160;        <span class="keyword">const</span> VkDeviceSize size = allocInfo.m_hAllocation-&gt;GetSize();</div><div class="line"><a name="l10254"></a><span class="lineno">10254</span>&#160;        <span class="keyword">const</span> VkDeviceSize srcOffset = allocInfo.m_hAllocation-&gt;GetOffset();</div><div class="line"><a name="l10255"></a><span class="lineno">10255</span>&#160;        <span class="keyword">const</span> VkDeviceSize alignment = allocInfo.m_hAllocation-&gt;GetAlignment();</div><div class="line"><a name="l10256"></a><span class="lineno">10256</span>&#160;        <span class="keyword">const</span> VmaSuballocationType suballocType = allocInfo.m_hAllocation-&gt;GetSuballocationType();</div><div class="line"><a name="l10257"></a><span class="lineno">10257</span>&#160;</div><div class="line"><a name="l10258"></a><span class="lineno">10258</span>&#160;        <span class="comment">// 2. Try to find new place for this allocation in preceding or current block.</span></div><div class="line"><a name="l10259"></a><span class="lineno">10259</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> dstBlockIndex = 0; dstBlockIndex &lt;= srcBlockIndex; ++dstBlockIndex)</div><div class="line"><a name="l10260"></a><span class="lineno">10260</span>&#160;        {</div><div class="line"><a name="l10261"></a><span class="lineno">10261</span>&#160;            BlockInfo* pDstBlockInfo = m_Blocks[dstBlockIndex];</div><div class="line"><a name="l10262"></a><span class="lineno">10262</span>&#160;            VmaAllocationRequest dstAllocRequest;</div><div class="line"><a name="l10263"></a><span class="lineno">10263</span>&#160;            <span class="keywordflow">if</span>(pDstBlockInfo-&gt;m_pBlock-&gt;m_pMetadata-&gt;CreateAllocationRequest(</div><div class="line"><a name="l10264"></a><span class="lineno">10264</span>&#160;                m_CurrentFrameIndex,</div><div class="line"><a name="l10265"></a><span class="lineno">10265</span>&#160;                m_pBlockVector-&gt;GetFrameInUseCount(),</div><div class="line"><a name="l10266"></a><span class="lineno">10266</span>&#160;                m_pBlockVector-&gt;GetBufferImageGranularity(),</div><div class="line"><a name="l10267"></a><span class="lineno">10267</span>&#160;                size,</div><div class="line"><a name="l10268"></a><span class="lineno">10268</span>&#160;                alignment,</div><div class="line"><a name="l10269"></a><span class="lineno">10269</span>&#160;                <span class="keyword">false</span>, <span class="comment">// upperAddress</span></div><div class="line"><a name="l10270"></a><span class="lineno">10270</span>&#160;                suballocType,</div><div class="line"><a name="l10271"></a><span class="lineno">10271</span>&#160;                <span class="keyword">false</span>, <span class="comment">// canMakeOtherLost</span></div><div class="line"><a name="l10272"></a><span class="lineno">10272</span>&#160;                &amp;dstAllocRequest) &amp;&amp;</div><div class="line"><a name="l10273"></a><span class="lineno">10273</span>&#160;            MoveMakesSense(</div><div class="line"><a name="l10274"></a><span class="lineno">10274</span>&#160;                dstBlockIndex, dstAllocRequest.offset, srcBlockIndex, srcOffset))</div><div class="line"><a name="l10275"></a><span class="lineno">10275</span>&#160;            {</div><div class="line"><a name="l10276"></a><span class="lineno">10276</span>&#160;                VMA_ASSERT(dstAllocRequest.itemsToMakeLostCount == 0);</div><div class="line"><a name="l10277"></a><span class="lineno">10277</span>&#160;</div><div class="line"><a name="l10278"></a><span class="lineno">10278</span>&#160;                <span class="comment">// Reached limit on number of allocations or bytes to move.</span></div><div class="line"><a name="l10279"></a><span class="lineno">10279</span>&#160;                <span class="keywordflow">if</span>((m_AllocationsMoved + 1 &gt; maxAllocationsToMove) ||</div><div class="line"><a name="l10280"></a><span class="lineno">10280</span>&#160;                    (m_BytesMoved + size &gt; maxBytesToMove))</div><div class="line"><a name="l10281"></a><span class="lineno">10281</span>&#160;                {</div><div class="line"><a name="l10282"></a><span class="lineno">10282</span>&#160;                    <span class="keywordflow">return</span> VK_INCOMPLETE;</div><div class="line"><a name="l10283"></a><span class="lineno">10283</span>&#160;                }</div><div class="line"><a name="l10284"></a><span class="lineno">10284</span>&#160;</div><div class="line"><a name="l10285"></a><span class="lineno">10285</span>&#160;                <span class="keywordtype">void</span>* pDstMappedData = VMA_NULL;</div><div class="line"><a name="l10286"></a><span class="lineno">10286</span>&#160;                VkResult res = pDstBlockInfo-&gt;EnsureMapping(m_hAllocator, &amp;pDstMappedData);</div><div class="line"><a name="l10287"></a><span class="lineno">10287</span>&#160;                <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l10288"></a><span class="lineno">10288</span>&#160;                {</div><div class="line"><a name="l10289"></a><span class="lineno">10289</span>&#160;                    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l10290"></a><span class="lineno">10290</span>&#160;                }</div><div class="line"><a name="l10291"></a><span class="lineno">10291</span>&#160;</div><div class="line"><a name="l10292"></a><span class="lineno">10292</span>&#160;                <span class="keywordtype">void</span>* pSrcMappedData = VMA_NULL;</div><div class="line"><a name="l10293"></a><span class="lineno">10293</span>&#160;                res = pSrcBlockInfo-&gt;EnsureMapping(m_hAllocator, &amp;pSrcMappedData);</div><div class="line"><a name="l10294"></a><span class="lineno">10294</span>&#160;                <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l10295"></a><span class="lineno">10295</span>&#160;                {</div><div class="line"><a name="l10296"></a><span class="lineno">10296</span>&#160;                    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l10297"></a><span class="lineno">10297</span>&#160;                }</div><div class="line"><a name="l10298"></a><span class="lineno">10298</span>&#160;                </div><div class="line"><a name="l10299"></a><span class="lineno">10299</span>&#160;                <span class="comment">// THE PLACE WHERE ACTUAL DATA COPY HAPPENS.</span></div><div class="line"><a name="l10300"></a><span class="lineno">10300</span>&#160;                memcpy(</div><div class="line"><a name="l10301"></a><span class="lineno">10301</span>&#160;                    reinterpret_cast&lt;char*&gt;(pDstMappedData) + dstAllocRequest.offset,</div><div class="line"><a name="l10302"></a><span class="lineno">10302</span>&#160;                    reinterpret_cast&lt;char*&gt;(pSrcMappedData) + srcOffset,</div><div class="line"><a name="l10303"></a><span class="lineno">10303</span>&#160;                    static_cast&lt;size_t&gt;(size));</div><div class="line"><a name="l10304"></a><span class="lineno">10304</span>&#160;</div><div class="line"><a name="l10305"></a><span class="lineno">10305</span>&#160;                <span class="keywordflow">if</span>(VMA_DEBUG_MARGIN &gt; 0)</div><div class="line"><a name="l10306"></a><span class="lineno">10306</span>&#160;                {</div><div class="line"><a name="l10307"></a><span class="lineno">10307</span>&#160;                    VmaWriteMagicValue(pDstMappedData, dstAllocRequest.offset - VMA_DEBUG_MARGIN);</div><div class="line"><a name="l10308"></a><span class="lineno">10308</span>&#160;                    VmaWriteMagicValue(pDstMappedData, dstAllocRequest.offset + size);</div><div class="line"><a name="l10309"></a><span class="lineno">10309</span>&#160;                }</div><div class="line"><a name="l10310"></a><span class="lineno">10310</span>&#160;                </div><div class="line"><a name="l10311"></a><span class="lineno">10311</span>&#160;                pDstBlockInfo-&gt;m_pBlock-&gt;m_pMetadata-&gt;Alloc(</div><div class="line"><a name="l10312"></a><span class="lineno">10312</span>&#160;                    dstAllocRequest,</div><div class="line"><a name="l10313"></a><span class="lineno">10313</span>&#160;                    suballocType,</div><div class="line"><a name="l10314"></a><span class="lineno">10314</span>&#160;                    size,</div><div class="line"><a name="l10315"></a><span class="lineno">10315</span>&#160;                    <span class="keyword">false</span>, <span class="comment">// upperAddress</span></div><div class="line"><a name="l10316"></a><span class="lineno">10316</span>&#160;                    allocInfo.m_hAllocation);</div><div class="line"><a name="l10317"></a><span class="lineno">10317</span>&#160;                pSrcBlockInfo-&gt;m_pBlock-&gt;m_pMetadata-&gt;FreeAtOffset(srcOffset);</div><div class="line"><a name="l10318"></a><span class="lineno">10318</span>&#160;                </div><div class="line"><a name="l10319"></a><span class="lineno">10319</span>&#160;                allocInfo.m_hAllocation-&gt;ChangeBlockAllocation(m_hAllocator, pDstBlockInfo-&gt;m_pBlock, dstAllocRequest.offset);</div><div class="line"><a name="l10320"></a><span class="lineno">10320</span>&#160;</div><div class="line"><a name="l10321"></a><span class="lineno">10321</span>&#160;                <span class="keywordflow">if</span>(allocInfo.m_pChanged != VMA_NULL)</div><div class="line"><a name="l10322"></a><span class="lineno">10322</span>&#160;                {</div><div class="line"><a name="l10323"></a><span class="lineno">10323</span>&#160;                    *allocInfo.m_pChanged = VK_TRUE;</div><div class="line"><a name="l10324"></a><span class="lineno">10324</span>&#160;                }</div><div class="line"><a name="l10325"></a><span class="lineno">10325</span>&#160;</div><div class="line"><a name="l10326"></a><span class="lineno">10326</span>&#160;                ++m_AllocationsMoved;</div><div class="line"><a name="l10327"></a><span class="lineno">10327</span>&#160;                m_BytesMoved += size;</div><div class="line"><a name="l10328"></a><span class="lineno">10328</span>&#160;</div><div class="line"><a name="l10329"></a><span class="lineno">10329</span>&#160;                VmaVectorRemove(pSrcBlockInfo-&gt;m_Allocations, srcAllocIndex);</div><div class="line"><a name="l10330"></a><span class="lineno">10330</span>&#160;</div><div class="line"><a name="l10331"></a><span class="lineno">10331</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l10332"></a><span class="lineno">10332</span>&#160;            }</div><div class="line"><a name="l10333"></a><span class="lineno">10333</span>&#160;        }</div><div class="line"><a name="l10334"></a><span class="lineno">10334</span>&#160;</div><div class="line"><a name="l10335"></a><span class="lineno">10335</span>&#160;        <span class="comment">// If not processed, this allocInfo remains in pBlockInfo-&gt;m_Allocations for next round.</span></div><div class="line"><a name="l10336"></a><span class="lineno">10336</span>&#160;</div><div class="line"><a name="l10337"></a><span class="lineno">10337</span>&#160;        <span class="keywordflow">if</span>(srcAllocIndex &gt; 0)</div><div class="line"><a name="l10338"></a><span class="lineno">10338</span>&#160;        {</div><div class="line"><a name="l10339"></a><span class="lineno">10339</span>&#160;            --srcAllocIndex;</div><div class="line"><a name="l10340"></a><span class="lineno">10340</span>&#160;        }</div><div class="line"><a name="l10341"></a><span class="lineno">10341</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l10342"></a><span class="lineno">10342</span>&#160;        {</div><div class="line"><a name="l10343"></a><span class="lineno">10343</span>&#160;            <span class="keywordflow">if</span>(srcBlockIndex &gt; 0)</div><div class="line"><a name="l10344"></a><span class="lineno">10344</span>&#160;            {</div><div class="line"><a name="l10345"></a><span class="lineno">10345</span>&#160;                --srcBlockIndex;</div><div class="line"><a name="l10346"></a><span class="lineno">10346</span>&#160;                srcAllocIndex = SIZE_MAX;</div><div class="line"><a name="l10347"></a><span class="lineno">10347</span>&#160;            }</div><div class="line"><a name="l10348"></a><span class="lineno">10348</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l10349"></a><span class="lineno">10349</span>&#160;            {</div><div class="line"><a name="l10350"></a><span class="lineno">10350</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10351"></a><span class="lineno">10351</span>&#160;            }</div><div class="line"><a name="l10352"></a><span class="lineno">10352</span>&#160;        }</div><div class="line"><a name="l10353"></a><span class="lineno">10353</span>&#160;    }</div><div class="line"><a name="l10354"></a><span class="lineno">10354</span>&#160;}</div><div class="line"><a name="l10355"></a><span class="lineno">10355</span>&#160;</div><div class="line"><a name="l10356"></a><span class="lineno">10356</span>&#160;VkResult VmaDefragmentator::Defragment(</div><div class="line"><a name="l10357"></a><span class="lineno">10357</span>&#160;    VkDeviceSize maxBytesToMove,</div><div class="line"><a name="l10358"></a><span class="lineno">10358</span>&#160;    uint32_t maxAllocationsToMove)</div><div class="line"><a name="l10359"></a><span class="lineno">10359</span>&#160;{</div><div class="line"><a name="l10360"></a><span class="lineno">10360</span>&#160;    <span class="keywordflow">if</span>(m_Allocations.empty())</div><div class="line"><a name="l10361"></a><span class="lineno">10361</span>&#160;    {</div><div class="line"><a name="l10362"></a><span class="lineno">10362</span>&#160;        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10363"></a><span class="lineno">10363</span>&#160;    }</div><div class="line"><a name="l10364"></a><span class="lineno">10364</span>&#160;</div><div class="line"><a name="l10365"></a><span class="lineno">10365</span>&#160;    <span class="comment">// Create block info for each block.</span></div><div class="line"><a name="l10366"></a><span class="lineno">10366</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> blockCount = m_pBlockVector-&gt;m_Blocks.size();</div><div class="line"><a name="l10367"></a><span class="lineno">10367</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; blockCount; ++blockIndex)</div><div class="line"><a name="l10368"></a><span class="lineno">10368</span>&#160;    {</div><div class="line"><a name="l10369"></a><span class="lineno">10369</span>&#160;        BlockInfo* pBlockInfo = vma_new(m_hAllocator, BlockInfo)(m_hAllocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l10370"></a><span class="lineno">10370</span>&#160;        pBlockInfo-&gt;m_pBlock = m_pBlockVector-&gt;m_Blocks[blockIndex];</div><div class="line"><a name="l10371"></a><span class="lineno">10371</span>&#160;        m_Blocks.push_back(pBlockInfo);</div><div class="line"><a name="l10372"></a><span class="lineno">10372</span>&#160;    }</div><div class="line"><a name="l10373"></a><span class="lineno">10373</span>&#160;</div><div class="line"><a name="l10374"></a><span class="lineno">10374</span>&#160;    <span class="comment">// Sort them by m_pBlock pointer value.</span></div><div class="line"><a name="l10375"></a><span class="lineno">10375</span>&#160;    VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockPointerLess());</div><div class="line"><a name="l10376"></a><span class="lineno">10376</span>&#160;</div><div class="line"><a name="l10377"></a><span class="lineno">10377</span>&#160;    <span class="comment">// Move allocation infos from m_Allocations to appropriate m_Blocks[memTypeIndex].m_Allocations.</span></div><div class="line"><a name="l10378"></a><span class="lineno">10378</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0, allocCount = m_Allocations.size(); blockIndex &lt; allocCount; ++blockIndex)</div><div class="line"><a name="l10379"></a><span class="lineno">10379</span>&#160;    {</div><div class="line"><a name="l10380"></a><span class="lineno">10380</span>&#160;        AllocationInfo&amp; allocInfo = m_Allocations[blockIndex];</div><div class="line"><a name="l10381"></a><span class="lineno">10381</span>&#160;        <span class="comment">// Now as we are inside VmaBlockVector::m_Mutex, we can make final check if this allocation was not lost.</span></div><div class="line"><a name="l10382"></a><span class="lineno">10382</span>&#160;        <span class="keywordflow">if</span>(allocInfo.m_hAllocation-&gt;GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l10383"></a><span class="lineno">10383</span>&#160;        {</div><div class="line"><a name="l10384"></a><span class="lineno">10384</span>&#160;            VmaDeviceMemoryBlock* pBlock = allocInfo.m_hAllocation-&gt;GetBlock();</div><div class="line"><a name="l10385"></a><span class="lineno">10385</span>&#160;            BlockInfoVector::iterator it = VmaBinaryFindFirstNotLess(m_Blocks.begin(), m_Blocks.end(), pBlock, BlockPointerLess());</div><div class="line"><a name="l10386"></a><span class="lineno">10386</span>&#160;            <span class="keywordflow">if</span>(it != m_Blocks.end() &amp;&amp; (*it)-&gt;m_pBlock == pBlock)</div><div class="line"><a name="l10387"></a><span class="lineno">10387</span>&#160;            {</div><div class="line"><a name="l10388"></a><span class="lineno">10388</span>&#160;                (*it)-&gt;m_Allocations.push_back(allocInfo);</div><div class="line"><a name="l10389"></a><span class="lineno">10389</span>&#160;            }</div><div class="line"><a name="l10390"></a><span class="lineno">10390</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l10391"></a><span class="lineno">10391</span>&#160;            {</div><div class="line"><a name="l10392"></a><span class="lineno">10392</span>&#160;                VMA_ASSERT(0);</div><div class="line"><a name="l10393"></a><span class="lineno">10393</span>&#160;            }</div><div class="line"><a name="l10394"></a><span class="lineno">10394</span>&#160;        }</div><div class="line"><a name="l10395"></a><span class="lineno">10395</span>&#160;    }</div><div class="line"><a name="l10396"></a><span class="lineno">10396</span>&#160;    m_Allocations.clear();</div><div class="line"><a name="l10397"></a><span class="lineno">10397</span>&#160;</div><div class="line"><a name="l10398"></a><span class="lineno">10398</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; blockCount; ++blockIndex)</div><div class="line"><a name="l10399"></a><span class="lineno">10399</span>&#160;    {</div><div class="line"><a name="l10400"></a><span class="lineno">10400</span>&#160;        BlockInfo* pBlockInfo = m_Blocks[blockIndex];</div><div class="line"><a name="l10401"></a><span class="lineno">10401</span>&#160;        pBlockInfo-&gt;CalcHasNonMovableAllocations();</div><div class="line"><a name="l10402"></a><span class="lineno">10402</span>&#160;        pBlockInfo-&gt;SortAllocationsBySizeDescecnding();</div><div class="line"><a name="l10403"></a><span class="lineno">10403</span>&#160;    }</div><div class="line"><a name="l10404"></a><span class="lineno">10404</span>&#160;</div><div class="line"><a name="l10405"></a><span class="lineno">10405</span>&#160;    <span class="comment">// Sort m_Blocks this time by the main criterium, from most &quot;destination&quot; to most &quot;source&quot; blocks.</span></div><div class="line"><a name="l10406"></a><span class="lineno">10406</span>&#160;    VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockInfoCompareMoveDestination());</div><div class="line"><a name="l10407"></a><span class="lineno">10407</span>&#160;</div><div class="line"><a name="l10408"></a><span class="lineno">10408</span>&#160;    <span class="comment">// Execute defragmentation rounds (the main part).</span></div><div class="line"><a name="l10409"></a><span class="lineno">10409</span>&#160;    VkResult result = VK_SUCCESS;</div><div class="line"><a name="l10410"></a><span class="lineno">10410</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> round = 0; (round &lt; 2) &amp;&amp; (result == VK_SUCCESS); ++round)</div><div class="line"><a name="l10411"></a><span class="lineno">10411</span>&#160;    {</div><div class="line"><a name="l10412"></a><span class="lineno">10412</span>&#160;        result = DefragmentRound(maxBytesToMove, maxAllocationsToMove);</div><div class="line"><a name="l10413"></a><span class="lineno">10413</span>&#160;    }</div><div class="line"><a name="l10414"></a><span class="lineno">10414</span>&#160;</div><div class="line"><a name="l10415"></a><span class="lineno">10415</span>&#160;    <span class="comment">// Unmap blocks that were mapped for defragmentation.</span></div><div class="line"><a name="l10416"></a><span class="lineno">10416</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> blockIndex = 0; blockIndex &lt; blockCount; ++blockIndex)</div><div class="line"><a name="l10417"></a><span class="lineno">10417</span>&#160;    {</div><div class="line"><a name="l10418"></a><span class="lineno">10418</span>&#160;        m_Blocks[blockIndex]-&gt;Unmap(m_hAllocator);</div><div class="line"><a name="l10419"></a><span class="lineno">10419</span>&#160;    }</div><div class="line"><a name="l10420"></a><span class="lineno">10420</span>&#160;</div><div class="line"><a name="l10421"></a><span class="lineno">10421</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l10422"></a><span class="lineno">10422</span>&#160;}</div><div class="line"><a name="l10423"></a><span class="lineno">10423</span>&#160;</div><div class="line"><a name="l10424"></a><span class="lineno">10424</span>&#160;<span class="keywordtype">bool</span> VmaDefragmentator::MoveMakesSense(</div><div class="line"><a name="l10425"></a><span class="lineno">10425</span>&#160;        <span class="keywordtype">size_t</span> dstBlockIndex, VkDeviceSize dstOffset,</div><div class="line"><a name="l10426"></a><span class="lineno">10426</span>&#160;        <span class="keywordtype">size_t</span> srcBlockIndex, VkDeviceSize srcOffset)</div><div class="line"><a name="l10427"></a><span class="lineno">10427</span>&#160;{</div><div class="line"><a name="l10428"></a><span class="lineno">10428</span>&#160;    <span class="keywordflow">if</span>(dstBlockIndex &lt; srcBlockIndex)</div><div class="line"><a name="l10429"></a><span class="lineno">10429</span>&#160;    {</div><div class="line"><a name="l10430"></a><span class="lineno">10430</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l10431"></a><span class="lineno">10431</span>&#160;    }</div><div class="line"><a name="l10432"></a><span class="lineno">10432</span>&#160;    <span class="keywordflow">if</span>(dstBlockIndex &gt; srcBlockIndex)</div><div class="line"><a name="l10433"></a><span class="lineno">10433</span>&#160;    {</div><div class="line"><a name="l10434"></a><span class="lineno">10434</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l10435"></a><span class="lineno">10435</span>&#160;    }</div><div class="line"><a name="l10436"></a><span class="lineno">10436</span>&#160;    <span class="keywordflow">if</span>(dstOffset &lt; srcOffset)</div><div class="line"><a name="l10437"></a><span class="lineno">10437</span>&#160;    {</div><div class="line"><a name="l10438"></a><span class="lineno">10438</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l10439"></a><span class="lineno">10439</span>&#160;    }</div><div class="line"><a name="l10440"></a><span class="lineno">10440</span>&#160;    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l10441"></a><span class="lineno">10441</span>&#160;}</div><div class="line"><a name="l10442"></a><span class="lineno">10442</span>&#160;</div><div class="line"><a name="l10444"></a><span class="lineno">10444</span>&#160;<span class="comment">// VmaRecorder</span></div><div class="line"><a name="l10445"></a><span class="lineno">10445</span>&#160;</div><div class="line"><a name="l10446"></a><span class="lineno">10446</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l10447"></a><span class="lineno">10447</span>&#160;</div><div class="line"><a name="l10448"></a><span class="lineno">10448</span>&#160;VmaRecorder::VmaRecorder() :</div><div class="line"><a name="l10449"></a><span class="lineno">10449</span>&#160;    m_UseMutex(true),</div><div class="line"><a name="l10450"></a><span class="lineno">10450</span>&#160;    m_Flags(0),</div><div class="line"><a name="l10451"></a><span class="lineno">10451</span>&#160;    m_File(VMA_NULL),</div><div class="line"><a name="l10452"></a><span class="lineno">10452</span>&#160;    m_Freq(INT64_MAX),</div><div class="line"><a name="l10453"></a><span class="lineno">10453</span>&#160;    m_StartCounter(INT64_MAX)</div><div class="line"><a name="l10454"></a><span class="lineno">10454</span>&#160;{</div><div class="line"><a name="l10455"></a><span class="lineno">10455</span>&#160;}</div><div class="line"><a name="l10456"></a><span class="lineno">10456</span>&#160;</div><div class="line"><a name="l10457"></a><span class="lineno">10457</span>&#160;VkResult VmaRecorder::Init(<span class="keyword">const</span> <a class="code" href="struct_vma_record_settings.html">VmaRecordSettings</a>&amp; settings, <span class="keywordtype">bool</span> useMutex)</div><div class="line"><a name="l10458"></a><span class="lineno">10458</span>&#160;{</div><div class="line"><a name="l10459"></a><span class="lineno">10459</span>&#160;    m_UseMutex = useMutex;</div><div class="line"><a name="l10460"></a><span class="lineno">10460</span>&#160;    m_Flags = settings.<a class="code" href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a">flags</a>;</div><div class="line"><a name="l10461"></a><span class="lineno">10461</span>&#160;</div><div class="line"><a name="l10462"></a><span class="lineno">10462</span>&#160;    QueryPerformanceFrequency((LARGE_INTEGER*)&amp;m_Freq);</div><div class="line"><a name="l10463"></a><span class="lineno">10463</span>&#160;    QueryPerformanceCounter((LARGE_INTEGER*)&amp;m_StartCounter);</div><div class="line"><a name="l10464"></a><span class="lineno">10464</span>&#160;</div><div class="line"><a name="l10465"></a><span class="lineno">10465</span>&#160;    <span class="comment">// Open file for writing.</span></div><div class="line"><a name="l10466"></a><span class="lineno">10466</span>&#160;    errno_t err = fopen_s(&amp;m_File, settings.<a class="code" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">pFilePath</a>, <span class="stringliteral">&quot;wb&quot;</span>);</div><div class="line"><a name="l10467"></a><span class="lineno">10467</span>&#160;    <span class="keywordflow">if</span>(err != 0)</div><div class="line"><a name="l10468"></a><span class="lineno">10468</span>&#160;    {</div><div class="line"><a name="l10469"></a><span class="lineno">10469</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_INITIALIZATION_FAILED;</div><div class="line"><a name="l10470"></a><span class="lineno">10470</span>&#160;    }</div><div class="line"><a name="l10471"></a><span class="lineno">10471</span>&#160;</div><div class="line"><a name="l10472"></a><span class="lineno">10472</span>&#160;    <span class="comment">// Write header.</span></div><div class="line"><a name="l10473"></a><span class="lineno">10473</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%s\n&quot;</span>, <span class="stringliteral">&quot;Vulkan Memory Allocator,Calls recording&quot;</span>);</div><div class="line"><a name="l10474"></a><span class="lineno">10474</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%s\n&quot;</span>, <span class="stringliteral">&quot;1,3&quot;</span>);</div><div class="line"><a name="l10475"></a><span class="lineno">10475</span>&#160;</div><div class="line"><a name="l10476"></a><span class="lineno">10476</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l10477"></a><span class="lineno">10477</span>&#160;}</div><div class="line"><a name="l10478"></a><span class="lineno">10478</span>&#160;</div><div class="line"><a name="l10479"></a><span class="lineno">10479</span>&#160;VmaRecorder::~VmaRecorder()</div><div class="line"><a name="l10480"></a><span class="lineno">10480</span>&#160;{</div><div class="line"><a name="l10481"></a><span class="lineno">10481</span>&#160;    <span class="keywordflow">if</span>(m_File != VMA_NULL)</div><div class="line"><a name="l10482"></a><span class="lineno">10482</span>&#160;    {</div><div class="line"><a name="l10483"></a><span class="lineno">10483</span>&#160;        fclose(m_File);</div><div class="line"><a name="l10484"></a><span class="lineno">10484</span>&#160;    }</div><div class="line"><a name="l10485"></a><span class="lineno">10485</span>&#160;}</div><div class="line"><a name="l10486"></a><span class="lineno">10486</span>&#160;</div><div class="line"><a name="l10487"></a><span class="lineno">10487</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordCreateAllocator(uint32_t frameIndex)</div><div class="line"><a name="l10488"></a><span class="lineno">10488</span>&#160;{</div><div class="line"><a name="l10489"></a><span class="lineno">10489</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10490"></a><span class="lineno">10490</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10491"></a><span class="lineno">10491</span>&#160;</div><div class="line"><a name="l10492"></a><span class="lineno">10492</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10493"></a><span class="lineno">10493</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaCreateAllocator\n&quot;</span>, callParams.threadId, callParams.time, frameIndex);</div><div class="line"><a name="l10494"></a><span class="lineno">10494</span>&#160;    Flush();</div><div class="line"><a name="l10495"></a><span class="lineno">10495</span>&#160;}</div><div class="line"><a name="l10496"></a><span class="lineno">10496</span>&#160;</div><div class="line"><a name="l10497"></a><span class="lineno">10497</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordDestroyAllocator(uint32_t frameIndex)</div><div class="line"><a name="l10498"></a><span class="lineno">10498</span>&#160;{</div><div class="line"><a name="l10499"></a><span class="lineno">10499</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10500"></a><span class="lineno">10500</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10501"></a><span class="lineno">10501</span>&#160;</div><div class="line"><a name="l10502"></a><span class="lineno">10502</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10503"></a><span class="lineno">10503</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaDestroyAllocator\n&quot;</span>, callParams.threadId, callParams.time, frameIndex);</div><div class="line"><a name="l10504"></a><span class="lineno">10504</span>&#160;    Flush();</div><div class="line"><a name="l10505"></a><span class="lineno">10505</span>&#160;}</div><div class="line"><a name="l10506"></a><span class="lineno">10506</span>&#160;</div><div class="line"><a name="l10507"></a><span class="lineno">10507</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordCreatePool(uint32_t frameIndex, <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>&amp; createInfo, <a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l10508"></a><span class="lineno">10508</span>&#160;{</div><div class="line"><a name="l10509"></a><span class="lineno">10509</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10510"></a><span class="lineno">10510</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10511"></a><span class="lineno">10511</span>&#160;</div><div class="line"><a name="l10512"></a><span class="lineno">10512</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10513"></a><span class="lineno">10513</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaCreatePool,%u,%u,%llu,%llu,%llu,%u,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10514"></a><span class="lineno">10514</span>&#160;        createInfo.<a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a>,</div><div class="line"><a name="l10515"></a><span class="lineno">10515</span>&#160;        createInfo.<a class="code" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">flags</a>,</div><div class="line"><a name="l10516"></a><span class="lineno">10516</span>&#160;        createInfo.<a class="code" href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">blockSize</a>,</div><div class="line"><a name="l10517"></a><span class="lineno">10517</span>&#160;        createInfo.<a class="code" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae">minBlockCount</a>,</div><div class="line"><a name="l10518"></a><span class="lineno">10518</span>&#160;        createInfo.<a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a>,</div><div class="line"><a name="l10519"></a><span class="lineno">10519</span>&#160;        createInfo.<a class="code" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa">frameInUseCount</a>,</div><div class="line"><a name="l10520"></a><span class="lineno">10520</span>&#160;        pool);</div><div class="line"><a name="l10521"></a><span class="lineno">10521</span>&#160;    Flush();</div><div class="line"><a name="l10522"></a><span class="lineno">10522</span>&#160;}</div><div class="line"><a name="l10523"></a><span class="lineno">10523</span>&#160;</div><div class="line"><a name="l10524"></a><span class="lineno">10524</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordDestroyPool(uint32_t frameIndex, <a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l10525"></a><span class="lineno">10525</span>&#160;{</div><div class="line"><a name="l10526"></a><span class="lineno">10526</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10527"></a><span class="lineno">10527</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10528"></a><span class="lineno">10528</span>&#160;</div><div class="line"><a name="l10529"></a><span class="lineno">10529</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10530"></a><span class="lineno">10530</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaDestroyPool,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10531"></a><span class="lineno">10531</span>&#160;        pool);</div><div class="line"><a name="l10532"></a><span class="lineno">10532</span>&#160;    Flush();</div><div class="line"><a name="l10533"></a><span class="lineno">10533</span>&#160;}</div><div class="line"><a name="l10534"></a><span class="lineno">10534</span>&#160;</div><div class="line"><a name="l10535"></a><span class="lineno">10535</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordAllocateMemory(uint32_t frameIndex,</div><div class="line"><a name="l10536"></a><span class="lineno">10536</span>&#160;        <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l10537"></a><span class="lineno">10537</span>&#160;        <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l10538"></a><span class="lineno">10538</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10539"></a><span class="lineno">10539</span>&#160;{</div><div class="line"><a name="l10540"></a><span class="lineno">10540</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10541"></a><span class="lineno">10541</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10542"></a><span class="lineno">10542</span>&#160;</div><div class="line"><a name="l10543"></a><span class="lineno">10543</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10544"></a><span class="lineno">10544</span>&#160;    UserDataString userDataStr(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>, createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l10545"></a><span class="lineno">10545</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaAllocateMemory,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,%p,%s\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10546"></a><span class="lineno">10546</span>&#160;        vkMemReq.size,</div><div class="line"><a name="l10547"></a><span class="lineno">10547</span>&#160;        vkMemReq.alignment,</div><div class="line"><a name="l10548"></a><span class="lineno">10548</span>&#160;        vkMemReq.memoryTypeBits,</div><div class="line"><a name="l10549"></a><span class="lineno">10549</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>,</div><div class="line"><a name="l10550"></a><span class="lineno">10550</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>,</div><div class="line"><a name="l10551"></a><span class="lineno">10551</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>,</div><div class="line"><a name="l10552"></a><span class="lineno">10552</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>,</div><div class="line"><a name="l10553"></a><span class="lineno">10553</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>,</div><div class="line"><a name="l10554"></a><span class="lineno">10554</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>,</div><div class="line"><a name="l10555"></a><span class="lineno">10555</span>&#160;        allocation,</div><div class="line"><a name="l10556"></a><span class="lineno">10556</span>&#160;        userDataStr.GetString());</div><div class="line"><a name="l10557"></a><span class="lineno">10557</span>&#160;    Flush();</div><div class="line"><a name="l10558"></a><span class="lineno">10558</span>&#160;}</div><div class="line"><a name="l10559"></a><span class="lineno">10559</span>&#160;</div><div class="line"><a name="l10560"></a><span class="lineno">10560</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordAllocateMemoryForBuffer(uint32_t frameIndex,</div><div class="line"><a name="l10561"></a><span class="lineno">10561</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l10562"></a><span class="lineno">10562</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l10563"></a><span class="lineno">10563</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l10564"></a><span class="lineno">10564</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l10565"></a><span class="lineno">10565</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10566"></a><span class="lineno">10566</span>&#160;{</div><div class="line"><a name="l10567"></a><span class="lineno">10567</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10568"></a><span class="lineno">10568</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10569"></a><span class="lineno">10569</span>&#160;</div><div class="line"><a name="l10570"></a><span class="lineno">10570</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10571"></a><span class="lineno">10571</span>&#160;    UserDataString userDataStr(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>, createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l10572"></a><span class="lineno">10572</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaAllocateMemoryForBuffer,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10573"></a><span class="lineno">10573</span>&#160;        vkMemReq.size,</div><div class="line"><a name="l10574"></a><span class="lineno">10574</span>&#160;        vkMemReq.alignment,</div><div class="line"><a name="l10575"></a><span class="lineno">10575</span>&#160;        vkMemReq.memoryTypeBits,</div><div class="line"><a name="l10576"></a><span class="lineno">10576</span>&#160;        requiresDedicatedAllocation ? 1 : 0,</div><div class="line"><a name="l10577"></a><span class="lineno">10577</span>&#160;        prefersDedicatedAllocation ? 1 : 0,</div><div class="line"><a name="l10578"></a><span class="lineno">10578</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>,</div><div class="line"><a name="l10579"></a><span class="lineno">10579</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>,</div><div class="line"><a name="l10580"></a><span class="lineno">10580</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>,</div><div class="line"><a name="l10581"></a><span class="lineno">10581</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>,</div><div class="line"><a name="l10582"></a><span class="lineno">10582</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>,</div><div class="line"><a name="l10583"></a><span class="lineno">10583</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>,</div><div class="line"><a name="l10584"></a><span class="lineno">10584</span>&#160;        allocation,</div><div class="line"><a name="l10585"></a><span class="lineno">10585</span>&#160;        userDataStr.GetString());</div><div class="line"><a name="l10586"></a><span class="lineno">10586</span>&#160;    Flush();</div><div class="line"><a name="l10587"></a><span class="lineno">10587</span>&#160;}</div><div class="line"><a name="l10588"></a><span class="lineno">10588</span>&#160;</div><div class="line"><a name="l10589"></a><span class="lineno">10589</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordAllocateMemoryForImage(uint32_t frameIndex,</div><div class="line"><a name="l10590"></a><span class="lineno">10590</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l10591"></a><span class="lineno">10591</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l10592"></a><span class="lineno">10592</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l10593"></a><span class="lineno">10593</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l10594"></a><span class="lineno">10594</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10595"></a><span class="lineno">10595</span>&#160;{</div><div class="line"><a name="l10596"></a><span class="lineno">10596</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10597"></a><span class="lineno">10597</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10598"></a><span class="lineno">10598</span>&#160;</div><div class="line"><a name="l10599"></a><span class="lineno">10599</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10600"></a><span class="lineno">10600</span>&#160;    UserDataString userDataStr(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>, createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l10601"></a><span class="lineno">10601</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaAllocateMemoryForImage,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10602"></a><span class="lineno">10602</span>&#160;        vkMemReq.size,</div><div class="line"><a name="l10603"></a><span class="lineno">10603</span>&#160;        vkMemReq.alignment,</div><div class="line"><a name="l10604"></a><span class="lineno">10604</span>&#160;        vkMemReq.memoryTypeBits,</div><div class="line"><a name="l10605"></a><span class="lineno">10605</span>&#160;        requiresDedicatedAllocation ? 1 : 0,</div><div class="line"><a name="l10606"></a><span class="lineno">10606</span>&#160;        prefersDedicatedAllocation ? 1 : 0,</div><div class="line"><a name="l10607"></a><span class="lineno">10607</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>,</div><div class="line"><a name="l10608"></a><span class="lineno">10608</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>,</div><div class="line"><a name="l10609"></a><span class="lineno">10609</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>,</div><div class="line"><a name="l10610"></a><span class="lineno">10610</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>,</div><div class="line"><a name="l10611"></a><span class="lineno">10611</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>,</div><div class="line"><a name="l10612"></a><span class="lineno">10612</span>&#160;        createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>,</div><div class="line"><a name="l10613"></a><span class="lineno">10613</span>&#160;        allocation,</div><div class="line"><a name="l10614"></a><span class="lineno">10614</span>&#160;        userDataStr.GetString());</div><div class="line"><a name="l10615"></a><span class="lineno">10615</span>&#160;    Flush();</div><div class="line"><a name="l10616"></a><span class="lineno">10616</span>&#160;}</div><div class="line"><a name="l10617"></a><span class="lineno">10617</span>&#160;</div><div class="line"><a name="l10618"></a><span class="lineno">10618</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordFreeMemory(uint32_t frameIndex,</div><div class="line"><a name="l10619"></a><span class="lineno">10619</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10620"></a><span class="lineno">10620</span>&#160;{</div><div class="line"><a name="l10621"></a><span class="lineno">10621</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10622"></a><span class="lineno">10622</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10623"></a><span class="lineno">10623</span>&#160;</div><div class="line"><a name="l10624"></a><span class="lineno">10624</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10625"></a><span class="lineno">10625</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaFreeMemory,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10626"></a><span class="lineno">10626</span>&#160;        allocation);</div><div class="line"><a name="l10627"></a><span class="lineno">10627</span>&#160;    Flush();</div><div class="line"><a name="l10628"></a><span class="lineno">10628</span>&#160;}</div><div class="line"><a name="l10629"></a><span class="lineno">10629</span>&#160;</div><div class="line"><a name="l10630"></a><span class="lineno">10630</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordSetAllocationUserData(uint32_t frameIndex,</div><div class="line"><a name="l10631"></a><span class="lineno">10631</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l10632"></a><span class="lineno">10632</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">void</span>* pUserData)</div><div class="line"><a name="l10633"></a><span class="lineno">10633</span>&#160;{</div><div class="line"><a name="l10634"></a><span class="lineno">10634</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10635"></a><span class="lineno">10635</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10636"></a><span class="lineno">10636</span>&#160;</div><div class="line"><a name="l10637"></a><span class="lineno">10637</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10638"></a><span class="lineno">10638</span>&#160;    UserDataString userDataStr(</div><div class="line"><a name="l10639"></a><span class="lineno">10639</span>&#160;        allocation-&gt;IsUserDataString() ? <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a> : 0,</div><div class="line"><a name="l10640"></a><span class="lineno">10640</span>&#160;        pUserData);</div><div class="line"><a name="l10641"></a><span class="lineno">10641</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaSetAllocationUserData,%p,%s\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10642"></a><span class="lineno">10642</span>&#160;        allocation,</div><div class="line"><a name="l10643"></a><span class="lineno">10643</span>&#160;        userDataStr.GetString());</div><div class="line"><a name="l10644"></a><span class="lineno">10644</span>&#160;    Flush();</div><div class="line"><a name="l10645"></a><span class="lineno">10645</span>&#160;}</div><div class="line"><a name="l10646"></a><span class="lineno">10646</span>&#160;</div><div class="line"><a name="l10647"></a><span class="lineno">10647</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordCreateLostAllocation(uint32_t frameIndex,</div><div class="line"><a name="l10648"></a><span class="lineno">10648</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10649"></a><span class="lineno">10649</span>&#160;{</div><div class="line"><a name="l10650"></a><span class="lineno">10650</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10651"></a><span class="lineno">10651</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10652"></a><span class="lineno">10652</span>&#160;</div><div class="line"><a name="l10653"></a><span class="lineno">10653</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10654"></a><span class="lineno">10654</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaCreateLostAllocation,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10655"></a><span class="lineno">10655</span>&#160;        allocation);</div><div class="line"><a name="l10656"></a><span class="lineno">10656</span>&#160;    Flush();</div><div class="line"><a name="l10657"></a><span class="lineno">10657</span>&#160;}</div><div class="line"><a name="l10658"></a><span class="lineno">10658</span>&#160;</div><div class="line"><a name="l10659"></a><span class="lineno">10659</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordMapMemory(uint32_t frameIndex,</div><div class="line"><a name="l10660"></a><span class="lineno">10660</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10661"></a><span class="lineno">10661</span>&#160;{</div><div class="line"><a name="l10662"></a><span class="lineno">10662</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10663"></a><span class="lineno">10663</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10664"></a><span class="lineno">10664</span>&#160;</div><div class="line"><a name="l10665"></a><span class="lineno">10665</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10666"></a><span class="lineno">10666</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaMapMemory,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10667"></a><span class="lineno">10667</span>&#160;        allocation);</div><div class="line"><a name="l10668"></a><span class="lineno">10668</span>&#160;    Flush();</div><div class="line"><a name="l10669"></a><span class="lineno">10669</span>&#160;}</div><div class="line"><a name="l10670"></a><span class="lineno">10670</span>&#160;</div><div class="line"><a name="l10671"></a><span class="lineno">10671</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordUnmapMemory(uint32_t frameIndex,</div><div class="line"><a name="l10672"></a><span class="lineno">10672</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10673"></a><span class="lineno">10673</span>&#160;{</div><div class="line"><a name="l10674"></a><span class="lineno">10674</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10675"></a><span class="lineno">10675</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10676"></a><span class="lineno">10676</span>&#160;</div><div class="line"><a name="l10677"></a><span class="lineno">10677</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10678"></a><span class="lineno">10678</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaUnmapMemory,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10679"></a><span class="lineno">10679</span>&#160;        allocation);</div><div class="line"><a name="l10680"></a><span class="lineno">10680</span>&#160;    Flush();</div><div class="line"><a name="l10681"></a><span class="lineno">10681</span>&#160;}</div><div class="line"><a name="l10682"></a><span class="lineno">10682</span>&#160;</div><div class="line"><a name="l10683"></a><span class="lineno">10683</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordFlushAllocation(uint32_t frameIndex,</div><div class="line"><a name="l10684"></a><span class="lineno">10684</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size)</div><div class="line"><a name="l10685"></a><span class="lineno">10685</span>&#160;{</div><div class="line"><a name="l10686"></a><span class="lineno">10686</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10687"></a><span class="lineno">10687</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10688"></a><span class="lineno">10688</span>&#160;</div><div class="line"><a name="l10689"></a><span class="lineno">10689</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10690"></a><span class="lineno">10690</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaFlushAllocation,%p,%llu,%llu\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10691"></a><span class="lineno">10691</span>&#160;        allocation,</div><div class="line"><a name="l10692"></a><span class="lineno">10692</span>&#160;        offset,</div><div class="line"><a name="l10693"></a><span class="lineno">10693</span>&#160;        size);</div><div class="line"><a name="l10694"></a><span class="lineno">10694</span>&#160;    Flush();</div><div class="line"><a name="l10695"></a><span class="lineno">10695</span>&#160;}</div><div class="line"><a name="l10696"></a><span class="lineno">10696</span>&#160;</div><div class="line"><a name="l10697"></a><span class="lineno">10697</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordInvalidateAllocation(uint32_t frameIndex,</div><div class="line"><a name="l10698"></a><span class="lineno">10698</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size)</div><div class="line"><a name="l10699"></a><span class="lineno">10699</span>&#160;{</div><div class="line"><a name="l10700"></a><span class="lineno">10700</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10701"></a><span class="lineno">10701</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10702"></a><span class="lineno">10702</span>&#160;</div><div class="line"><a name="l10703"></a><span class="lineno">10703</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10704"></a><span class="lineno">10704</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaInvalidateAllocation,%p,%llu,%llu\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10705"></a><span class="lineno">10705</span>&#160;        allocation,</div><div class="line"><a name="l10706"></a><span class="lineno">10706</span>&#160;        offset,</div><div class="line"><a name="l10707"></a><span class="lineno">10707</span>&#160;        size);</div><div class="line"><a name="l10708"></a><span class="lineno">10708</span>&#160;    Flush();</div><div class="line"><a name="l10709"></a><span class="lineno">10709</span>&#160;}</div><div class="line"><a name="l10710"></a><span class="lineno">10710</span>&#160;</div><div class="line"><a name="l10711"></a><span class="lineno">10711</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordCreateBuffer(uint32_t frameIndex,</div><div class="line"><a name="l10712"></a><span class="lineno">10712</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo&amp; bufCreateInfo,</div><div class="line"><a name="l10713"></a><span class="lineno">10713</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; allocCreateInfo,</div><div class="line"><a name="l10714"></a><span class="lineno">10714</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10715"></a><span class="lineno">10715</span>&#160;{</div><div class="line"><a name="l10716"></a><span class="lineno">10716</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10717"></a><span class="lineno">10717</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10718"></a><span class="lineno">10718</span>&#160;</div><div class="line"><a name="l10719"></a><span class="lineno">10719</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10720"></a><span class="lineno">10720</span>&#160;    UserDataString userDataStr(allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>, allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l10721"></a><span class="lineno">10721</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaCreateBuffer,%u,%llu,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10722"></a><span class="lineno">10722</span>&#160;        bufCreateInfo.flags,</div><div class="line"><a name="l10723"></a><span class="lineno">10723</span>&#160;        bufCreateInfo.size,</div><div class="line"><a name="l10724"></a><span class="lineno">10724</span>&#160;        bufCreateInfo.usage,</div><div class="line"><a name="l10725"></a><span class="lineno">10725</span>&#160;        bufCreateInfo.sharingMode,</div><div class="line"><a name="l10726"></a><span class="lineno">10726</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>,</div><div class="line"><a name="l10727"></a><span class="lineno">10727</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>,</div><div class="line"><a name="l10728"></a><span class="lineno">10728</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>,</div><div class="line"><a name="l10729"></a><span class="lineno">10729</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>,</div><div class="line"><a name="l10730"></a><span class="lineno">10730</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>,</div><div class="line"><a name="l10731"></a><span class="lineno">10731</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>,</div><div class="line"><a name="l10732"></a><span class="lineno">10732</span>&#160;        allocation,</div><div class="line"><a name="l10733"></a><span class="lineno">10733</span>&#160;        userDataStr.GetString());</div><div class="line"><a name="l10734"></a><span class="lineno">10734</span>&#160;    Flush();</div><div class="line"><a name="l10735"></a><span class="lineno">10735</span>&#160;}</div><div class="line"><a name="l10736"></a><span class="lineno">10736</span>&#160;</div><div class="line"><a name="l10737"></a><span class="lineno">10737</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordCreateImage(uint32_t frameIndex,</div><div class="line"><a name="l10738"></a><span class="lineno">10738</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo&amp; imageCreateInfo,</div><div class="line"><a name="l10739"></a><span class="lineno">10739</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; allocCreateInfo,</div><div class="line"><a name="l10740"></a><span class="lineno">10740</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10741"></a><span class="lineno">10741</span>&#160;{</div><div class="line"><a name="l10742"></a><span class="lineno">10742</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10743"></a><span class="lineno">10743</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10744"></a><span class="lineno">10744</span>&#160;</div><div class="line"><a name="l10745"></a><span class="lineno">10745</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10746"></a><span class="lineno">10746</span>&#160;    UserDataString userDataStr(allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>, allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>);</div><div class="line"><a name="l10747"></a><span class="lineno">10747</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaCreateImage,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10748"></a><span class="lineno">10748</span>&#160;        imageCreateInfo.flags,</div><div class="line"><a name="l10749"></a><span class="lineno">10749</span>&#160;        imageCreateInfo.imageType,</div><div class="line"><a name="l10750"></a><span class="lineno">10750</span>&#160;        imageCreateInfo.format,</div><div class="line"><a name="l10751"></a><span class="lineno">10751</span>&#160;        imageCreateInfo.extent.width,</div><div class="line"><a name="l10752"></a><span class="lineno">10752</span>&#160;        imageCreateInfo.extent.height,</div><div class="line"><a name="l10753"></a><span class="lineno">10753</span>&#160;        imageCreateInfo.extent.depth,</div><div class="line"><a name="l10754"></a><span class="lineno">10754</span>&#160;        imageCreateInfo.mipLevels,</div><div class="line"><a name="l10755"></a><span class="lineno">10755</span>&#160;        imageCreateInfo.arrayLayers,</div><div class="line"><a name="l10756"></a><span class="lineno">10756</span>&#160;        imageCreateInfo.samples,</div><div class="line"><a name="l10757"></a><span class="lineno">10757</span>&#160;        imageCreateInfo.tiling,</div><div class="line"><a name="l10758"></a><span class="lineno">10758</span>&#160;        imageCreateInfo.usage,</div><div class="line"><a name="l10759"></a><span class="lineno">10759</span>&#160;        imageCreateInfo.sharingMode,</div><div class="line"><a name="l10760"></a><span class="lineno">10760</span>&#160;        imageCreateInfo.initialLayout,</div><div class="line"><a name="l10761"></a><span class="lineno">10761</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a>,</div><div class="line"><a name="l10762"></a><span class="lineno">10762</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>,</div><div class="line"><a name="l10763"></a><span class="lineno">10763</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>,</div><div class="line"><a name="l10764"></a><span class="lineno">10764</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>,</div><div class="line"><a name="l10765"></a><span class="lineno">10765</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>,</div><div class="line"><a name="l10766"></a><span class="lineno">10766</span>&#160;        allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>,</div><div class="line"><a name="l10767"></a><span class="lineno">10767</span>&#160;        allocation,</div><div class="line"><a name="l10768"></a><span class="lineno">10768</span>&#160;        userDataStr.GetString());</div><div class="line"><a name="l10769"></a><span class="lineno">10769</span>&#160;    Flush();</div><div class="line"><a name="l10770"></a><span class="lineno">10770</span>&#160;}</div><div class="line"><a name="l10771"></a><span class="lineno">10771</span>&#160;</div><div class="line"><a name="l10772"></a><span class="lineno">10772</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordDestroyBuffer(uint32_t frameIndex,</div><div class="line"><a name="l10773"></a><span class="lineno">10773</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10774"></a><span class="lineno">10774</span>&#160;{</div><div class="line"><a name="l10775"></a><span class="lineno">10775</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10776"></a><span class="lineno">10776</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10777"></a><span class="lineno">10777</span>&#160;</div><div class="line"><a name="l10778"></a><span class="lineno">10778</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10779"></a><span class="lineno">10779</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaDestroyBuffer,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10780"></a><span class="lineno">10780</span>&#160;        allocation);</div><div class="line"><a name="l10781"></a><span class="lineno">10781</span>&#160;    Flush();</div><div class="line"><a name="l10782"></a><span class="lineno">10782</span>&#160;}</div><div class="line"><a name="l10783"></a><span class="lineno">10783</span>&#160;</div><div class="line"><a name="l10784"></a><span class="lineno">10784</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordDestroyImage(uint32_t frameIndex,</div><div class="line"><a name="l10785"></a><span class="lineno">10785</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10786"></a><span class="lineno">10786</span>&#160;{</div><div class="line"><a name="l10787"></a><span class="lineno">10787</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10788"></a><span class="lineno">10788</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10789"></a><span class="lineno">10789</span>&#160;</div><div class="line"><a name="l10790"></a><span class="lineno">10790</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10791"></a><span class="lineno">10791</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaDestroyImage,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10792"></a><span class="lineno">10792</span>&#160;        allocation);</div><div class="line"><a name="l10793"></a><span class="lineno">10793</span>&#160;    Flush();</div><div class="line"><a name="l10794"></a><span class="lineno">10794</span>&#160;}</div><div class="line"><a name="l10795"></a><span class="lineno">10795</span>&#160;</div><div class="line"><a name="l10796"></a><span class="lineno">10796</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordTouchAllocation(uint32_t frameIndex,</div><div class="line"><a name="l10797"></a><span class="lineno">10797</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10798"></a><span class="lineno">10798</span>&#160;{</div><div class="line"><a name="l10799"></a><span class="lineno">10799</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10800"></a><span class="lineno">10800</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10801"></a><span class="lineno">10801</span>&#160;</div><div class="line"><a name="l10802"></a><span class="lineno">10802</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10803"></a><span class="lineno">10803</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaTouchAllocation,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10804"></a><span class="lineno">10804</span>&#160;        allocation);</div><div class="line"><a name="l10805"></a><span class="lineno">10805</span>&#160;    Flush();</div><div class="line"><a name="l10806"></a><span class="lineno">10806</span>&#160;}</div><div class="line"><a name="l10807"></a><span class="lineno">10807</span>&#160;</div><div class="line"><a name="l10808"></a><span class="lineno">10808</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordGetAllocationInfo(uint32_t frameIndex,</div><div class="line"><a name="l10809"></a><span class="lineno">10809</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l10810"></a><span class="lineno">10810</span>&#160;{</div><div class="line"><a name="l10811"></a><span class="lineno">10811</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10812"></a><span class="lineno">10812</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10813"></a><span class="lineno">10813</span>&#160;</div><div class="line"><a name="l10814"></a><span class="lineno">10814</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10815"></a><span class="lineno">10815</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaGetAllocationInfo,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10816"></a><span class="lineno">10816</span>&#160;        allocation);</div><div class="line"><a name="l10817"></a><span class="lineno">10817</span>&#160;    Flush();</div><div class="line"><a name="l10818"></a><span class="lineno">10818</span>&#160;}</div><div class="line"><a name="l10819"></a><span class="lineno">10819</span>&#160;</div><div class="line"><a name="l10820"></a><span class="lineno">10820</span>&#160;<span class="keywordtype">void</span> VmaRecorder::RecordMakePoolAllocationsLost(uint32_t frameIndex,</div><div class="line"><a name="l10821"></a><span class="lineno">10821</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l10822"></a><span class="lineno">10822</span>&#160;{</div><div class="line"><a name="l10823"></a><span class="lineno">10823</span>&#160;    CallParams callParams;</div><div class="line"><a name="l10824"></a><span class="lineno">10824</span>&#160;    GetBasicParams(callParams);</div><div class="line"><a name="l10825"></a><span class="lineno">10825</span>&#160;</div><div class="line"><a name="l10826"></a><span class="lineno">10826</span>&#160;    VmaMutexLock lock(m_FileMutex, m_UseMutex);</div><div class="line"><a name="l10827"></a><span class="lineno">10827</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;%u,%.3f,%u,vmaMakePoolAllocationsLost,%p\n&quot;</span>, callParams.threadId, callParams.time, frameIndex,</div><div class="line"><a name="l10828"></a><span class="lineno">10828</span>&#160;        pool);</div><div class="line"><a name="l10829"></a><span class="lineno">10829</span>&#160;    Flush();</div><div class="line"><a name="l10830"></a><span class="lineno">10830</span>&#160;}</div><div class="line"><a name="l10831"></a><span class="lineno">10831</span>&#160;</div><div class="line"><a name="l10832"></a><span class="lineno">10832</span>&#160;VmaRecorder::UserDataString::UserDataString(<a class="code" href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a> allocFlags, <span class="keyword">const</span> <span class="keywordtype">void</span>* pUserData)</div><div class="line"><a name="l10833"></a><span class="lineno">10833</span>&#160;{</div><div class="line"><a name="l10834"></a><span class="lineno">10834</span>&#160;    <span class="keywordflow">if</span>(pUserData != VMA_NULL)</div><div class="line"><a name="l10835"></a><span class="lineno">10835</span>&#160;    {</div><div class="line"><a name="l10836"></a><span class="lineno">10836</span>&#160;        <span class="keywordflow">if</span>((allocFlags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0)</div><div class="line"><a name="l10837"></a><span class="lineno">10837</span>&#160;        {</div><div class="line"><a name="l10838"></a><span class="lineno">10838</span>&#160;            m_Str = (<span class="keyword">const</span> <span class="keywordtype">char</span>*)pUserData;</div><div class="line"><a name="l10839"></a><span class="lineno">10839</span>&#160;        }</div><div class="line"><a name="l10840"></a><span class="lineno">10840</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l10841"></a><span class="lineno">10841</span>&#160;        {</div><div class="line"><a name="l10842"></a><span class="lineno">10842</span>&#160;            sprintf_s(m_PtrStr, <span class="stringliteral">&quot;%p&quot;</span>, pUserData);</div><div class="line"><a name="l10843"></a><span class="lineno">10843</span>&#160;            m_Str = m_PtrStr;</div><div class="line"><a name="l10844"></a><span class="lineno">10844</span>&#160;        }</div><div class="line"><a name="l10845"></a><span class="lineno">10845</span>&#160;    }</div><div class="line"><a name="l10846"></a><span class="lineno">10846</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l10847"></a><span class="lineno">10847</span>&#160;    {</div><div class="line"><a name="l10848"></a><span class="lineno">10848</span>&#160;        m_Str = <span class="stringliteral">&quot;&quot;</span>;</div><div class="line"><a name="l10849"></a><span class="lineno">10849</span>&#160;    }</div><div class="line"><a name="l10850"></a><span class="lineno">10850</span>&#160;}</div><div class="line"><a name="l10851"></a><span class="lineno">10851</span>&#160;</div><div class="line"><a name="l10852"></a><span class="lineno">10852</span>&#160;<span class="keywordtype">void</span> VmaRecorder::WriteConfiguration(</div><div class="line"><a name="l10853"></a><span class="lineno">10853</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceProperties&amp; devProps,</div><div class="line"><a name="l10854"></a><span class="lineno">10854</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceMemoryProperties&amp; memProps,</div><div class="line"><a name="l10855"></a><span class="lineno">10855</span>&#160;    <span class="keywordtype">bool</span> dedicatedAllocationExtensionEnabled)</div><div class="line"><a name="l10856"></a><span class="lineno">10856</span>&#160;{</div><div class="line"><a name="l10857"></a><span class="lineno">10857</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Config,Begin\n&quot;</span>);</div><div class="line"><a name="l10858"></a><span class="lineno">10858</span>&#160;</div><div class="line"><a name="l10859"></a><span class="lineno">10859</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDevice,apiVersion,%u\n&quot;</span>, devProps.apiVersion);</div><div class="line"><a name="l10860"></a><span class="lineno">10860</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDevice,driverVersion,%u\n&quot;</span>, devProps.driverVersion);</div><div class="line"><a name="l10861"></a><span class="lineno">10861</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDevice,vendorID,%u\n&quot;</span>, devProps.vendorID);</div><div class="line"><a name="l10862"></a><span class="lineno">10862</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDevice,deviceID,%u\n&quot;</span>, devProps.deviceID);</div><div class="line"><a name="l10863"></a><span class="lineno">10863</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDevice,deviceType,%u\n&quot;</span>, devProps.deviceType);</div><div class="line"><a name="l10864"></a><span class="lineno">10864</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDevice,deviceName,%s\n&quot;</span>, devProps.deviceName);</div><div class="line"><a name="l10865"></a><span class="lineno">10865</span>&#160;</div><div class="line"><a name="l10866"></a><span class="lineno">10866</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceLimits,maxMemoryAllocationCount,%u\n&quot;</span>, devProps.limits.maxMemoryAllocationCount);</div><div class="line"><a name="l10867"></a><span class="lineno">10867</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceLimits,bufferImageGranularity,%llu\n&quot;</span>, devProps.limits.bufferImageGranularity);</div><div class="line"><a name="l10868"></a><span class="lineno">10868</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceLimits,nonCoherentAtomSize,%llu\n&quot;</span>, devProps.limits.nonCoherentAtomSize);</div><div class="line"><a name="l10869"></a><span class="lineno">10869</span>&#160;</div><div class="line"><a name="l10870"></a><span class="lineno">10870</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceMemory,HeapCount,%u\n&quot;</span>, memProps.memoryHeapCount);</div><div class="line"><a name="l10871"></a><span class="lineno">10871</span>&#160;    <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; memProps.memoryHeapCount; ++i)</div><div class="line"><a name="l10872"></a><span class="lineno">10872</span>&#160;    {</div><div class="line"><a name="l10873"></a><span class="lineno">10873</span>&#160;        fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceMemory,Heap,%u,size,%llu\n&quot;</span>, i, memProps.memoryHeaps[i].size);</div><div class="line"><a name="l10874"></a><span class="lineno">10874</span>&#160;        fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceMemory,Heap,%u,flags,%u\n&quot;</span>, i, memProps.memoryHeaps[i].flags);</div><div class="line"><a name="l10875"></a><span class="lineno">10875</span>&#160;    }</div><div class="line"><a name="l10876"></a><span class="lineno">10876</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceMemory,TypeCount,%u\n&quot;</span>, memProps.memoryTypeCount);</div><div class="line"><a name="l10877"></a><span class="lineno">10877</span>&#160;    <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; memProps.memoryTypeCount; ++i)</div><div class="line"><a name="l10878"></a><span class="lineno">10878</span>&#160;    {</div><div class="line"><a name="l10879"></a><span class="lineno">10879</span>&#160;        fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceMemory,Type,%u,heapIndex,%u\n&quot;</span>, i, memProps.memoryTypes[i].heapIndex);</div><div class="line"><a name="l10880"></a><span class="lineno">10880</span>&#160;        fprintf(m_File, <span class="stringliteral">&quot;PhysicalDeviceMemory,Type,%u,propertyFlags,%u\n&quot;</span>, i, memProps.memoryTypes[i].propertyFlags);</div><div class="line"><a name="l10881"></a><span class="lineno">10881</span>&#160;    }</div><div class="line"><a name="l10882"></a><span class="lineno">10882</span>&#160;</div><div class="line"><a name="l10883"></a><span class="lineno">10883</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Extension,VK_KHR_dedicated_allocation,%u\n&quot;</span>, dedicatedAllocationExtensionEnabled ? 1 : 0);</div><div class="line"><a name="l10884"></a><span class="lineno">10884</span>&#160;</div><div class="line"><a name="l10885"></a><span class="lineno">10885</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,%u\n&quot;</span>, VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ? 1 : 0);</div><div class="line"><a name="l10886"></a><span class="lineno">10886</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEBUG_ALIGNMENT,%llu\n&quot;</span>, (VkDeviceSize)VMA_DEBUG_ALIGNMENT);</div><div class="line"><a name="l10887"></a><span class="lineno">10887</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEBUG_MARGIN,%llu\n&quot;</span>, (VkDeviceSize)VMA_DEBUG_MARGIN);</div><div class="line"><a name="l10888"></a><span class="lineno">10888</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEBUG_INITIALIZE_ALLOCATIONS,%u\n&quot;</span>, VMA_DEBUG_INITIALIZE_ALLOCATIONS ? 1 : 0);</div><div class="line"><a name="l10889"></a><span class="lineno">10889</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEBUG_DETECT_CORRUPTION,%u\n&quot;</span>, VMA_DEBUG_DETECT_CORRUPTION ? 1 : 0);</div><div class="line"><a name="l10890"></a><span class="lineno">10890</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEBUG_GLOBAL_MUTEX,%u\n&quot;</span>, VMA_DEBUG_GLOBAL_MUTEX ? 1 : 0);</div><div class="line"><a name="l10891"></a><span class="lineno">10891</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,%llu\n&quot;</span>, (VkDeviceSize)VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY);</div><div class="line"><a name="l10892"></a><span class="lineno">10892</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_SMALL_HEAP_MAX_SIZE,%llu\n&quot;</span>, (VkDeviceSize)VMA_SMALL_HEAP_MAX_SIZE);</div><div class="line"><a name="l10893"></a><span class="lineno">10893</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Macro,VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,%llu\n&quot;</span>, (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE);</div><div class="line"><a name="l10894"></a><span class="lineno">10894</span>&#160;</div><div class="line"><a name="l10895"></a><span class="lineno">10895</span>&#160;    fprintf(m_File, <span class="stringliteral">&quot;Config,End\n&quot;</span>);</div><div class="line"><a name="l10896"></a><span class="lineno">10896</span>&#160;}</div><div class="line"><a name="l10897"></a><span class="lineno">10897</span>&#160;</div><div class="line"><a name="l10898"></a><span class="lineno">10898</span>&#160;<span class="keywordtype">void</span> VmaRecorder::GetBasicParams(CallParams&amp; outParams)</div><div class="line"><a name="l10899"></a><span class="lineno">10899</span>&#160;{</div><div class="line"><a name="l10900"></a><span class="lineno">10900</span>&#160;    outParams.threadId = GetCurrentThreadId();</div><div class="line"><a name="l10901"></a><span class="lineno">10901</span>&#160;</div><div class="line"><a name="l10902"></a><span class="lineno">10902</span>&#160;    LARGE_INTEGER counter;</div><div class="line"><a name="l10903"></a><span class="lineno">10903</span>&#160;    QueryPerformanceCounter(&amp;counter);</div><div class="line"><a name="l10904"></a><span class="lineno">10904</span>&#160;    outParams.time = (double)(counter.QuadPart - m_StartCounter) / (double)m_Freq;</div><div class="line"><a name="l10905"></a><span class="lineno">10905</span>&#160;}</div><div class="line"><a name="l10906"></a><span class="lineno">10906</span>&#160;</div><div class="line"><a name="l10907"></a><span class="lineno">10907</span>&#160;<span class="keywordtype">void</span> VmaRecorder::Flush()</div><div class="line"><a name="l10908"></a><span class="lineno">10908</span>&#160;{</div><div class="line"><a name="l10909"></a><span class="lineno">10909</span>&#160;    <span class="keywordflow">if</span>((m_Flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7">VMA_RECORD_FLUSH_AFTER_CALL_BIT</a>) != 0)</div><div class="line"><a name="l10910"></a><span class="lineno">10910</span>&#160;    {</div><div class="line"><a name="l10911"></a><span class="lineno">10911</span>&#160;        fflush(m_File);</div><div class="line"><a name="l10912"></a><span class="lineno">10912</span>&#160;    }</div><div class="line"><a name="l10913"></a><span class="lineno">10913</span>&#160;}</div><div class="line"><a name="l10914"></a><span class="lineno">10914</span>&#160;</div><div class="line"><a name="l10915"></a><span class="lineno">10915</span>&#160;<span class="preprocessor">#endif // #if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l10916"></a><span class="lineno">10916</span>&#160;</div><div class="line"><a name="l10918"></a><span class="lineno">10918</span>&#160;<span class="comment">// VmaAllocator_T</span></div><div class="line"><a name="l10919"></a><span class="lineno">10919</span>&#160;</div><div class="line"><a name="l10920"></a><span class="lineno">10920</span>&#160;VmaAllocator_T::VmaAllocator_T(<span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo) :</div><div class="line"><a name="l10921"></a><span class="lineno">10921</span>&#160;    m_UseMutex((pCreateInfo-&gt;flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a>) == 0),</div><div class="line"><a name="l10922"></a><span class="lineno">10922</span>&#160;    m_UseKhrDedicatedAllocation((pCreateInfo-&gt;flags &amp; <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a>) != 0),</div><div class="line"><a name="l10923"></a><span class="lineno">10923</span>&#160;    m_hDevice(pCreateInfo-&gt;device),</div><div class="line"><a name="l10924"></a><span class="lineno">10924</span>&#160;    m_AllocationCallbacksSpecified(pCreateInfo-&gt;pAllocationCallbacks != VMA_NULL),</div><div class="line"><a name="l10925"></a><span class="lineno">10925</span>&#160;    m_AllocationCallbacks(pCreateInfo-&gt;pAllocationCallbacks ?</div><div class="line"><a name="l10926"></a><span class="lineno">10926</span>&#160;        *pCreateInfo-&gt;pAllocationCallbacks : VmaEmptyAllocationCallbacks),</div><div class="line"><a name="l10927"></a><span class="lineno">10927</span>&#160;    m_PreferredLargeHeapBlockSize(0),</div><div class="line"><a name="l10928"></a><span class="lineno">10928</span>&#160;    m_PhysicalDevice(pCreateInfo-&gt;physicalDevice),</div><div class="line"><a name="l10929"></a><span class="lineno">10929</span>&#160;    m_CurrentFrameIndex(0),</div><div class="line"><a name="l10930"></a><span class="lineno">10930</span>&#160;    m_Pools(VmaStlAllocator&lt;<a class="code" href="struct_vma_pool.html">VmaPool</a>&gt;(GetAllocationCallbacks())),</div><div class="line"><a name="l10931"></a><span class="lineno">10931</span>&#160;    m_NextPoolId(0)</div><div class="line"><a name="l10932"></a><span class="lineno">10932</span>&#160;#if <a class="code" href="vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c">VMA_RECORDING_ENABLED</a></div><div class="line"><a name="l10933"></a><span class="lineno">10933</span>&#160;    ,m_pRecorder(VMA_NULL)</div><div class="line"><a name="l10934"></a><span class="lineno">10934</span>&#160;#endif</div><div class="line"><a name="l10935"></a><span class="lineno">10935</span>&#160;{</div><div class="line"><a name="l10936"></a><span class="lineno">10936</span>&#160;    <span class="keywordflow">if</span>(VMA_DEBUG_DETECT_CORRUPTION)</div><div class="line"><a name="l10937"></a><span class="lineno">10937</span>&#160;    {</div><div class="line"><a name="l10938"></a><span class="lineno">10938</span>&#160;        <span class="comment">// Needs to be multiply of uint32_t size because we are going to write VMA_CORRUPTION_DETECTION_MAGIC_VALUE to it.</span></div><div class="line"><a name="l10939"></a><span class="lineno">10939</span>&#160;        VMA_ASSERT(VMA_DEBUG_MARGIN % <span class="keyword">sizeof</span>(uint32_t) == 0);</div><div class="line"><a name="l10940"></a><span class="lineno">10940</span>&#160;    }</div><div class="line"><a name="l10941"></a><span class="lineno">10941</span>&#160;</div><div class="line"><a name="l10942"></a><span class="lineno">10942</span>&#160;    VMA_ASSERT(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a> &amp;&amp; pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500">device</a>);</div><div class="line"><a name="l10943"></a><span class="lineno">10943</span>&#160;</div><div class="line"><a name="l10944"></a><span class="lineno">10944</span>&#160;<span class="preprocessor">#if !(VMA_DEDICATED_ALLOCATION)</span></div><div class="line"><a name="l10945"></a><span class="lineno">10945</span>&#160;    <span class="keywordflow">if</span>((pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a>) != 0)</div><div class="line"><a name="l10946"></a><span class="lineno">10946</span>&#160;    {</div><div class="line"><a name="l10947"></a><span class="lineno">10947</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT set but required extensions are disabled by preprocessor macros.&quot;</span>);</div><div class="line"><a name="l10948"></a><span class="lineno">10948</span>&#160;    }</div><div class="line"><a name="l10949"></a><span class="lineno">10949</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l10950"></a><span class="lineno">10950</span>&#160;</div><div class="line"><a name="l10951"></a><span class="lineno">10951</span>&#160;    memset(&amp;m_DeviceMemoryCallbacks, 0 ,<span class="keyword">sizeof</span>(m_DeviceMemoryCallbacks));</div><div class="line"><a name="l10952"></a><span class="lineno">10952</span>&#160;    memset(&amp;m_PhysicalDeviceProperties, 0, <span class="keyword">sizeof</span>(m_PhysicalDeviceProperties));</div><div class="line"><a name="l10953"></a><span class="lineno">10953</span>&#160;    memset(&amp;m_MemProps, 0, <span class="keyword">sizeof</span>(m_MemProps));</div><div class="line"><a name="l10954"></a><span class="lineno">10954</span>&#160;        </div><div class="line"><a name="l10955"></a><span class="lineno">10955</span>&#160;    memset(&amp;m_pBlockVectors, 0, <span class="keyword">sizeof</span>(m_pBlockVectors));</div><div class="line"><a name="l10956"></a><span class="lineno">10956</span>&#160;    memset(&amp;m_pDedicatedAllocations, 0, <span class="keyword">sizeof</span>(m_pDedicatedAllocations));</div><div class="line"><a name="l10957"></a><span class="lineno">10957</span>&#160;</div><div class="line"><a name="l10958"></a><span class="lineno">10958</span>&#160;    <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; VK_MAX_MEMORY_HEAPS; ++i)</div><div class="line"><a name="l10959"></a><span class="lineno">10959</span>&#160;    {</div><div class="line"><a name="l10960"></a><span class="lineno">10960</span>&#160;        m_HeapSizeLimit[i] = VK_WHOLE_SIZE;</div><div class="line"><a name="l10961"></a><span class="lineno">10961</span>&#160;    }</div><div class="line"><a name="l10962"></a><span class="lineno">10962</span>&#160;</div><div class="line"><a name="l10963"></a><span class="lineno">10963</span>&#160;    <span class="keywordflow">if</span>(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a> != VMA_NULL)</div><div class="line"><a name="l10964"></a><span class="lineno">10964</span>&#160;    {</div><div class="line"><a name="l10965"></a><span class="lineno">10965</span>&#160;        m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a> = pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a>-&gt;<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a>;</div><div class="line"><a name="l10966"></a><span class="lineno">10966</span>&#160;        m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a> = pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a>-&gt;<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a>;</div><div class="line"><a name="l10967"></a><span class="lineno">10967</span>&#160;    }</div><div class="line"><a name="l10968"></a><span class="lineno">10968</span>&#160;</div><div class="line"><a name="l10969"></a><span class="lineno">10969</span>&#160;    ImportVulkanFunctions(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a>);</div><div class="line"><a name="l10970"></a><span class="lineno">10970</span>&#160;</div><div class="line"><a name="l10971"></a><span class="lineno">10971</span>&#160;    (*m_VulkanFunctions.vkGetPhysicalDeviceProperties)(m_PhysicalDevice, &amp;m_PhysicalDeviceProperties);</div><div class="line"><a name="l10972"></a><span class="lineno">10972</span>&#160;    (*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &amp;m_MemProps);</div><div class="line"><a name="l10973"></a><span class="lineno">10973</span>&#160;</div><div class="line"><a name="l10974"></a><span class="lineno">10974</span>&#160;    m_PreferredLargeHeapBlockSize = (pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a> != 0) ?</div><div class="line"><a name="l10975"></a><span class="lineno">10975</span>&#160;        pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a> : static_cast&lt;VkDeviceSize&gt;(VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE);</div><div class="line"><a name="l10976"></a><span class="lineno">10976</span>&#160;</div><div class="line"><a name="l10977"></a><span class="lineno">10977</span>&#160;    <span class="keywordflow">if</span>(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a> != VMA_NULL)</div><div class="line"><a name="l10978"></a><span class="lineno">10978</span>&#160;    {</div><div class="line"><a name="l10979"></a><span class="lineno">10979</span>&#160;        <span class="keywordflow">for</span>(uint32_t heapIndex = 0; heapIndex &lt; GetMemoryHeapCount(); ++heapIndex)</div><div class="line"><a name="l10980"></a><span class="lineno">10980</span>&#160;        {</div><div class="line"><a name="l10981"></a><span class="lineno">10981</span>&#160;            <span class="keyword">const</span> VkDeviceSize limit = pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a>[heapIndex];</div><div class="line"><a name="l10982"></a><span class="lineno">10982</span>&#160;            <span class="keywordflow">if</span>(limit != VK_WHOLE_SIZE)</div><div class="line"><a name="l10983"></a><span class="lineno">10983</span>&#160;            {</div><div class="line"><a name="l10984"></a><span class="lineno">10984</span>&#160;                m_HeapSizeLimit[heapIndex] = limit;</div><div class="line"><a name="l10985"></a><span class="lineno">10985</span>&#160;                <span class="keywordflow">if</span>(limit &lt; m_MemProps.memoryHeaps[heapIndex].size)</div><div class="line"><a name="l10986"></a><span class="lineno">10986</span>&#160;                {</div><div class="line"><a name="l10987"></a><span class="lineno">10987</span>&#160;                    m_MemProps.memoryHeaps[heapIndex].size = limit;</div><div class="line"><a name="l10988"></a><span class="lineno">10988</span>&#160;                }</div><div class="line"><a name="l10989"></a><span class="lineno">10989</span>&#160;            }</div><div class="line"><a name="l10990"></a><span class="lineno">10990</span>&#160;        }</div><div class="line"><a name="l10991"></a><span class="lineno">10991</span>&#160;    }</div><div class="line"><a name="l10992"></a><span class="lineno">10992</span>&#160;</div><div class="line"><a name="l10993"></a><span class="lineno">10993</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l10994"></a><span class="lineno">10994</span>&#160;    {</div><div class="line"><a name="l10995"></a><span class="lineno">10995</span>&#160;        <span class="keyword">const</span> VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(memTypeIndex);</div><div class="line"><a name="l10996"></a><span class="lineno">10996</span>&#160;</div><div class="line"><a name="l10997"></a><span class="lineno">10997</span>&#160;        m_pBlockVectors[memTypeIndex] = vma_new(<span class="keyword">this</span>, VmaBlockVector)(</div><div class="line"><a name="l10998"></a><span class="lineno">10998</span>&#160;            <span class="keyword">this</span>,</div><div class="line"><a name="l10999"></a><span class="lineno">10999</span>&#160;            memTypeIndex,</div><div class="line"><a name="l11000"></a><span class="lineno">11000</span>&#160;            preferredBlockSize,</div><div class="line"><a name="l11001"></a><span class="lineno">11001</span>&#160;            0,</div><div class="line"><a name="l11002"></a><span class="lineno">11002</span>&#160;            SIZE_MAX,</div><div class="line"><a name="l11003"></a><span class="lineno">11003</span>&#160;            GetBufferImageGranularity(),</div><div class="line"><a name="l11004"></a><span class="lineno">11004</span>&#160;            pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">frameInUseCount</a>,</div><div class="line"><a name="l11005"></a><span class="lineno">11005</span>&#160;            <span class="keyword">false</span>, <span class="comment">// isCustomPool</span></div><div class="line"><a name="l11006"></a><span class="lineno">11006</span>&#160;            <span class="keyword">false</span>, <span class="comment">// explicitBlockSize</span></div><div class="line"><a name="l11007"></a><span class="lineno">11007</span>&#160;            <span class="keyword">false</span>); <span class="comment">// linearAlgorithm</span></div><div class="line"><a name="l11008"></a><span class="lineno">11008</span>&#160;        <span class="comment">// No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]-&gt;CreateMinBlocks here,</span></div><div class="line"><a name="l11009"></a><span class="lineno">11009</span>&#160;        <span class="comment">// becase minBlockCount is 0.</span></div><div class="line"><a name="l11010"></a><span class="lineno">11010</span>&#160;        m_pDedicatedAllocations[memTypeIndex] = vma_new(<span class="keyword">this</span>, AllocationVectorType)(VmaStlAllocator&lt;VmaAllocation&gt;(GetAllocationCallbacks()));</div><div class="line"><a name="l11011"></a><span class="lineno">11011</span>&#160;</div><div class="line"><a name="l11012"></a><span class="lineno">11012</span>&#160;    }</div><div class="line"><a name="l11013"></a><span class="lineno">11013</span>&#160;}</div><div class="line"><a name="l11014"></a><span class="lineno">11014</span>&#160;</div><div class="line"><a name="l11015"></a><span class="lineno">11015</span>&#160;VkResult VmaAllocator_T::Init(<span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo)</div><div class="line"><a name="l11016"></a><span class="lineno">11016</span>&#160;{</div><div class="line"><a name="l11017"></a><span class="lineno">11017</span>&#160;    VkResult res = VK_SUCCESS;</div><div class="line"><a name="l11018"></a><span class="lineno">11018</span>&#160;</div><div class="line"><a name="l11019"></a><span class="lineno">11019</span>&#160;    <span class="keywordflow">if</span>(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">pRecordSettings</a> != VMA_NULL &amp;&amp;</div><div class="line"><a name="l11020"></a><span class="lineno">11020</span>&#160;        !VmaStrIsEmpty(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">pRecordSettings</a>-&gt;<a class="code" href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">pFilePath</a>))</div><div class="line"><a name="l11021"></a><span class="lineno">11021</span>&#160;    {</div><div class="line"><a name="l11022"></a><span class="lineno">11022</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l11023"></a><span class="lineno">11023</span>&#160;        m_pRecorder = vma_new(<span class="keyword">this</span>, VmaRecorder)();</div><div class="line"><a name="l11024"></a><span class="lineno">11024</span>&#160;        res = m_pRecorder-&gt;Init(*pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">pRecordSettings</a>, m_UseMutex);</div><div class="line"><a name="l11025"></a><span class="lineno">11025</span>&#160;        <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l11026"></a><span class="lineno">11026</span>&#160;        {</div><div class="line"><a name="l11027"></a><span class="lineno">11027</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11028"></a><span class="lineno">11028</span>&#160;        }</div><div class="line"><a name="l11029"></a><span class="lineno">11029</span>&#160;        m_pRecorder-&gt;WriteConfiguration(</div><div class="line"><a name="l11030"></a><span class="lineno">11030</span>&#160;            m_PhysicalDeviceProperties,</div><div class="line"><a name="l11031"></a><span class="lineno">11031</span>&#160;            m_MemProps,</div><div class="line"><a name="l11032"></a><span class="lineno">11032</span>&#160;            m_UseKhrDedicatedAllocation);</div><div class="line"><a name="l11033"></a><span class="lineno">11033</span>&#160;        m_pRecorder-&gt;RecordCreateAllocator(GetCurrentFrameIndex());</div><div class="line"><a name="l11034"></a><span class="lineno">11034</span>&#160;<span class="preprocessor">#else</span></div><div class="line"><a name="l11035"></a><span class="lineno">11035</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;VmaAllocatorCreateInfo::pRecordSettings used, but not supported due to VMA_RECORDING_ENABLED not defined to 1.&quot;</span>);</div><div class="line"><a name="l11036"></a><span class="lineno">11036</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_FEATURE_NOT_PRESENT;</div><div class="line"><a name="l11037"></a><span class="lineno">11037</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l11038"></a><span class="lineno">11038</span>&#160;    }</div><div class="line"><a name="l11039"></a><span class="lineno">11039</span>&#160;</div><div class="line"><a name="l11040"></a><span class="lineno">11040</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11041"></a><span class="lineno">11041</span>&#160;}</div><div class="line"><a name="l11042"></a><span class="lineno">11042</span>&#160;</div><div class="line"><a name="l11043"></a><span class="lineno">11043</span>&#160;VmaAllocator_T::~VmaAllocator_T()</div><div class="line"><a name="l11044"></a><span class="lineno">11044</span>&#160;{</div><div class="line"><a name="l11045"></a><span class="lineno">11045</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l11046"></a><span class="lineno">11046</span>&#160;    <span class="keywordflow">if</span>(m_pRecorder != VMA_NULL)</div><div class="line"><a name="l11047"></a><span class="lineno">11047</span>&#160;    {</div><div class="line"><a name="l11048"></a><span class="lineno">11048</span>&#160;        m_pRecorder-&gt;RecordDestroyAllocator(GetCurrentFrameIndex());</div><div class="line"><a name="l11049"></a><span class="lineno">11049</span>&#160;        vma_delete(<span class="keyword">this</span>, m_pRecorder);</div><div class="line"><a name="l11050"></a><span class="lineno">11050</span>&#160;    }</div><div class="line"><a name="l11051"></a><span class="lineno">11051</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l11052"></a><span class="lineno">11052</span>&#160;    </div><div class="line"><a name="l11053"></a><span class="lineno">11053</span>&#160;    VMA_ASSERT(m_Pools.empty());</div><div class="line"><a name="l11054"></a><span class="lineno">11054</span>&#160;</div><div class="line"><a name="l11055"></a><span class="lineno">11055</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = GetMemoryTypeCount(); i--; )</div><div class="line"><a name="l11056"></a><span class="lineno">11056</span>&#160;    {</div><div class="line"><a name="l11057"></a><span class="lineno">11057</span>&#160;        vma_delete(<span class="keyword">this</span>, m_pDedicatedAllocations[i]);</div><div class="line"><a name="l11058"></a><span class="lineno">11058</span>&#160;        vma_delete(<span class="keyword">this</span>, m_pBlockVectors[i]);</div><div class="line"><a name="l11059"></a><span class="lineno">11059</span>&#160;    }</div><div class="line"><a name="l11060"></a><span class="lineno">11060</span>&#160;}</div><div class="line"><a name="l11061"></a><span class="lineno">11061</span>&#160;</div><div class="line"><a name="l11062"></a><span class="lineno">11062</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::ImportVulkanFunctions(<span class="keyword">const</span> <a class="code" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a>* pVulkanFunctions)</div><div class="line"><a name="l11063"></a><span class="lineno">11063</span>&#160;{</div><div class="line"><a name="l11064"></a><span class="lineno">11064</span>&#160;<span class="preprocessor">#if VMA_STATIC_VULKAN_FUNCTIONS == 1</span></div><div class="line"><a name="l11065"></a><span class="lineno">11065</span>&#160;    m_VulkanFunctions.vkGetPhysicalDeviceProperties = &amp;vkGetPhysicalDeviceProperties;</div><div class="line"><a name="l11066"></a><span class="lineno">11066</span>&#160;    m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties = &amp;vkGetPhysicalDeviceMemoryProperties;</div><div class="line"><a name="l11067"></a><span class="lineno">11067</span>&#160;    m_VulkanFunctions.vkAllocateMemory = &amp;vkAllocateMemory;</div><div class="line"><a name="l11068"></a><span class="lineno">11068</span>&#160;    m_VulkanFunctions.vkFreeMemory = &amp;vkFreeMemory;</div><div class="line"><a name="l11069"></a><span class="lineno">11069</span>&#160;    m_VulkanFunctions.vkMapMemory = &amp;vkMapMemory;</div><div class="line"><a name="l11070"></a><span class="lineno">11070</span>&#160;    m_VulkanFunctions.vkUnmapMemory = &amp;vkUnmapMemory;</div><div class="line"><a name="l11071"></a><span class="lineno">11071</span>&#160;    m_VulkanFunctions.vkFlushMappedMemoryRanges = &amp;vkFlushMappedMemoryRanges;</div><div class="line"><a name="l11072"></a><span class="lineno">11072</span>&#160;    m_VulkanFunctions.vkInvalidateMappedMemoryRanges = &amp;vkInvalidateMappedMemoryRanges;</div><div class="line"><a name="l11073"></a><span class="lineno">11073</span>&#160;    m_VulkanFunctions.vkBindBufferMemory = &amp;vkBindBufferMemory;</div><div class="line"><a name="l11074"></a><span class="lineno">11074</span>&#160;    m_VulkanFunctions.vkBindImageMemory = &amp;vkBindImageMemory;</div><div class="line"><a name="l11075"></a><span class="lineno">11075</span>&#160;    m_VulkanFunctions.vkGetBufferMemoryRequirements = &amp;vkGetBufferMemoryRequirements;</div><div class="line"><a name="l11076"></a><span class="lineno">11076</span>&#160;    m_VulkanFunctions.vkGetImageMemoryRequirements = &amp;vkGetImageMemoryRequirements;</div><div class="line"><a name="l11077"></a><span class="lineno">11077</span>&#160;    m_VulkanFunctions.vkCreateBuffer = &amp;vkCreateBuffer;</div><div class="line"><a name="l11078"></a><span class="lineno">11078</span>&#160;    m_VulkanFunctions.vkDestroyBuffer = &amp;vkDestroyBuffer;</div><div class="line"><a name="l11079"></a><span class="lineno">11079</span>&#160;    m_VulkanFunctions.vkCreateImage = &amp;vkCreateImage;</div><div class="line"><a name="l11080"></a><span class="lineno">11080</span>&#160;    m_VulkanFunctions.vkDestroyImage = &amp;vkDestroyImage;</div><div class="line"><a name="l11081"></a><span class="lineno">11081</span>&#160;<span class="preprocessor">#if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11082"></a><span class="lineno">11082</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l11083"></a><span class="lineno">11083</span>&#160;    {</div><div class="line"><a name="l11084"></a><span class="lineno">11084</span>&#160;        m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR =</div><div class="line"><a name="l11085"></a><span class="lineno">11085</span>&#160;            (PFN_vkGetBufferMemoryRequirements2KHR)vkGetDeviceProcAddr(m_hDevice, <span class="stringliteral">&quot;vkGetBufferMemoryRequirements2KHR&quot;</span>);</div><div class="line"><a name="l11086"></a><span class="lineno">11086</span>&#160;        m_VulkanFunctions.vkGetImageMemoryRequirements2KHR =</div><div class="line"><a name="l11087"></a><span class="lineno">11087</span>&#160;            (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(m_hDevice, <span class="stringliteral">&quot;vkGetImageMemoryRequirements2KHR&quot;</span>);</div><div class="line"><a name="l11088"></a><span class="lineno">11088</span>&#160;    }</div><div class="line"><a name="l11089"></a><span class="lineno">11089</span>&#160;<span class="preprocessor">#endif // #if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11090"></a><span class="lineno">11090</span>&#160;<span class="preprocessor">#endif // #if VMA_STATIC_VULKAN_FUNCTIONS == 1</span></div><div class="line"><a name="l11091"></a><span class="lineno">11091</span>&#160;</div><div class="line"><a name="l11092"></a><span class="lineno">11092</span>&#160;<span class="preprocessor">#define VMA_COPY_IF_NOT_NULL(funcName) \</span></div><div class="line"><a name="l11093"></a><span class="lineno">11093</span>&#160;<span class="preprocessor">    if(pVulkanFunctions-&gt;funcName != VMA_NULL) m_VulkanFunctions.funcName = pVulkanFunctions-&gt;funcName;</span></div><div class="line"><a name="l11094"></a><span class="lineno">11094</span>&#160;</div><div class="line"><a name="l11095"></a><span class="lineno">11095</span>&#160;    <span class="keywordflow">if</span>(pVulkanFunctions != VMA_NULL)</div><div class="line"><a name="l11096"></a><span class="lineno">11096</span>&#160;    {</div><div class="line"><a name="l11097"></a><span class="lineno">11097</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties);</div><div class="line"><a name="l11098"></a><span class="lineno">11098</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties);</div><div class="line"><a name="l11099"></a><span class="lineno">11099</span>&#160;        VMA_COPY_IF_NOT_NULL(vkAllocateMemory);</div><div class="line"><a name="l11100"></a><span class="lineno">11100</span>&#160;        VMA_COPY_IF_NOT_NULL(vkFreeMemory);</div><div class="line"><a name="l11101"></a><span class="lineno">11101</span>&#160;        VMA_COPY_IF_NOT_NULL(vkMapMemory);</div><div class="line"><a name="l11102"></a><span class="lineno">11102</span>&#160;        VMA_COPY_IF_NOT_NULL(vkUnmapMemory);</div><div class="line"><a name="l11103"></a><span class="lineno">11103</span>&#160;        VMA_COPY_IF_NOT_NULL(vkFlushMappedMemoryRanges);</div><div class="line"><a name="l11104"></a><span class="lineno">11104</span>&#160;        VMA_COPY_IF_NOT_NULL(vkInvalidateMappedMemoryRanges);</div><div class="line"><a name="l11105"></a><span class="lineno">11105</span>&#160;        VMA_COPY_IF_NOT_NULL(vkBindBufferMemory);</div><div class="line"><a name="l11106"></a><span class="lineno">11106</span>&#160;        VMA_COPY_IF_NOT_NULL(vkBindImageMemory);</div><div class="line"><a name="l11107"></a><span class="lineno">11107</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements);</div><div class="line"><a name="l11108"></a><span class="lineno">11108</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements);</div><div class="line"><a name="l11109"></a><span class="lineno">11109</span>&#160;        VMA_COPY_IF_NOT_NULL(vkCreateBuffer);</div><div class="line"><a name="l11110"></a><span class="lineno">11110</span>&#160;        VMA_COPY_IF_NOT_NULL(vkDestroyBuffer);</div><div class="line"><a name="l11111"></a><span class="lineno">11111</span>&#160;        VMA_COPY_IF_NOT_NULL(vkCreateImage);</div><div class="line"><a name="l11112"></a><span class="lineno">11112</span>&#160;        VMA_COPY_IF_NOT_NULL(vkDestroyImage);</div><div class="line"><a name="l11113"></a><span class="lineno">11113</span>&#160;<span class="preprocessor">#if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11114"></a><span class="lineno">11114</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements2KHR);</div><div class="line"><a name="l11115"></a><span class="lineno">11115</span>&#160;        VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements2KHR);</div><div class="line"><a name="l11116"></a><span class="lineno">11116</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l11117"></a><span class="lineno">11117</span>&#160;    }</div><div class="line"><a name="l11118"></a><span class="lineno">11118</span>&#160;</div><div class="line"><a name="l11119"></a><span class="lineno">11119</span>&#160;<span class="preprocessor">#undef VMA_COPY_IF_NOT_NULL</span></div><div class="line"><a name="l11120"></a><span class="lineno">11120</span>&#160;</div><div class="line"><a name="l11121"></a><span class="lineno">11121</span>&#160;    <span class="comment">// If these asserts are hit, you must either #define VMA_STATIC_VULKAN_FUNCTIONS 1</span></div><div class="line"><a name="l11122"></a><span class="lineno">11122</span>&#160;    <span class="comment">// or pass valid pointers as VmaAllocatorCreateInfo::pVulkanFunctions.</span></div><div class="line"><a name="l11123"></a><span class="lineno">11123</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceProperties != VMA_NULL);</div><div class="line"><a name="l11124"></a><span class="lineno">11124</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties != VMA_NULL);</div><div class="line"><a name="l11125"></a><span class="lineno">11125</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkAllocateMemory != VMA_NULL);</div><div class="line"><a name="l11126"></a><span class="lineno">11126</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkFreeMemory != VMA_NULL);</div><div class="line"><a name="l11127"></a><span class="lineno">11127</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkMapMemory != VMA_NULL);</div><div class="line"><a name="l11128"></a><span class="lineno">11128</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkUnmapMemory != VMA_NULL);</div><div class="line"><a name="l11129"></a><span class="lineno">11129</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkFlushMappedMemoryRanges != VMA_NULL);</div><div class="line"><a name="l11130"></a><span class="lineno">11130</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkInvalidateMappedMemoryRanges != VMA_NULL);</div><div class="line"><a name="l11131"></a><span class="lineno">11131</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkBindBufferMemory != VMA_NULL);</div><div class="line"><a name="l11132"></a><span class="lineno">11132</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkBindImageMemory != VMA_NULL);</div><div class="line"><a name="l11133"></a><span class="lineno">11133</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements != VMA_NULL);</div><div class="line"><a name="l11134"></a><span class="lineno">11134</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements != VMA_NULL);</div><div class="line"><a name="l11135"></a><span class="lineno">11135</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkCreateBuffer != VMA_NULL);</div><div class="line"><a name="l11136"></a><span class="lineno">11136</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkDestroyBuffer != VMA_NULL);</div><div class="line"><a name="l11137"></a><span class="lineno">11137</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkCreateImage != VMA_NULL);</div><div class="line"><a name="l11138"></a><span class="lineno">11138</span>&#160;    VMA_ASSERT(m_VulkanFunctions.vkDestroyImage != VMA_NULL);</div><div class="line"><a name="l11139"></a><span class="lineno">11139</span>&#160;<span class="preprocessor">#if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11140"></a><span class="lineno">11140</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l11141"></a><span class="lineno">11141</span>&#160;    {</div><div class="line"><a name="l11142"></a><span class="lineno">11142</span>&#160;        VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR != VMA_NULL);</div><div class="line"><a name="l11143"></a><span class="lineno">11143</span>&#160;        VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements2KHR != VMA_NULL);</div><div class="line"><a name="l11144"></a><span class="lineno">11144</span>&#160;    }</div><div class="line"><a name="l11145"></a><span class="lineno">11145</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l11146"></a><span class="lineno">11146</span>&#160;}</div><div class="line"><a name="l11147"></a><span class="lineno">11147</span>&#160;</div><div class="line"><a name="l11148"></a><span class="lineno">11148</span>&#160;VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)</div><div class="line"><a name="l11149"></a><span class="lineno">11149</span>&#160;{</div><div class="line"><a name="l11150"></a><span class="lineno">11150</span>&#160;    <span class="keyword">const</span> uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);</div><div class="line"><a name="l11151"></a><span class="lineno">11151</span>&#160;    <span class="keyword">const</span> VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size;</div><div class="line"><a name="l11152"></a><span class="lineno">11152</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isSmallHeap = heapSize &lt;= VMA_SMALL_HEAP_MAX_SIZE;</div><div class="line"><a name="l11153"></a><span class="lineno">11153</span>&#160;    <span class="keywordflow">return</span> isSmallHeap ? (heapSize / 8) : m_PreferredLargeHeapBlockSize;</div><div class="line"><a name="l11154"></a><span class="lineno">11154</span>&#160;}</div><div class="line"><a name="l11155"></a><span class="lineno">11155</span>&#160;</div><div class="line"><a name="l11156"></a><span class="lineno">11156</span>&#160;VkResult VmaAllocator_T::AllocateMemoryOfType(</div><div class="line"><a name="l11157"></a><span class="lineno">11157</span>&#160;    VkDeviceSize size,</div><div class="line"><a name="l11158"></a><span class="lineno">11158</span>&#160;    VkDeviceSize alignment,</div><div class="line"><a name="l11159"></a><span class="lineno">11159</span>&#160;    <span class="keywordtype">bool</span> dedicatedAllocation,</div><div class="line"><a name="l11160"></a><span class="lineno">11160</span>&#160;    VkBuffer dedicatedBuffer,</div><div class="line"><a name="l11161"></a><span class="lineno">11161</span>&#160;    VkImage dedicatedImage,</div><div class="line"><a name="l11162"></a><span class="lineno">11162</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l11163"></a><span class="lineno">11163</span>&#160;    uint32_t memTypeIndex,</div><div class="line"><a name="l11164"></a><span class="lineno">11164</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l11165"></a><span class="lineno">11165</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l11166"></a><span class="lineno">11166</span>&#160;{</div><div class="line"><a name="l11167"></a><span class="lineno">11167</span>&#160;    VMA_ASSERT(pAllocation != VMA_NULL);</div><div class="line"><a name="l11168"></a><span class="lineno">11168</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;  AllocateMemory: MemoryTypeIndex=%u, Size=%llu&quot;</span>, memTypeIndex, vkMemReq.size);</div><div class="line"><a name="l11169"></a><span class="lineno">11169</span>&#160;</div><div class="line"><a name="l11170"></a><span class="lineno">11170</span>&#160;    <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> finalCreateInfo = createInfo;</div><div class="line"><a name="l11171"></a><span class="lineno">11171</span>&#160;</div><div class="line"><a name="l11172"></a><span class="lineno">11172</span>&#160;    <span class="comment">// If memory type is not HOST_VISIBLE, disable MAPPED.</span></div><div class="line"><a name="l11173"></a><span class="lineno">11173</span>&#160;    <span class="keywordflow">if</span>((finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0 &amp;&amp;</div><div class="line"><a name="l11174"></a><span class="lineno">11174</span>&#160;        (m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)</div><div class="line"><a name="l11175"></a><span class="lineno">11175</span>&#160;    {</div><div class="line"><a name="l11176"></a><span class="lineno">11176</span>&#160;        finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp;= ~<a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><div class="line"><a name="l11177"></a><span class="lineno">11177</span>&#160;    }</div><div class="line"><a name="l11178"></a><span class="lineno">11178</span>&#160;</div><div class="line"><a name="l11179"></a><span class="lineno">11179</span>&#160;    VmaBlockVector* <span class="keyword">const</span> blockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l11180"></a><span class="lineno">11180</span>&#160;    VMA_ASSERT(blockVector);</div><div class="line"><a name="l11181"></a><span class="lineno">11181</span>&#160;</div><div class="line"><a name="l11182"></a><span class="lineno">11182</span>&#160;    <span class="keyword">const</span> VkDeviceSize preferredBlockSize = blockVector-&gt;GetPreferredBlockSize();</div><div class="line"><a name="l11183"></a><span class="lineno">11183</span>&#160;    <span class="keywordtype">bool</span> preferDedicatedMemory =</div><div class="line"><a name="l11184"></a><span class="lineno">11184</span>&#160;        VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ||</div><div class="line"><a name="l11185"></a><span class="lineno">11185</span>&#160;        dedicatedAllocation ||</div><div class="line"><a name="l11186"></a><span class="lineno">11186</span>&#160;        <span class="comment">// Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size.</span></div><div class="line"><a name="l11187"></a><span class="lineno">11187</span>&#160;        size &gt; preferredBlockSize / 2;</div><div class="line"><a name="l11188"></a><span class="lineno">11188</span>&#160;</div><div class="line"><a name="l11189"></a><span class="lineno">11189</span>&#160;    <span class="keywordflow">if</span>(preferDedicatedMemory &amp;&amp;</div><div class="line"><a name="l11190"></a><span class="lineno">11190</span>&#160;        (finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) == 0 &amp;&amp;</div><div class="line"><a name="l11191"></a><span class="lineno">11191</span>&#160;        finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> == VK_NULL_HANDLE)</div><div class="line"><a name="l11192"></a><span class="lineno">11192</span>&#160;    {</div><div class="line"><a name="l11193"></a><span class="lineno">11193</span>&#160;        finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> |= <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>;</div><div class="line"><a name="l11194"></a><span class="lineno">11194</span>&#160;    }</div><div class="line"><a name="l11195"></a><span class="lineno">11195</span>&#160;</div><div class="line"><a name="l11196"></a><span class="lineno">11196</span>&#160;    <span class="keywordflow">if</span>((finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>) != 0)</div><div class="line"><a name="l11197"></a><span class="lineno">11197</span>&#160;    {</div><div class="line"><a name="l11198"></a><span class="lineno">11198</span>&#160;        <span class="keywordflow">if</span>((finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l11199"></a><span class="lineno">11199</span>&#160;        {</div><div class="line"><a name="l11200"></a><span class="lineno">11200</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11201"></a><span class="lineno">11201</span>&#160;        }</div><div class="line"><a name="l11202"></a><span class="lineno">11202</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l11203"></a><span class="lineno">11203</span>&#160;        {</div><div class="line"><a name="l11204"></a><span class="lineno">11204</span>&#160;            <span class="keywordflow">return</span> AllocateDedicatedMemory(</div><div class="line"><a name="l11205"></a><span class="lineno">11205</span>&#160;                size,</div><div class="line"><a name="l11206"></a><span class="lineno">11206</span>&#160;                suballocType,</div><div class="line"><a name="l11207"></a><span class="lineno">11207</span>&#160;                memTypeIndex,</div><div class="line"><a name="l11208"></a><span class="lineno">11208</span>&#160;                (finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0,</div><div class="line"><a name="l11209"></a><span class="lineno">11209</span>&#160;                (finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0,</div><div class="line"><a name="l11210"></a><span class="lineno">11210</span>&#160;                finalCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a>,</div><div class="line"><a name="l11211"></a><span class="lineno">11211</span>&#160;                dedicatedBuffer,</div><div class="line"><a name="l11212"></a><span class="lineno">11212</span>&#160;                dedicatedImage,</div><div class="line"><a name="l11213"></a><span class="lineno">11213</span>&#160;                pAllocation);</div><div class="line"><a name="l11214"></a><span class="lineno">11214</span>&#160;        }</div><div class="line"><a name="l11215"></a><span class="lineno">11215</span>&#160;    }</div><div class="line"><a name="l11216"></a><span class="lineno">11216</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l11217"></a><span class="lineno">11217</span>&#160;    {</div><div class="line"><a name="l11218"></a><span class="lineno">11218</span>&#160;        VkResult res = blockVector-&gt;Allocate(</div><div class="line"><a name="l11219"></a><span class="lineno">11219</span>&#160;            VK_NULL_HANDLE, <span class="comment">// hCurrentPool</span></div><div class="line"><a name="l11220"></a><span class="lineno">11220</span>&#160;            m_CurrentFrameIndex.load(),</div><div class="line"><a name="l11221"></a><span class="lineno">11221</span>&#160;            size,</div><div class="line"><a name="l11222"></a><span class="lineno">11222</span>&#160;            alignment,</div><div class="line"><a name="l11223"></a><span class="lineno">11223</span>&#160;            finalCreateInfo,</div><div class="line"><a name="l11224"></a><span class="lineno">11224</span>&#160;            suballocType,</div><div class="line"><a name="l11225"></a><span class="lineno">11225</span>&#160;            pAllocation);</div><div class="line"><a name="l11226"></a><span class="lineno">11226</span>&#160;        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l11227"></a><span class="lineno">11227</span>&#160;        {</div><div class="line"><a name="l11228"></a><span class="lineno">11228</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11229"></a><span class="lineno">11229</span>&#160;        }</div><div class="line"><a name="l11230"></a><span class="lineno">11230</span>&#160;</div><div class="line"><a name="l11231"></a><span class="lineno">11231</span>&#160;        <span class="comment">// 5. Try dedicated memory.</span></div><div class="line"><a name="l11232"></a><span class="lineno">11232</span>&#160;        <span class="keywordflow">if</span>((finalCreateInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l11233"></a><span class="lineno">11233</span>&#160;        {</div><div class="line"><a name="l11234"></a><span class="lineno">11234</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11235"></a><span class="lineno">11235</span>&#160;        }</div><div class="line"><a name="l11236"></a><span class="lineno">11236</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l11237"></a><span class="lineno">11237</span>&#160;        {</div><div class="line"><a name="l11238"></a><span class="lineno">11238</span>&#160;            res = AllocateDedicatedMemory(</div><div class="line"><a name="l11239"></a><span class="lineno">11239</span>&#160;                size,</div><div class="line"><a name="l11240"></a><span class="lineno">11240</span>&#160;                suballocType,</div><div class="line"><a name="l11241"></a><span class="lineno">11241</span>&#160;                memTypeIndex,</div><div class="line"><a name="l11242"></a><span class="lineno">11242</span>&#160;                (finalCreateInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0,</div><div class="line"><a name="l11243"></a><span class="lineno">11243</span>&#160;                (finalCreateInfo.flags &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>) != 0,</div><div class="line"><a name="l11244"></a><span class="lineno">11244</span>&#160;                finalCreateInfo.pUserData,</div><div class="line"><a name="l11245"></a><span class="lineno">11245</span>&#160;                dedicatedBuffer,</div><div class="line"><a name="l11246"></a><span class="lineno">11246</span>&#160;                dedicatedImage,</div><div class="line"><a name="l11247"></a><span class="lineno">11247</span>&#160;                pAllocation);</div><div class="line"><a name="l11248"></a><span class="lineno">11248</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l11249"></a><span class="lineno">11249</span>&#160;            {</div><div class="line"><a name="l11250"></a><span class="lineno">11250</span>&#160;                <span class="comment">// Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here.</span></div><div class="line"><a name="l11251"></a><span class="lineno">11251</span>&#160;                VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Allocated as DedicatedMemory&quot;</span>);</div><div class="line"><a name="l11252"></a><span class="lineno">11252</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l11253"></a><span class="lineno">11253</span>&#160;            }</div><div class="line"><a name="l11254"></a><span class="lineno">11254</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l11255"></a><span class="lineno">11255</span>&#160;            {</div><div class="line"><a name="l11256"></a><span class="lineno">11256</span>&#160;                <span class="comment">// Everything failed: Return error code.</span></div><div class="line"><a name="l11257"></a><span class="lineno">11257</span>&#160;                VMA_DEBUG_LOG(<span class="stringliteral">&quot;    vkAllocateMemory FAILED&quot;</span>);</div><div class="line"><a name="l11258"></a><span class="lineno">11258</span>&#160;                <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11259"></a><span class="lineno">11259</span>&#160;            }</div><div class="line"><a name="l11260"></a><span class="lineno">11260</span>&#160;        }</div><div class="line"><a name="l11261"></a><span class="lineno">11261</span>&#160;    }</div><div class="line"><a name="l11262"></a><span class="lineno">11262</span>&#160;}</div><div class="line"><a name="l11263"></a><span class="lineno">11263</span>&#160;</div><div class="line"><a name="l11264"></a><span class="lineno">11264</span>&#160;VkResult VmaAllocator_T::AllocateDedicatedMemory(</div><div class="line"><a name="l11265"></a><span class="lineno">11265</span>&#160;    VkDeviceSize size,</div><div class="line"><a name="l11266"></a><span class="lineno">11266</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l11267"></a><span class="lineno">11267</span>&#160;    uint32_t memTypeIndex,</div><div class="line"><a name="l11268"></a><span class="lineno">11268</span>&#160;    <span class="keywordtype">bool</span> map,</div><div class="line"><a name="l11269"></a><span class="lineno">11269</span>&#160;    <span class="keywordtype">bool</span> isUserDataString,</div><div class="line"><a name="l11270"></a><span class="lineno">11270</span>&#160;    <span class="keywordtype">void</span>* pUserData,</div><div class="line"><a name="l11271"></a><span class="lineno">11271</span>&#160;    VkBuffer dedicatedBuffer,</div><div class="line"><a name="l11272"></a><span class="lineno">11272</span>&#160;    VkImage dedicatedImage,</div><div class="line"><a name="l11273"></a><span class="lineno">11273</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l11274"></a><span class="lineno">11274</span>&#160;{</div><div class="line"><a name="l11275"></a><span class="lineno">11275</span>&#160;    VMA_ASSERT(pAllocation);</div><div class="line"><a name="l11276"></a><span class="lineno">11276</span>&#160;</div><div class="line"><a name="l11277"></a><span class="lineno">11277</span>&#160;    VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };</div><div class="line"><a name="l11278"></a><span class="lineno">11278</span>&#160;    allocInfo.memoryTypeIndex = memTypeIndex;</div><div class="line"><a name="l11279"></a><span class="lineno">11279</span>&#160;    allocInfo.allocationSize = size;</div><div class="line"><a name="l11280"></a><span class="lineno">11280</span>&#160;</div><div class="line"><a name="l11281"></a><span class="lineno">11281</span>&#160;<span class="preprocessor">#if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11282"></a><span class="lineno">11282</span>&#160;    VkMemoryDedicatedAllocateInfoKHR dedicatedAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR };</div><div class="line"><a name="l11283"></a><span class="lineno">11283</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l11284"></a><span class="lineno">11284</span>&#160;    {</div><div class="line"><a name="l11285"></a><span class="lineno">11285</span>&#160;        <span class="keywordflow">if</span>(dedicatedBuffer != VK_NULL_HANDLE)</div><div class="line"><a name="l11286"></a><span class="lineno">11286</span>&#160;        {</div><div class="line"><a name="l11287"></a><span class="lineno">11287</span>&#160;            VMA_ASSERT(dedicatedImage == VK_NULL_HANDLE);</div><div class="line"><a name="l11288"></a><span class="lineno">11288</span>&#160;            dedicatedAllocInfo.buffer = dedicatedBuffer;</div><div class="line"><a name="l11289"></a><span class="lineno">11289</span>&#160;            allocInfo.pNext = &amp;dedicatedAllocInfo;</div><div class="line"><a name="l11290"></a><span class="lineno">11290</span>&#160;        }</div><div class="line"><a name="l11291"></a><span class="lineno">11291</span>&#160;        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(dedicatedImage != VK_NULL_HANDLE)</div><div class="line"><a name="l11292"></a><span class="lineno">11292</span>&#160;        {</div><div class="line"><a name="l11293"></a><span class="lineno">11293</span>&#160;            dedicatedAllocInfo.image = dedicatedImage;</div><div class="line"><a name="l11294"></a><span class="lineno">11294</span>&#160;            allocInfo.pNext = &amp;dedicatedAllocInfo;</div><div class="line"><a name="l11295"></a><span class="lineno">11295</span>&#160;        }</div><div class="line"><a name="l11296"></a><span class="lineno">11296</span>&#160;    }</div><div class="line"><a name="l11297"></a><span class="lineno">11297</span>&#160;<span class="preprocessor">#endif // #if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11298"></a><span class="lineno">11298</span>&#160;</div><div class="line"><a name="l11299"></a><span class="lineno">11299</span>&#160;    <span class="comment">// Allocate VkDeviceMemory.</span></div><div class="line"><a name="l11300"></a><span class="lineno">11300</span>&#160;    VkDeviceMemory hMemory = VK_NULL_HANDLE;</div><div class="line"><a name="l11301"></a><span class="lineno">11301</span>&#160;    VkResult res = AllocateVulkanMemory(&amp;allocInfo, &amp;hMemory);</div><div class="line"><a name="l11302"></a><span class="lineno">11302</span>&#160;    <span class="keywordflow">if</span>(res &lt; 0)</div><div class="line"><a name="l11303"></a><span class="lineno">11303</span>&#160;    {</div><div class="line"><a name="l11304"></a><span class="lineno">11304</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;    vkAllocateMemory FAILED&quot;</span>);</div><div class="line"><a name="l11305"></a><span class="lineno">11305</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11306"></a><span class="lineno">11306</span>&#160;    }</div><div class="line"><a name="l11307"></a><span class="lineno">11307</span>&#160;</div><div class="line"><a name="l11308"></a><span class="lineno">11308</span>&#160;    <span class="keywordtype">void</span>* pMappedData = VMA_NULL;</div><div class="line"><a name="l11309"></a><span class="lineno">11309</span>&#160;    <span class="keywordflow">if</span>(map)</div><div class="line"><a name="l11310"></a><span class="lineno">11310</span>&#160;    {</div><div class="line"><a name="l11311"></a><span class="lineno">11311</span>&#160;        res = (*m_VulkanFunctions.vkMapMemory)(</div><div class="line"><a name="l11312"></a><span class="lineno">11312</span>&#160;            m_hDevice,</div><div class="line"><a name="l11313"></a><span class="lineno">11313</span>&#160;            hMemory,</div><div class="line"><a name="l11314"></a><span class="lineno">11314</span>&#160;            0,</div><div class="line"><a name="l11315"></a><span class="lineno">11315</span>&#160;            VK_WHOLE_SIZE,</div><div class="line"><a name="l11316"></a><span class="lineno">11316</span>&#160;            0,</div><div class="line"><a name="l11317"></a><span class="lineno">11317</span>&#160;            &amp;pMappedData);</div><div class="line"><a name="l11318"></a><span class="lineno">11318</span>&#160;        <span class="keywordflow">if</span>(res &lt; 0)</div><div class="line"><a name="l11319"></a><span class="lineno">11319</span>&#160;        {</div><div class="line"><a name="l11320"></a><span class="lineno">11320</span>&#160;            VMA_DEBUG_LOG(<span class="stringliteral">&quot;    vkMapMemory FAILED&quot;</span>);</div><div class="line"><a name="l11321"></a><span class="lineno">11321</span>&#160;            FreeVulkanMemory(memTypeIndex, size, hMemory);</div><div class="line"><a name="l11322"></a><span class="lineno">11322</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11323"></a><span class="lineno">11323</span>&#160;        }</div><div class="line"><a name="l11324"></a><span class="lineno">11324</span>&#160;    }</div><div class="line"><a name="l11325"></a><span class="lineno">11325</span>&#160;</div><div class="line"><a name="l11326"></a><span class="lineno">11326</span>&#160;    *pAllocation = vma_new(<span class="keyword">this</span>, VmaAllocation_T)(m_CurrentFrameIndex.load(), isUserDataString);</div><div class="line"><a name="l11327"></a><span class="lineno">11327</span>&#160;    (*pAllocation)-&gt;InitDedicatedAllocation(memTypeIndex, hMemory, suballocType, pMappedData, size);</div><div class="line"><a name="l11328"></a><span class="lineno">11328</span>&#160;    (*pAllocation)-&gt;SetUserData(<span class="keyword">this</span>, pUserData);</div><div class="line"><a name="l11329"></a><span class="lineno">11329</span>&#160;    <span class="keywordflow">if</span>(VMA_DEBUG_INITIALIZE_ALLOCATIONS)</div><div class="line"><a name="l11330"></a><span class="lineno">11330</span>&#160;    {</div><div class="line"><a name="l11331"></a><span class="lineno">11331</span>&#160;        FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);</div><div class="line"><a name="l11332"></a><span class="lineno">11332</span>&#160;    }</div><div class="line"><a name="l11333"></a><span class="lineno">11333</span>&#160;</div><div class="line"><a name="l11334"></a><span class="lineno">11334</span>&#160;    <span class="comment">// Register it in m_pDedicatedAllocations.</span></div><div class="line"><a name="l11335"></a><span class="lineno">11335</span>&#160;    {</div><div class="line"><a name="l11336"></a><span class="lineno">11336</span>&#160;        VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l11337"></a><span class="lineno">11337</span>&#160;        AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l11338"></a><span class="lineno">11338</span>&#160;        VMA_ASSERT(pDedicatedAllocations);</div><div class="line"><a name="l11339"></a><span class="lineno">11339</span>&#160;        VmaVectorInsertSorted&lt;VmaPointerLess&gt;(*pDedicatedAllocations, *pAllocation);</div><div class="line"><a name="l11340"></a><span class="lineno">11340</span>&#160;    }</div><div class="line"><a name="l11341"></a><span class="lineno">11341</span>&#160;</div><div class="line"><a name="l11342"></a><span class="lineno">11342</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Allocated DedicatedMemory MemoryTypeIndex=#%u&quot;</span>, memTypeIndex);</div><div class="line"><a name="l11343"></a><span class="lineno">11343</span>&#160;</div><div class="line"><a name="l11344"></a><span class="lineno">11344</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l11345"></a><span class="lineno">11345</span>&#160;}</div><div class="line"><a name="l11346"></a><span class="lineno">11346</span>&#160;</div><div class="line"><a name="l11347"></a><span class="lineno">11347</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetBufferMemoryRequirements(</div><div class="line"><a name="l11348"></a><span class="lineno">11348</span>&#160;    VkBuffer hBuffer,</div><div class="line"><a name="l11349"></a><span class="lineno">11349</span>&#160;    VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l11350"></a><span class="lineno">11350</span>&#160;    <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l11351"></a><span class="lineno">11351</span>&#160;    <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation)<span class="keyword"> const</span></div><div class="line"><a name="l11352"></a><span class="lineno">11352</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l11353"></a><span class="lineno">11353</span>&#160;<span class="preprocessor">#if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11354"></a><span class="lineno">11354</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l11355"></a><span class="lineno">11355</span>&#160;    {</div><div class="line"><a name="l11356"></a><span class="lineno">11356</span>&#160;        VkBufferMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR };</div><div class="line"><a name="l11357"></a><span class="lineno">11357</span>&#160;        memReqInfo.buffer = hBuffer;</div><div class="line"><a name="l11358"></a><span class="lineno">11358</span>&#160;</div><div class="line"><a name="l11359"></a><span class="lineno">11359</span>&#160;        VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };</div><div class="line"><a name="l11360"></a><span class="lineno">11360</span>&#160;</div><div class="line"><a name="l11361"></a><span class="lineno">11361</span>&#160;        VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };</div><div class="line"><a name="l11362"></a><span class="lineno">11362</span>&#160;        memReq2.pNext = &amp;memDedicatedReq;</div><div class="line"><a name="l11363"></a><span class="lineno">11363</span>&#160;</div><div class="line"><a name="l11364"></a><span class="lineno">11364</span>&#160;        (*m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR)(m_hDevice, &amp;memReqInfo, &amp;memReq2);</div><div class="line"><a name="l11365"></a><span class="lineno">11365</span>&#160;</div><div class="line"><a name="l11366"></a><span class="lineno">11366</span>&#160;        memReq = memReq2.memoryRequirements;</div><div class="line"><a name="l11367"></a><span class="lineno">11367</span>&#160;        requiresDedicatedAllocation = (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE);</div><div class="line"><a name="l11368"></a><span class="lineno">11368</span>&#160;        prefersDedicatedAllocation  = (memDedicatedReq.prefersDedicatedAllocation  != VK_FALSE);</div><div class="line"><a name="l11369"></a><span class="lineno">11369</span>&#160;    }</div><div class="line"><a name="l11370"></a><span class="lineno">11370</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l11371"></a><span class="lineno">11371</span>&#160;<span class="preprocessor">#endif // #if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11372"></a><span class="lineno">11372</span>&#160;    {</div><div class="line"><a name="l11373"></a><span class="lineno">11373</span>&#160;        (*m_VulkanFunctions.vkGetBufferMemoryRequirements)(m_hDevice, hBuffer, &amp;memReq);</div><div class="line"><a name="l11374"></a><span class="lineno">11374</span>&#160;        requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l11375"></a><span class="lineno">11375</span>&#160;        prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l11376"></a><span class="lineno">11376</span>&#160;    }</div><div class="line"><a name="l11377"></a><span class="lineno">11377</span>&#160;}</div><div class="line"><a name="l11378"></a><span class="lineno">11378</span>&#160;</div><div class="line"><a name="l11379"></a><span class="lineno">11379</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetImageMemoryRequirements(</div><div class="line"><a name="l11380"></a><span class="lineno">11380</span>&#160;    VkImage hImage,</div><div class="line"><a name="l11381"></a><span class="lineno">11381</span>&#160;    VkMemoryRequirements&amp; memReq,</div><div class="line"><a name="l11382"></a><span class="lineno">11382</span>&#160;    <span class="keywordtype">bool</span>&amp; requiresDedicatedAllocation,</div><div class="line"><a name="l11383"></a><span class="lineno">11383</span>&#160;    <span class="keywordtype">bool</span>&amp; prefersDedicatedAllocation)<span class="keyword"> const</span></div><div class="line"><a name="l11384"></a><span class="lineno">11384</span>&#160;<span class="keyword"></span>{</div><div class="line"><a name="l11385"></a><span class="lineno">11385</span>&#160;<span class="preprocessor">#if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11386"></a><span class="lineno">11386</span>&#160;    <span class="keywordflow">if</span>(m_UseKhrDedicatedAllocation)</div><div class="line"><a name="l11387"></a><span class="lineno">11387</span>&#160;    {</div><div class="line"><a name="l11388"></a><span class="lineno">11388</span>&#160;        VkImageMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR };</div><div class="line"><a name="l11389"></a><span class="lineno">11389</span>&#160;        memReqInfo.image = hImage;</div><div class="line"><a name="l11390"></a><span class="lineno">11390</span>&#160;</div><div class="line"><a name="l11391"></a><span class="lineno">11391</span>&#160;        VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };</div><div class="line"><a name="l11392"></a><span class="lineno">11392</span>&#160;</div><div class="line"><a name="l11393"></a><span class="lineno">11393</span>&#160;        VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };</div><div class="line"><a name="l11394"></a><span class="lineno">11394</span>&#160;        memReq2.pNext = &amp;memDedicatedReq;</div><div class="line"><a name="l11395"></a><span class="lineno">11395</span>&#160;</div><div class="line"><a name="l11396"></a><span class="lineno">11396</span>&#160;        (*m_VulkanFunctions.vkGetImageMemoryRequirements2KHR)(m_hDevice, &amp;memReqInfo, &amp;memReq2);</div><div class="line"><a name="l11397"></a><span class="lineno">11397</span>&#160;</div><div class="line"><a name="l11398"></a><span class="lineno">11398</span>&#160;        memReq = memReq2.memoryRequirements;</div><div class="line"><a name="l11399"></a><span class="lineno">11399</span>&#160;        requiresDedicatedAllocation = (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE);</div><div class="line"><a name="l11400"></a><span class="lineno">11400</span>&#160;        prefersDedicatedAllocation  = (memDedicatedReq.prefersDedicatedAllocation  != VK_FALSE);</div><div class="line"><a name="l11401"></a><span class="lineno">11401</span>&#160;    }</div><div class="line"><a name="l11402"></a><span class="lineno">11402</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l11403"></a><span class="lineno">11403</span>&#160;<span class="preprocessor">#endif // #if VMA_DEDICATED_ALLOCATION</span></div><div class="line"><a name="l11404"></a><span class="lineno">11404</span>&#160;    {</div><div class="line"><a name="l11405"></a><span class="lineno">11405</span>&#160;        (*m_VulkanFunctions.vkGetImageMemoryRequirements)(m_hDevice, hImage, &amp;memReq);</div><div class="line"><a name="l11406"></a><span class="lineno">11406</span>&#160;        requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l11407"></a><span class="lineno">11407</span>&#160;        prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l11408"></a><span class="lineno">11408</span>&#160;    }</div><div class="line"><a name="l11409"></a><span class="lineno">11409</span>&#160;}</div><div class="line"><a name="l11410"></a><span class="lineno">11410</span>&#160;</div><div class="line"><a name="l11411"></a><span class="lineno">11411</span>&#160;VkResult VmaAllocator_T::AllocateMemory(</div><div class="line"><a name="l11412"></a><span class="lineno">11412</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements&amp; vkMemReq,</div><div class="line"><a name="l11413"></a><span class="lineno">11413</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation,</div><div class="line"><a name="l11414"></a><span class="lineno">11414</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation,</div><div class="line"><a name="l11415"></a><span class="lineno">11415</span>&#160;    VkBuffer dedicatedBuffer,</div><div class="line"><a name="l11416"></a><span class="lineno">11416</span>&#160;    VkImage dedicatedImage,</div><div class="line"><a name="l11417"></a><span class="lineno">11417</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>&amp; createInfo,</div><div class="line"><a name="l11418"></a><span class="lineno">11418</span>&#160;    VmaSuballocationType suballocType,</div><div class="line"><a name="l11419"></a><span class="lineno">11419</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l11420"></a><span class="lineno">11420</span>&#160;{</div><div class="line"><a name="l11421"></a><span class="lineno">11421</span>&#160;    <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>) != 0 &amp;&amp;</div><div class="line"><a name="l11422"></a><span class="lineno">11422</span>&#160;        (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l11423"></a><span class="lineno">11423</span>&#160;    {</div><div class="line"><a name="l11424"></a><span class="lineno">11424</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT together with VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT makes no sense.&quot;</span>);</div><div class="line"><a name="l11425"></a><span class="lineno">11425</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11426"></a><span class="lineno">11426</span>&#160;    }</div><div class="line"><a name="l11427"></a><span class="lineno">11427</span>&#160;    <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0 &amp;&amp;</div><div class="line"><a name="l11428"></a><span class="lineno">11428</span>&#160;        (createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0)</div><div class="line"><a name="l11429"></a><span class="lineno">11429</span>&#160;    {</div><div class="line"><a name="l11430"></a><span class="lineno">11430</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Specifying VMA_ALLOCATION_CREATE_MAPPED_BIT together with VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT is invalid.&quot;</span>);</div><div class="line"><a name="l11431"></a><span class="lineno">11431</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11432"></a><span class="lineno">11432</span>&#160;    }</div><div class="line"><a name="l11433"></a><span class="lineno">11433</span>&#160;    <span class="keywordflow">if</span>(requiresDedicatedAllocation)</div><div class="line"><a name="l11434"></a><span class="lineno">11434</span>&#160;    {</div><div class="line"><a name="l11435"></a><span class="lineno">11435</span>&#160;        <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a>) != 0)</div><div class="line"><a name="l11436"></a><span class="lineno">11436</span>&#160;        {</div><div class="line"><a name="l11437"></a><span class="lineno">11437</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT specified while dedicated allocation is required.&quot;</span>);</div><div class="line"><a name="l11438"></a><span class="lineno">11438</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11439"></a><span class="lineno">11439</span>&#160;        }</div><div class="line"><a name="l11440"></a><span class="lineno">11440</span>&#160;        <span class="keywordflow">if</span>(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> != VK_NULL_HANDLE)</div><div class="line"><a name="l11441"></a><span class="lineno">11441</span>&#160;        {</div><div class="line"><a name="l11442"></a><span class="lineno">11442</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Pool specified while dedicated allocation is required.&quot;</span>);</div><div class="line"><a name="l11443"></a><span class="lineno">11443</span>&#160;            <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11444"></a><span class="lineno">11444</span>&#160;        }</div><div class="line"><a name="l11445"></a><span class="lineno">11445</span>&#160;    }</div><div class="line"><a name="l11446"></a><span class="lineno">11446</span>&#160;    <span class="keywordflow">if</span>((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> != VK_NULL_HANDLE) &amp;&amp;</div><div class="line"><a name="l11447"></a><span class="lineno">11447</span>&#160;        ((createInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; (<a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>)) != 0))</div><div class="line"><a name="l11448"></a><span class="lineno">11448</span>&#160;    {</div><div class="line"><a name="l11449"></a><span class="lineno">11449</span>&#160;        VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT when pool != null is invalid.&quot;</span>);</div><div class="line"><a name="l11450"></a><span class="lineno">11450</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11451"></a><span class="lineno">11451</span>&#160;    }</div><div class="line"><a name="l11452"></a><span class="lineno">11452</span>&#160;</div><div class="line"><a name="l11453"></a><span class="lineno">11453</span>&#160;    <span class="keywordflow">if</span>(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> != VK_NULL_HANDLE)</div><div class="line"><a name="l11454"></a><span class="lineno">11454</span>&#160;    {</div><div class="line"><a name="l11455"></a><span class="lineno">11455</span>&#160;        <span class="keyword">const</span> VkDeviceSize alignmentForPool = VMA_MAX(</div><div class="line"><a name="l11456"></a><span class="lineno">11456</span>&#160;            vkMemReq.alignment,</div><div class="line"><a name="l11457"></a><span class="lineno">11457</span>&#160;            GetMemoryTypeMinAlignment(createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>-&gt;m_BlockVector.GetMemoryTypeIndex()));</div><div class="line"><a name="l11458"></a><span class="lineno">11458</span>&#160;        <span class="keywordflow">return</span> createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>-&gt;m_BlockVector.Allocate(</div><div class="line"><a name="l11459"></a><span class="lineno">11459</span>&#160;            createInfo.<a class="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a>,</div><div class="line"><a name="l11460"></a><span class="lineno">11460</span>&#160;            m_CurrentFrameIndex.load(),</div><div class="line"><a name="l11461"></a><span class="lineno">11461</span>&#160;            vkMemReq.size,</div><div class="line"><a name="l11462"></a><span class="lineno">11462</span>&#160;            alignmentForPool,</div><div class="line"><a name="l11463"></a><span class="lineno">11463</span>&#160;            createInfo,</div><div class="line"><a name="l11464"></a><span class="lineno">11464</span>&#160;            suballocType,</div><div class="line"><a name="l11465"></a><span class="lineno">11465</span>&#160;            pAllocation);</div><div class="line"><a name="l11466"></a><span class="lineno">11466</span>&#160;    }</div><div class="line"><a name="l11467"></a><span class="lineno">11467</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l11468"></a><span class="lineno">11468</span>&#160;    {</div><div class="line"><a name="l11469"></a><span class="lineno">11469</span>&#160;        <span class="comment">// Bit mask of memory Vulkan types acceptable for this allocation.</span></div><div class="line"><a name="l11470"></a><span class="lineno">11470</span>&#160;        uint32_t memoryTypeBits = vkMemReq.memoryTypeBits;</div><div class="line"><a name="l11471"></a><span class="lineno">11471</span>&#160;        uint32_t memTypeIndex = UINT32_MAX;</div><div class="line"><a name="l11472"></a><span class="lineno">11472</span>&#160;        VkResult res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(<span class="keyword">this</span>, memoryTypeBits, &amp;createInfo, &amp;memTypeIndex);</div><div class="line"><a name="l11473"></a><span class="lineno">11473</span>&#160;        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l11474"></a><span class="lineno">11474</span>&#160;        {</div><div class="line"><a name="l11475"></a><span class="lineno">11475</span>&#160;            VkDeviceSize alignmentForMemType = VMA_MAX(</div><div class="line"><a name="l11476"></a><span class="lineno">11476</span>&#160;                vkMemReq.alignment,</div><div class="line"><a name="l11477"></a><span class="lineno">11477</span>&#160;                GetMemoryTypeMinAlignment(memTypeIndex));</div><div class="line"><a name="l11478"></a><span class="lineno">11478</span>&#160;</div><div class="line"><a name="l11479"></a><span class="lineno">11479</span>&#160;            res = AllocateMemoryOfType(</div><div class="line"><a name="l11480"></a><span class="lineno">11480</span>&#160;                vkMemReq.size,</div><div class="line"><a name="l11481"></a><span class="lineno">11481</span>&#160;                alignmentForMemType,</div><div class="line"><a name="l11482"></a><span class="lineno">11482</span>&#160;                requiresDedicatedAllocation || prefersDedicatedAllocation,</div><div class="line"><a name="l11483"></a><span class="lineno">11483</span>&#160;                dedicatedBuffer,</div><div class="line"><a name="l11484"></a><span class="lineno">11484</span>&#160;                dedicatedImage,</div><div class="line"><a name="l11485"></a><span class="lineno">11485</span>&#160;                createInfo,</div><div class="line"><a name="l11486"></a><span class="lineno">11486</span>&#160;                memTypeIndex,</div><div class="line"><a name="l11487"></a><span class="lineno">11487</span>&#160;                suballocType,</div><div class="line"><a name="l11488"></a><span class="lineno">11488</span>&#160;                pAllocation);</div><div class="line"><a name="l11489"></a><span class="lineno">11489</span>&#160;            <span class="comment">// Succeeded on first try.</span></div><div class="line"><a name="l11490"></a><span class="lineno">11490</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l11491"></a><span class="lineno">11491</span>&#160;            {</div><div class="line"><a name="l11492"></a><span class="lineno">11492</span>&#160;                <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11493"></a><span class="lineno">11493</span>&#160;            }</div><div class="line"><a name="l11494"></a><span class="lineno">11494</span>&#160;            <span class="comment">// Allocation from this memory type failed. Try other compatible memory types.</span></div><div class="line"><a name="l11495"></a><span class="lineno">11495</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l11496"></a><span class="lineno">11496</span>&#160;            {</div><div class="line"><a name="l11497"></a><span class="lineno">11497</span>&#160;                <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l11498"></a><span class="lineno">11498</span>&#160;                {</div><div class="line"><a name="l11499"></a><span class="lineno">11499</span>&#160;                    <span class="comment">// Remove old memTypeIndex from list of possibilities.</span></div><div class="line"><a name="l11500"></a><span class="lineno">11500</span>&#160;                    memoryTypeBits &amp;= ~(1u &lt;&lt; memTypeIndex);</div><div class="line"><a name="l11501"></a><span class="lineno">11501</span>&#160;                    <span class="comment">// Find alternative memTypeIndex.</span></div><div class="line"><a name="l11502"></a><span class="lineno">11502</span>&#160;                    res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(<span class="keyword">this</span>, memoryTypeBits, &amp;createInfo, &amp;memTypeIndex);</div><div class="line"><a name="l11503"></a><span class="lineno">11503</span>&#160;                    <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l11504"></a><span class="lineno">11504</span>&#160;                    {</div><div class="line"><a name="l11505"></a><span class="lineno">11505</span>&#160;                        alignmentForMemType = VMA_MAX(</div><div class="line"><a name="l11506"></a><span class="lineno">11506</span>&#160;                            vkMemReq.alignment,</div><div class="line"><a name="l11507"></a><span class="lineno">11507</span>&#160;                            GetMemoryTypeMinAlignment(memTypeIndex));</div><div class="line"><a name="l11508"></a><span class="lineno">11508</span>&#160;                        </div><div class="line"><a name="l11509"></a><span class="lineno">11509</span>&#160;                        res = AllocateMemoryOfType(</div><div class="line"><a name="l11510"></a><span class="lineno">11510</span>&#160;                            vkMemReq.size,</div><div class="line"><a name="l11511"></a><span class="lineno">11511</span>&#160;                            alignmentForMemType,</div><div class="line"><a name="l11512"></a><span class="lineno">11512</span>&#160;                            requiresDedicatedAllocation || prefersDedicatedAllocation,</div><div class="line"><a name="l11513"></a><span class="lineno">11513</span>&#160;                            dedicatedBuffer,</div><div class="line"><a name="l11514"></a><span class="lineno">11514</span>&#160;                            dedicatedImage,</div><div class="line"><a name="l11515"></a><span class="lineno">11515</span>&#160;                            createInfo,</div><div class="line"><a name="l11516"></a><span class="lineno">11516</span>&#160;                            memTypeIndex,</div><div class="line"><a name="l11517"></a><span class="lineno">11517</span>&#160;                            suballocType,</div><div class="line"><a name="l11518"></a><span class="lineno">11518</span>&#160;                            pAllocation);</div><div class="line"><a name="l11519"></a><span class="lineno">11519</span>&#160;                        <span class="comment">// Allocation from this alternative memory type succeeded.</span></div><div class="line"><a name="l11520"></a><span class="lineno">11520</span>&#160;                        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l11521"></a><span class="lineno">11521</span>&#160;                        {</div><div class="line"><a name="l11522"></a><span class="lineno">11522</span>&#160;                            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11523"></a><span class="lineno">11523</span>&#160;                        }</div><div class="line"><a name="l11524"></a><span class="lineno">11524</span>&#160;                        <span class="comment">// else: Allocation from this memory type failed. Try next one - next loop iteration.</span></div><div class="line"><a name="l11525"></a><span class="lineno">11525</span>&#160;                    }</div><div class="line"><a name="l11526"></a><span class="lineno">11526</span>&#160;                    <span class="comment">// No other matching memory type index could be found.</span></div><div class="line"><a name="l11527"></a><span class="lineno">11527</span>&#160;                    <span class="keywordflow">else</span></div><div class="line"><a name="l11528"></a><span class="lineno">11528</span>&#160;                    {</div><div class="line"><a name="l11529"></a><span class="lineno">11529</span>&#160;                        <span class="comment">// Not returning res, which is VK_ERROR_FEATURE_NOT_PRESENT, because we already failed to allocate once.</span></div><div class="line"><a name="l11530"></a><span class="lineno">11530</span>&#160;                        <span class="keywordflow">return</span> VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l11531"></a><span class="lineno">11531</span>&#160;                    }</div><div class="line"><a name="l11532"></a><span class="lineno">11532</span>&#160;                }</div><div class="line"><a name="l11533"></a><span class="lineno">11533</span>&#160;            }</div><div class="line"><a name="l11534"></a><span class="lineno">11534</span>&#160;        }</div><div class="line"><a name="l11535"></a><span class="lineno">11535</span>&#160;        <span class="comment">// Can&#39;t find any single memory type maching requirements. res is VK_ERROR_FEATURE_NOT_PRESENT.</span></div><div class="line"><a name="l11536"></a><span class="lineno">11536</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l11537"></a><span class="lineno">11537</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11538"></a><span class="lineno">11538</span>&#160;    }</div><div class="line"><a name="l11539"></a><span class="lineno">11539</span>&#160;}</div><div class="line"><a name="l11540"></a><span class="lineno">11540</span>&#160;</div><div class="line"><a name="l11541"></a><span class="lineno">11541</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FreeMemory(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l11542"></a><span class="lineno">11542</span>&#160;{</div><div class="line"><a name="l11543"></a><span class="lineno">11543</span>&#160;    VMA_ASSERT(allocation);</div><div class="line"><a name="l11544"></a><span class="lineno">11544</span>&#160;</div><div class="line"><a name="l11545"></a><span class="lineno">11545</span>&#160;    <span class="keywordflow">if</span>(allocation-&gt;CanBecomeLost() == <span class="keyword">false</span> ||</div><div class="line"><a name="l11546"></a><span class="lineno">11546</span>&#160;        allocation-&gt;GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l11547"></a><span class="lineno">11547</span>&#160;    {</div><div class="line"><a name="l11548"></a><span class="lineno">11548</span>&#160;        <span class="keywordflow">if</span>(VMA_DEBUG_INITIALIZE_ALLOCATIONS)</div><div class="line"><a name="l11549"></a><span class="lineno">11549</span>&#160;        {</div><div class="line"><a name="l11550"></a><span class="lineno">11550</span>&#160;            FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);</div><div class="line"><a name="l11551"></a><span class="lineno">11551</span>&#160;        }</div><div class="line"><a name="l11552"></a><span class="lineno">11552</span>&#160;</div><div class="line"><a name="l11553"></a><span class="lineno">11553</span>&#160;        <span class="keywordflow">switch</span>(allocation-&gt;GetType())</div><div class="line"><a name="l11554"></a><span class="lineno">11554</span>&#160;        {</div><div class="line"><a name="l11555"></a><span class="lineno">11555</span>&#160;        <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l11556"></a><span class="lineno">11556</span>&#160;            {</div><div class="line"><a name="l11557"></a><span class="lineno">11557</span>&#160;                VmaBlockVector* pBlockVector = VMA_NULL;</div><div class="line"><a name="l11558"></a><span class="lineno">11558</span>&#160;                <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool = allocation-&gt;GetPool();</div><div class="line"><a name="l11559"></a><span class="lineno">11559</span>&#160;                <span class="keywordflow">if</span>(hPool != VK_NULL_HANDLE)</div><div class="line"><a name="l11560"></a><span class="lineno">11560</span>&#160;                {</div><div class="line"><a name="l11561"></a><span class="lineno">11561</span>&#160;                    pBlockVector = &amp;hPool-&gt;m_BlockVector;</div><div class="line"><a name="l11562"></a><span class="lineno">11562</span>&#160;                }</div><div class="line"><a name="l11563"></a><span class="lineno">11563</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l11564"></a><span class="lineno">11564</span>&#160;                {</div><div class="line"><a name="l11565"></a><span class="lineno">11565</span>&#160;                    <span class="keyword">const</span> uint32_t memTypeIndex = allocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l11566"></a><span class="lineno">11566</span>&#160;                    pBlockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l11567"></a><span class="lineno">11567</span>&#160;                }</div><div class="line"><a name="l11568"></a><span class="lineno">11568</span>&#160;                pBlockVector-&gt;Free(allocation);</div><div class="line"><a name="l11569"></a><span class="lineno">11569</span>&#160;            }</div><div class="line"><a name="l11570"></a><span class="lineno">11570</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l11571"></a><span class="lineno">11571</span>&#160;        <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l11572"></a><span class="lineno">11572</span>&#160;            FreeDedicatedMemory(allocation);</div><div class="line"><a name="l11573"></a><span class="lineno">11573</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l11574"></a><span class="lineno">11574</span>&#160;        <span class="keywordflow">default</span>:</div><div class="line"><a name="l11575"></a><span class="lineno">11575</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l11576"></a><span class="lineno">11576</span>&#160;        }</div><div class="line"><a name="l11577"></a><span class="lineno">11577</span>&#160;    }</div><div class="line"><a name="l11578"></a><span class="lineno">11578</span>&#160;</div><div class="line"><a name="l11579"></a><span class="lineno">11579</span>&#160;    allocation-&gt;SetUserData(<span class="keyword">this</span>, VMA_NULL);</div><div class="line"><a name="l11580"></a><span class="lineno">11580</span>&#160;    vma_delete(<span class="keyword">this</span>, allocation);</div><div class="line"><a name="l11581"></a><span class="lineno">11581</span>&#160;}</div><div class="line"><a name="l11582"></a><span class="lineno">11582</span>&#160;</div><div class="line"><a name="l11583"></a><span class="lineno">11583</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::CalculateStats(<a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats)</div><div class="line"><a name="l11584"></a><span class="lineno">11584</span>&#160;{</div><div class="line"><a name="l11585"></a><span class="lineno">11585</span>&#160;    <span class="comment">// Initialize.</span></div><div class="line"><a name="l11586"></a><span class="lineno">11586</span>&#160;    InitStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>);</div><div class="line"><a name="l11587"></a><span class="lineno">11587</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; VK_MAX_MEMORY_TYPES; ++i)</div><div class="line"><a name="l11588"></a><span class="lineno">11588</span>&#160;        InitStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[i]);</div><div class="line"><a name="l11589"></a><span class="lineno">11589</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; VK_MAX_MEMORY_HEAPS; ++i)</div><div class="line"><a name="l11590"></a><span class="lineno">11590</span>&#160;        InitStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[i]);</div><div class="line"><a name="l11591"></a><span class="lineno">11591</span>&#160;    </div><div class="line"><a name="l11592"></a><span class="lineno">11592</span>&#160;    <span class="comment">// Process default pools.</span></div><div class="line"><a name="l11593"></a><span class="lineno">11593</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l11594"></a><span class="lineno">11594</span>&#160;    {</div><div class="line"><a name="l11595"></a><span class="lineno">11595</span>&#160;        VmaBlockVector* <span class="keyword">const</span> pBlockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l11596"></a><span class="lineno">11596</span>&#160;        VMA_ASSERT(pBlockVector);</div><div class="line"><a name="l11597"></a><span class="lineno">11597</span>&#160;        pBlockVector-&gt;AddStats(pStats);</div><div class="line"><a name="l11598"></a><span class="lineno">11598</span>&#160;    }</div><div class="line"><a name="l11599"></a><span class="lineno">11599</span>&#160;</div><div class="line"><a name="l11600"></a><span class="lineno">11600</span>&#160;    <span class="comment">// Process custom pools.</span></div><div class="line"><a name="l11601"></a><span class="lineno">11601</span>&#160;    {</div><div class="line"><a name="l11602"></a><span class="lineno">11602</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l11603"></a><span class="lineno">11603</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = 0, poolCount = m_Pools.size(); poolIndex &lt; poolCount; ++poolIndex)</div><div class="line"><a name="l11604"></a><span class="lineno">11604</span>&#160;        {</div><div class="line"><a name="l11605"></a><span class="lineno">11605</span>&#160;            m_Pools[poolIndex]-&gt;m_BlockVector.AddStats(pStats);</div><div class="line"><a name="l11606"></a><span class="lineno">11606</span>&#160;        }</div><div class="line"><a name="l11607"></a><span class="lineno">11607</span>&#160;    }</div><div class="line"><a name="l11608"></a><span class="lineno">11608</span>&#160;</div><div class="line"><a name="l11609"></a><span class="lineno">11609</span>&#160;    <span class="comment">// Process dedicated allocations.</span></div><div class="line"><a name="l11610"></a><span class="lineno">11610</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l11611"></a><span class="lineno">11611</span>&#160;    {</div><div class="line"><a name="l11612"></a><span class="lineno">11612</span>&#160;        <span class="keyword">const</span> uint32_t memHeapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);</div><div class="line"><a name="l11613"></a><span class="lineno">11613</span>&#160;        VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l11614"></a><span class="lineno">11614</span>&#160;        AllocationVectorType* <span class="keyword">const</span> pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l11615"></a><span class="lineno">11615</span>&#160;        VMA_ASSERT(pDedicatedAllocVector);</div><div class="line"><a name="l11616"></a><span class="lineno">11616</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> allocIndex = 0, allocCount = pDedicatedAllocVector-&gt;size(); allocIndex &lt; allocCount; ++allocIndex)</div><div class="line"><a name="l11617"></a><span class="lineno">11617</span>&#160;        {</div><div class="line"><a name="l11618"></a><span class="lineno">11618</span>&#160;            <a class="code" href="struct_vma_stat_info.html">VmaStatInfo</a> allocationStatInfo;</div><div class="line"><a name="l11619"></a><span class="lineno">11619</span>&#160;            (*pDedicatedAllocVector)[allocIndex]-&gt;DedicatedAllocCalcStatsInfo(allocationStatInfo);</div><div class="line"><a name="l11620"></a><span class="lineno">11620</span>&#160;            VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>, allocationStatInfo);</div><div class="line"><a name="l11621"></a><span class="lineno">11621</span>&#160;            VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[memTypeIndex], allocationStatInfo);</div><div class="line"><a name="l11622"></a><span class="lineno">11622</span>&#160;            VmaAddStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[memHeapIndex], allocationStatInfo);</div><div class="line"><a name="l11623"></a><span class="lineno">11623</span>&#160;        }</div><div class="line"><a name="l11624"></a><span class="lineno">11624</span>&#160;    }</div><div class="line"><a name="l11625"></a><span class="lineno">11625</span>&#160;</div><div class="line"><a name="l11626"></a><span class="lineno">11626</span>&#160;    <span class="comment">// Postprocess.</span></div><div class="line"><a name="l11627"></a><span class="lineno">11627</span>&#160;    VmaPostprocessCalcStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>);</div><div class="line"><a name="l11628"></a><span class="lineno">11628</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; GetMemoryTypeCount(); ++i)</div><div class="line"><a name="l11629"></a><span class="lineno">11629</span>&#160;        VmaPostprocessCalcStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[i]);</div><div class="line"><a name="l11630"></a><span class="lineno">11630</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; GetMemoryHeapCount(); ++i)</div><div class="line"><a name="l11631"></a><span class="lineno">11631</span>&#160;        VmaPostprocessCalcStatInfo(pStats-&gt;<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[i]);</div><div class="line"><a name="l11632"></a><span class="lineno">11632</span>&#160;}</div><div class="line"><a name="l11633"></a><span class="lineno">11633</span>&#160;</div><div class="line"><a name="l11634"></a><span class="lineno">11634</span>&#160;<span class="keyword">static</span> <span class="keyword">const</span> uint32_t VMA_VENDOR_ID_AMD = 4098;</div><div class="line"><a name="l11635"></a><span class="lineno">11635</span>&#160;</div><div class="line"><a name="l11636"></a><span class="lineno">11636</span>&#160;VkResult VmaAllocator_T::Defragment(</div><div class="line"><a name="l11637"></a><span class="lineno">11637</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l11638"></a><span class="lineno">11638</span>&#160;    <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l11639"></a><span class="lineno">11639</span>&#160;    VkBool32* pAllocationsChanged,</div><div class="line"><a name="l11640"></a><span class="lineno">11640</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a>* pDefragmentationInfo,</div><div class="line"><a name="l11641"></a><span class="lineno">11641</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats)</div><div class="line"><a name="l11642"></a><span class="lineno">11642</span>&#160;{</div><div class="line"><a name="l11643"></a><span class="lineno">11643</span>&#160;    <span class="keywordflow">if</span>(pAllocationsChanged != VMA_NULL)</div><div class="line"><a name="l11644"></a><span class="lineno">11644</span>&#160;    {</div><div class="line"><a name="l11645"></a><span class="lineno">11645</span>&#160;        memset(pAllocationsChanged, 0, <span class="keyword">sizeof</span>(*pAllocationsChanged));</div><div class="line"><a name="l11646"></a><span class="lineno">11646</span>&#160;    }</div><div class="line"><a name="l11647"></a><span class="lineno">11647</span>&#160;    <span class="keywordflow">if</span>(pDefragmentationStats != VMA_NULL)</div><div class="line"><a name="l11648"></a><span class="lineno">11648</span>&#160;    {</div><div class="line"><a name="l11649"></a><span class="lineno">11649</span>&#160;        memset(pDefragmentationStats, 0, <span class="keyword">sizeof</span>(*pDefragmentationStats));</div><div class="line"><a name="l11650"></a><span class="lineno">11650</span>&#160;    }</div><div class="line"><a name="l11651"></a><span class="lineno">11651</span>&#160;</div><div class="line"><a name="l11652"></a><span class="lineno">11652</span>&#160;    <span class="keyword">const</span> uint32_t currentFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l11653"></a><span class="lineno">11653</span>&#160;</div><div class="line"><a name="l11654"></a><span class="lineno">11654</span>&#160;    VmaMutexLock poolsLock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l11655"></a><span class="lineno">11655</span>&#160;</div><div class="line"><a name="l11656"></a><span class="lineno">11656</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> poolCount = m_Pools.size();</div><div class="line"><a name="l11657"></a><span class="lineno">11657</span>&#160;</div><div class="line"><a name="l11658"></a><span class="lineno">11658</span>&#160;    <span class="comment">// Dispatch pAllocations among defragmentators. Create them in BlockVectors when necessary.</span></div><div class="line"><a name="l11659"></a><span class="lineno">11659</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> allocIndex = 0; allocIndex &lt; allocationCount; ++allocIndex)</div><div class="line"><a name="l11660"></a><span class="lineno">11660</span>&#160;    {</div><div class="line"><a name="l11661"></a><span class="lineno">11661</span>&#160;        <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc = pAllocations[allocIndex];</div><div class="line"><a name="l11662"></a><span class="lineno">11662</span>&#160;        VMA_ASSERT(hAlloc);</div><div class="line"><a name="l11663"></a><span class="lineno">11663</span>&#160;        <span class="keyword">const</span> uint32_t memTypeIndex = hAlloc-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l11664"></a><span class="lineno">11664</span>&#160;        <span class="comment">// DedicatedAlloc cannot be defragmented.</span></div><div class="line"><a name="l11665"></a><span class="lineno">11665</span>&#160;        <span class="keyword">const</span> VkMemoryPropertyFlags requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;</div><div class="line"><a name="l11666"></a><span class="lineno">11666</span>&#160;        <span class="keywordflow">if</span>((hAlloc-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK) &amp;&amp;</div><div class="line"><a name="l11667"></a><span class="lineno">11667</span>&#160;            <span class="comment">// Only HOST_VISIBLE and HOST_COHERENT memory types can be defragmented.</span></div><div class="line"><a name="l11668"></a><span class="lineno">11668</span>&#160;            ((m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; requiredMemFlags) == requiredMemFlags) &amp;&amp;</div><div class="line"><a name="l11669"></a><span class="lineno">11669</span>&#160;            <span class="comment">// Lost allocation cannot be defragmented.</span></div><div class="line"><a name="l11670"></a><span class="lineno">11670</span>&#160;            (hAlloc-&gt;GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST))</div><div class="line"><a name="l11671"></a><span class="lineno">11671</span>&#160;        {</div><div class="line"><a name="l11672"></a><span class="lineno">11672</span>&#160;            VmaBlockVector* pAllocBlockVector = VMA_NULL;</div><div class="line"><a name="l11673"></a><span class="lineno">11673</span>&#160;</div><div class="line"><a name="l11674"></a><span class="lineno">11674</span>&#160;            <span class="keyword">const</span> <a class="code" href="struct_vma_pool.html">VmaPool</a> hAllocPool = hAlloc-&gt;GetPool();</div><div class="line"><a name="l11675"></a><span class="lineno">11675</span>&#160;            <span class="comment">// This allocation belongs to custom pool.</span></div><div class="line"><a name="l11676"></a><span class="lineno">11676</span>&#160;            <span class="keywordflow">if</span>(hAllocPool != VK_NULL_HANDLE)</div><div class="line"><a name="l11677"></a><span class="lineno">11677</span>&#160;            {</div><div class="line"><a name="l11678"></a><span class="lineno">11678</span>&#160;                <span class="comment">// Pools with linear algorithm are not defragmented.</span></div><div class="line"><a name="l11679"></a><span class="lineno">11679</span>&#160;                <span class="keywordflow">if</span>(!hAllocPool-&gt;m_BlockVector.UsesLinearAlgorithm())</div><div class="line"><a name="l11680"></a><span class="lineno">11680</span>&#160;                {</div><div class="line"><a name="l11681"></a><span class="lineno">11681</span>&#160;                    pAllocBlockVector = &amp;hAllocPool-&gt;m_BlockVector;</div><div class="line"><a name="l11682"></a><span class="lineno">11682</span>&#160;                }</div><div class="line"><a name="l11683"></a><span class="lineno">11683</span>&#160;            }</div><div class="line"><a name="l11684"></a><span class="lineno">11684</span>&#160;            <span class="comment">// This allocation belongs to general pool.</span></div><div class="line"><a name="l11685"></a><span class="lineno">11685</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l11686"></a><span class="lineno">11686</span>&#160;            {</div><div class="line"><a name="l11687"></a><span class="lineno">11687</span>&#160;                pAllocBlockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l11688"></a><span class="lineno">11688</span>&#160;            }</div><div class="line"><a name="l11689"></a><span class="lineno">11689</span>&#160;</div><div class="line"><a name="l11690"></a><span class="lineno">11690</span>&#160;            <span class="keywordflow">if</span>(pAllocBlockVector != VMA_NULL)</div><div class="line"><a name="l11691"></a><span class="lineno">11691</span>&#160;            {</div><div class="line"><a name="l11692"></a><span class="lineno">11692</span>&#160;                VmaDefragmentator* <span class="keyword">const</span> pDefragmentator =</div><div class="line"><a name="l11693"></a><span class="lineno">11693</span>&#160;                    pAllocBlockVector-&gt;EnsureDefragmentator(<span class="keyword">this</span>, currentFrameIndex);</div><div class="line"><a name="l11694"></a><span class="lineno">11694</span>&#160;                VkBool32* <span class="keyword">const</span> pChanged = (pAllocationsChanged != VMA_NULL) ?</div><div class="line"><a name="l11695"></a><span class="lineno">11695</span>&#160;                    &amp;pAllocationsChanged[allocIndex] : VMA_NULL;</div><div class="line"><a name="l11696"></a><span class="lineno">11696</span>&#160;                pDefragmentator-&gt;AddAllocation(hAlloc, pChanged);</div><div class="line"><a name="l11697"></a><span class="lineno">11697</span>&#160;            }</div><div class="line"><a name="l11698"></a><span class="lineno">11698</span>&#160;        }</div><div class="line"><a name="l11699"></a><span class="lineno">11699</span>&#160;    }</div><div class="line"><a name="l11700"></a><span class="lineno">11700</span>&#160;</div><div class="line"><a name="l11701"></a><span class="lineno">11701</span>&#160;    VkResult result = VK_SUCCESS;</div><div class="line"><a name="l11702"></a><span class="lineno">11702</span>&#160;</div><div class="line"><a name="l11703"></a><span class="lineno">11703</span>&#160;    <span class="comment">// ======== Main processing.</span></div><div class="line"><a name="l11704"></a><span class="lineno">11704</span>&#160;</div><div class="line"><a name="l11705"></a><span class="lineno">11705</span>&#160;    VkDeviceSize maxBytesToMove = SIZE_MAX;</div><div class="line"><a name="l11706"></a><span class="lineno">11706</span>&#160;    uint32_t maxAllocationsToMove = UINT32_MAX;</div><div class="line"><a name="l11707"></a><span class="lineno">11707</span>&#160;    <span class="keywordflow">if</span>(pDefragmentationInfo != VMA_NULL)</div><div class="line"><a name="l11708"></a><span class="lineno">11708</span>&#160;    {</div><div class="line"><a name="l11709"></a><span class="lineno">11709</span>&#160;        maxBytesToMove = pDefragmentationInfo-&gt;<a class="code" href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d">maxBytesToMove</a>;</div><div class="line"><a name="l11710"></a><span class="lineno">11710</span>&#160;        maxAllocationsToMove = pDefragmentationInfo-&gt;<a class="code" href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc">maxAllocationsToMove</a>;</div><div class="line"><a name="l11711"></a><span class="lineno">11711</span>&#160;    }</div><div class="line"><a name="l11712"></a><span class="lineno">11712</span>&#160;</div><div class="line"><a name="l11713"></a><span class="lineno">11713</span>&#160;    <span class="comment">// Process standard memory.</span></div><div class="line"><a name="l11714"></a><span class="lineno">11714</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0;</div><div class="line"><a name="l11715"></a><span class="lineno">11715</span>&#160;        (memTypeIndex &lt; GetMemoryTypeCount()) &amp;&amp; (result == VK_SUCCESS);</div><div class="line"><a name="l11716"></a><span class="lineno">11716</span>&#160;        ++memTypeIndex)</div><div class="line"><a name="l11717"></a><span class="lineno">11717</span>&#160;    {</div><div class="line"><a name="l11718"></a><span class="lineno">11718</span>&#160;        <span class="comment">// Only HOST_VISIBLE memory types can be defragmented.</span></div><div class="line"><a name="l11719"></a><span class="lineno">11719</span>&#160;        <span class="keywordflow">if</span>((m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)</div><div class="line"><a name="l11720"></a><span class="lineno">11720</span>&#160;        {</div><div class="line"><a name="l11721"></a><span class="lineno">11721</span>&#160;            result = m_pBlockVectors[memTypeIndex]-&gt;Defragment(</div><div class="line"><a name="l11722"></a><span class="lineno">11722</span>&#160;                pDefragmentationStats,</div><div class="line"><a name="l11723"></a><span class="lineno">11723</span>&#160;                maxBytesToMove,</div><div class="line"><a name="l11724"></a><span class="lineno">11724</span>&#160;                maxAllocationsToMove);</div><div class="line"><a name="l11725"></a><span class="lineno">11725</span>&#160;        }</div><div class="line"><a name="l11726"></a><span class="lineno">11726</span>&#160;    }</div><div class="line"><a name="l11727"></a><span class="lineno">11727</span>&#160;</div><div class="line"><a name="l11728"></a><span class="lineno">11728</span>&#160;    <span class="comment">// Process custom pools.</span></div><div class="line"><a name="l11729"></a><span class="lineno">11729</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = 0; (poolIndex &lt; poolCount) &amp;&amp; (result == VK_SUCCESS); ++poolIndex)</div><div class="line"><a name="l11730"></a><span class="lineno">11730</span>&#160;    {</div><div class="line"><a name="l11731"></a><span class="lineno">11731</span>&#160;        result = m_Pools[poolIndex]-&gt;m_BlockVector.Defragment(</div><div class="line"><a name="l11732"></a><span class="lineno">11732</span>&#160;            pDefragmentationStats,</div><div class="line"><a name="l11733"></a><span class="lineno">11733</span>&#160;            maxBytesToMove,</div><div class="line"><a name="l11734"></a><span class="lineno">11734</span>&#160;            maxAllocationsToMove);</div><div class="line"><a name="l11735"></a><span class="lineno">11735</span>&#160;    }</div><div class="line"><a name="l11736"></a><span class="lineno">11736</span>&#160;</div><div class="line"><a name="l11737"></a><span class="lineno">11737</span>&#160;    <span class="comment">// ========  Destroy defragmentators.</span></div><div class="line"><a name="l11738"></a><span class="lineno">11738</span>&#160;</div><div class="line"><a name="l11739"></a><span class="lineno">11739</span>&#160;    <span class="comment">// Process custom pools.</span></div><div class="line"><a name="l11740"></a><span class="lineno">11740</span>&#160;    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = poolCount; poolIndex--; )</div><div class="line"><a name="l11741"></a><span class="lineno">11741</span>&#160;    {</div><div class="line"><a name="l11742"></a><span class="lineno">11742</span>&#160;        m_Pools[poolIndex]-&gt;m_BlockVector.DestroyDefragmentator();</div><div class="line"><a name="l11743"></a><span class="lineno">11743</span>&#160;    }</div><div class="line"><a name="l11744"></a><span class="lineno">11744</span>&#160;</div><div class="line"><a name="l11745"></a><span class="lineno">11745</span>&#160;    <span class="comment">// Process standard memory.</span></div><div class="line"><a name="l11746"></a><span class="lineno">11746</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; )</div><div class="line"><a name="l11747"></a><span class="lineno">11747</span>&#160;    {</div><div class="line"><a name="l11748"></a><span class="lineno">11748</span>&#160;        <span class="keywordflow">if</span>((m_MemProps.memoryTypes[memTypeIndex].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)</div><div class="line"><a name="l11749"></a><span class="lineno">11749</span>&#160;        {</div><div class="line"><a name="l11750"></a><span class="lineno">11750</span>&#160;            m_pBlockVectors[memTypeIndex]-&gt;DestroyDefragmentator();</div><div class="line"><a name="l11751"></a><span class="lineno">11751</span>&#160;        }</div><div class="line"><a name="l11752"></a><span class="lineno">11752</span>&#160;    }</div><div class="line"><a name="l11753"></a><span class="lineno">11753</span>&#160;</div><div class="line"><a name="l11754"></a><span class="lineno">11754</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l11755"></a><span class="lineno">11755</span>&#160;}</div><div class="line"><a name="l11756"></a><span class="lineno">11756</span>&#160;</div><div class="line"><a name="l11757"></a><span class="lineno">11757</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetAllocationInfo(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l11758"></a><span class="lineno">11758</span>&#160;{</div><div class="line"><a name="l11759"></a><span class="lineno">11759</span>&#160;    <span class="keywordflow">if</span>(hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l11760"></a><span class="lineno">11760</span>&#160;    {</div><div class="line"><a name="l11761"></a><span class="lineno">11761</span>&#160;        <span class="comment">/*</span></div><div class="line"><a name="l11762"></a><span class="lineno">11762</span>&#160;<span class="comment">        Warning: This is a carefully designed algorithm.</span></div><div class="line"><a name="l11763"></a><span class="lineno">11763</span>&#160;<span class="comment">        Do not modify unless you really know what you&#39;re doing :)</span></div><div class="line"><a name="l11764"></a><span class="lineno">11764</span>&#160;<span class="comment">        */</span></div><div class="line"><a name="l11765"></a><span class="lineno">11765</span>&#160;        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l11766"></a><span class="lineno">11766</span>&#160;        uint32_t localLastUseFrameIndex = hAllocation-&gt;GetLastUseFrameIndex();</div><div class="line"><a name="l11767"></a><span class="lineno">11767</span>&#160;        <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l11768"></a><span class="lineno">11768</span>&#160;        {</div><div class="line"><a name="l11769"></a><span class="lineno">11769</span>&#160;            <span class="keywordflow">if</span>(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l11770"></a><span class="lineno">11770</span>&#160;            {</div><div class="line"><a name="l11771"></a><span class="lineno">11771</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a> = UINT32_MAX;</div><div class="line"><a name="l11772"></a><span class="lineno">11772</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a> = VK_NULL_HANDLE;</div><div class="line"><a name="l11773"></a><span class="lineno">11773</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a> = 0;</div><div class="line"><a name="l11774"></a><span class="lineno">11774</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a> = hAllocation-&gt;GetSize();</div><div class="line"><a name="l11775"></a><span class="lineno">11775</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a> = VMA_NULL;</div><div class="line"><a name="l11776"></a><span class="lineno">11776</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> = hAllocation-&gt;GetUserData();</div><div class="line"><a name="l11777"></a><span class="lineno">11777</span>&#160;                <span class="keywordflow">return</span>;</div><div class="line"><a name="l11778"></a><span class="lineno">11778</span>&#160;            }</div><div class="line"><a name="l11779"></a><span class="lineno">11779</span>&#160;            <span class="keywordflow">else</span> <span class="keywordflow">if</span>(localLastUseFrameIndex == localCurrFrameIndex)</div><div class="line"><a name="l11780"></a><span class="lineno">11780</span>&#160;            {</div><div class="line"><a name="l11781"></a><span class="lineno">11781</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a> = hAllocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l11782"></a><span class="lineno">11782</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a> = hAllocation-&gt;GetMemory();</div><div class="line"><a name="l11783"></a><span class="lineno">11783</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a> = hAllocation-&gt;GetOffset();</div><div class="line"><a name="l11784"></a><span class="lineno">11784</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a> = hAllocation-&gt;GetSize();</div><div class="line"><a name="l11785"></a><span class="lineno">11785</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a> = VMA_NULL;</div><div class="line"><a name="l11786"></a><span class="lineno">11786</span>&#160;                pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> = hAllocation-&gt;GetUserData();</div><div class="line"><a name="l11787"></a><span class="lineno">11787</span>&#160;                <span class="keywordflow">return</span>;</div><div class="line"><a name="l11788"></a><span class="lineno">11788</span>&#160;            }</div><div class="line"><a name="l11789"></a><span class="lineno">11789</span>&#160;            <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l11790"></a><span class="lineno">11790</span>&#160;            {</div><div class="line"><a name="l11791"></a><span class="lineno">11791</span>&#160;                <span class="keywordflow">if</span>(hAllocation-&gt;CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))</div><div class="line"><a name="l11792"></a><span class="lineno">11792</span>&#160;                {</div><div class="line"><a name="l11793"></a><span class="lineno">11793</span>&#160;                    localLastUseFrameIndex = localCurrFrameIndex;</div><div class="line"><a name="l11794"></a><span class="lineno">11794</span>&#160;                }</div><div class="line"><a name="l11795"></a><span class="lineno">11795</span>&#160;            }</div><div class="line"><a name="l11796"></a><span class="lineno">11796</span>&#160;        }</div><div class="line"><a name="l11797"></a><span class="lineno">11797</span>&#160;    }</div><div class="line"><a name="l11798"></a><span class="lineno">11798</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l11799"></a><span class="lineno">11799</span>&#160;    {</div><div class="line"><a name="l11800"></a><span class="lineno">11800</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l11801"></a><span class="lineno">11801</span>&#160;        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l11802"></a><span class="lineno">11802</span>&#160;        uint32_t localLastUseFrameIndex = hAllocation-&gt;GetLastUseFrameIndex();</div><div class="line"><a name="l11803"></a><span class="lineno">11803</span>&#160;        <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l11804"></a><span class="lineno">11804</span>&#160;        {</div><div class="line"><a name="l11805"></a><span class="lineno">11805</span>&#160;            VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST);</div><div class="line"><a name="l11806"></a><span class="lineno">11806</span>&#160;            <span class="keywordflow">if</span>(localLastUseFrameIndex == localCurrFrameIndex)</div><div class="line"><a name="l11807"></a><span class="lineno">11807</span>&#160;            {</div><div class="line"><a name="l11808"></a><span class="lineno">11808</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l11809"></a><span class="lineno">11809</span>&#160;            }</div><div class="line"><a name="l11810"></a><span class="lineno">11810</span>&#160;            <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l11811"></a><span class="lineno">11811</span>&#160;            {</div><div class="line"><a name="l11812"></a><span class="lineno">11812</span>&#160;                <span class="keywordflow">if</span>(hAllocation-&gt;CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))</div><div class="line"><a name="l11813"></a><span class="lineno">11813</span>&#160;                {</div><div class="line"><a name="l11814"></a><span class="lineno">11814</span>&#160;                    localLastUseFrameIndex = localCurrFrameIndex;</div><div class="line"><a name="l11815"></a><span class="lineno">11815</span>&#160;                }</div><div class="line"><a name="l11816"></a><span class="lineno">11816</span>&#160;            }</div><div class="line"><a name="l11817"></a><span class="lineno">11817</span>&#160;        }</div><div class="line"><a name="l11818"></a><span class="lineno">11818</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l11819"></a><span class="lineno">11819</span>&#160;</div><div class="line"><a name="l11820"></a><span class="lineno">11820</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a> = hAllocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l11821"></a><span class="lineno">11821</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a> = hAllocation-&gt;GetMemory();</div><div class="line"><a name="l11822"></a><span class="lineno">11822</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a> = hAllocation-&gt;GetOffset();</div><div class="line"><a name="l11823"></a><span class="lineno">11823</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a> = hAllocation-&gt;GetSize();</div><div class="line"><a name="l11824"></a><span class="lineno">11824</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a> = hAllocation-&gt;GetMappedData();</div><div class="line"><a name="l11825"></a><span class="lineno">11825</span>&#160;        pAllocationInfo-&gt;<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> = hAllocation-&gt;GetUserData();</div><div class="line"><a name="l11826"></a><span class="lineno">11826</span>&#160;    }</div><div class="line"><a name="l11827"></a><span class="lineno">11827</span>&#160;}</div><div class="line"><a name="l11828"></a><span class="lineno">11828</span>&#160;</div><div class="line"><a name="l11829"></a><span class="lineno">11829</span>&#160;<span class="keywordtype">bool</span> VmaAllocator_T::TouchAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l11830"></a><span class="lineno">11830</span>&#160;{</div><div class="line"><a name="l11831"></a><span class="lineno">11831</span>&#160;    <span class="comment">// This is a stripped-down version of VmaAllocator_T::GetAllocationInfo.</span></div><div class="line"><a name="l11832"></a><span class="lineno">11832</span>&#160;    <span class="keywordflow">if</span>(hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l11833"></a><span class="lineno">11833</span>&#160;    {</div><div class="line"><a name="l11834"></a><span class="lineno">11834</span>&#160;        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l11835"></a><span class="lineno">11835</span>&#160;        uint32_t localLastUseFrameIndex = hAllocation-&gt;GetLastUseFrameIndex();</div><div class="line"><a name="l11836"></a><span class="lineno">11836</span>&#160;        <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l11837"></a><span class="lineno">11837</span>&#160;        {</div><div class="line"><a name="l11838"></a><span class="lineno">11838</span>&#160;            <span class="keywordflow">if</span>(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST)</div><div class="line"><a name="l11839"></a><span class="lineno">11839</span>&#160;            {</div><div class="line"><a name="l11840"></a><span class="lineno">11840</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l11841"></a><span class="lineno">11841</span>&#160;            }</div><div class="line"><a name="l11842"></a><span class="lineno">11842</span>&#160;            <span class="keywordflow">else</span> <span class="keywordflow">if</span>(localLastUseFrameIndex == localCurrFrameIndex)</div><div class="line"><a name="l11843"></a><span class="lineno">11843</span>&#160;            {</div><div class="line"><a name="l11844"></a><span class="lineno">11844</span>&#160;                <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l11845"></a><span class="lineno">11845</span>&#160;            }</div><div class="line"><a name="l11846"></a><span class="lineno">11846</span>&#160;            <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l11847"></a><span class="lineno">11847</span>&#160;            {</div><div class="line"><a name="l11848"></a><span class="lineno">11848</span>&#160;                <span class="keywordflow">if</span>(hAllocation-&gt;CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))</div><div class="line"><a name="l11849"></a><span class="lineno">11849</span>&#160;                {</div><div class="line"><a name="l11850"></a><span class="lineno">11850</span>&#160;                    localLastUseFrameIndex = localCurrFrameIndex;</div><div class="line"><a name="l11851"></a><span class="lineno">11851</span>&#160;                }</div><div class="line"><a name="l11852"></a><span class="lineno">11852</span>&#160;            }</div><div class="line"><a name="l11853"></a><span class="lineno">11853</span>&#160;        }</div><div class="line"><a name="l11854"></a><span class="lineno">11854</span>&#160;    }</div><div class="line"><a name="l11855"></a><span class="lineno">11855</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l11856"></a><span class="lineno">11856</span>&#160;    {</div><div class="line"><a name="l11857"></a><span class="lineno">11857</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l11858"></a><span class="lineno">11858</span>&#160;        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();</div><div class="line"><a name="l11859"></a><span class="lineno">11859</span>&#160;        uint32_t localLastUseFrameIndex = hAllocation-&gt;GetLastUseFrameIndex();</div><div class="line"><a name="l11860"></a><span class="lineno">11860</span>&#160;        <span class="keywordflow">for</span>(;;)</div><div class="line"><a name="l11861"></a><span class="lineno">11861</span>&#160;        {</div><div class="line"><a name="l11862"></a><span class="lineno">11862</span>&#160;            VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST);</div><div class="line"><a name="l11863"></a><span class="lineno">11863</span>&#160;            <span class="keywordflow">if</span>(localLastUseFrameIndex == localCurrFrameIndex)</div><div class="line"><a name="l11864"></a><span class="lineno">11864</span>&#160;            {</div><div class="line"><a name="l11865"></a><span class="lineno">11865</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l11866"></a><span class="lineno">11866</span>&#160;            }</div><div class="line"><a name="l11867"></a><span class="lineno">11867</span>&#160;            <span class="keywordflow">else</span> <span class="comment">// Last use time earlier than current time.</span></div><div class="line"><a name="l11868"></a><span class="lineno">11868</span>&#160;            {</div><div class="line"><a name="l11869"></a><span class="lineno">11869</span>&#160;                <span class="keywordflow">if</span>(hAllocation-&gt;CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))</div><div class="line"><a name="l11870"></a><span class="lineno">11870</span>&#160;                {</div><div class="line"><a name="l11871"></a><span class="lineno">11871</span>&#160;                    localLastUseFrameIndex = localCurrFrameIndex;</div><div class="line"><a name="l11872"></a><span class="lineno">11872</span>&#160;                }</div><div class="line"><a name="l11873"></a><span class="lineno">11873</span>&#160;            }</div><div class="line"><a name="l11874"></a><span class="lineno">11874</span>&#160;        }</div><div class="line"><a name="l11875"></a><span class="lineno">11875</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l11876"></a><span class="lineno">11876</span>&#160;</div><div class="line"><a name="l11877"></a><span class="lineno">11877</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l11878"></a><span class="lineno">11878</span>&#160;    }</div><div class="line"><a name="l11879"></a><span class="lineno">11879</span>&#160;}</div><div class="line"><a name="l11880"></a><span class="lineno">11880</span>&#160;</div><div class="line"><a name="l11881"></a><span class="lineno">11881</span>&#160;VkResult VmaAllocator_T::CreatePool(<span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo, <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool)</div><div class="line"><a name="l11882"></a><span class="lineno">11882</span>&#160;{</div><div class="line"><a name="l11883"></a><span class="lineno">11883</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;  CreatePool: MemoryTypeIndex=%u, flags=%u&quot;</span>, pCreateInfo-&gt;<a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a>, pCreateInfo-&gt;<a class="code" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">flags</a>);</div><div class="line"><a name="l11884"></a><span class="lineno">11884</span>&#160;</div><div class="line"><a name="l11885"></a><span class="lineno">11885</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> isLinearAlgorithm = (pCreateInfo-&gt;<a class="code" href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a>) != 0;</div><div class="line"><a name="l11886"></a><span class="lineno">11886</span>&#160;</div><div class="line"><a name="l11887"></a><span class="lineno">11887</span>&#160;    <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> newCreateInfo = *pCreateInfo;</div><div class="line"><a name="l11888"></a><span class="lineno">11888</span>&#160;</div><div class="line"><a name="l11889"></a><span class="lineno">11889</span>&#160;    <span class="keywordflow">if</span>(newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a> == 0)</div><div class="line"><a name="l11890"></a><span class="lineno">11890</span>&#160;    {</div><div class="line"><a name="l11891"></a><span class="lineno">11891</span>&#160;        newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a> = SIZE_MAX;</div><div class="line"><a name="l11892"></a><span class="lineno">11892</span>&#160;    }</div><div class="line"><a name="l11893"></a><span class="lineno">11893</span>&#160;    <span class="keywordflow">if</span>(newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae">minBlockCount</a> &gt; newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a>)</div><div class="line"><a name="l11894"></a><span class="lineno">11894</span>&#160;    {</div><div class="line"><a name="l11895"></a><span class="lineno">11895</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_INITIALIZATION_FAILED;</div><div class="line"><a name="l11896"></a><span class="lineno">11896</span>&#160;    }</div><div class="line"><a name="l11897"></a><span class="lineno">11897</span>&#160;</div><div class="line"><a name="l11898"></a><span class="lineno">11898</span>&#160;    <span class="keyword">const</span> VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(newCreateInfo.<a class="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a>);</div><div class="line"><a name="l11899"></a><span class="lineno">11899</span>&#160;</div><div class="line"><a name="l11900"></a><span class="lineno">11900</span>&#160;    *pPool = vma_new(<span class="keyword">this</span>, VmaPool_T)(<span class="keyword">this</span>, newCreateInfo, preferredBlockSize);</div><div class="line"><a name="l11901"></a><span class="lineno">11901</span>&#160;</div><div class="line"><a name="l11902"></a><span class="lineno">11902</span>&#160;    VkResult res = (*pPool)-&gt;m_BlockVector.CreateMinBlocks();</div><div class="line"><a name="l11903"></a><span class="lineno">11903</span>&#160;    <span class="keywordflow">if</span>(res != VK_SUCCESS)</div><div class="line"><a name="l11904"></a><span class="lineno">11904</span>&#160;    {</div><div class="line"><a name="l11905"></a><span class="lineno">11905</span>&#160;        vma_delete(<span class="keyword">this</span>, *pPool);</div><div class="line"><a name="l11906"></a><span class="lineno">11906</span>&#160;        *pPool = VMA_NULL;</div><div class="line"><a name="l11907"></a><span class="lineno">11907</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l11908"></a><span class="lineno">11908</span>&#160;    }</div><div class="line"><a name="l11909"></a><span class="lineno">11909</span>&#160;</div><div class="line"><a name="l11910"></a><span class="lineno">11910</span>&#160;    <span class="comment">// Add to m_Pools.</span></div><div class="line"><a name="l11911"></a><span class="lineno">11911</span>&#160;    {</div><div class="line"><a name="l11912"></a><span class="lineno">11912</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l11913"></a><span class="lineno">11913</span>&#160;        (*pPool)-&gt;SetId(m_NextPoolId++);</div><div class="line"><a name="l11914"></a><span class="lineno">11914</span>&#160;        VmaVectorInsertSorted&lt;VmaPointerLess&gt;(m_Pools, *pPool);</div><div class="line"><a name="l11915"></a><span class="lineno">11915</span>&#160;    }</div><div class="line"><a name="l11916"></a><span class="lineno">11916</span>&#160;</div><div class="line"><a name="l11917"></a><span class="lineno">11917</span>&#160;    <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l11918"></a><span class="lineno">11918</span>&#160;}</div><div class="line"><a name="l11919"></a><span class="lineno">11919</span>&#160;</div><div class="line"><a name="l11920"></a><span class="lineno">11920</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::DestroyPool(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l11921"></a><span class="lineno">11921</span>&#160;{</div><div class="line"><a name="l11922"></a><span class="lineno">11922</span>&#160;    <span class="comment">// Remove from m_Pools.</span></div><div class="line"><a name="l11923"></a><span class="lineno">11923</span>&#160;    {</div><div class="line"><a name="l11924"></a><span class="lineno">11924</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l11925"></a><span class="lineno">11925</span>&#160;        <span class="keywordtype">bool</span> success = VmaVectorRemoveSorted&lt;VmaPointerLess&gt;(m_Pools, pool);</div><div class="line"><a name="l11926"></a><span class="lineno">11926</span>&#160;        VMA_ASSERT(success &amp;&amp; <span class="stringliteral">&quot;Pool not found in Allocator.&quot;</span>);</div><div class="line"><a name="l11927"></a><span class="lineno">11927</span>&#160;    }</div><div class="line"><a name="l11928"></a><span class="lineno">11928</span>&#160;</div><div class="line"><a name="l11929"></a><span class="lineno">11929</span>&#160;    vma_delete(<span class="keyword">this</span>, pool);</div><div class="line"><a name="l11930"></a><span class="lineno">11930</span>&#160;}</div><div class="line"><a name="l11931"></a><span class="lineno">11931</span>&#160;</div><div class="line"><a name="l11932"></a><span class="lineno">11932</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::GetPoolStats(<a class="code" href="struct_vma_pool.html">VmaPool</a> pool, <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats)</div><div class="line"><a name="l11933"></a><span class="lineno">11933</span>&#160;{</div><div class="line"><a name="l11934"></a><span class="lineno">11934</span>&#160;    pool-&gt;m_BlockVector.GetPoolStats(pPoolStats);</div><div class="line"><a name="l11935"></a><span class="lineno">11935</span>&#160;}</div><div class="line"><a name="l11936"></a><span class="lineno">11936</span>&#160;</div><div class="line"><a name="l11937"></a><span class="lineno">11937</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::SetCurrentFrameIndex(uint32_t frameIndex)</div><div class="line"><a name="l11938"></a><span class="lineno">11938</span>&#160;{</div><div class="line"><a name="l11939"></a><span class="lineno">11939</span>&#160;    m_CurrentFrameIndex.store(frameIndex);</div><div class="line"><a name="l11940"></a><span class="lineno">11940</span>&#160;}</div><div class="line"><a name="l11941"></a><span class="lineno">11941</span>&#160;</div><div class="line"><a name="l11942"></a><span class="lineno">11942</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::MakePoolAllocationsLost(</div><div class="line"><a name="l11943"></a><span class="lineno">11943</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> hPool,</div><div class="line"><a name="l11944"></a><span class="lineno">11944</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount)</div><div class="line"><a name="l11945"></a><span class="lineno">11945</span>&#160;{</div><div class="line"><a name="l11946"></a><span class="lineno">11946</span>&#160;    hPool-&gt;m_BlockVector.MakePoolAllocationsLost(</div><div class="line"><a name="l11947"></a><span class="lineno">11947</span>&#160;        m_CurrentFrameIndex.load(),</div><div class="line"><a name="l11948"></a><span class="lineno">11948</span>&#160;        pLostAllocationCount);</div><div class="line"><a name="l11949"></a><span class="lineno">11949</span>&#160;}</div><div class="line"><a name="l11950"></a><span class="lineno">11950</span>&#160;</div><div class="line"><a name="l11951"></a><span class="lineno">11951</span>&#160;VkResult VmaAllocator_T::CheckPoolCorruption(<a class="code" href="struct_vma_pool.html">VmaPool</a> hPool)</div><div class="line"><a name="l11952"></a><span class="lineno">11952</span>&#160;{</div><div class="line"><a name="l11953"></a><span class="lineno">11953</span>&#160;    <span class="keywordflow">return</span> hPool-&gt;m_BlockVector.CheckCorruption();</div><div class="line"><a name="l11954"></a><span class="lineno">11954</span>&#160;}</div><div class="line"><a name="l11955"></a><span class="lineno">11955</span>&#160;</div><div class="line"><a name="l11956"></a><span class="lineno">11956</span>&#160;VkResult VmaAllocator_T::CheckCorruption(uint32_t memoryTypeBits)</div><div class="line"><a name="l11957"></a><span class="lineno">11957</span>&#160;{</div><div class="line"><a name="l11958"></a><span class="lineno">11958</span>&#160;    VkResult finalRes = VK_ERROR_FEATURE_NOT_PRESENT;</div><div class="line"><a name="l11959"></a><span class="lineno">11959</span>&#160;</div><div class="line"><a name="l11960"></a><span class="lineno">11960</span>&#160;    <span class="comment">// Process default pools.</span></div><div class="line"><a name="l11961"></a><span class="lineno">11961</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l11962"></a><span class="lineno">11962</span>&#160;    {</div><div class="line"><a name="l11963"></a><span class="lineno">11963</span>&#160;        <span class="keywordflow">if</span>(((1u &lt;&lt; memTypeIndex) &amp; memoryTypeBits) != 0)</div><div class="line"><a name="l11964"></a><span class="lineno">11964</span>&#160;        {</div><div class="line"><a name="l11965"></a><span class="lineno">11965</span>&#160;            VmaBlockVector* <span class="keyword">const</span> pBlockVector = m_pBlockVectors[memTypeIndex];</div><div class="line"><a name="l11966"></a><span class="lineno">11966</span>&#160;            VMA_ASSERT(pBlockVector);</div><div class="line"><a name="l11967"></a><span class="lineno">11967</span>&#160;            VkResult localRes = pBlockVector-&gt;CheckCorruption();</div><div class="line"><a name="l11968"></a><span class="lineno">11968</span>&#160;            <span class="keywordflow">switch</span>(localRes)</div><div class="line"><a name="l11969"></a><span class="lineno">11969</span>&#160;            {</div><div class="line"><a name="l11970"></a><span class="lineno">11970</span>&#160;            <span class="keywordflow">case</span> VK_ERROR_FEATURE_NOT_PRESENT:</div><div class="line"><a name="l11971"></a><span class="lineno">11971</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l11972"></a><span class="lineno">11972</span>&#160;            <span class="keywordflow">case</span> VK_SUCCESS:</div><div class="line"><a name="l11973"></a><span class="lineno">11973</span>&#160;                finalRes = VK_SUCCESS;</div><div class="line"><a name="l11974"></a><span class="lineno">11974</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l11975"></a><span class="lineno">11975</span>&#160;            <span class="keywordflow">default</span>:</div><div class="line"><a name="l11976"></a><span class="lineno">11976</span>&#160;                <span class="keywordflow">return</span> localRes;</div><div class="line"><a name="l11977"></a><span class="lineno">11977</span>&#160;            }</div><div class="line"><a name="l11978"></a><span class="lineno">11978</span>&#160;        }</div><div class="line"><a name="l11979"></a><span class="lineno">11979</span>&#160;    }</div><div class="line"><a name="l11980"></a><span class="lineno">11980</span>&#160;</div><div class="line"><a name="l11981"></a><span class="lineno">11981</span>&#160;    <span class="comment">// Process custom pools.</span></div><div class="line"><a name="l11982"></a><span class="lineno">11982</span>&#160;    {</div><div class="line"><a name="l11983"></a><span class="lineno">11983</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l11984"></a><span class="lineno">11984</span>&#160;        <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = 0, poolCount = m_Pools.size(); poolIndex &lt; poolCount; ++poolIndex)</div><div class="line"><a name="l11985"></a><span class="lineno">11985</span>&#160;        {</div><div class="line"><a name="l11986"></a><span class="lineno">11986</span>&#160;            <span class="keywordflow">if</span>(((1u &lt;&lt; m_Pools[poolIndex]-&gt;m_BlockVector.GetMemoryTypeIndex()) &amp; memoryTypeBits) != 0)</div><div class="line"><a name="l11987"></a><span class="lineno">11987</span>&#160;            {</div><div class="line"><a name="l11988"></a><span class="lineno">11988</span>&#160;                VkResult localRes = m_Pools[poolIndex]-&gt;m_BlockVector.CheckCorruption();</div><div class="line"><a name="l11989"></a><span class="lineno">11989</span>&#160;                <span class="keywordflow">switch</span>(localRes)</div><div class="line"><a name="l11990"></a><span class="lineno">11990</span>&#160;                {</div><div class="line"><a name="l11991"></a><span class="lineno">11991</span>&#160;                <span class="keywordflow">case</span> VK_ERROR_FEATURE_NOT_PRESENT:</div><div class="line"><a name="l11992"></a><span class="lineno">11992</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l11993"></a><span class="lineno">11993</span>&#160;                <span class="keywordflow">case</span> VK_SUCCESS:</div><div class="line"><a name="l11994"></a><span class="lineno">11994</span>&#160;                    finalRes = VK_SUCCESS;</div><div class="line"><a name="l11995"></a><span class="lineno">11995</span>&#160;                    <span class="keywordflow">break</span>;</div><div class="line"><a name="l11996"></a><span class="lineno">11996</span>&#160;                <span class="keywordflow">default</span>:</div><div class="line"><a name="l11997"></a><span class="lineno">11997</span>&#160;                    <span class="keywordflow">return</span> localRes;</div><div class="line"><a name="l11998"></a><span class="lineno">11998</span>&#160;                }</div><div class="line"><a name="l11999"></a><span class="lineno">11999</span>&#160;            }</div><div class="line"><a name="l12000"></a><span class="lineno">12000</span>&#160;        }</div><div class="line"><a name="l12001"></a><span class="lineno">12001</span>&#160;    }</div><div class="line"><a name="l12002"></a><span class="lineno">12002</span>&#160;</div><div class="line"><a name="l12003"></a><span class="lineno">12003</span>&#160;    <span class="keywordflow">return</span> finalRes;</div><div class="line"><a name="l12004"></a><span class="lineno">12004</span>&#160;}</div><div class="line"><a name="l12005"></a><span class="lineno">12005</span>&#160;</div><div class="line"><a name="l12006"></a><span class="lineno">12006</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::CreateLostAllocation(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l12007"></a><span class="lineno">12007</span>&#160;{</div><div class="line"><a name="l12008"></a><span class="lineno">12008</span>&#160;    *pAllocation = vma_new(<span class="keyword">this</span>, VmaAllocation_T)(VMA_FRAME_INDEX_LOST, <span class="keyword">false</span>);</div><div class="line"><a name="l12009"></a><span class="lineno">12009</span>&#160;    (*pAllocation)-&gt;InitLost();</div><div class="line"><a name="l12010"></a><span class="lineno">12010</span>&#160;}</div><div class="line"><a name="l12011"></a><span class="lineno">12011</span>&#160;</div><div class="line"><a name="l12012"></a><span class="lineno">12012</span>&#160;VkResult VmaAllocator_T::AllocateVulkanMemory(<span class="keyword">const</span> VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory)</div><div class="line"><a name="l12013"></a><span class="lineno">12013</span>&#160;{</div><div class="line"><a name="l12014"></a><span class="lineno">12014</span>&#160;    <span class="keyword">const</span> uint32_t heapIndex = MemoryTypeIndexToHeapIndex(pAllocateInfo-&gt;memoryTypeIndex);</div><div class="line"><a name="l12015"></a><span class="lineno">12015</span>&#160;</div><div class="line"><a name="l12016"></a><span class="lineno">12016</span>&#160;    VkResult res;</div><div class="line"><a name="l12017"></a><span class="lineno">12017</span>&#160;    <span class="keywordflow">if</span>(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE)</div><div class="line"><a name="l12018"></a><span class="lineno">12018</span>&#160;    {</div><div class="line"><a name="l12019"></a><span class="lineno">12019</span>&#160;        VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex);</div><div class="line"><a name="l12020"></a><span class="lineno">12020</span>&#160;        <span class="keywordflow">if</span>(m_HeapSizeLimit[heapIndex] &gt;= pAllocateInfo-&gt;allocationSize)</div><div class="line"><a name="l12021"></a><span class="lineno">12021</span>&#160;        {</div><div class="line"><a name="l12022"></a><span class="lineno">12022</span>&#160;            res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory);</div><div class="line"><a name="l12023"></a><span class="lineno">12023</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l12024"></a><span class="lineno">12024</span>&#160;            {</div><div class="line"><a name="l12025"></a><span class="lineno">12025</span>&#160;                m_HeapSizeLimit[heapIndex] -= pAllocateInfo-&gt;allocationSize;</div><div class="line"><a name="l12026"></a><span class="lineno">12026</span>&#160;            }</div><div class="line"><a name="l12027"></a><span class="lineno">12027</span>&#160;        }</div><div class="line"><a name="l12028"></a><span class="lineno">12028</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l12029"></a><span class="lineno">12029</span>&#160;        {</div><div class="line"><a name="l12030"></a><span class="lineno">12030</span>&#160;            res = VK_ERROR_OUT_OF_DEVICE_MEMORY;</div><div class="line"><a name="l12031"></a><span class="lineno">12031</span>&#160;        }</div><div class="line"><a name="l12032"></a><span class="lineno">12032</span>&#160;    }</div><div class="line"><a name="l12033"></a><span class="lineno">12033</span>&#160;    <span class="keywordflow">else</span></div><div class="line"><a name="l12034"></a><span class="lineno">12034</span>&#160;    {</div><div class="line"><a name="l12035"></a><span class="lineno">12035</span>&#160;        res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory);</div><div class="line"><a name="l12036"></a><span class="lineno">12036</span>&#160;    }</div><div class="line"><a name="l12037"></a><span class="lineno">12037</span>&#160;</div><div class="line"><a name="l12038"></a><span class="lineno">12038</span>&#160;    <span class="keywordflow">if</span>(res == VK_SUCCESS &amp;&amp; m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a> != VMA_NULL)</div><div class="line"><a name="l12039"></a><span class="lineno">12039</span>&#160;    {</div><div class="line"><a name="l12040"></a><span class="lineno">12040</span>&#160;        (*m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">pfnAllocate</a>)(<span class="keyword">this</span>, pAllocateInfo-&gt;memoryTypeIndex, *pMemory, pAllocateInfo-&gt;allocationSize);</div><div class="line"><a name="l12041"></a><span class="lineno">12041</span>&#160;    }</div><div class="line"><a name="l12042"></a><span class="lineno">12042</span>&#160;</div><div class="line"><a name="l12043"></a><span class="lineno">12043</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l12044"></a><span class="lineno">12044</span>&#160;}</div><div class="line"><a name="l12045"></a><span class="lineno">12045</span>&#160;</div><div class="line"><a name="l12046"></a><span class="lineno">12046</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory)</div><div class="line"><a name="l12047"></a><span class="lineno">12047</span>&#160;{</div><div class="line"><a name="l12048"></a><span class="lineno">12048</span>&#160;    <span class="keywordflow">if</span>(m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a> != VMA_NULL)</div><div class="line"><a name="l12049"></a><span class="lineno">12049</span>&#160;    {</div><div class="line"><a name="l12050"></a><span class="lineno">12050</span>&#160;        (*m_DeviceMemoryCallbacks.<a class="code" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">pfnFree</a>)(<span class="keyword">this</span>, memoryType, hMemory, size);</div><div class="line"><a name="l12051"></a><span class="lineno">12051</span>&#160;    }</div><div class="line"><a name="l12052"></a><span class="lineno">12052</span>&#160;</div><div class="line"><a name="l12053"></a><span class="lineno">12053</span>&#160;    (*m_VulkanFunctions.vkFreeMemory)(m_hDevice, hMemory, GetAllocationCallbacks());</div><div class="line"><a name="l12054"></a><span class="lineno">12054</span>&#160;</div><div class="line"><a name="l12055"></a><span class="lineno">12055</span>&#160;    <span class="keyword">const</span> uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memoryType);</div><div class="line"><a name="l12056"></a><span class="lineno">12056</span>&#160;    <span class="keywordflow">if</span>(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE)</div><div class="line"><a name="l12057"></a><span class="lineno">12057</span>&#160;    {</div><div class="line"><a name="l12058"></a><span class="lineno">12058</span>&#160;        VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex);</div><div class="line"><a name="l12059"></a><span class="lineno">12059</span>&#160;        m_HeapSizeLimit[heapIndex] += size;</div><div class="line"><a name="l12060"></a><span class="lineno">12060</span>&#160;    }</div><div class="line"><a name="l12061"></a><span class="lineno">12061</span>&#160;}</div><div class="line"><a name="l12062"></a><span class="lineno">12062</span>&#160;</div><div class="line"><a name="l12063"></a><span class="lineno">12063</span>&#160;VkResult VmaAllocator_T::Map(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l12064"></a><span class="lineno">12064</span>&#160;{</div><div class="line"><a name="l12065"></a><span class="lineno">12065</span>&#160;    <span class="keywordflow">if</span>(hAllocation-&gt;CanBecomeLost())</div><div class="line"><a name="l12066"></a><span class="lineno">12066</span>&#160;    {</div><div class="line"><a name="l12067"></a><span class="lineno">12067</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_MEMORY_MAP_FAILED;</div><div class="line"><a name="l12068"></a><span class="lineno">12068</span>&#160;    }</div><div class="line"><a name="l12069"></a><span class="lineno">12069</span>&#160;</div><div class="line"><a name="l12070"></a><span class="lineno">12070</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l12071"></a><span class="lineno">12071</span>&#160;    {</div><div class="line"><a name="l12072"></a><span class="lineno">12072</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l12073"></a><span class="lineno">12073</span>&#160;        {</div><div class="line"><a name="l12074"></a><span class="lineno">12074</span>&#160;            VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l12075"></a><span class="lineno">12075</span>&#160;            <span class="keywordtype">char</span> *pBytes = VMA_NULL;</div><div class="line"><a name="l12076"></a><span class="lineno">12076</span>&#160;            VkResult res = pBlock-&gt;Map(<span class="keyword">this</span>, 1, (<span class="keywordtype">void</span>**)&amp;pBytes);</div><div class="line"><a name="l12077"></a><span class="lineno">12077</span>&#160;            <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l12078"></a><span class="lineno">12078</span>&#160;            {</div><div class="line"><a name="l12079"></a><span class="lineno">12079</span>&#160;                *ppData = pBytes + (ptrdiff_t)hAllocation-&gt;GetOffset();</div><div class="line"><a name="l12080"></a><span class="lineno">12080</span>&#160;                hAllocation-&gt;BlockAllocMap();</div><div class="line"><a name="l12081"></a><span class="lineno">12081</span>&#160;            }</div><div class="line"><a name="l12082"></a><span class="lineno">12082</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l12083"></a><span class="lineno">12083</span>&#160;        }</div><div class="line"><a name="l12084"></a><span class="lineno">12084</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l12085"></a><span class="lineno">12085</span>&#160;        <span class="keywordflow">return</span> hAllocation-&gt;DedicatedAllocMap(<span class="keyword">this</span>, ppData);</div><div class="line"><a name="l12086"></a><span class="lineno">12086</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l12087"></a><span class="lineno">12087</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l12088"></a><span class="lineno">12088</span>&#160;        <span class="keywordflow">return</span> VK_ERROR_MEMORY_MAP_FAILED;</div><div class="line"><a name="l12089"></a><span class="lineno">12089</span>&#160;    }</div><div class="line"><a name="l12090"></a><span class="lineno">12090</span>&#160;}</div><div class="line"><a name="l12091"></a><span class="lineno">12091</span>&#160;</div><div class="line"><a name="l12092"></a><span class="lineno">12092</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::Unmap(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation)</div><div class="line"><a name="l12093"></a><span class="lineno">12093</span>&#160;{</div><div class="line"><a name="l12094"></a><span class="lineno">12094</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l12095"></a><span class="lineno">12095</span>&#160;    {</div><div class="line"><a name="l12096"></a><span class="lineno">12096</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l12097"></a><span class="lineno">12097</span>&#160;        {</div><div class="line"><a name="l12098"></a><span class="lineno">12098</span>&#160;            VmaDeviceMemoryBlock* <span class="keyword">const</span> pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l12099"></a><span class="lineno">12099</span>&#160;            hAllocation-&gt;BlockAllocUnmap();</div><div class="line"><a name="l12100"></a><span class="lineno">12100</span>&#160;            pBlock-&gt;Unmap(<span class="keyword">this</span>, 1);</div><div class="line"><a name="l12101"></a><span class="lineno">12101</span>&#160;        }</div><div class="line"><a name="l12102"></a><span class="lineno">12102</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12103"></a><span class="lineno">12103</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l12104"></a><span class="lineno">12104</span>&#160;        hAllocation-&gt;DedicatedAllocUnmap(<span class="keyword">this</span>);</div><div class="line"><a name="l12105"></a><span class="lineno">12105</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12106"></a><span class="lineno">12106</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l12107"></a><span class="lineno">12107</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l12108"></a><span class="lineno">12108</span>&#160;    }</div><div class="line"><a name="l12109"></a><span class="lineno">12109</span>&#160;}</div><div class="line"><a name="l12110"></a><span class="lineno">12110</span>&#160;</div><div class="line"><a name="l12111"></a><span class="lineno">12111</span>&#160;VkResult VmaAllocator_T::BindBufferMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkBuffer hBuffer)</div><div class="line"><a name="l12112"></a><span class="lineno">12112</span>&#160;{</div><div class="line"><a name="l12113"></a><span class="lineno">12113</span>&#160;    VkResult res = VK_SUCCESS;</div><div class="line"><a name="l12114"></a><span class="lineno">12114</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l12115"></a><span class="lineno">12115</span>&#160;    {</div><div class="line"><a name="l12116"></a><span class="lineno">12116</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l12117"></a><span class="lineno">12117</span>&#160;        res = GetVulkanFunctions().vkBindBufferMemory(</div><div class="line"><a name="l12118"></a><span class="lineno">12118</span>&#160;            m_hDevice,</div><div class="line"><a name="l12119"></a><span class="lineno">12119</span>&#160;            hBuffer,</div><div class="line"><a name="l12120"></a><span class="lineno">12120</span>&#160;            hAllocation-&gt;GetMemory(),</div><div class="line"><a name="l12121"></a><span class="lineno">12121</span>&#160;            0); <span class="comment">//memoryOffset</span></div><div class="line"><a name="l12122"></a><span class="lineno">12122</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12123"></a><span class="lineno">12123</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l12124"></a><span class="lineno">12124</span>&#160;    {</div><div class="line"><a name="l12125"></a><span class="lineno">12125</span>&#160;        VmaDeviceMemoryBlock* pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l12126"></a><span class="lineno">12126</span>&#160;        VMA_ASSERT(pBlock &amp;&amp; <span class="stringliteral">&quot;Binding buffer to allocation that doesn&#39;t belong to any block. Is the allocation lost?&quot;</span>);</div><div class="line"><a name="l12127"></a><span class="lineno">12127</span>&#160;        res = pBlock-&gt;BindBufferMemory(<span class="keyword">this</span>, hAllocation, hBuffer);</div><div class="line"><a name="l12128"></a><span class="lineno">12128</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12129"></a><span class="lineno">12129</span>&#160;    }</div><div class="line"><a name="l12130"></a><span class="lineno">12130</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l12131"></a><span class="lineno">12131</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l12132"></a><span class="lineno">12132</span>&#160;    }</div><div class="line"><a name="l12133"></a><span class="lineno">12133</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l12134"></a><span class="lineno">12134</span>&#160;}</div><div class="line"><a name="l12135"></a><span class="lineno">12135</span>&#160;</div><div class="line"><a name="l12136"></a><span class="lineno">12136</span>&#160;VkResult VmaAllocator_T::BindImageMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, VkImage hImage)</div><div class="line"><a name="l12137"></a><span class="lineno">12137</span>&#160;{</div><div class="line"><a name="l12138"></a><span class="lineno">12138</span>&#160;    VkResult res = VK_SUCCESS;</div><div class="line"><a name="l12139"></a><span class="lineno">12139</span>&#160;    <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l12140"></a><span class="lineno">12140</span>&#160;    {</div><div class="line"><a name="l12141"></a><span class="lineno">12141</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l12142"></a><span class="lineno">12142</span>&#160;        res = GetVulkanFunctions().vkBindImageMemory(</div><div class="line"><a name="l12143"></a><span class="lineno">12143</span>&#160;            m_hDevice,</div><div class="line"><a name="l12144"></a><span class="lineno">12144</span>&#160;            hImage,</div><div class="line"><a name="l12145"></a><span class="lineno">12145</span>&#160;            hAllocation-&gt;GetMemory(),</div><div class="line"><a name="l12146"></a><span class="lineno">12146</span>&#160;            0); <span class="comment">//memoryOffset</span></div><div class="line"><a name="l12147"></a><span class="lineno">12147</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12148"></a><span class="lineno">12148</span>&#160;    <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l12149"></a><span class="lineno">12149</span>&#160;    {</div><div class="line"><a name="l12150"></a><span class="lineno">12150</span>&#160;        VmaDeviceMemoryBlock* pBlock = hAllocation-&gt;GetBlock();</div><div class="line"><a name="l12151"></a><span class="lineno">12151</span>&#160;        VMA_ASSERT(pBlock &amp;&amp; <span class="stringliteral">&quot;Binding image to allocation that doesn&#39;t belong to any block. Is the allocation lost?&quot;</span>);</div><div class="line"><a name="l12152"></a><span class="lineno">12152</span>&#160;        res = pBlock-&gt;BindImageMemory(<span class="keyword">this</span>, hAllocation, hImage);</div><div class="line"><a name="l12153"></a><span class="lineno">12153</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12154"></a><span class="lineno">12154</span>&#160;    }</div><div class="line"><a name="l12155"></a><span class="lineno">12155</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l12156"></a><span class="lineno">12156</span>&#160;        VMA_ASSERT(0);</div><div class="line"><a name="l12157"></a><span class="lineno">12157</span>&#160;    }</div><div class="line"><a name="l12158"></a><span class="lineno">12158</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l12159"></a><span class="lineno">12159</span>&#160;}</div><div class="line"><a name="l12160"></a><span class="lineno">12160</span>&#160;</div><div class="line"><a name="l12161"></a><span class="lineno">12161</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FlushOrInvalidateAllocation(</div><div class="line"><a name="l12162"></a><span class="lineno">12162</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation,</div><div class="line"><a name="l12163"></a><span class="lineno">12163</span>&#160;    VkDeviceSize offset, VkDeviceSize size,</div><div class="line"><a name="l12164"></a><span class="lineno">12164</span>&#160;    VMA_CACHE_OPERATION op)</div><div class="line"><a name="l12165"></a><span class="lineno">12165</span>&#160;{</div><div class="line"><a name="l12166"></a><span class="lineno">12166</span>&#160;    <span class="keyword">const</span> uint32_t memTypeIndex = hAllocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l12167"></a><span class="lineno">12167</span>&#160;    <span class="keywordflow">if</span>(size &gt; 0 &amp;&amp; IsMemoryTypeNonCoherent(memTypeIndex))</div><div class="line"><a name="l12168"></a><span class="lineno">12168</span>&#160;    {</div><div class="line"><a name="l12169"></a><span class="lineno">12169</span>&#160;        <span class="keyword">const</span> VkDeviceSize allocationSize = hAllocation-&gt;GetSize();</div><div class="line"><a name="l12170"></a><span class="lineno">12170</span>&#160;        VMA_ASSERT(offset &lt;= allocationSize);</div><div class="line"><a name="l12171"></a><span class="lineno">12171</span>&#160;</div><div class="line"><a name="l12172"></a><span class="lineno">12172</span>&#160;        <span class="keyword">const</span> VkDeviceSize nonCoherentAtomSize = m_PhysicalDeviceProperties.limits.nonCoherentAtomSize;</div><div class="line"><a name="l12173"></a><span class="lineno">12173</span>&#160;</div><div class="line"><a name="l12174"></a><span class="lineno">12174</span>&#160;        VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };</div><div class="line"><a name="l12175"></a><span class="lineno">12175</span>&#160;        memRange.memory = hAllocation-&gt;GetMemory();</div><div class="line"><a name="l12176"></a><span class="lineno">12176</span>&#160;        </div><div class="line"><a name="l12177"></a><span class="lineno">12177</span>&#160;        <span class="keywordflow">switch</span>(hAllocation-&gt;GetType())</div><div class="line"><a name="l12178"></a><span class="lineno">12178</span>&#160;        {</div><div class="line"><a name="l12179"></a><span class="lineno">12179</span>&#160;        <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:</div><div class="line"><a name="l12180"></a><span class="lineno">12180</span>&#160;            memRange.offset = VmaAlignDown(offset, nonCoherentAtomSize);</div><div class="line"><a name="l12181"></a><span class="lineno">12181</span>&#160;            <span class="keywordflow">if</span>(size == VK_WHOLE_SIZE)</div><div class="line"><a name="l12182"></a><span class="lineno">12182</span>&#160;            {</div><div class="line"><a name="l12183"></a><span class="lineno">12183</span>&#160;                memRange.size = allocationSize - memRange.offset;</div><div class="line"><a name="l12184"></a><span class="lineno">12184</span>&#160;            }</div><div class="line"><a name="l12185"></a><span class="lineno">12185</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l12186"></a><span class="lineno">12186</span>&#160;            {</div><div class="line"><a name="l12187"></a><span class="lineno">12187</span>&#160;                VMA_ASSERT(offset + size &lt;= allocationSize);</div><div class="line"><a name="l12188"></a><span class="lineno">12188</span>&#160;                memRange.size = VMA_MIN(</div><div class="line"><a name="l12189"></a><span class="lineno">12189</span>&#160;                    VmaAlignUp(size + (offset - memRange.offset), nonCoherentAtomSize),</div><div class="line"><a name="l12190"></a><span class="lineno">12190</span>&#160;                    allocationSize - memRange.offset);</div><div class="line"><a name="l12191"></a><span class="lineno">12191</span>&#160;            }</div><div class="line"><a name="l12192"></a><span class="lineno">12192</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l12193"></a><span class="lineno">12193</span>&#160;</div><div class="line"><a name="l12194"></a><span class="lineno">12194</span>&#160;        <span class="keywordflow">case</span> VmaAllocation_T::ALLOCATION_TYPE_BLOCK:</div><div class="line"><a name="l12195"></a><span class="lineno">12195</span>&#160;        {</div><div class="line"><a name="l12196"></a><span class="lineno">12196</span>&#160;            <span class="comment">// 1. Still within this allocation.</span></div><div class="line"><a name="l12197"></a><span class="lineno">12197</span>&#160;            memRange.offset = VmaAlignDown(offset, nonCoherentAtomSize);</div><div class="line"><a name="l12198"></a><span class="lineno">12198</span>&#160;            <span class="keywordflow">if</span>(size == VK_WHOLE_SIZE)</div><div class="line"><a name="l12199"></a><span class="lineno">12199</span>&#160;            {</div><div class="line"><a name="l12200"></a><span class="lineno">12200</span>&#160;                size = allocationSize - offset;</div><div class="line"><a name="l12201"></a><span class="lineno">12201</span>&#160;            }</div><div class="line"><a name="l12202"></a><span class="lineno">12202</span>&#160;            <span class="keywordflow">else</span></div><div class="line"><a name="l12203"></a><span class="lineno">12203</span>&#160;            {</div><div class="line"><a name="l12204"></a><span class="lineno">12204</span>&#160;                VMA_ASSERT(offset + size &lt;= allocationSize);</div><div class="line"><a name="l12205"></a><span class="lineno">12205</span>&#160;            }</div><div class="line"><a name="l12206"></a><span class="lineno">12206</span>&#160;            memRange.size = VmaAlignUp(size + (offset - memRange.offset), nonCoherentAtomSize);</div><div class="line"><a name="l12207"></a><span class="lineno">12207</span>&#160;</div><div class="line"><a name="l12208"></a><span class="lineno">12208</span>&#160;            <span class="comment">// 2. Adjust to whole block.</span></div><div class="line"><a name="l12209"></a><span class="lineno">12209</span>&#160;            <span class="keyword">const</span> VkDeviceSize allocationOffset = hAllocation-&gt;GetOffset();</div><div class="line"><a name="l12210"></a><span class="lineno">12210</span>&#160;            VMA_ASSERT(allocationOffset % nonCoherentAtomSize == 0);</div><div class="line"><a name="l12211"></a><span class="lineno">12211</span>&#160;            <span class="keyword">const</span> VkDeviceSize blockSize = hAllocation-&gt;GetBlock()-&gt;m_pMetadata-&gt;GetSize();</div><div class="line"><a name="l12212"></a><span class="lineno">12212</span>&#160;            memRange.offset += allocationOffset;</div><div class="line"><a name="l12213"></a><span class="lineno">12213</span>&#160;            memRange.size = VMA_MIN(memRange.size, blockSize - memRange.offset);</div><div class="line"><a name="l12214"></a><span class="lineno">12214</span>&#160;            </div><div class="line"><a name="l12215"></a><span class="lineno">12215</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l12216"></a><span class="lineno">12216</span>&#160;        }</div><div class="line"><a name="l12217"></a><span class="lineno">12217</span>&#160;        </div><div class="line"><a name="l12218"></a><span class="lineno">12218</span>&#160;        <span class="keywordflow">default</span>:</div><div class="line"><a name="l12219"></a><span class="lineno">12219</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l12220"></a><span class="lineno">12220</span>&#160;        }</div><div class="line"><a name="l12221"></a><span class="lineno">12221</span>&#160;</div><div class="line"><a name="l12222"></a><span class="lineno">12222</span>&#160;        <span class="keywordflow">switch</span>(op)</div><div class="line"><a name="l12223"></a><span class="lineno">12223</span>&#160;        {</div><div class="line"><a name="l12224"></a><span class="lineno">12224</span>&#160;        <span class="keywordflow">case</span> VMA_CACHE_FLUSH:</div><div class="line"><a name="l12225"></a><span class="lineno">12225</span>&#160;            (*GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hDevice, 1, &amp;memRange);</div><div class="line"><a name="l12226"></a><span class="lineno">12226</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l12227"></a><span class="lineno">12227</span>&#160;        <span class="keywordflow">case</span> VMA_CACHE_INVALIDATE:</div><div class="line"><a name="l12228"></a><span class="lineno">12228</span>&#160;            (*GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hDevice, 1, &amp;memRange);</div><div class="line"><a name="l12229"></a><span class="lineno">12229</span>&#160;            <span class="keywordflow">break</span>;</div><div class="line"><a name="l12230"></a><span class="lineno">12230</span>&#160;        <span class="keywordflow">default</span>:</div><div class="line"><a name="l12231"></a><span class="lineno">12231</span>&#160;            VMA_ASSERT(0);</div><div class="line"><a name="l12232"></a><span class="lineno">12232</span>&#160;        }</div><div class="line"><a name="l12233"></a><span class="lineno">12233</span>&#160;    }</div><div class="line"><a name="l12234"></a><span class="lineno">12234</span>&#160;    <span class="comment">// else: Just ignore this call.</span></div><div class="line"><a name="l12235"></a><span class="lineno">12235</span>&#160;}</div><div class="line"><a name="l12236"></a><span class="lineno">12236</span>&#160;</div><div class="line"><a name="l12237"></a><span class="lineno">12237</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FreeDedicatedMemory(<a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l12238"></a><span class="lineno">12238</span>&#160;{</div><div class="line"><a name="l12239"></a><span class="lineno">12239</span>&#160;    VMA_ASSERT(allocation &amp;&amp; allocation-&gt;GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);</div><div class="line"><a name="l12240"></a><span class="lineno">12240</span>&#160;</div><div class="line"><a name="l12241"></a><span class="lineno">12241</span>&#160;    <span class="keyword">const</span> uint32_t memTypeIndex = allocation-&gt;GetMemoryTypeIndex();</div><div class="line"><a name="l12242"></a><span class="lineno">12242</span>&#160;    {</div><div class="line"><a name="l12243"></a><span class="lineno">12243</span>&#160;        VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l12244"></a><span class="lineno">12244</span>&#160;        AllocationVectorType* <span class="keyword">const</span> pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l12245"></a><span class="lineno">12245</span>&#160;        VMA_ASSERT(pDedicatedAllocations);</div><div class="line"><a name="l12246"></a><span class="lineno">12246</span>&#160;        <span class="keywordtype">bool</span> success = VmaVectorRemoveSorted&lt;VmaPointerLess&gt;(*pDedicatedAllocations, allocation);</div><div class="line"><a name="l12247"></a><span class="lineno">12247</span>&#160;        VMA_ASSERT(success);</div><div class="line"><a name="l12248"></a><span class="lineno">12248</span>&#160;    }</div><div class="line"><a name="l12249"></a><span class="lineno">12249</span>&#160;</div><div class="line"><a name="l12250"></a><span class="lineno">12250</span>&#160;    VkDeviceMemory hMemory = allocation-&gt;GetMemory();</div><div class="line"><a name="l12251"></a><span class="lineno">12251</span>&#160;    </div><div class="line"><a name="l12252"></a><span class="lineno">12252</span>&#160;    <span class="keywordflow">if</span>(allocation-&gt;GetMappedData() != VMA_NULL)</div><div class="line"><a name="l12253"></a><span class="lineno">12253</span>&#160;    {</div><div class="line"><a name="l12254"></a><span class="lineno">12254</span>&#160;        (*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory);</div><div class="line"><a name="l12255"></a><span class="lineno">12255</span>&#160;    }</div><div class="line"><a name="l12256"></a><span class="lineno">12256</span>&#160;    </div><div class="line"><a name="l12257"></a><span class="lineno">12257</span>&#160;    FreeVulkanMemory(memTypeIndex, allocation-&gt;GetSize(), hMemory);</div><div class="line"><a name="l12258"></a><span class="lineno">12258</span>&#160;</div><div class="line"><a name="l12259"></a><span class="lineno">12259</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;    Freed DedicatedMemory MemoryTypeIndex=%u&quot;</span>, memTypeIndex);</div><div class="line"><a name="l12260"></a><span class="lineno">12260</span>&#160;}</div><div class="line"><a name="l12261"></a><span class="lineno">12261</span>&#160;</div><div class="line"><a name="l12262"></a><span class="lineno">12262</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::FillAllocation(<span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAllocation, uint8_t pattern)</div><div class="line"><a name="l12263"></a><span class="lineno">12263</span>&#160;{</div><div class="line"><a name="l12264"></a><span class="lineno">12264</span>&#160;    <span class="keywordflow">if</span>(VMA_DEBUG_INITIALIZE_ALLOCATIONS &amp;&amp;</div><div class="line"><a name="l12265"></a><span class="lineno">12265</span>&#160;        !hAllocation-&gt;CanBecomeLost() &amp;&amp;</div><div class="line"><a name="l12266"></a><span class="lineno">12266</span>&#160;        (m_MemProps.memoryTypes[hAllocation-&gt;GetMemoryTypeIndex()].propertyFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)</div><div class="line"><a name="l12267"></a><span class="lineno">12267</span>&#160;    {</div><div class="line"><a name="l12268"></a><span class="lineno">12268</span>&#160;        <span class="keywordtype">void</span>* pData = VMA_NULL;</div><div class="line"><a name="l12269"></a><span class="lineno">12269</span>&#160;        VkResult res = Map(hAllocation, &amp;pData);</div><div class="line"><a name="l12270"></a><span class="lineno">12270</span>&#160;        <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l12271"></a><span class="lineno">12271</span>&#160;        {</div><div class="line"><a name="l12272"></a><span class="lineno">12272</span>&#160;            memset(pData, (<span class="keywordtype">int</span>)pattern, (<span class="keywordtype">size_t</span>)hAllocation-&gt;GetSize());</div><div class="line"><a name="l12273"></a><span class="lineno">12273</span>&#160;            FlushOrInvalidateAllocation(hAllocation, 0, VK_WHOLE_SIZE, VMA_CACHE_FLUSH);</div><div class="line"><a name="l12274"></a><span class="lineno">12274</span>&#160;            Unmap(hAllocation);</div><div class="line"><a name="l12275"></a><span class="lineno">12275</span>&#160;        }</div><div class="line"><a name="l12276"></a><span class="lineno">12276</span>&#160;        <span class="keywordflow">else</span></div><div class="line"><a name="l12277"></a><span class="lineno">12277</span>&#160;        {</div><div class="line"><a name="l12278"></a><span class="lineno">12278</span>&#160;            VMA_ASSERT(0 &amp;&amp; <span class="stringliteral">&quot;VMA_DEBUG_INITIALIZE_ALLOCATIONS is enabled, but couldn&#39;t map memory to fill allocation.&quot;</span>);</div><div class="line"><a name="l12279"></a><span class="lineno">12279</span>&#160;        }</div><div class="line"><a name="l12280"></a><span class="lineno">12280</span>&#160;    }</div><div class="line"><a name="l12281"></a><span class="lineno">12281</span>&#160;}</div><div class="line"><a name="l12282"></a><span class="lineno">12282</span>&#160;</div><div class="line"><a name="l12283"></a><span class="lineno">12283</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l12284"></a><span class="lineno">12284</span>&#160;</div><div class="line"><a name="l12285"></a><span class="lineno">12285</span>&#160;<span class="keywordtype">void</span> VmaAllocator_T::PrintDetailedMap(VmaJsonWriter&amp; json)</div><div class="line"><a name="l12286"></a><span class="lineno">12286</span>&#160;{</div><div class="line"><a name="l12287"></a><span class="lineno">12287</span>&#160;    <span class="keywordtype">bool</span> dedicatedAllocationsStarted = <span class="keyword">false</span>;</div><div class="line"><a name="l12288"></a><span class="lineno">12288</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l12289"></a><span class="lineno">12289</span>&#160;    {</div><div class="line"><a name="l12290"></a><span class="lineno">12290</span>&#160;        VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);</div><div class="line"><a name="l12291"></a><span class="lineno">12291</span>&#160;        AllocationVectorType* <span class="keyword">const</span> pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex];</div><div class="line"><a name="l12292"></a><span class="lineno">12292</span>&#160;        VMA_ASSERT(pDedicatedAllocVector);</div><div class="line"><a name="l12293"></a><span class="lineno">12293</span>&#160;        <span class="keywordflow">if</span>(pDedicatedAllocVector-&gt;empty() == <span class="keyword">false</span>)</div><div class="line"><a name="l12294"></a><span class="lineno">12294</span>&#160;        {</div><div class="line"><a name="l12295"></a><span class="lineno">12295</span>&#160;            <span class="keywordflow">if</span>(dedicatedAllocationsStarted == <span class="keyword">false</span>)</div><div class="line"><a name="l12296"></a><span class="lineno">12296</span>&#160;            {</div><div class="line"><a name="l12297"></a><span class="lineno">12297</span>&#160;                dedicatedAllocationsStarted = <span class="keyword">true</span>;</div><div class="line"><a name="l12298"></a><span class="lineno">12298</span>&#160;                json.WriteString(<span class="stringliteral">&quot;DedicatedAllocations&quot;</span>);</div><div class="line"><a name="l12299"></a><span class="lineno">12299</span>&#160;                json.BeginObject();</div><div class="line"><a name="l12300"></a><span class="lineno">12300</span>&#160;            }</div><div class="line"><a name="l12301"></a><span class="lineno">12301</span>&#160;</div><div class="line"><a name="l12302"></a><span class="lineno">12302</span>&#160;            json.BeginString(<span class="stringliteral">&quot;Type &quot;</span>);</div><div class="line"><a name="l12303"></a><span class="lineno">12303</span>&#160;            json.ContinueString(memTypeIndex);</div><div class="line"><a name="l12304"></a><span class="lineno">12304</span>&#160;            json.EndString();</div><div class="line"><a name="l12305"></a><span class="lineno">12305</span>&#160;                </div><div class="line"><a name="l12306"></a><span class="lineno">12306</span>&#160;            json.BeginArray();</div><div class="line"><a name="l12307"></a><span class="lineno">12307</span>&#160;</div><div class="line"><a name="l12308"></a><span class="lineno">12308</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; pDedicatedAllocVector-&gt;size(); ++i)</div><div class="line"><a name="l12309"></a><span class="lineno">12309</span>&#160;            {</div><div class="line"><a name="l12310"></a><span class="lineno">12310</span>&#160;                json.BeginObject(<span class="keyword">true</span>);</div><div class="line"><a name="l12311"></a><span class="lineno">12311</span>&#160;                <span class="keyword">const</span> <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> hAlloc = (*pDedicatedAllocVector)[i];</div><div class="line"><a name="l12312"></a><span class="lineno">12312</span>&#160;                hAlloc-&gt;PrintParameters(json);</div><div class="line"><a name="l12313"></a><span class="lineno">12313</span>&#160;                json.EndObject();</div><div class="line"><a name="l12314"></a><span class="lineno">12314</span>&#160;            }</div><div class="line"><a name="l12315"></a><span class="lineno">12315</span>&#160;</div><div class="line"><a name="l12316"></a><span class="lineno">12316</span>&#160;            json.EndArray();</div><div class="line"><a name="l12317"></a><span class="lineno">12317</span>&#160;        }</div><div class="line"><a name="l12318"></a><span class="lineno">12318</span>&#160;    }</div><div class="line"><a name="l12319"></a><span class="lineno">12319</span>&#160;    <span class="keywordflow">if</span>(dedicatedAllocationsStarted)</div><div class="line"><a name="l12320"></a><span class="lineno">12320</span>&#160;    {</div><div class="line"><a name="l12321"></a><span class="lineno">12321</span>&#160;        json.EndObject();</div><div class="line"><a name="l12322"></a><span class="lineno">12322</span>&#160;    }</div><div class="line"><a name="l12323"></a><span class="lineno">12323</span>&#160;</div><div class="line"><a name="l12324"></a><span class="lineno">12324</span>&#160;    {</div><div class="line"><a name="l12325"></a><span class="lineno">12325</span>&#160;        <span class="keywordtype">bool</span> allocationsStarted = <span class="keyword">false</span>;</div><div class="line"><a name="l12326"></a><span class="lineno">12326</span>&#160;        <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0; memTypeIndex &lt; GetMemoryTypeCount(); ++memTypeIndex)</div><div class="line"><a name="l12327"></a><span class="lineno">12327</span>&#160;        {</div><div class="line"><a name="l12328"></a><span class="lineno">12328</span>&#160;            <span class="keywordflow">if</span>(m_pBlockVectors[memTypeIndex]-&gt;IsEmpty() == <span class="keyword">false</span>)</div><div class="line"><a name="l12329"></a><span class="lineno">12329</span>&#160;            {</div><div class="line"><a name="l12330"></a><span class="lineno">12330</span>&#160;                <span class="keywordflow">if</span>(allocationsStarted == <span class="keyword">false</span>)</div><div class="line"><a name="l12331"></a><span class="lineno">12331</span>&#160;                {</div><div class="line"><a name="l12332"></a><span class="lineno">12332</span>&#160;                    allocationsStarted = <span class="keyword">true</span>;</div><div class="line"><a name="l12333"></a><span class="lineno">12333</span>&#160;                    json.WriteString(<span class="stringliteral">&quot;DefaultPools&quot;</span>);</div><div class="line"><a name="l12334"></a><span class="lineno">12334</span>&#160;                    json.BeginObject();</div><div class="line"><a name="l12335"></a><span class="lineno">12335</span>&#160;                }</div><div class="line"><a name="l12336"></a><span class="lineno">12336</span>&#160;</div><div class="line"><a name="l12337"></a><span class="lineno">12337</span>&#160;                json.BeginString(<span class="stringliteral">&quot;Type &quot;</span>);</div><div class="line"><a name="l12338"></a><span class="lineno">12338</span>&#160;                json.ContinueString(memTypeIndex);</div><div class="line"><a name="l12339"></a><span class="lineno">12339</span>&#160;                json.EndString();</div><div class="line"><a name="l12340"></a><span class="lineno">12340</span>&#160;</div><div class="line"><a name="l12341"></a><span class="lineno">12341</span>&#160;                m_pBlockVectors[memTypeIndex]-&gt;PrintDetailedMap(json);</div><div class="line"><a name="l12342"></a><span class="lineno">12342</span>&#160;            }</div><div class="line"><a name="l12343"></a><span class="lineno">12343</span>&#160;        }</div><div class="line"><a name="l12344"></a><span class="lineno">12344</span>&#160;        <span class="keywordflow">if</span>(allocationsStarted)</div><div class="line"><a name="l12345"></a><span class="lineno">12345</span>&#160;        {</div><div class="line"><a name="l12346"></a><span class="lineno">12346</span>&#160;            json.EndObject();</div><div class="line"><a name="l12347"></a><span class="lineno">12347</span>&#160;        }</div><div class="line"><a name="l12348"></a><span class="lineno">12348</span>&#160;    }</div><div class="line"><a name="l12349"></a><span class="lineno">12349</span>&#160;</div><div class="line"><a name="l12350"></a><span class="lineno">12350</span>&#160;    <span class="comment">// Custom pools</span></div><div class="line"><a name="l12351"></a><span class="lineno">12351</span>&#160;    {</div><div class="line"><a name="l12352"></a><span class="lineno">12352</span>&#160;        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);</div><div class="line"><a name="l12353"></a><span class="lineno">12353</span>&#160;        <span class="keyword">const</span> <span class="keywordtype">size_t</span> poolCount = m_Pools.size();</div><div class="line"><a name="l12354"></a><span class="lineno">12354</span>&#160;        <span class="keywordflow">if</span>(poolCount &gt; 0)</div><div class="line"><a name="l12355"></a><span class="lineno">12355</span>&#160;        {</div><div class="line"><a name="l12356"></a><span class="lineno">12356</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Pools&quot;</span>);</div><div class="line"><a name="l12357"></a><span class="lineno">12357</span>&#160;            json.BeginObject();</div><div class="line"><a name="l12358"></a><span class="lineno">12358</span>&#160;            <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> poolIndex = 0; poolIndex &lt; poolCount; ++poolIndex)</div><div class="line"><a name="l12359"></a><span class="lineno">12359</span>&#160;            {</div><div class="line"><a name="l12360"></a><span class="lineno">12360</span>&#160;                json.BeginString();</div><div class="line"><a name="l12361"></a><span class="lineno">12361</span>&#160;                json.ContinueString(m_Pools[poolIndex]-&gt;GetId());</div><div class="line"><a name="l12362"></a><span class="lineno">12362</span>&#160;                json.EndString();</div><div class="line"><a name="l12363"></a><span class="lineno">12363</span>&#160;</div><div class="line"><a name="l12364"></a><span class="lineno">12364</span>&#160;                m_Pools[poolIndex]-&gt;m_BlockVector.PrintDetailedMap(json);</div><div class="line"><a name="l12365"></a><span class="lineno">12365</span>&#160;            }</div><div class="line"><a name="l12366"></a><span class="lineno">12366</span>&#160;            json.EndObject();</div><div class="line"><a name="l12367"></a><span class="lineno">12367</span>&#160;        }</div><div class="line"><a name="l12368"></a><span class="lineno">12368</span>&#160;    }</div><div class="line"><a name="l12369"></a><span class="lineno">12369</span>&#160;}</div><div class="line"><a name="l12370"></a><span class="lineno">12370</span>&#160;</div><div class="line"><a name="l12371"></a><span class="lineno">12371</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l12372"></a><span class="lineno">12372</span>&#160;</div><div class="line"><a name="l12374"></a><span class="lineno">12374</span>&#160;<span class="comment">// Public interface</span></div><div class="line"><a name="l12375"></a><span class="lineno">12375</span>&#160;</div><div class="line"><a name="l12376"></a><span class="lineno">12376</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a>(</div><div class="line"><a name="l12377"></a><span class="lineno">12377</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l12378"></a><span class="lineno">12378</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a>* pAllocator)</div><div class="line"><a name="l12379"></a><span class="lineno">12379</span>&#160;{</div><div class="line"><a name="l12380"></a><span class="lineno">12380</span>&#160;    VMA_ASSERT(pCreateInfo &amp;&amp; pAllocator);</div><div class="line"><a name="l12381"></a><span class="lineno">12381</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreateAllocator&quot;</span>);</div><div class="line"><a name="l12382"></a><span class="lineno">12382</span>&#160;    *pAllocator = vma_new(pCreateInfo-&gt;<a class="code" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">pAllocationCallbacks</a>, VmaAllocator_T)(pCreateInfo);</div><div class="line"><a name="l12383"></a><span class="lineno">12383</span>&#160;    <span class="keywordflow">return</span> (*pAllocator)-&gt;Init(pCreateInfo);</div><div class="line"><a name="l12384"></a><span class="lineno">12384</span>&#160;}</div><div class="line"><a name="l12385"></a><span class="lineno">12385</span>&#160;</div><div class="line"><a name="l12386"></a><span class="lineno">12386</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa8d164061c88f22fb1fd3c8f3534bc1d">vmaDestroyAllocator</a>(</div><div class="line"><a name="l12387"></a><span class="lineno">12387</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator)</div><div class="line"><a name="l12388"></a><span class="lineno">12388</span>&#160;{</div><div class="line"><a name="l12389"></a><span class="lineno">12389</span>&#160;    <span class="keywordflow">if</span>(allocator != VK_NULL_HANDLE)</div><div class="line"><a name="l12390"></a><span class="lineno">12390</span>&#160;    {</div><div class="line"><a name="l12391"></a><span class="lineno">12391</span>&#160;        VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyAllocator&quot;</span>);</div><div class="line"><a name="l12392"></a><span class="lineno">12392</span>&#160;        VkAllocationCallbacks allocationCallbacks = allocator-&gt;m_AllocationCallbacks;</div><div class="line"><a name="l12393"></a><span class="lineno">12393</span>&#160;        vma_delete(&amp;allocationCallbacks, allocator);</div><div class="line"><a name="l12394"></a><span class="lineno">12394</span>&#160;    }</div><div class="line"><a name="l12395"></a><span class="lineno">12395</span>&#160;}</div><div class="line"><a name="l12396"></a><span class="lineno">12396</span>&#160;</div><div class="line"><a name="l12397"></a><span class="lineno">12397</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aecabf7b6e91ea87d0316fa0a9e014fe0">vmaGetPhysicalDeviceProperties</a>(</div><div class="line"><a name="l12398"></a><span class="lineno">12398</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12399"></a><span class="lineno">12399</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)</div><div class="line"><a name="l12400"></a><span class="lineno">12400</span>&#160;{</div><div class="line"><a name="l12401"></a><span class="lineno">12401</span>&#160;    VMA_ASSERT(allocator &amp;&amp; ppPhysicalDeviceProperties);</div><div class="line"><a name="l12402"></a><span class="lineno">12402</span>&#160;    *ppPhysicalDeviceProperties = &amp;allocator-&gt;m_PhysicalDeviceProperties;</div><div class="line"><a name="l12403"></a><span class="lineno">12403</span>&#160;}</div><div class="line"><a name="l12404"></a><span class="lineno">12404</span>&#160;</div><div class="line"><a name="l12405"></a><span class="lineno">12405</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ab88db292a17974f911182543fda52d19">vmaGetMemoryProperties</a>(</div><div class="line"><a name="l12406"></a><span class="lineno">12406</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12407"></a><span class="lineno">12407</span>&#160;    <span class="keyword">const</span> VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties)</div><div class="line"><a name="l12408"></a><span class="lineno">12408</span>&#160;{</div><div class="line"><a name="l12409"></a><span class="lineno">12409</span>&#160;    VMA_ASSERT(allocator &amp;&amp; ppPhysicalDeviceMemoryProperties);</div><div class="line"><a name="l12410"></a><span class="lineno">12410</span>&#160;    *ppPhysicalDeviceMemoryProperties = &amp;allocator-&gt;m_MemProps;</div><div class="line"><a name="l12411"></a><span class="lineno">12411</span>&#160;}</div><div class="line"><a name="l12412"></a><span class="lineno">12412</span>&#160;</div><div class="line"><a name="l12413"></a><span class="lineno">12413</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(</div><div class="line"><a name="l12414"></a><span class="lineno">12414</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12415"></a><span class="lineno">12415</span>&#160;    uint32_t memoryTypeIndex,</div><div class="line"><a name="l12416"></a><span class="lineno">12416</span>&#160;    VkMemoryPropertyFlags* pFlags)</div><div class="line"><a name="l12417"></a><span class="lineno">12417</span>&#160;{</div><div class="line"><a name="l12418"></a><span class="lineno">12418</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pFlags);</div><div class="line"><a name="l12419"></a><span class="lineno">12419</span>&#160;    VMA_ASSERT(memoryTypeIndex &lt; allocator-&gt;GetMemoryTypeCount());</div><div class="line"><a name="l12420"></a><span class="lineno">12420</span>&#160;    *pFlags = allocator-&gt;m_MemProps.memoryTypes[memoryTypeIndex].propertyFlags;</div><div class="line"><a name="l12421"></a><span class="lineno">12421</span>&#160;}</div><div class="line"><a name="l12422"></a><span class="lineno">12422</span>&#160;</div><div class="line"><a name="l12423"></a><span class="lineno">12423</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236">vmaSetCurrentFrameIndex</a>(</div><div class="line"><a name="l12424"></a><span class="lineno">12424</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12425"></a><span class="lineno">12425</span>&#160;    uint32_t frameIndex)</div><div class="line"><a name="l12426"></a><span class="lineno">12426</span>&#160;{</div><div class="line"><a name="l12427"></a><span class="lineno">12427</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l12428"></a><span class="lineno">12428</span>&#160;    VMA_ASSERT(frameIndex != VMA_FRAME_INDEX_LOST);</div><div class="line"><a name="l12429"></a><span class="lineno">12429</span>&#160;</div><div class="line"><a name="l12430"></a><span class="lineno">12430</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12431"></a><span class="lineno">12431</span>&#160;</div><div class="line"><a name="l12432"></a><span class="lineno">12432</span>&#160;    allocator-&gt;SetCurrentFrameIndex(frameIndex);</div><div class="line"><a name="l12433"></a><span class="lineno">12433</span>&#160;}</div><div class="line"><a name="l12434"></a><span class="lineno">12434</span>&#160;</div><div class="line"><a name="l12435"></a><span class="lineno">12435</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3">vmaCalculateStats</a>(</div><div class="line"><a name="l12436"></a><span class="lineno">12436</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12437"></a><span class="lineno">12437</span>&#160;    <a class="code" href="struct_vma_stats.html">VmaStats</a>* pStats)</div><div class="line"><a name="l12438"></a><span class="lineno">12438</span>&#160;{</div><div class="line"><a name="l12439"></a><span class="lineno">12439</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pStats);</div><div class="line"><a name="l12440"></a><span class="lineno">12440</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12441"></a><span class="lineno">12441</span>&#160;    allocator-&gt;CalculateStats(pStats);</div><div class="line"><a name="l12442"></a><span class="lineno">12442</span>&#160;}</div><div class="line"><a name="l12443"></a><span class="lineno">12443</span>&#160;</div><div class="line"><a name="l12444"></a><span class="lineno">12444</span>&#160;<span class="preprocessor">#if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l12445"></a><span class="lineno">12445</span>&#160;</div><div class="line"><a name="l12446"></a><span class="lineno">12446</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0">vmaBuildStatsString</a>(</div><div class="line"><a name="l12447"></a><span class="lineno">12447</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12448"></a><span class="lineno">12448</span>&#160;    <span class="keywordtype">char</span>** ppStatsString,</div><div class="line"><a name="l12449"></a><span class="lineno">12449</span>&#160;    VkBool32 detailedMap)</div><div class="line"><a name="l12450"></a><span class="lineno">12450</span>&#160;{</div><div class="line"><a name="l12451"></a><span class="lineno">12451</span>&#160;    VMA_ASSERT(allocator &amp;&amp; ppStatsString);</div><div class="line"><a name="l12452"></a><span class="lineno">12452</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12453"></a><span class="lineno">12453</span>&#160;</div><div class="line"><a name="l12454"></a><span class="lineno">12454</span>&#160;    VmaStringBuilder sb(allocator);</div><div class="line"><a name="l12455"></a><span class="lineno">12455</span>&#160;    {</div><div class="line"><a name="l12456"></a><span class="lineno">12456</span>&#160;        VmaJsonWriter json(allocator-&gt;GetAllocationCallbacks(), sb);</div><div class="line"><a name="l12457"></a><span class="lineno">12457</span>&#160;        json.BeginObject();</div><div class="line"><a name="l12458"></a><span class="lineno">12458</span>&#160;</div><div class="line"><a name="l12459"></a><span class="lineno">12459</span>&#160;        <a class="code" href="struct_vma_stats.html">VmaStats</a> stats;</div><div class="line"><a name="l12460"></a><span class="lineno">12460</span>&#160;        allocator-&gt;CalculateStats(&amp;stats);</div><div class="line"><a name="l12461"></a><span class="lineno">12461</span>&#160;</div><div class="line"><a name="l12462"></a><span class="lineno">12462</span>&#160;        json.WriteString(<span class="stringliteral">&quot;Total&quot;</span>);</div><div class="line"><a name="l12463"></a><span class="lineno">12463</span>&#160;        VmaPrintStatInfo(json, stats.<a class="code" href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">total</a>);</div><div class="line"><a name="l12464"></a><span class="lineno">12464</span>&#160;    </div><div class="line"><a name="l12465"></a><span class="lineno">12465</span>&#160;        <span class="keywordflow">for</span>(uint32_t heapIndex = 0; heapIndex &lt; allocator-&gt;GetMemoryHeapCount(); ++heapIndex)</div><div class="line"><a name="l12466"></a><span class="lineno">12466</span>&#160;        {</div><div class="line"><a name="l12467"></a><span class="lineno">12467</span>&#160;            json.BeginString(<span class="stringliteral">&quot;Heap &quot;</span>);</div><div class="line"><a name="l12468"></a><span class="lineno">12468</span>&#160;            json.ContinueString(heapIndex);</div><div class="line"><a name="l12469"></a><span class="lineno">12469</span>&#160;            json.EndString();</div><div class="line"><a name="l12470"></a><span class="lineno">12470</span>&#160;            json.BeginObject();</div><div class="line"><a name="l12471"></a><span class="lineno">12471</span>&#160;</div><div class="line"><a name="l12472"></a><span class="lineno">12472</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Size&quot;</span>);</div><div class="line"><a name="l12473"></a><span class="lineno">12473</span>&#160;            json.WriteNumber(allocator-&gt;m_MemProps.memoryHeaps[heapIndex].size);</div><div class="line"><a name="l12474"></a><span class="lineno">12474</span>&#160;</div><div class="line"><a name="l12475"></a><span class="lineno">12475</span>&#160;            json.WriteString(<span class="stringliteral">&quot;Flags&quot;</span>);</div><div class="line"><a name="l12476"></a><span class="lineno">12476</span>&#160;            json.BeginArray(<span class="keyword">true</span>);</div><div class="line"><a name="l12477"></a><span class="lineno">12477</span>&#160;            <span class="keywordflow">if</span>((allocator-&gt;m_MemProps.memoryHeaps[heapIndex].flags &amp; VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)</div><div class="line"><a name="l12478"></a><span class="lineno">12478</span>&#160;            {</div><div class="line"><a name="l12479"></a><span class="lineno">12479</span>&#160;                json.WriteString(<span class="stringliteral">&quot;DEVICE_LOCAL&quot;</span>);</div><div class="line"><a name="l12480"></a><span class="lineno">12480</span>&#160;            }</div><div class="line"><a name="l12481"></a><span class="lineno">12481</span>&#160;            json.EndArray();</div><div class="line"><a name="l12482"></a><span class="lineno">12482</span>&#160;</div><div class="line"><a name="l12483"></a><span class="lineno">12483</span>&#160;            <span class="keywordflow">if</span>(stats.<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[heapIndex].<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> &gt; 0)</div><div class="line"><a name="l12484"></a><span class="lineno">12484</span>&#160;            {</div><div class="line"><a name="l12485"></a><span class="lineno">12485</span>&#160;                json.WriteString(<span class="stringliteral">&quot;Stats&quot;</span>);</div><div class="line"><a name="l12486"></a><span class="lineno">12486</span>&#160;                VmaPrintStatInfo(json, stats.<a class="code" href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">memoryHeap</a>[heapIndex]);</div><div class="line"><a name="l12487"></a><span class="lineno">12487</span>&#160;            }</div><div class="line"><a name="l12488"></a><span class="lineno">12488</span>&#160;</div><div class="line"><a name="l12489"></a><span class="lineno">12489</span>&#160;            <span class="keywordflow">for</span>(uint32_t typeIndex = 0; typeIndex &lt; allocator-&gt;GetMemoryTypeCount(); ++typeIndex)</div><div class="line"><a name="l12490"></a><span class="lineno">12490</span>&#160;            {</div><div class="line"><a name="l12491"></a><span class="lineno">12491</span>&#160;                <span class="keywordflow">if</span>(allocator-&gt;MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex)</div><div class="line"><a name="l12492"></a><span class="lineno">12492</span>&#160;                {</div><div class="line"><a name="l12493"></a><span class="lineno">12493</span>&#160;                    json.BeginString(<span class="stringliteral">&quot;Type &quot;</span>);</div><div class="line"><a name="l12494"></a><span class="lineno">12494</span>&#160;                    json.ContinueString(typeIndex);</div><div class="line"><a name="l12495"></a><span class="lineno">12495</span>&#160;                    json.EndString();</div><div class="line"><a name="l12496"></a><span class="lineno">12496</span>&#160;</div><div class="line"><a name="l12497"></a><span class="lineno">12497</span>&#160;                    json.BeginObject();</div><div class="line"><a name="l12498"></a><span class="lineno">12498</span>&#160;</div><div class="line"><a name="l12499"></a><span class="lineno">12499</span>&#160;                    json.WriteString(<span class="stringliteral">&quot;Flags&quot;</span>);</div><div class="line"><a name="l12500"></a><span class="lineno">12500</span>&#160;                    json.BeginArray(<span class="keyword">true</span>);</div><div class="line"><a name="l12501"></a><span class="lineno">12501</span>&#160;                    VkMemoryPropertyFlags flags = allocator-&gt;m_MemProps.memoryTypes[typeIndex].propertyFlags;</div><div class="line"><a name="l12502"></a><span class="lineno">12502</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)</div><div class="line"><a name="l12503"></a><span class="lineno">12503</span>&#160;                    {</div><div class="line"><a name="l12504"></a><span class="lineno">12504</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;DEVICE_LOCAL&quot;</span>);</div><div class="line"><a name="l12505"></a><span class="lineno">12505</span>&#160;                    }</div><div class="line"><a name="l12506"></a><span class="lineno">12506</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)</div><div class="line"><a name="l12507"></a><span class="lineno">12507</span>&#160;                    {</div><div class="line"><a name="l12508"></a><span class="lineno">12508</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;HOST_VISIBLE&quot;</span>);</div><div class="line"><a name="l12509"></a><span class="lineno">12509</span>&#160;                    }</div><div class="line"><a name="l12510"></a><span class="lineno">12510</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)</div><div class="line"><a name="l12511"></a><span class="lineno">12511</span>&#160;                    {</div><div class="line"><a name="l12512"></a><span class="lineno">12512</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;HOST_COHERENT&quot;</span>);</div><div class="line"><a name="l12513"></a><span class="lineno">12513</span>&#160;                    }</div><div class="line"><a name="l12514"></a><span class="lineno">12514</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)</div><div class="line"><a name="l12515"></a><span class="lineno">12515</span>&#160;                    {</div><div class="line"><a name="l12516"></a><span class="lineno">12516</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;HOST_CACHED&quot;</span>);</div><div class="line"><a name="l12517"></a><span class="lineno">12517</span>&#160;                    }</div><div class="line"><a name="l12518"></a><span class="lineno">12518</span>&#160;                    <span class="keywordflow">if</span>((flags &amp; VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)</div><div class="line"><a name="l12519"></a><span class="lineno">12519</span>&#160;                    {</div><div class="line"><a name="l12520"></a><span class="lineno">12520</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;LAZILY_ALLOCATED&quot;</span>);</div><div class="line"><a name="l12521"></a><span class="lineno">12521</span>&#160;                    }</div><div class="line"><a name="l12522"></a><span class="lineno">12522</span>&#160;                    json.EndArray();</div><div class="line"><a name="l12523"></a><span class="lineno">12523</span>&#160;</div><div class="line"><a name="l12524"></a><span class="lineno">12524</span>&#160;                    <span class="keywordflow">if</span>(stats.<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[typeIndex].<a class="code" href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">blockCount</a> &gt; 0)</div><div class="line"><a name="l12525"></a><span class="lineno">12525</span>&#160;                    {</div><div class="line"><a name="l12526"></a><span class="lineno">12526</span>&#160;                        json.WriteString(<span class="stringliteral">&quot;Stats&quot;</span>);</div><div class="line"><a name="l12527"></a><span class="lineno">12527</span>&#160;                        VmaPrintStatInfo(json, stats.<a class="code" href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">memoryType</a>[typeIndex]);</div><div class="line"><a name="l12528"></a><span class="lineno">12528</span>&#160;                    }</div><div class="line"><a name="l12529"></a><span class="lineno">12529</span>&#160;</div><div class="line"><a name="l12530"></a><span class="lineno">12530</span>&#160;                    json.EndObject();</div><div class="line"><a name="l12531"></a><span class="lineno">12531</span>&#160;                }</div><div class="line"><a name="l12532"></a><span class="lineno">12532</span>&#160;            }</div><div class="line"><a name="l12533"></a><span class="lineno">12533</span>&#160;</div><div class="line"><a name="l12534"></a><span class="lineno">12534</span>&#160;            json.EndObject();</div><div class="line"><a name="l12535"></a><span class="lineno">12535</span>&#160;        }</div><div class="line"><a name="l12536"></a><span class="lineno">12536</span>&#160;        <span class="keywordflow">if</span>(detailedMap == VK_TRUE)</div><div class="line"><a name="l12537"></a><span class="lineno">12537</span>&#160;        {</div><div class="line"><a name="l12538"></a><span class="lineno">12538</span>&#160;            allocator-&gt;PrintDetailedMap(json);</div><div class="line"><a name="l12539"></a><span class="lineno">12539</span>&#160;        }</div><div class="line"><a name="l12540"></a><span class="lineno">12540</span>&#160;</div><div class="line"><a name="l12541"></a><span class="lineno">12541</span>&#160;        json.EndObject();</div><div class="line"><a name="l12542"></a><span class="lineno">12542</span>&#160;    }</div><div class="line"><a name="l12543"></a><span class="lineno">12543</span>&#160;</div><div class="line"><a name="l12544"></a><span class="lineno">12544</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">size_t</span> len = sb.GetLength();</div><div class="line"><a name="l12545"></a><span class="lineno">12545</span>&#160;    <span class="keywordtype">char</span>* <span class="keyword">const</span> pChars = vma_new_array(allocator, <span class="keywordtype">char</span>, len + 1);</div><div class="line"><a name="l12546"></a><span class="lineno">12546</span>&#160;    <span class="keywordflow">if</span>(len &gt; 0)</div><div class="line"><a name="l12547"></a><span class="lineno">12547</span>&#160;    {</div><div class="line"><a name="l12548"></a><span class="lineno">12548</span>&#160;        memcpy(pChars, sb.GetData(), len);</div><div class="line"><a name="l12549"></a><span class="lineno">12549</span>&#160;    }</div><div class="line"><a name="l12550"></a><span class="lineno">12550</span>&#160;    pChars[len] = <span class="charliteral">&#39;\0&#39;</span>;</div><div class="line"><a name="l12551"></a><span class="lineno">12551</span>&#160;    *ppStatsString = pChars;</div><div class="line"><a name="l12552"></a><span class="lineno">12552</span>&#160;}</div><div class="line"><a name="l12553"></a><span class="lineno">12553</span>&#160;</div><div class="line"><a name="l12554"></a><span class="lineno">12554</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vmaFreeStatsString</a>(</div><div class="line"><a name="l12555"></a><span class="lineno">12555</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12556"></a><span class="lineno">12556</span>&#160;    <span class="keywordtype">char</span>* pStatsString)</div><div class="line"><a name="l12557"></a><span class="lineno">12557</span>&#160;{</div><div class="line"><a name="l12558"></a><span class="lineno">12558</span>&#160;    <span class="keywordflow">if</span>(pStatsString != VMA_NULL)</div><div class="line"><a name="l12559"></a><span class="lineno">12559</span>&#160;    {</div><div class="line"><a name="l12560"></a><span class="lineno">12560</span>&#160;        VMA_ASSERT(allocator);</div><div class="line"><a name="l12561"></a><span class="lineno">12561</span>&#160;        <span class="keywordtype">size_t</span> len = strlen(pStatsString);</div><div class="line"><a name="l12562"></a><span class="lineno">12562</span>&#160;        vma_delete_array(allocator, pStatsString, len + 1);</div><div class="line"><a name="l12563"></a><span class="lineno">12563</span>&#160;    }</div><div class="line"><a name="l12564"></a><span class="lineno">12564</span>&#160;}</div><div class="line"><a name="l12565"></a><span class="lineno">12565</span>&#160;</div><div class="line"><a name="l12566"></a><span class="lineno">12566</span>&#160;<span class="preprocessor">#endif // #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l12567"></a><span class="lineno">12567</span>&#160;</div><div class="line"><a name="l12568"></a><span class="lineno">12568</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l12569"></a><span class="lineno">12569</span>&#160;<span class="comment">This function is not protected by any mutex because it just reads immutable data.</span></div><div class="line"><a name="l12570"></a><span class="lineno">12570</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l12571"></a><span class="lineno">12571</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l12572"></a><span class="lineno">12572</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12573"></a><span class="lineno">12573</span>&#160;    uint32_t memoryTypeBits,</div><div class="line"><a name="l12574"></a><span class="lineno">12574</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l12575"></a><span class="lineno">12575</span>&#160;    uint32_t* pMemoryTypeIndex)</div><div class="line"><a name="l12576"></a><span class="lineno">12576</span>&#160;{</div><div class="line"><a name="l12577"></a><span class="lineno">12577</span>&#160;    VMA_ASSERT(allocator != VK_NULL_HANDLE);</div><div class="line"><a name="l12578"></a><span class="lineno">12578</span>&#160;    VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);</div><div class="line"><a name="l12579"></a><span class="lineno">12579</span>&#160;    VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);</div><div class="line"><a name="l12580"></a><span class="lineno">12580</span>&#160;</div><div class="line"><a name="l12581"></a><span class="lineno">12581</span>&#160;    <span class="keywordflow">if</span>(pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a> != 0)</div><div class="line"><a name="l12582"></a><span class="lineno">12582</span>&#160;    {</div><div class="line"><a name="l12583"></a><span class="lineno">12583</span>&#160;        memoryTypeBits &amp;= pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a>;</div><div class="line"><a name="l12584"></a><span class="lineno">12584</span>&#160;    }</div><div class="line"><a name="l12585"></a><span class="lineno">12585</span>&#160;    </div><div class="line"><a name="l12586"></a><span class="lineno">12586</span>&#160;    uint32_t requiredFlags = pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">requiredFlags</a>;</div><div class="line"><a name="l12587"></a><span class="lineno">12587</span>&#160;    uint32_t preferredFlags = pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">preferredFlags</a>;</div><div class="line"><a name="l12588"></a><span class="lineno">12588</span>&#160;</div><div class="line"><a name="l12589"></a><span class="lineno">12589</span>&#160;    <span class="keyword">const</span> <span class="keywordtype">bool</span> mapped = (pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> &amp; <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>) != 0;</div><div class="line"><a name="l12590"></a><span class="lineno">12590</span>&#160;    <span class="keywordflow">if</span>(mapped)</div><div class="line"><a name="l12591"></a><span class="lineno">12591</span>&#160;    {</div><div class="line"><a name="l12592"></a><span class="lineno">12592</span>&#160;        preferredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;</div><div class="line"><a name="l12593"></a><span class="lineno">12593</span>&#160;    }</div><div class="line"><a name="l12594"></a><span class="lineno">12594</span>&#160;</div><div class="line"><a name="l12595"></a><span class="lineno">12595</span>&#160;    <span class="comment">// Convert usage to requiredFlags and preferredFlags.</span></div><div class="line"><a name="l12596"></a><span class="lineno">12596</span>&#160;    <span class="keywordflow">switch</span>(pAllocationCreateInfo-&gt;<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a>)</div><div class="line"><a name="l12597"></a><span class="lineno">12597</span>&#160;    {</div><div class="line"><a name="l12598"></a><span class="lineno">12598</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a>:</div><div class="line"><a name="l12599"></a><span class="lineno">12599</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12600"></a><span class="lineno">12600</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>:</div><div class="line"><a name="l12601"></a><span class="lineno">12601</span>&#160;        <span class="keywordflow">if</span>(!allocator-&gt;IsIntegratedGpu() || (preferredFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)</div><div class="line"><a name="l12602"></a><span class="lineno">12602</span>&#160;        {</div><div class="line"><a name="l12603"></a><span class="lineno">12603</span>&#160;            preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;</div><div class="line"><a name="l12604"></a><span class="lineno">12604</span>&#160;        }</div><div class="line"><a name="l12605"></a><span class="lineno">12605</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12606"></a><span class="lineno">12606</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a>:</div><div class="line"><a name="l12607"></a><span class="lineno">12607</span>&#160;        requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;</div><div class="line"><a name="l12608"></a><span class="lineno">12608</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12609"></a><span class="lineno">12609</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a>:</div><div class="line"><a name="l12610"></a><span class="lineno">12610</span>&#160;        requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;</div><div class="line"><a name="l12611"></a><span class="lineno">12611</span>&#160;        <span class="keywordflow">if</span>(!allocator-&gt;IsIntegratedGpu() || (preferredFlags &amp; VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)</div><div class="line"><a name="l12612"></a><span class="lineno">12612</span>&#160;        {</div><div class="line"><a name="l12613"></a><span class="lineno">12613</span>&#160;            preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;</div><div class="line"><a name="l12614"></a><span class="lineno">12614</span>&#160;        }</div><div class="line"><a name="l12615"></a><span class="lineno">12615</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12616"></a><span class="lineno">12616</span>&#160;    <span class="keywordflow">case</span> <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a>:</div><div class="line"><a name="l12617"></a><span class="lineno">12617</span>&#160;        requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;</div><div class="line"><a name="l12618"></a><span class="lineno">12618</span>&#160;        preferredFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;</div><div class="line"><a name="l12619"></a><span class="lineno">12619</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12620"></a><span class="lineno">12620</span>&#160;    <span class="keywordflow">default</span>:</div><div class="line"><a name="l12621"></a><span class="lineno">12621</span>&#160;        <span class="keywordflow">break</span>;</div><div class="line"><a name="l12622"></a><span class="lineno">12622</span>&#160;    }</div><div class="line"><a name="l12623"></a><span class="lineno">12623</span>&#160;</div><div class="line"><a name="l12624"></a><span class="lineno">12624</span>&#160;    *pMemoryTypeIndex = UINT32_MAX;</div><div class="line"><a name="l12625"></a><span class="lineno">12625</span>&#160;    uint32_t minCost = UINT32_MAX;</div><div class="line"><a name="l12626"></a><span class="lineno">12626</span>&#160;    <span class="keywordflow">for</span>(uint32_t memTypeIndex = 0, memTypeBit = 1;</div><div class="line"><a name="l12627"></a><span class="lineno">12627</span>&#160;        memTypeIndex &lt; allocator-&gt;GetMemoryTypeCount();</div><div class="line"><a name="l12628"></a><span class="lineno">12628</span>&#160;        ++memTypeIndex, memTypeBit &lt;&lt;= 1)</div><div class="line"><a name="l12629"></a><span class="lineno">12629</span>&#160;    {</div><div class="line"><a name="l12630"></a><span class="lineno">12630</span>&#160;        <span class="comment">// This memory type is acceptable according to memoryTypeBits bitmask.</span></div><div class="line"><a name="l12631"></a><span class="lineno">12631</span>&#160;        <span class="keywordflow">if</span>((memTypeBit &amp; memoryTypeBits) != 0)</div><div class="line"><a name="l12632"></a><span class="lineno">12632</span>&#160;        {</div><div class="line"><a name="l12633"></a><span class="lineno">12633</span>&#160;            <span class="keyword">const</span> VkMemoryPropertyFlags currFlags =</div><div class="line"><a name="l12634"></a><span class="lineno">12634</span>&#160;                allocator-&gt;m_MemProps.memoryTypes[memTypeIndex].propertyFlags;</div><div class="line"><a name="l12635"></a><span class="lineno">12635</span>&#160;            <span class="comment">// This memory type contains requiredFlags.</span></div><div class="line"><a name="l12636"></a><span class="lineno">12636</span>&#160;            <span class="keywordflow">if</span>((requiredFlags &amp; ~currFlags) == 0)</div><div class="line"><a name="l12637"></a><span class="lineno">12637</span>&#160;            {</div><div class="line"><a name="l12638"></a><span class="lineno">12638</span>&#160;                <span class="comment">// Calculate cost as number of bits from preferredFlags not present in this memory type.</span></div><div class="line"><a name="l12639"></a><span class="lineno">12639</span>&#160;                uint32_t currCost = VmaCountBitsSet(preferredFlags &amp; ~currFlags);</div><div class="line"><a name="l12640"></a><span class="lineno">12640</span>&#160;                <span class="comment">// Remember memory type with lowest cost.</span></div><div class="line"><a name="l12641"></a><span class="lineno">12641</span>&#160;                <span class="keywordflow">if</span>(currCost &lt; minCost)</div><div class="line"><a name="l12642"></a><span class="lineno">12642</span>&#160;                {</div><div class="line"><a name="l12643"></a><span class="lineno">12643</span>&#160;                    *pMemoryTypeIndex = memTypeIndex;</div><div class="line"><a name="l12644"></a><span class="lineno">12644</span>&#160;                    <span class="keywordflow">if</span>(currCost == 0)</div><div class="line"><a name="l12645"></a><span class="lineno">12645</span>&#160;                    {</div><div class="line"><a name="l12646"></a><span class="lineno">12646</span>&#160;                        <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l12647"></a><span class="lineno">12647</span>&#160;                    }</div><div class="line"><a name="l12648"></a><span class="lineno">12648</span>&#160;                    minCost = currCost;</div><div class="line"><a name="l12649"></a><span class="lineno">12649</span>&#160;                }</div><div class="line"><a name="l12650"></a><span class="lineno">12650</span>&#160;            }</div><div class="line"><a name="l12651"></a><span class="lineno">12651</span>&#160;        }</div><div class="line"><a name="l12652"></a><span class="lineno">12652</span>&#160;    }</div><div class="line"><a name="l12653"></a><span class="lineno">12653</span>&#160;    <span class="keywordflow">return</span> (*pMemoryTypeIndex != UINT32_MAX) ? VK_SUCCESS : VK_ERROR_FEATURE_NOT_PRESENT;</div><div class="line"><a name="l12654"></a><span class="lineno">12654</span>&#160;}</div><div class="line"><a name="l12655"></a><span class="lineno">12655</span>&#160;</div><div class="line"><a name="l12656"></a><span class="lineno">12656</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(</div><div class="line"><a name="l12657"></a><span class="lineno">12657</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12658"></a><span class="lineno">12658</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l12659"></a><span class="lineno">12659</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l12660"></a><span class="lineno">12660</span>&#160;    uint32_t* pMemoryTypeIndex)</div><div class="line"><a name="l12661"></a><span class="lineno">12661</span>&#160;{</div><div class="line"><a name="l12662"></a><span class="lineno">12662</span>&#160;    VMA_ASSERT(allocator != VK_NULL_HANDLE);</div><div class="line"><a name="l12663"></a><span class="lineno">12663</span>&#160;    VMA_ASSERT(pBufferCreateInfo != VMA_NULL);</div><div class="line"><a name="l12664"></a><span class="lineno">12664</span>&#160;    VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);</div><div class="line"><a name="l12665"></a><span class="lineno">12665</span>&#160;    VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);</div><div class="line"><a name="l12666"></a><span class="lineno">12666</span>&#160;</div><div class="line"><a name="l12667"></a><span class="lineno">12667</span>&#160;    <span class="keyword">const</span> VkDevice hDev = allocator-&gt;m_hDevice;</div><div class="line"><a name="l12668"></a><span class="lineno">12668</span>&#160;    VkBuffer hBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l12669"></a><span class="lineno">12669</span>&#160;    VkResult res = allocator-&gt;GetVulkanFunctions().vkCreateBuffer(</div><div class="line"><a name="l12670"></a><span class="lineno">12670</span>&#160;        hDev, pBufferCreateInfo, allocator-&gt;GetAllocationCallbacks(), &amp;hBuffer);</div><div class="line"><a name="l12671"></a><span class="lineno">12671</span>&#160;    <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l12672"></a><span class="lineno">12672</span>&#160;    {</div><div class="line"><a name="l12673"></a><span class="lineno">12673</span>&#160;        VkMemoryRequirements memReq = {};</div><div class="line"><a name="l12674"></a><span class="lineno">12674</span>&#160;        allocator-&gt;GetVulkanFunctions().vkGetBufferMemoryRequirements(</div><div class="line"><a name="l12675"></a><span class="lineno">12675</span>&#160;            hDev, hBuffer, &amp;memReq);</div><div class="line"><a name="l12676"></a><span class="lineno">12676</span>&#160;</div><div class="line"><a name="l12677"></a><span class="lineno">12677</span>&#160;        res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l12678"></a><span class="lineno">12678</span>&#160;            allocator,</div><div class="line"><a name="l12679"></a><span class="lineno">12679</span>&#160;            memReq.memoryTypeBits,</div><div class="line"><a name="l12680"></a><span class="lineno">12680</span>&#160;            pAllocationCreateInfo,</div><div class="line"><a name="l12681"></a><span class="lineno">12681</span>&#160;            pMemoryTypeIndex);</div><div class="line"><a name="l12682"></a><span class="lineno">12682</span>&#160;</div><div class="line"><a name="l12683"></a><span class="lineno">12683</span>&#160;        allocator-&gt;GetVulkanFunctions().vkDestroyBuffer(</div><div class="line"><a name="l12684"></a><span class="lineno">12684</span>&#160;            hDev, hBuffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l12685"></a><span class="lineno">12685</span>&#160;    }</div><div class="line"><a name="l12686"></a><span class="lineno">12686</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l12687"></a><span class="lineno">12687</span>&#160;}</div><div class="line"><a name="l12688"></a><span class="lineno">12688</span>&#160;</div><div class="line"><a name="l12689"></a><span class="lineno">12689</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472">vmaFindMemoryTypeIndexForImageInfo</a>(</div><div class="line"><a name="l12690"></a><span class="lineno">12690</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12691"></a><span class="lineno">12691</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l12692"></a><span class="lineno">12692</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l12693"></a><span class="lineno">12693</span>&#160;    uint32_t* pMemoryTypeIndex)</div><div class="line"><a name="l12694"></a><span class="lineno">12694</span>&#160;{</div><div class="line"><a name="l12695"></a><span class="lineno">12695</span>&#160;    VMA_ASSERT(allocator != VK_NULL_HANDLE);</div><div class="line"><a name="l12696"></a><span class="lineno">12696</span>&#160;    VMA_ASSERT(pImageCreateInfo != VMA_NULL);</div><div class="line"><a name="l12697"></a><span class="lineno">12697</span>&#160;    VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);</div><div class="line"><a name="l12698"></a><span class="lineno">12698</span>&#160;    VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);</div><div class="line"><a name="l12699"></a><span class="lineno">12699</span>&#160;</div><div class="line"><a name="l12700"></a><span class="lineno">12700</span>&#160;    <span class="keyword">const</span> VkDevice hDev = allocator-&gt;m_hDevice;</div><div class="line"><a name="l12701"></a><span class="lineno">12701</span>&#160;    VkImage hImage = VK_NULL_HANDLE;</div><div class="line"><a name="l12702"></a><span class="lineno">12702</span>&#160;    VkResult res = allocator-&gt;GetVulkanFunctions().vkCreateImage(</div><div class="line"><a name="l12703"></a><span class="lineno">12703</span>&#160;        hDev, pImageCreateInfo, allocator-&gt;GetAllocationCallbacks(), &amp;hImage);</div><div class="line"><a name="l12704"></a><span class="lineno">12704</span>&#160;    <span class="keywordflow">if</span>(res == VK_SUCCESS)</div><div class="line"><a name="l12705"></a><span class="lineno">12705</span>&#160;    {</div><div class="line"><a name="l12706"></a><span class="lineno">12706</span>&#160;        VkMemoryRequirements memReq = {};</div><div class="line"><a name="l12707"></a><span class="lineno">12707</span>&#160;        allocator-&gt;GetVulkanFunctions().vkGetImageMemoryRequirements(</div><div class="line"><a name="l12708"></a><span class="lineno">12708</span>&#160;            hDev, hImage, &amp;memReq);</div><div class="line"><a name="l12709"></a><span class="lineno">12709</span>&#160;</div><div class="line"><a name="l12710"></a><span class="lineno">12710</span>&#160;        res = <a class="code" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a>(</div><div class="line"><a name="l12711"></a><span class="lineno">12711</span>&#160;            allocator,</div><div class="line"><a name="l12712"></a><span class="lineno">12712</span>&#160;            memReq.memoryTypeBits,</div><div class="line"><a name="l12713"></a><span class="lineno">12713</span>&#160;            pAllocationCreateInfo,</div><div class="line"><a name="l12714"></a><span class="lineno">12714</span>&#160;            pMemoryTypeIndex);</div><div class="line"><a name="l12715"></a><span class="lineno">12715</span>&#160;</div><div class="line"><a name="l12716"></a><span class="lineno">12716</span>&#160;        allocator-&gt;GetVulkanFunctions().vkDestroyImage(</div><div class="line"><a name="l12717"></a><span class="lineno">12717</span>&#160;            hDev, hImage, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l12718"></a><span class="lineno">12718</span>&#160;    }</div><div class="line"><a name="l12719"></a><span class="lineno">12719</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l12720"></a><span class="lineno">12720</span>&#160;}</div><div class="line"><a name="l12721"></a><span class="lineno">12721</span>&#160;</div><div class="line"><a name="l12722"></a><span class="lineno">12722</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(</div><div class="line"><a name="l12723"></a><span class="lineno">12723</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12724"></a><span class="lineno">12724</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l12725"></a><span class="lineno">12725</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a>* pPool)</div><div class="line"><a name="l12726"></a><span class="lineno">12726</span>&#160;{</div><div class="line"><a name="l12727"></a><span class="lineno">12727</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pCreateInfo &amp;&amp; pPool);</div><div class="line"><a name="l12728"></a><span class="lineno">12728</span>&#160;    </div><div class="line"><a name="l12729"></a><span class="lineno">12729</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreatePool&quot;</span>);</div><div class="line"><a name="l12730"></a><span class="lineno">12730</span>&#160;    </div><div class="line"><a name="l12731"></a><span class="lineno">12731</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12732"></a><span class="lineno">12732</span>&#160;    </div><div class="line"><a name="l12733"></a><span class="lineno">12733</span>&#160;    VkResult res = allocator-&gt;CreatePool(pCreateInfo, pPool);</div><div class="line"><a name="l12734"></a><span class="lineno">12734</span>&#160;    </div><div class="line"><a name="l12735"></a><span class="lineno">12735</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12736"></a><span class="lineno">12736</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12737"></a><span class="lineno">12737</span>&#160;    {</div><div class="line"><a name="l12738"></a><span class="lineno">12738</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordCreatePool(allocator-&gt;GetCurrentFrameIndex(), *pCreateInfo, *pPool);</div><div class="line"><a name="l12739"></a><span class="lineno">12739</span>&#160;    }</div><div class="line"><a name="l12740"></a><span class="lineno">12740</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12741"></a><span class="lineno">12741</span>&#160;    </div><div class="line"><a name="l12742"></a><span class="lineno">12742</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l12743"></a><span class="lineno">12743</span>&#160;}</div><div class="line"><a name="l12744"></a><span class="lineno">12744</span>&#160;</div><div class="line"><a name="l12745"></a><span class="lineno">12745</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a>(</div><div class="line"><a name="l12746"></a><span class="lineno">12746</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12747"></a><span class="lineno">12747</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l12748"></a><span class="lineno">12748</span>&#160;{</div><div class="line"><a name="l12749"></a><span class="lineno">12749</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l12750"></a><span class="lineno">12750</span>&#160;    </div><div class="line"><a name="l12751"></a><span class="lineno">12751</span>&#160;    <span class="keywordflow">if</span>(pool == VK_NULL_HANDLE)</div><div class="line"><a name="l12752"></a><span class="lineno">12752</span>&#160;    {</div><div class="line"><a name="l12753"></a><span class="lineno">12753</span>&#160;        <span class="keywordflow">return</span>;</div><div class="line"><a name="l12754"></a><span class="lineno">12754</span>&#160;    }</div><div class="line"><a name="l12755"></a><span class="lineno">12755</span>&#160;    </div><div class="line"><a name="l12756"></a><span class="lineno">12756</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyPool&quot;</span>);</div><div class="line"><a name="l12757"></a><span class="lineno">12757</span>&#160;    </div><div class="line"><a name="l12758"></a><span class="lineno">12758</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12759"></a><span class="lineno">12759</span>&#160;    </div><div class="line"><a name="l12760"></a><span class="lineno">12760</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12761"></a><span class="lineno">12761</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12762"></a><span class="lineno">12762</span>&#160;    {</div><div class="line"><a name="l12763"></a><span class="lineno">12763</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordDestroyPool(allocator-&gt;GetCurrentFrameIndex(), pool);</div><div class="line"><a name="l12764"></a><span class="lineno">12764</span>&#160;    }</div><div class="line"><a name="l12765"></a><span class="lineno">12765</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12766"></a><span class="lineno">12766</span>&#160;</div><div class="line"><a name="l12767"></a><span class="lineno">12767</span>&#160;    allocator-&gt;DestroyPool(pool);</div><div class="line"><a name="l12768"></a><span class="lineno">12768</span>&#160;}</div><div class="line"><a name="l12769"></a><span class="lineno">12769</span>&#160;</div><div class="line"><a name="l12770"></a><span class="lineno">12770</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153">vmaGetPoolStats</a>(</div><div class="line"><a name="l12771"></a><span class="lineno">12771</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12772"></a><span class="lineno">12772</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l12773"></a><span class="lineno">12773</span>&#160;    <a class="code" href="struct_vma_pool_stats.html">VmaPoolStats</a>* pPoolStats)</div><div class="line"><a name="l12774"></a><span class="lineno">12774</span>&#160;{</div><div class="line"><a name="l12775"></a><span class="lineno">12775</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pool &amp;&amp; pPoolStats);</div><div class="line"><a name="l12776"></a><span class="lineno">12776</span>&#160;</div><div class="line"><a name="l12777"></a><span class="lineno">12777</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12778"></a><span class="lineno">12778</span>&#160;</div><div class="line"><a name="l12779"></a><span class="lineno">12779</span>&#160;    allocator-&gt;GetPoolStats(pool, pPoolStats);</div><div class="line"><a name="l12780"></a><span class="lineno">12780</span>&#160;}</div><div class="line"><a name="l12781"></a><span class="lineno">12781</span>&#160;</div><div class="line"><a name="l12782"></a><span class="lineno">12782</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vmaMakePoolAllocationsLost</a>(</div><div class="line"><a name="l12783"></a><span class="lineno">12783</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12784"></a><span class="lineno">12784</span>&#160;    <a class="code" href="struct_vma_pool.html">VmaPool</a> pool,</div><div class="line"><a name="l12785"></a><span class="lineno">12785</span>&#160;    <span class="keywordtype">size_t</span>* pLostAllocationCount)</div><div class="line"><a name="l12786"></a><span class="lineno">12786</span>&#160;{</div><div class="line"><a name="l12787"></a><span class="lineno">12787</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pool);</div><div class="line"><a name="l12788"></a><span class="lineno">12788</span>&#160;</div><div class="line"><a name="l12789"></a><span class="lineno">12789</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12790"></a><span class="lineno">12790</span>&#160;</div><div class="line"><a name="l12791"></a><span class="lineno">12791</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12792"></a><span class="lineno">12792</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12793"></a><span class="lineno">12793</span>&#160;    {</div><div class="line"><a name="l12794"></a><span class="lineno">12794</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordMakePoolAllocationsLost(allocator-&gt;GetCurrentFrameIndex(), pool);</div><div class="line"><a name="l12795"></a><span class="lineno">12795</span>&#160;    }</div><div class="line"><a name="l12796"></a><span class="lineno">12796</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12797"></a><span class="lineno">12797</span>&#160;</div><div class="line"><a name="l12798"></a><span class="lineno">12798</span>&#160;    allocator-&gt;MakePoolAllocationsLost(pool, pLostAllocationCount);</div><div class="line"><a name="l12799"></a><span class="lineno">12799</span>&#160;}</div><div class="line"><a name="l12800"></a><span class="lineno">12800</span>&#160;</div><div class="line"><a name="l12801"></a><span class="lineno">12801</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89">vmaCheckPoolCorruption</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="code" href="struct_vma_pool.html">VmaPool</a> pool)</div><div class="line"><a name="l12802"></a><span class="lineno">12802</span>&#160;{</div><div class="line"><a name="l12803"></a><span class="lineno">12803</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pool);</div><div class="line"><a name="l12804"></a><span class="lineno">12804</span>&#160;</div><div class="line"><a name="l12805"></a><span class="lineno">12805</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12806"></a><span class="lineno">12806</span>&#160;</div><div class="line"><a name="l12807"></a><span class="lineno">12807</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCheckPoolCorruption&quot;</span>);</div><div class="line"><a name="l12808"></a><span class="lineno">12808</span>&#160;</div><div class="line"><a name="l12809"></a><span class="lineno">12809</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;CheckPoolCorruption(pool);</div><div class="line"><a name="l12810"></a><span class="lineno">12810</span>&#160;}</div><div class="line"><a name="l12811"></a><span class="lineno">12811</span>&#160;</div><div class="line"><a name="l12812"></a><span class="lineno">12812</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a>(</div><div class="line"><a name="l12813"></a><span class="lineno">12813</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12814"></a><span class="lineno">12814</span>&#160;    <span class="keyword">const</span> VkMemoryRequirements* pVkMemoryRequirements,</div><div class="line"><a name="l12815"></a><span class="lineno">12815</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l12816"></a><span class="lineno">12816</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l12817"></a><span class="lineno">12817</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l12818"></a><span class="lineno">12818</span>&#160;{</div><div class="line"><a name="l12819"></a><span class="lineno">12819</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pVkMemoryRequirements &amp;&amp; pCreateInfo &amp;&amp; pAllocation);</div><div class="line"><a name="l12820"></a><span class="lineno">12820</span>&#160;</div><div class="line"><a name="l12821"></a><span class="lineno">12821</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaAllocateMemory&quot;</span>);</div><div class="line"><a name="l12822"></a><span class="lineno">12822</span>&#160;</div><div class="line"><a name="l12823"></a><span class="lineno">12823</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12824"></a><span class="lineno">12824</span>&#160;</div><div class="line"><a name="l12825"></a><span class="lineno">12825</span>&#160;    VkResult result = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l12826"></a><span class="lineno">12826</span>&#160;        *pVkMemoryRequirements,</div><div class="line"><a name="l12827"></a><span class="lineno">12827</span>&#160;        <span class="keyword">false</span>, <span class="comment">// requiresDedicatedAllocation</span></div><div class="line"><a name="l12828"></a><span class="lineno">12828</span>&#160;        <span class="keyword">false</span>, <span class="comment">// prefersDedicatedAllocation</span></div><div class="line"><a name="l12829"></a><span class="lineno">12829</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l12830"></a><span class="lineno">12830</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l12831"></a><span class="lineno">12831</span>&#160;        *pCreateInfo,</div><div class="line"><a name="l12832"></a><span class="lineno">12832</span>&#160;        VMA_SUBALLOCATION_TYPE_UNKNOWN,</div><div class="line"><a name="l12833"></a><span class="lineno">12833</span>&#160;        pAllocation);</div><div class="line"><a name="l12834"></a><span class="lineno">12834</span>&#160;</div><div class="line"><a name="l12835"></a><span class="lineno">12835</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12836"></a><span class="lineno">12836</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12837"></a><span class="lineno">12837</span>&#160;    {</div><div class="line"><a name="l12838"></a><span class="lineno">12838</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordAllocateMemory(</div><div class="line"><a name="l12839"></a><span class="lineno">12839</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l12840"></a><span class="lineno">12840</span>&#160;            *pVkMemoryRequirements,</div><div class="line"><a name="l12841"></a><span class="lineno">12841</span>&#160;            *pCreateInfo,</div><div class="line"><a name="l12842"></a><span class="lineno">12842</span>&#160;            *pAllocation);</div><div class="line"><a name="l12843"></a><span class="lineno">12843</span>&#160;    }</div><div class="line"><a name="l12844"></a><span class="lineno">12844</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12845"></a><span class="lineno">12845</span>&#160;        </div><div class="line"><a name="l12846"></a><span class="lineno">12846</span>&#160;    <span class="keywordflow">if</span>(pAllocationInfo != VMA_NULL &amp;&amp; result == VK_SUCCESS)</div><div class="line"><a name="l12847"></a><span class="lineno">12847</span>&#160;    {</div><div class="line"><a name="l12848"></a><span class="lineno">12848</span>&#160;        allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l12849"></a><span class="lineno">12849</span>&#160;    }</div><div class="line"><a name="l12850"></a><span class="lineno">12850</span>&#160;</div><div class="line"><a name="l12851"></a><span class="lineno">12851</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l12852"></a><span class="lineno">12852</span>&#160;}</div><div class="line"><a name="l12853"></a><span class="lineno">12853</span>&#160;</div><div class="line"><a name="l12854"></a><span class="lineno">12854</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer</a>(</div><div class="line"><a name="l12855"></a><span class="lineno">12855</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12856"></a><span class="lineno">12856</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l12857"></a><span class="lineno">12857</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l12858"></a><span class="lineno">12858</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l12859"></a><span class="lineno">12859</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l12860"></a><span class="lineno">12860</span>&#160;{</div><div class="line"><a name="l12861"></a><span class="lineno">12861</span>&#160;    VMA_ASSERT(allocator &amp;&amp; buffer != VK_NULL_HANDLE &amp;&amp; pCreateInfo &amp;&amp; pAllocation);</div><div class="line"><a name="l12862"></a><span class="lineno">12862</span>&#160;</div><div class="line"><a name="l12863"></a><span class="lineno">12863</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaAllocateMemoryForBuffer&quot;</span>);</div><div class="line"><a name="l12864"></a><span class="lineno">12864</span>&#160;</div><div class="line"><a name="l12865"></a><span class="lineno">12865</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12866"></a><span class="lineno">12866</span>&#160;</div><div class="line"><a name="l12867"></a><span class="lineno">12867</span>&#160;    VkMemoryRequirements vkMemReq = {};</div><div class="line"><a name="l12868"></a><span class="lineno">12868</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l12869"></a><span class="lineno">12869</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l12870"></a><span class="lineno">12870</span>&#160;    allocator-&gt;GetBufferMemoryRequirements(buffer, vkMemReq,</div><div class="line"><a name="l12871"></a><span class="lineno">12871</span>&#160;        requiresDedicatedAllocation,</div><div class="line"><a name="l12872"></a><span class="lineno">12872</span>&#160;        prefersDedicatedAllocation);</div><div class="line"><a name="l12873"></a><span class="lineno">12873</span>&#160;</div><div class="line"><a name="l12874"></a><span class="lineno">12874</span>&#160;    VkResult result = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l12875"></a><span class="lineno">12875</span>&#160;        vkMemReq,</div><div class="line"><a name="l12876"></a><span class="lineno">12876</span>&#160;        requiresDedicatedAllocation,</div><div class="line"><a name="l12877"></a><span class="lineno">12877</span>&#160;        prefersDedicatedAllocation,</div><div class="line"><a name="l12878"></a><span class="lineno">12878</span>&#160;        buffer, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l12879"></a><span class="lineno">12879</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l12880"></a><span class="lineno">12880</span>&#160;        *pCreateInfo,</div><div class="line"><a name="l12881"></a><span class="lineno">12881</span>&#160;        VMA_SUBALLOCATION_TYPE_BUFFER,</div><div class="line"><a name="l12882"></a><span class="lineno">12882</span>&#160;        pAllocation);</div><div class="line"><a name="l12883"></a><span class="lineno">12883</span>&#160;</div><div class="line"><a name="l12884"></a><span class="lineno">12884</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12885"></a><span class="lineno">12885</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12886"></a><span class="lineno">12886</span>&#160;    {</div><div class="line"><a name="l12887"></a><span class="lineno">12887</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordAllocateMemoryForBuffer(</div><div class="line"><a name="l12888"></a><span class="lineno">12888</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l12889"></a><span class="lineno">12889</span>&#160;            vkMemReq,</div><div class="line"><a name="l12890"></a><span class="lineno">12890</span>&#160;            requiresDedicatedAllocation,</div><div class="line"><a name="l12891"></a><span class="lineno">12891</span>&#160;            prefersDedicatedAllocation,</div><div class="line"><a name="l12892"></a><span class="lineno">12892</span>&#160;            *pCreateInfo,</div><div class="line"><a name="l12893"></a><span class="lineno">12893</span>&#160;            *pAllocation);</div><div class="line"><a name="l12894"></a><span class="lineno">12894</span>&#160;    }</div><div class="line"><a name="l12895"></a><span class="lineno">12895</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12896"></a><span class="lineno">12896</span>&#160;</div><div class="line"><a name="l12897"></a><span class="lineno">12897</span>&#160;    <span class="keywordflow">if</span>(pAllocationInfo &amp;&amp; result == VK_SUCCESS)</div><div class="line"><a name="l12898"></a><span class="lineno">12898</span>&#160;    {</div><div class="line"><a name="l12899"></a><span class="lineno">12899</span>&#160;        allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l12900"></a><span class="lineno">12900</span>&#160;    }</div><div class="line"><a name="l12901"></a><span class="lineno">12901</span>&#160;</div><div class="line"><a name="l12902"></a><span class="lineno">12902</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l12903"></a><span class="lineno">12903</span>&#160;}</div><div class="line"><a name="l12904"></a><span class="lineno">12904</span>&#160;</div><div class="line"><a name="l12905"></a><span class="lineno">12905</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vmaAllocateMemoryForImage</a>(</div><div class="line"><a name="l12906"></a><span class="lineno">12906</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12907"></a><span class="lineno">12907</span>&#160;    VkImage image,</div><div class="line"><a name="l12908"></a><span class="lineno">12908</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pCreateInfo,</div><div class="line"><a name="l12909"></a><span class="lineno">12909</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l12910"></a><span class="lineno">12910</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l12911"></a><span class="lineno">12911</span>&#160;{</div><div class="line"><a name="l12912"></a><span class="lineno">12912</span>&#160;    VMA_ASSERT(allocator &amp;&amp; image != VK_NULL_HANDLE &amp;&amp; pCreateInfo &amp;&amp; pAllocation);</div><div class="line"><a name="l12913"></a><span class="lineno">12913</span>&#160;</div><div class="line"><a name="l12914"></a><span class="lineno">12914</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaAllocateMemoryForImage&quot;</span>);</div><div class="line"><a name="l12915"></a><span class="lineno">12915</span>&#160;</div><div class="line"><a name="l12916"></a><span class="lineno">12916</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12917"></a><span class="lineno">12917</span>&#160;</div><div class="line"><a name="l12918"></a><span class="lineno">12918</span>&#160;    VkMemoryRequirements vkMemReq = {};</div><div class="line"><a name="l12919"></a><span class="lineno">12919</span>&#160;    <span class="keywordtype">bool</span> requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l12920"></a><span class="lineno">12920</span>&#160;    <span class="keywordtype">bool</span> prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l12921"></a><span class="lineno">12921</span>&#160;    allocator-&gt;GetImageMemoryRequirements(image, vkMemReq,</div><div class="line"><a name="l12922"></a><span class="lineno">12922</span>&#160;        requiresDedicatedAllocation, prefersDedicatedAllocation);</div><div class="line"><a name="l12923"></a><span class="lineno">12923</span>&#160;</div><div class="line"><a name="l12924"></a><span class="lineno">12924</span>&#160;    VkResult result = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l12925"></a><span class="lineno">12925</span>&#160;        vkMemReq,</div><div class="line"><a name="l12926"></a><span class="lineno">12926</span>&#160;        requiresDedicatedAllocation,</div><div class="line"><a name="l12927"></a><span class="lineno">12927</span>&#160;        prefersDedicatedAllocation,</div><div class="line"><a name="l12928"></a><span class="lineno">12928</span>&#160;        VK_NULL_HANDLE, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l12929"></a><span class="lineno">12929</span>&#160;        image, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l12930"></a><span class="lineno">12930</span>&#160;        *pCreateInfo,</div><div class="line"><a name="l12931"></a><span class="lineno">12931</span>&#160;        VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,</div><div class="line"><a name="l12932"></a><span class="lineno">12932</span>&#160;        pAllocation);</div><div class="line"><a name="l12933"></a><span class="lineno">12933</span>&#160;</div><div class="line"><a name="l12934"></a><span class="lineno">12934</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12935"></a><span class="lineno">12935</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12936"></a><span class="lineno">12936</span>&#160;    {</div><div class="line"><a name="l12937"></a><span class="lineno">12937</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordAllocateMemoryForImage(</div><div class="line"><a name="l12938"></a><span class="lineno">12938</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l12939"></a><span class="lineno">12939</span>&#160;            vkMemReq,</div><div class="line"><a name="l12940"></a><span class="lineno">12940</span>&#160;            requiresDedicatedAllocation,</div><div class="line"><a name="l12941"></a><span class="lineno">12941</span>&#160;            prefersDedicatedAllocation,</div><div class="line"><a name="l12942"></a><span class="lineno">12942</span>&#160;            *pCreateInfo,</div><div class="line"><a name="l12943"></a><span class="lineno">12943</span>&#160;            *pAllocation);</div><div class="line"><a name="l12944"></a><span class="lineno">12944</span>&#160;    }</div><div class="line"><a name="l12945"></a><span class="lineno">12945</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12946"></a><span class="lineno">12946</span>&#160;</div><div class="line"><a name="l12947"></a><span class="lineno">12947</span>&#160;    <span class="keywordflow">if</span>(pAllocationInfo &amp;&amp; result == VK_SUCCESS)</div><div class="line"><a name="l12948"></a><span class="lineno">12948</span>&#160;    {</div><div class="line"><a name="l12949"></a><span class="lineno">12949</span>&#160;        allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l12950"></a><span class="lineno">12950</span>&#160;    }</div><div class="line"><a name="l12951"></a><span class="lineno">12951</span>&#160;</div><div class="line"><a name="l12952"></a><span class="lineno">12952</span>&#160;    <span class="keywordflow">return</span> result;</div><div class="line"><a name="l12953"></a><span class="lineno">12953</span>&#160;}</div><div class="line"><a name="l12954"></a><span class="lineno">12954</span>&#160;</div><div class="line"><a name="l12955"></a><span class="lineno">12955</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vmaFreeMemory</a>(</div><div class="line"><a name="l12956"></a><span class="lineno">12956</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12957"></a><span class="lineno">12957</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l12958"></a><span class="lineno">12958</span>&#160;{</div><div class="line"><a name="l12959"></a><span class="lineno">12959</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l12960"></a><span class="lineno">12960</span>&#160;    </div><div class="line"><a name="l12961"></a><span class="lineno">12961</span>&#160;    <span class="keywordflow">if</span>(allocation == VK_NULL_HANDLE)</div><div class="line"><a name="l12962"></a><span class="lineno">12962</span>&#160;    {</div><div class="line"><a name="l12963"></a><span class="lineno">12963</span>&#160;        <span class="keywordflow">return</span>;</div><div class="line"><a name="l12964"></a><span class="lineno">12964</span>&#160;    }</div><div class="line"><a name="l12965"></a><span class="lineno">12965</span>&#160;    </div><div class="line"><a name="l12966"></a><span class="lineno">12966</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaFreeMemory&quot;</span>);</div><div class="line"><a name="l12967"></a><span class="lineno">12967</span>&#160;    </div><div class="line"><a name="l12968"></a><span class="lineno">12968</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12969"></a><span class="lineno">12969</span>&#160;</div><div class="line"><a name="l12970"></a><span class="lineno">12970</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12971"></a><span class="lineno">12971</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12972"></a><span class="lineno">12972</span>&#160;    {</div><div class="line"><a name="l12973"></a><span class="lineno">12973</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordFreeMemory(</div><div class="line"><a name="l12974"></a><span class="lineno">12974</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l12975"></a><span class="lineno">12975</span>&#160;            allocation);</div><div class="line"><a name="l12976"></a><span class="lineno">12976</span>&#160;    }</div><div class="line"><a name="l12977"></a><span class="lineno">12977</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12978"></a><span class="lineno">12978</span>&#160;    </div><div class="line"><a name="l12979"></a><span class="lineno">12979</span>&#160;    allocator-&gt;FreeMemory(allocation);</div><div class="line"><a name="l12980"></a><span class="lineno">12980</span>&#160;}</div><div class="line"><a name="l12981"></a><span class="lineno">12981</span>&#160;</div><div class="line"><a name="l12982"></a><span class="lineno">12982</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(</div><div class="line"><a name="l12983"></a><span class="lineno">12983</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l12984"></a><span class="lineno">12984</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l12985"></a><span class="lineno">12985</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l12986"></a><span class="lineno">12986</span>&#160;{</div><div class="line"><a name="l12987"></a><span class="lineno">12987</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; pAllocationInfo);</div><div class="line"><a name="l12988"></a><span class="lineno">12988</span>&#160;</div><div class="line"><a name="l12989"></a><span class="lineno">12989</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l12990"></a><span class="lineno">12990</span>&#160;</div><div class="line"><a name="l12991"></a><span class="lineno">12991</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l12992"></a><span class="lineno">12992</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l12993"></a><span class="lineno">12993</span>&#160;    {</div><div class="line"><a name="l12994"></a><span class="lineno">12994</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordGetAllocationInfo(</div><div class="line"><a name="l12995"></a><span class="lineno">12995</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l12996"></a><span class="lineno">12996</span>&#160;            allocation);</div><div class="line"><a name="l12997"></a><span class="lineno">12997</span>&#160;    }</div><div class="line"><a name="l12998"></a><span class="lineno">12998</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l12999"></a><span class="lineno">12999</span>&#160;</div><div class="line"><a name="l13000"></a><span class="lineno">13000</span>&#160;    allocator-&gt;GetAllocationInfo(allocation, pAllocationInfo);</div><div class="line"><a name="l13001"></a><span class="lineno">13001</span>&#160;}</div><div class="line"><a name="l13002"></a><span class="lineno">13002</span>&#160;</div><div class="line"><a name="l13003"></a><span class="lineno">13003</span>&#160;VkBool32 <a class="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(</div><div class="line"><a name="l13004"></a><span class="lineno">13004</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13005"></a><span class="lineno">13005</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l13006"></a><span class="lineno">13006</span>&#160;{</div><div class="line"><a name="l13007"></a><span class="lineno">13007</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l13008"></a><span class="lineno">13008</span>&#160;</div><div class="line"><a name="l13009"></a><span class="lineno">13009</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13010"></a><span class="lineno">13010</span>&#160;</div><div class="line"><a name="l13011"></a><span class="lineno">13011</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13012"></a><span class="lineno">13012</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13013"></a><span class="lineno">13013</span>&#160;    {</div><div class="line"><a name="l13014"></a><span class="lineno">13014</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordTouchAllocation(</div><div class="line"><a name="l13015"></a><span class="lineno">13015</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13016"></a><span class="lineno">13016</span>&#160;            allocation);</div><div class="line"><a name="l13017"></a><span class="lineno">13017</span>&#160;    }</div><div class="line"><a name="l13018"></a><span class="lineno">13018</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13019"></a><span class="lineno">13019</span>&#160;</div><div class="line"><a name="l13020"></a><span class="lineno">13020</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;TouchAllocation(allocation);</div><div class="line"><a name="l13021"></a><span class="lineno">13021</span>&#160;}</div><div class="line"><a name="l13022"></a><span class="lineno">13022</span>&#160;</div><div class="line"><a name="l13023"></a><span class="lineno">13023</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f">vmaSetAllocationUserData</a>(</div><div class="line"><a name="l13024"></a><span class="lineno">13024</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13025"></a><span class="lineno">13025</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l13026"></a><span class="lineno">13026</span>&#160;    <span class="keywordtype">void</span>* pUserData)</div><div class="line"><a name="l13027"></a><span class="lineno">13027</span>&#160;{</div><div class="line"><a name="l13028"></a><span class="lineno">13028</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l13029"></a><span class="lineno">13029</span>&#160;</div><div class="line"><a name="l13030"></a><span class="lineno">13030</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13031"></a><span class="lineno">13031</span>&#160;</div><div class="line"><a name="l13032"></a><span class="lineno">13032</span>&#160;    allocation-&gt;SetUserData(allocator, pUserData);</div><div class="line"><a name="l13033"></a><span class="lineno">13033</span>&#160;</div><div class="line"><a name="l13034"></a><span class="lineno">13034</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13035"></a><span class="lineno">13035</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13036"></a><span class="lineno">13036</span>&#160;    {</div><div class="line"><a name="l13037"></a><span class="lineno">13037</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordSetAllocationUserData(</div><div class="line"><a name="l13038"></a><span class="lineno">13038</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13039"></a><span class="lineno">13039</span>&#160;            allocation,</div><div class="line"><a name="l13040"></a><span class="lineno">13040</span>&#160;            pUserData);</div><div class="line"><a name="l13041"></a><span class="lineno">13041</span>&#160;    }</div><div class="line"><a name="l13042"></a><span class="lineno">13042</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13043"></a><span class="lineno">13043</span>&#160;}</div><div class="line"><a name="l13044"></a><span class="lineno">13044</span>&#160;</div><div class="line"><a name="l13045"></a><span class="lineno">13045</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae5c9657d9e94756269145b01c05d16f1">vmaCreateLostAllocation</a>(</div><div class="line"><a name="l13046"></a><span class="lineno">13046</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13047"></a><span class="lineno">13047</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation)</div><div class="line"><a name="l13048"></a><span class="lineno">13048</span>&#160;{</div><div class="line"><a name="l13049"></a><span class="lineno">13049</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pAllocation);</div><div class="line"><a name="l13050"></a><span class="lineno">13050</span>&#160;</div><div class="line"><a name="l13051"></a><span class="lineno">13051</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK;</div><div class="line"><a name="l13052"></a><span class="lineno">13052</span>&#160;</div><div class="line"><a name="l13053"></a><span class="lineno">13053</span>&#160;    allocator-&gt;CreateLostAllocation(pAllocation);</div><div class="line"><a name="l13054"></a><span class="lineno">13054</span>&#160;</div><div class="line"><a name="l13055"></a><span class="lineno">13055</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13056"></a><span class="lineno">13056</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13057"></a><span class="lineno">13057</span>&#160;    {</div><div class="line"><a name="l13058"></a><span class="lineno">13058</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordCreateLostAllocation(</div><div class="line"><a name="l13059"></a><span class="lineno">13059</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13060"></a><span class="lineno">13060</span>&#160;            *pAllocation);</div><div class="line"><a name="l13061"></a><span class="lineno">13061</span>&#160;    }</div><div class="line"><a name="l13062"></a><span class="lineno">13062</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13063"></a><span class="lineno">13063</span>&#160;}</div><div class="line"><a name="l13064"></a><span class="lineno">13064</span>&#160;</div><div class="line"><a name="l13065"></a><span class="lineno">13065</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(</div><div class="line"><a name="l13066"></a><span class="lineno">13066</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13067"></a><span class="lineno">13067</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l13068"></a><span class="lineno">13068</span>&#160;    <span class="keywordtype">void</span>** ppData)</div><div class="line"><a name="l13069"></a><span class="lineno">13069</span>&#160;{</div><div class="line"><a name="l13070"></a><span class="lineno">13070</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; ppData);</div><div class="line"><a name="l13071"></a><span class="lineno">13071</span>&#160;</div><div class="line"><a name="l13072"></a><span class="lineno">13072</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13073"></a><span class="lineno">13073</span>&#160;</div><div class="line"><a name="l13074"></a><span class="lineno">13074</span>&#160;    VkResult res = allocator-&gt;Map(allocation, ppData);</div><div class="line"><a name="l13075"></a><span class="lineno">13075</span>&#160;</div><div class="line"><a name="l13076"></a><span class="lineno">13076</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13077"></a><span class="lineno">13077</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13078"></a><span class="lineno">13078</span>&#160;    {</div><div class="line"><a name="l13079"></a><span class="lineno">13079</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordMapMemory(</div><div class="line"><a name="l13080"></a><span class="lineno">13080</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13081"></a><span class="lineno">13081</span>&#160;            allocation);</div><div class="line"><a name="l13082"></a><span class="lineno">13082</span>&#160;    }</div><div class="line"><a name="l13083"></a><span class="lineno">13083</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13084"></a><span class="lineno">13084</span>&#160;</div><div class="line"><a name="l13085"></a><span class="lineno">13085</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l13086"></a><span class="lineno">13086</span>&#160;}</div><div class="line"><a name="l13087"></a><span class="lineno">13087</span>&#160;</div><div class="line"><a name="l13088"></a><span class="lineno">13088</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(</div><div class="line"><a name="l13089"></a><span class="lineno">13089</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13090"></a><span class="lineno">13090</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l13091"></a><span class="lineno">13091</span>&#160;{</div><div class="line"><a name="l13092"></a><span class="lineno">13092</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l13093"></a><span class="lineno">13093</span>&#160;</div><div class="line"><a name="l13094"></a><span class="lineno">13094</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13095"></a><span class="lineno">13095</span>&#160;</div><div class="line"><a name="l13096"></a><span class="lineno">13096</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13097"></a><span class="lineno">13097</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13098"></a><span class="lineno">13098</span>&#160;    {</div><div class="line"><a name="l13099"></a><span class="lineno">13099</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordUnmapMemory(</div><div class="line"><a name="l13100"></a><span class="lineno">13100</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13101"></a><span class="lineno">13101</span>&#160;            allocation);</div><div class="line"><a name="l13102"></a><span class="lineno">13102</span>&#160;    }</div><div class="line"><a name="l13103"></a><span class="lineno">13103</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13104"></a><span class="lineno">13104</span>&#160;</div><div class="line"><a name="l13105"></a><span class="lineno">13105</span>&#160;    allocator-&gt;Unmap(allocation);</div><div class="line"><a name="l13106"></a><span class="lineno">13106</span>&#160;}</div><div class="line"><a name="l13107"></a><span class="lineno">13107</span>&#160;</div><div class="line"><a name="l13108"></a><span class="lineno">13108</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de">vmaFlushAllocation</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size)</div><div class="line"><a name="l13109"></a><span class="lineno">13109</span>&#160;{</div><div class="line"><a name="l13110"></a><span class="lineno">13110</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l13111"></a><span class="lineno">13111</span>&#160;</div><div class="line"><a name="l13112"></a><span class="lineno">13112</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaFlushAllocation&quot;</span>);</div><div class="line"><a name="l13113"></a><span class="lineno">13113</span>&#160;</div><div class="line"><a name="l13114"></a><span class="lineno">13114</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13115"></a><span class="lineno">13115</span>&#160;</div><div class="line"><a name="l13116"></a><span class="lineno">13116</span>&#160;    allocator-&gt;FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_FLUSH);</div><div class="line"><a name="l13117"></a><span class="lineno">13117</span>&#160;</div><div class="line"><a name="l13118"></a><span class="lineno">13118</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13119"></a><span class="lineno">13119</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13120"></a><span class="lineno">13120</span>&#160;    {</div><div class="line"><a name="l13121"></a><span class="lineno">13121</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordFlushAllocation(</div><div class="line"><a name="l13122"></a><span class="lineno">13122</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13123"></a><span class="lineno">13123</span>&#160;            allocation, offset, size);</div><div class="line"><a name="l13124"></a><span class="lineno">13124</span>&#160;    }</div><div class="line"><a name="l13125"></a><span class="lineno">13125</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13126"></a><span class="lineno">13126</span>&#160;}</div><div class="line"><a name="l13127"></a><span class="lineno">13127</span>&#160;</div><div class="line"><a name="l13128"></a><span class="lineno">13128</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006">vmaInvalidateAllocation</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkDeviceSize offset, VkDeviceSize size)</div><div class="line"><a name="l13129"></a><span class="lineno">13129</span>&#160;{</div><div class="line"><a name="l13130"></a><span class="lineno">13130</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation);</div><div class="line"><a name="l13131"></a><span class="lineno">13131</span>&#160;</div><div class="line"><a name="l13132"></a><span class="lineno">13132</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaInvalidateAllocation&quot;</span>);</div><div class="line"><a name="l13133"></a><span class="lineno">13133</span>&#160;</div><div class="line"><a name="l13134"></a><span class="lineno">13134</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13135"></a><span class="lineno">13135</span>&#160;</div><div class="line"><a name="l13136"></a><span class="lineno">13136</span>&#160;    allocator-&gt;FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_INVALIDATE);</div><div class="line"><a name="l13137"></a><span class="lineno">13137</span>&#160;</div><div class="line"><a name="l13138"></a><span class="lineno">13138</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13139"></a><span class="lineno">13139</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13140"></a><span class="lineno">13140</span>&#160;    {</div><div class="line"><a name="l13141"></a><span class="lineno">13141</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordInvalidateAllocation(</div><div class="line"><a name="l13142"></a><span class="lineno">13142</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13143"></a><span class="lineno">13143</span>&#160;            allocation, offset, size);</div><div class="line"><a name="l13144"></a><span class="lineno">13144</span>&#160;    }</div><div class="line"><a name="l13145"></a><span class="lineno">13145</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13146"></a><span class="lineno">13146</span>&#160;}</div><div class="line"><a name="l13147"></a><span class="lineno">13147</span>&#160;</div><div class="line"><a name="l13148"></a><span class="lineno">13148</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98">vmaCheckCorruption</a>(<a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator, uint32_t memoryTypeBits)</div><div class="line"><a name="l13149"></a><span class="lineno">13149</span>&#160;{</div><div class="line"><a name="l13150"></a><span class="lineno">13150</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l13151"></a><span class="lineno">13151</span>&#160;</div><div class="line"><a name="l13152"></a><span class="lineno">13152</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCheckCorruption&quot;</span>);</div><div class="line"><a name="l13153"></a><span class="lineno">13153</span>&#160;</div><div class="line"><a name="l13154"></a><span class="lineno">13154</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13155"></a><span class="lineno">13155</span>&#160;</div><div class="line"><a name="l13156"></a><span class="lineno">13156</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;CheckCorruption(memoryTypeBits);</div><div class="line"><a name="l13157"></a><span class="lineno">13157</span>&#160;}</div><div class="line"><a name="l13158"></a><span class="lineno">13158</span>&#160;</div><div class="line"><a name="l13159"></a><span class="lineno">13159</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a>(</div><div class="line"><a name="l13160"></a><span class="lineno">13160</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13161"></a><span class="lineno">13161</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocations,</div><div class="line"><a name="l13162"></a><span class="lineno">13162</span>&#160;    <span class="keywordtype">size_t</span> allocationCount,</div><div class="line"><a name="l13163"></a><span class="lineno">13163</span>&#160;    VkBool32* pAllocationsChanged,</div><div class="line"><a name="l13164"></a><span class="lineno">13164</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *pDefragmentationInfo,</div><div class="line"><a name="l13165"></a><span class="lineno">13165</span>&#160;    <a class="code" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a>* pDefragmentationStats)</div><div class="line"><a name="l13166"></a><span class="lineno">13166</span>&#160;{</div><div class="line"><a name="l13167"></a><span class="lineno">13167</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pAllocations);</div><div class="line"><a name="l13168"></a><span class="lineno">13168</span>&#160;</div><div class="line"><a name="l13169"></a><span class="lineno">13169</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDefragment&quot;</span>);</div><div class="line"><a name="l13170"></a><span class="lineno">13170</span>&#160;</div><div class="line"><a name="l13171"></a><span class="lineno">13171</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13172"></a><span class="lineno">13172</span>&#160;</div><div class="line"><a name="l13173"></a><span class="lineno">13173</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;Defragment(pAllocations, allocationCount, pAllocationsChanged, pDefragmentationInfo, pDefragmentationStats);</div><div class="line"><a name="l13174"></a><span class="lineno">13174</span>&#160;}</div><div class="line"><a name="l13175"></a><span class="lineno">13175</span>&#160;</div><div class="line"><a name="l13176"></a><span class="lineno">13176</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vmaBindBufferMemory</a>(</div><div class="line"><a name="l13177"></a><span class="lineno">13177</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13178"></a><span class="lineno">13178</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l13179"></a><span class="lineno">13179</span>&#160;    VkBuffer buffer)</div><div class="line"><a name="l13180"></a><span class="lineno">13180</span>&#160;{</div><div class="line"><a name="l13181"></a><span class="lineno">13181</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; buffer);</div><div class="line"><a name="l13182"></a><span class="lineno">13182</span>&#160;</div><div class="line"><a name="l13183"></a><span class="lineno">13183</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaBindBufferMemory&quot;</span>);</div><div class="line"><a name="l13184"></a><span class="lineno">13184</span>&#160;</div><div class="line"><a name="l13185"></a><span class="lineno">13185</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13186"></a><span class="lineno">13186</span>&#160;</div><div class="line"><a name="l13187"></a><span class="lineno">13187</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;BindBufferMemory(allocation, buffer);</div><div class="line"><a name="l13188"></a><span class="lineno">13188</span>&#160;}</div><div class="line"><a name="l13189"></a><span class="lineno">13189</span>&#160;</div><div class="line"><a name="l13190"></a><span class="lineno">13190</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vmaBindImageMemory</a>(</div><div class="line"><a name="l13191"></a><span class="lineno">13191</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13192"></a><span class="lineno">13192</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation,</div><div class="line"><a name="l13193"></a><span class="lineno">13193</span>&#160;    VkImage image)</div><div class="line"><a name="l13194"></a><span class="lineno">13194</span>&#160;{</div><div class="line"><a name="l13195"></a><span class="lineno">13195</span>&#160;    VMA_ASSERT(allocator &amp;&amp; allocation &amp;&amp; image);</div><div class="line"><a name="l13196"></a><span class="lineno">13196</span>&#160;</div><div class="line"><a name="l13197"></a><span class="lineno">13197</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaBindImageMemory&quot;</span>);</div><div class="line"><a name="l13198"></a><span class="lineno">13198</span>&#160;</div><div class="line"><a name="l13199"></a><span class="lineno">13199</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13200"></a><span class="lineno">13200</span>&#160;</div><div class="line"><a name="l13201"></a><span class="lineno">13201</span>&#160;    <span class="keywordflow">return</span> allocator-&gt;BindImageMemory(allocation, image);</div><div class="line"><a name="l13202"></a><span class="lineno">13202</span>&#160;}</div><div class="line"><a name="l13203"></a><span class="lineno">13203</span>&#160;</div><div class="line"><a name="l13204"></a><span class="lineno">13204</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(</div><div class="line"><a name="l13205"></a><span class="lineno">13205</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13206"></a><span class="lineno">13206</span>&#160;    <span class="keyword">const</span> VkBufferCreateInfo* pBufferCreateInfo,</div><div class="line"><a name="l13207"></a><span class="lineno">13207</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l13208"></a><span class="lineno">13208</span>&#160;    VkBuffer* pBuffer,</div><div class="line"><a name="l13209"></a><span class="lineno">13209</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l13210"></a><span class="lineno">13210</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l13211"></a><span class="lineno">13211</span>&#160;{</div><div class="line"><a name="l13212"></a><span class="lineno">13212</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pBufferCreateInfo &amp;&amp; pAllocationCreateInfo &amp;&amp; pBuffer &amp;&amp; pAllocation);</div><div class="line"><a name="l13213"></a><span class="lineno">13213</span>&#160;    </div><div class="line"><a name="l13214"></a><span class="lineno">13214</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreateBuffer&quot;</span>);</div><div class="line"><a name="l13215"></a><span class="lineno">13215</span>&#160;    </div><div class="line"><a name="l13216"></a><span class="lineno">13216</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13217"></a><span class="lineno">13217</span>&#160;</div><div class="line"><a name="l13218"></a><span class="lineno">13218</span>&#160;    *pBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l13219"></a><span class="lineno">13219</span>&#160;    *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l13220"></a><span class="lineno">13220</span>&#160;</div><div class="line"><a name="l13221"></a><span class="lineno">13221</span>&#160;    <span class="comment">// 1. Create VkBuffer.</span></div><div class="line"><a name="l13222"></a><span class="lineno">13222</span>&#160;    VkResult res = (*allocator-&gt;GetVulkanFunctions().vkCreateBuffer)(</div><div class="line"><a name="l13223"></a><span class="lineno">13223</span>&#160;        allocator-&gt;m_hDevice,</div><div class="line"><a name="l13224"></a><span class="lineno">13224</span>&#160;        pBufferCreateInfo,</div><div class="line"><a name="l13225"></a><span class="lineno">13225</span>&#160;        allocator-&gt;GetAllocationCallbacks(),</div><div class="line"><a name="l13226"></a><span class="lineno">13226</span>&#160;        pBuffer);</div><div class="line"><a name="l13227"></a><span class="lineno">13227</span>&#160;    <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l13228"></a><span class="lineno">13228</span>&#160;    {</div><div class="line"><a name="l13229"></a><span class="lineno">13229</span>&#160;        <span class="comment">// 2. vkGetBufferMemoryRequirements.</span></div><div class="line"><a name="l13230"></a><span class="lineno">13230</span>&#160;        VkMemoryRequirements vkMemReq = {};</div><div class="line"><a name="l13231"></a><span class="lineno">13231</span>&#160;        <span class="keywordtype">bool</span> requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l13232"></a><span class="lineno">13232</span>&#160;        <span class="keywordtype">bool</span> prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l13233"></a><span class="lineno">13233</span>&#160;        allocator-&gt;GetBufferMemoryRequirements(*pBuffer, vkMemReq,</div><div class="line"><a name="l13234"></a><span class="lineno">13234</span>&#160;            requiresDedicatedAllocation, prefersDedicatedAllocation);</div><div class="line"><a name="l13235"></a><span class="lineno">13235</span>&#160;</div><div class="line"><a name="l13236"></a><span class="lineno">13236</span>&#160;        <span class="comment">// Make sure alignment requirements for specific buffer usages reported</span></div><div class="line"><a name="l13237"></a><span class="lineno">13237</span>&#160;        <span class="comment">// in Physical Device Properties are included in alignment reported by memory requirements.</span></div><div class="line"><a name="l13238"></a><span class="lineno">13238</span>&#160;        <span class="keywordflow">if</span>((pBufferCreateInfo-&gt;usage &amp; VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) != 0)</div><div class="line"><a name="l13239"></a><span class="lineno">13239</span>&#160;        {</div><div class="line"><a name="l13240"></a><span class="lineno">13240</span>&#160;           VMA_ASSERT(vkMemReq.alignment %</div><div class="line"><a name="l13241"></a><span class="lineno">13241</span>&#160;              allocator-&gt;m_PhysicalDeviceProperties.limits.minTexelBufferOffsetAlignment == 0);</div><div class="line"><a name="l13242"></a><span class="lineno">13242</span>&#160;        }</div><div class="line"><a name="l13243"></a><span class="lineno">13243</span>&#160;        <span class="keywordflow">if</span>((pBufferCreateInfo-&gt;usage &amp; VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) != 0)</div><div class="line"><a name="l13244"></a><span class="lineno">13244</span>&#160;        {</div><div class="line"><a name="l13245"></a><span class="lineno">13245</span>&#160;           VMA_ASSERT(vkMemReq.alignment %</div><div class="line"><a name="l13246"></a><span class="lineno">13246</span>&#160;              allocator-&gt;m_PhysicalDeviceProperties.limits.minUniformBufferOffsetAlignment == 0);</div><div class="line"><a name="l13247"></a><span class="lineno">13247</span>&#160;        }</div><div class="line"><a name="l13248"></a><span class="lineno">13248</span>&#160;        <span class="keywordflow">if</span>((pBufferCreateInfo-&gt;usage &amp; VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0)</div><div class="line"><a name="l13249"></a><span class="lineno">13249</span>&#160;        {</div><div class="line"><a name="l13250"></a><span class="lineno">13250</span>&#160;           VMA_ASSERT(vkMemReq.alignment %</div><div class="line"><a name="l13251"></a><span class="lineno">13251</span>&#160;              allocator-&gt;m_PhysicalDeviceProperties.limits.minStorageBufferOffsetAlignment == 0);</div><div class="line"><a name="l13252"></a><span class="lineno">13252</span>&#160;        }</div><div class="line"><a name="l13253"></a><span class="lineno">13253</span>&#160;</div><div class="line"><a name="l13254"></a><span class="lineno">13254</span>&#160;        <span class="comment">// 3. Allocate memory using allocator.</span></div><div class="line"><a name="l13255"></a><span class="lineno">13255</span>&#160;        res = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l13256"></a><span class="lineno">13256</span>&#160;            vkMemReq,</div><div class="line"><a name="l13257"></a><span class="lineno">13257</span>&#160;            requiresDedicatedAllocation,</div><div class="line"><a name="l13258"></a><span class="lineno">13258</span>&#160;            prefersDedicatedAllocation,</div><div class="line"><a name="l13259"></a><span class="lineno">13259</span>&#160;            *pBuffer, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l13260"></a><span class="lineno">13260</span>&#160;            VK_NULL_HANDLE, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l13261"></a><span class="lineno">13261</span>&#160;            *pAllocationCreateInfo,</div><div class="line"><a name="l13262"></a><span class="lineno">13262</span>&#160;            VMA_SUBALLOCATION_TYPE_BUFFER,</div><div class="line"><a name="l13263"></a><span class="lineno">13263</span>&#160;            pAllocation);</div><div class="line"><a name="l13264"></a><span class="lineno">13264</span>&#160;</div><div class="line"><a name="l13265"></a><span class="lineno">13265</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13266"></a><span class="lineno">13266</span>&#160;        <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13267"></a><span class="lineno">13267</span>&#160;        {</div><div class="line"><a name="l13268"></a><span class="lineno">13268</span>&#160;            allocator-&gt;GetRecorder()-&gt;RecordCreateBuffer(</div><div class="line"><a name="l13269"></a><span class="lineno">13269</span>&#160;                allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13270"></a><span class="lineno">13270</span>&#160;                *pBufferCreateInfo,</div><div class="line"><a name="l13271"></a><span class="lineno">13271</span>&#160;                *pAllocationCreateInfo,</div><div class="line"><a name="l13272"></a><span class="lineno">13272</span>&#160;                *pAllocation);</div><div class="line"><a name="l13273"></a><span class="lineno">13273</span>&#160;        }</div><div class="line"><a name="l13274"></a><span class="lineno">13274</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13275"></a><span class="lineno">13275</span>&#160;</div><div class="line"><a name="l13276"></a><span class="lineno">13276</span>&#160;        <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l13277"></a><span class="lineno">13277</span>&#160;        {</div><div class="line"><a name="l13278"></a><span class="lineno">13278</span>&#160;            <span class="comment">// 3. Bind buffer with memory.</span></div><div class="line"><a name="l13279"></a><span class="lineno">13279</span>&#160;            res = allocator-&gt;BindBufferMemory(*pAllocation, *pBuffer);</div><div class="line"><a name="l13280"></a><span class="lineno">13280</span>&#160;            <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l13281"></a><span class="lineno">13281</span>&#160;            {</div><div class="line"><a name="l13282"></a><span class="lineno">13282</span>&#160;                <span class="comment">// All steps succeeded.</span></div><div class="line"><a name="l13283"></a><span class="lineno">13283</span>&#160;<span class="preprocessor">                #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l13284"></a><span class="lineno">13284</span>&#160;                    (*pAllocation)-&gt;InitBufferImageUsage(pBufferCreateInfo-&gt;usage);</div><div class="line"><a name="l13285"></a><span class="lineno">13285</span>&#160;<span class="preprocessor">                #endif</span></div><div class="line"><a name="l13286"></a><span class="lineno">13286</span>&#160;                <span class="keywordflow">if</span>(pAllocationInfo != VMA_NULL)</div><div class="line"><a name="l13287"></a><span class="lineno">13287</span>&#160;                {</div><div class="line"><a name="l13288"></a><span class="lineno">13288</span>&#160;                    allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l13289"></a><span class="lineno">13289</span>&#160;                }</div><div class="line"><a name="l13290"></a><span class="lineno">13290</span>&#160;</div><div class="line"><a name="l13291"></a><span class="lineno">13291</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l13292"></a><span class="lineno">13292</span>&#160;            }</div><div class="line"><a name="l13293"></a><span class="lineno">13293</span>&#160;            allocator-&gt;FreeMemory(*pAllocation);</div><div class="line"><a name="l13294"></a><span class="lineno">13294</span>&#160;            *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l13295"></a><span class="lineno">13295</span>&#160;            (*allocator-&gt;GetVulkanFunctions().vkDestroyBuffer)(allocator-&gt;m_hDevice, *pBuffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l13296"></a><span class="lineno">13296</span>&#160;            *pBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l13297"></a><span class="lineno">13297</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l13298"></a><span class="lineno">13298</span>&#160;        }</div><div class="line"><a name="l13299"></a><span class="lineno">13299</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyBuffer)(allocator-&gt;m_hDevice, *pBuffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l13300"></a><span class="lineno">13300</span>&#160;        *pBuffer = VK_NULL_HANDLE;</div><div class="line"><a name="l13301"></a><span class="lineno">13301</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l13302"></a><span class="lineno">13302</span>&#160;    }</div><div class="line"><a name="l13303"></a><span class="lineno">13303</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l13304"></a><span class="lineno">13304</span>&#160;}</div><div class="line"><a name="l13305"></a><span class="lineno">13305</span>&#160;</div><div class="line"><a name="l13306"></a><span class="lineno">13306</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(</div><div class="line"><a name="l13307"></a><span class="lineno">13307</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13308"></a><span class="lineno">13308</span>&#160;    VkBuffer buffer,</div><div class="line"><a name="l13309"></a><span class="lineno">13309</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l13310"></a><span class="lineno">13310</span>&#160;{</div><div class="line"><a name="l13311"></a><span class="lineno">13311</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l13312"></a><span class="lineno">13312</span>&#160;</div><div class="line"><a name="l13313"></a><span class="lineno">13313</span>&#160;    <span class="keywordflow">if</span>(buffer == VK_NULL_HANDLE &amp;&amp; allocation == VK_NULL_HANDLE)</div><div class="line"><a name="l13314"></a><span class="lineno">13314</span>&#160;    {</div><div class="line"><a name="l13315"></a><span class="lineno">13315</span>&#160;        <span class="keywordflow">return</span>;</div><div class="line"><a name="l13316"></a><span class="lineno">13316</span>&#160;    }</div><div class="line"><a name="l13317"></a><span class="lineno">13317</span>&#160;</div><div class="line"><a name="l13318"></a><span class="lineno">13318</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyBuffer&quot;</span>);</div><div class="line"><a name="l13319"></a><span class="lineno">13319</span>&#160;</div><div class="line"><a name="l13320"></a><span class="lineno">13320</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13321"></a><span class="lineno">13321</span>&#160;</div><div class="line"><a name="l13322"></a><span class="lineno">13322</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13323"></a><span class="lineno">13323</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13324"></a><span class="lineno">13324</span>&#160;    {</div><div class="line"><a name="l13325"></a><span class="lineno">13325</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordDestroyBuffer(</div><div class="line"><a name="l13326"></a><span class="lineno">13326</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13327"></a><span class="lineno">13327</span>&#160;            allocation);</div><div class="line"><a name="l13328"></a><span class="lineno">13328</span>&#160;    }</div><div class="line"><a name="l13329"></a><span class="lineno">13329</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13330"></a><span class="lineno">13330</span>&#160;</div><div class="line"><a name="l13331"></a><span class="lineno">13331</span>&#160;    <span class="keywordflow">if</span>(buffer != VK_NULL_HANDLE)</div><div class="line"><a name="l13332"></a><span class="lineno">13332</span>&#160;    {</div><div class="line"><a name="l13333"></a><span class="lineno">13333</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyBuffer)(allocator-&gt;m_hDevice, buffer, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l13334"></a><span class="lineno">13334</span>&#160;    }</div><div class="line"><a name="l13335"></a><span class="lineno">13335</span>&#160;</div><div class="line"><a name="l13336"></a><span class="lineno">13336</span>&#160;    <span class="keywordflow">if</span>(allocation != VK_NULL_HANDLE)</div><div class="line"><a name="l13337"></a><span class="lineno">13337</span>&#160;    {</div><div class="line"><a name="l13338"></a><span class="lineno">13338</span>&#160;        allocator-&gt;FreeMemory(allocation);</div><div class="line"><a name="l13339"></a><span class="lineno">13339</span>&#160;    }</div><div class="line"><a name="l13340"></a><span class="lineno">13340</span>&#160;}</div><div class="line"><a name="l13341"></a><span class="lineno">13341</span>&#160;</div><div class="line"><a name="l13342"></a><span class="lineno">13342</span>&#160;VkResult <a class="code" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73">vmaCreateImage</a>(</div><div class="line"><a name="l13343"></a><span class="lineno">13343</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13344"></a><span class="lineno">13344</span>&#160;    <span class="keyword">const</span> VkImageCreateInfo* pImageCreateInfo,</div><div class="line"><a name="l13345"></a><span class="lineno">13345</span>&#160;    <span class="keyword">const</span> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a>* pAllocationCreateInfo,</div><div class="line"><a name="l13346"></a><span class="lineno">13346</span>&#160;    VkImage* pImage,</div><div class="line"><a name="l13347"></a><span class="lineno">13347</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a>* pAllocation,</div><div class="line"><a name="l13348"></a><span class="lineno">13348</span>&#160;    <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a>* pAllocationInfo)</div><div class="line"><a name="l13349"></a><span class="lineno">13349</span>&#160;{</div><div class="line"><a name="l13350"></a><span class="lineno">13350</span>&#160;    VMA_ASSERT(allocator &amp;&amp; pImageCreateInfo &amp;&amp; pAllocationCreateInfo &amp;&amp; pImage &amp;&amp; pAllocation);</div><div class="line"><a name="l13351"></a><span class="lineno">13351</span>&#160;</div><div class="line"><a name="l13352"></a><span class="lineno">13352</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaCreateImage&quot;</span>);</div><div class="line"><a name="l13353"></a><span class="lineno">13353</span>&#160;</div><div class="line"><a name="l13354"></a><span class="lineno">13354</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13355"></a><span class="lineno">13355</span>&#160;</div><div class="line"><a name="l13356"></a><span class="lineno">13356</span>&#160;    *pImage = VK_NULL_HANDLE;</div><div class="line"><a name="l13357"></a><span class="lineno">13357</span>&#160;    *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l13358"></a><span class="lineno">13358</span>&#160;</div><div class="line"><a name="l13359"></a><span class="lineno">13359</span>&#160;    <span class="comment">// 1. Create VkImage.</span></div><div class="line"><a name="l13360"></a><span class="lineno">13360</span>&#160;    VkResult res = (*allocator-&gt;GetVulkanFunctions().vkCreateImage)(</div><div class="line"><a name="l13361"></a><span class="lineno">13361</span>&#160;        allocator-&gt;m_hDevice,</div><div class="line"><a name="l13362"></a><span class="lineno">13362</span>&#160;        pImageCreateInfo,</div><div class="line"><a name="l13363"></a><span class="lineno">13363</span>&#160;        allocator-&gt;GetAllocationCallbacks(),</div><div class="line"><a name="l13364"></a><span class="lineno">13364</span>&#160;        pImage);</div><div class="line"><a name="l13365"></a><span class="lineno">13365</span>&#160;    <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l13366"></a><span class="lineno">13366</span>&#160;    {</div><div class="line"><a name="l13367"></a><span class="lineno">13367</span>&#160;        VmaSuballocationType suballocType = pImageCreateInfo-&gt;tiling == VK_IMAGE_TILING_OPTIMAL ?</div><div class="line"><a name="l13368"></a><span class="lineno">13368</span>&#160;            VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :</div><div class="line"><a name="l13369"></a><span class="lineno">13369</span>&#160;            VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR;</div><div class="line"><a name="l13370"></a><span class="lineno">13370</span>&#160;        </div><div class="line"><a name="l13371"></a><span class="lineno">13371</span>&#160;        <span class="comment">// 2. Allocate memory using allocator.</span></div><div class="line"><a name="l13372"></a><span class="lineno">13372</span>&#160;        VkMemoryRequirements vkMemReq = {};</div><div class="line"><a name="l13373"></a><span class="lineno">13373</span>&#160;        <span class="keywordtype">bool</span> requiresDedicatedAllocation = <span class="keyword">false</span>;</div><div class="line"><a name="l13374"></a><span class="lineno">13374</span>&#160;        <span class="keywordtype">bool</span> prefersDedicatedAllocation  = <span class="keyword">false</span>;</div><div class="line"><a name="l13375"></a><span class="lineno">13375</span>&#160;        allocator-&gt;GetImageMemoryRequirements(*pImage, vkMemReq,</div><div class="line"><a name="l13376"></a><span class="lineno">13376</span>&#160;            requiresDedicatedAllocation, prefersDedicatedAllocation);</div><div class="line"><a name="l13377"></a><span class="lineno">13377</span>&#160;</div><div class="line"><a name="l13378"></a><span class="lineno">13378</span>&#160;        res = allocator-&gt;AllocateMemory(</div><div class="line"><a name="l13379"></a><span class="lineno">13379</span>&#160;            vkMemReq,</div><div class="line"><a name="l13380"></a><span class="lineno">13380</span>&#160;            requiresDedicatedAllocation,</div><div class="line"><a name="l13381"></a><span class="lineno">13381</span>&#160;            prefersDedicatedAllocation,</div><div class="line"><a name="l13382"></a><span class="lineno">13382</span>&#160;            VK_NULL_HANDLE, <span class="comment">// dedicatedBuffer</span></div><div class="line"><a name="l13383"></a><span class="lineno">13383</span>&#160;            *pImage, <span class="comment">// dedicatedImage</span></div><div class="line"><a name="l13384"></a><span class="lineno">13384</span>&#160;            *pAllocationCreateInfo,</div><div class="line"><a name="l13385"></a><span class="lineno">13385</span>&#160;            suballocType,</div><div class="line"><a name="l13386"></a><span class="lineno">13386</span>&#160;            pAllocation);</div><div class="line"><a name="l13387"></a><span class="lineno">13387</span>&#160;</div><div class="line"><a name="l13388"></a><span class="lineno">13388</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13389"></a><span class="lineno">13389</span>&#160;        <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13390"></a><span class="lineno">13390</span>&#160;        {</div><div class="line"><a name="l13391"></a><span class="lineno">13391</span>&#160;            allocator-&gt;GetRecorder()-&gt;RecordCreateImage(</div><div class="line"><a name="l13392"></a><span class="lineno">13392</span>&#160;                allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13393"></a><span class="lineno">13393</span>&#160;                *pImageCreateInfo,</div><div class="line"><a name="l13394"></a><span class="lineno">13394</span>&#160;                *pAllocationCreateInfo,</div><div class="line"><a name="l13395"></a><span class="lineno">13395</span>&#160;                *pAllocation);</div><div class="line"><a name="l13396"></a><span class="lineno">13396</span>&#160;        }</div><div class="line"><a name="l13397"></a><span class="lineno">13397</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13398"></a><span class="lineno">13398</span>&#160;</div><div class="line"><a name="l13399"></a><span class="lineno">13399</span>&#160;        <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l13400"></a><span class="lineno">13400</span>&#160;        {</div><div class="line"><a name="l13401"></a><span class="lineno">13401</span>&#160;            <span class="comment">// 3. Bind image with memory.</span></div><div class="line"><a name="l13402"></a><span class="lineno">13402</span>&#160;            res = allocator-&gt;BindImageMemory(*pAllocation, *pImage);</div><div class="line"><a name="l13403"></a><span class="lineno">13403</span>&#160;            <span class="keywordflow">if</span>(res &gt;= 0)</div><div class="line"><a name="l13404"></a><span class="lineno">13404</span>&#160;            {</div><div class="line"><a name="l13405"></a><span class="lineno">13405</span>&#160;                <span class="comment">// All steps succeeded.</span></div><div class="line"><a name="l13406"></a><span class="lineno">13406</span>&#160;<span class="preprocessor">                #if VMA_STATS_STRING_ENABLED</span></div><div class="line"><a name="l13407"></a><span class="lineno">13407</span>&#160;                    (*pAllocation)-&gt;InitBufferImageUsage(pImageCreateInfo-&gt;usage);</div><div class="line"><a name="l13408"></a><span class="lineno">13408</span>&#160;<span class="preprocessor">                #endif</span></div><div class="line"><a name="l13409"></a><span class="lineno">13409</span>&#160;                <span class="keywordflow">if</span>(pAllocationInfo != VMA_NULL)</div><div class="line"><a name="l13410"></a><span class="lineno">13410</span>&#160;                {</div><div class="line"><a name="l13411"></a><span class="lineno">13411</span>&#160;                    allocator-&gt;GetAllocationInfo(*pAllocation, pAllocationInfo);</div><div class="line"><a name="l13412"></a><span class="lineno">13412</span>&#160;                }</div><div class="line"><a name="l13413"></a><span class="lineno">13413</span>&#160;</div><div class="line"><a name="l13414"></a><span class="lineno">13414</span>&#160;                <span class="keywordflow">return</span> VK_SUCCESS;</div><div class="line"><a name="l13415"></a><span class="lineno">13415</span>&#160;            }</div><div class="line"><a name="l13416"></a><span class="lineno">13416</span>&#160;            allocator-&gt;FreeMemory(*pAllocation);</div><div class="line"><a name="l13417"></a><span class="lineno">13417</span>&#160;            *pAllocation = VK_NULL_HANDLE;</div><div class="line"><a name="l13418"></a><span class="lineno">13418</span>&#160;            (*allocator-&gt;GetVulkanFunctions().vkDestroyImage)(allocator-&gt;m_hDevice, *pImage, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l13419"></a><span class="lineno">13419</span>&#160;            *pImage = VK_NULL_HANDLE;</div><div class="line"><a name="l13420"></a><span class="lineno">13420</span>&#160;            <span class="keywordflow">return</span> res;</div><div class="line"><a name="l13421"></a><span class="lineno">13421</span>&#160;        }</div><div class="line"><a name="l13422"></a><span class="lineno">13422</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyImage)(allocator-&gt;m_hDevice, *pImage, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l13423"></a><span class="lineno">13423</span>&#160;        *pImage = VK_NULL_HANDLE;</div><div class="line"><a name="l13424"></a><span class="lineno">13424</span>&#160;        <span class="keywordflow">return</span> res;</div><div class="line"><a name="l13425"></a><span class="lineno">13425</span>&#160;    }</div><div class="line"><a name="l13426"></a><span class="lineno">13426</span>&#160;    <span class="keywordflow">return</span> res;</div><div class="line"><a name="l13427"></a><span class="lineno">13427</span>&#160;}</div><div class="line"><a name="l13428"></a><span class="lineno">13428</span>&#160;</div><div class="line"><a name="l13429"></a><span class="lineno">13429</span>&#160;<span class="keywordtype">void</span> <a class="code" href="vk__mem__alloc_8h.html#ae50d2cb3b4a3bfd4dd40987234e50e7e">vmaDestroyImage</a>(</div><div class="line"><a name="l13430"></a><span class="lineno">13430</span>&#160;    <a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator,</div><div class="line"><a name="l13431"></a><span class="lineno">13431</span>&#160;    VkImage image,</div><div class="line"><a name="l13432"></a><span class="lineno">13432</span>&#160;    <a class="code" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</div><div class="line"><a name="l13433"></a><span class="lineno">13433</span>&#160;{</div><div class="line"><a name="l13434"></a><span class="lineno">13434</span>&#160;    VMA_ASSERT(allocator);</div><div class="line"><a name="l13435"></a><span class="lineno">13435</span>&#160;</div><div class="line"><a name="l13436"></a><span class="lineno">13436</span>&#160;    <span class="keywordflow">if</span>(image == VK_NULL_HANDLE &amp;&amp; allocation == VK_NULL_HANDLE)</div><div class="line"><a name="l13437"></a><span class="lineno">13437</span>&#160;    {</div><div class="line"><a name="l13438"></a><span class="lineno">13438</span>&#160;        <span class="keywordflow">return</span>;</div><div class="line"><a name="l13439"></a><span class="lineno">13439</span>&#160;    }</div><div class="line"><a name="l13440"></a><span class="lineno">13440</span>&#160;</div><div class="line"><a name="l13441"></a><span class="lineno">13441</span>&#160;    VMA_DEBUG_LOG(<span class="stringliteral">&quot;vmaDestroyImage&quot;</span>);</div><div class="line"><a name="l13442"></a><span class="lineno">13442</span>&#160;</div><div class="line"><a name="l13443"></a><span class="lineno">13443</span>&#160;    VMA_DEBUG_GLOBAL_MUTEX_LOCK</div><div class="line"><a name="l13444"></a><span class="lineno">13444</span>&#160;</div><div class="line"><a name="l13445"></a><span class="lineno">13445</span>&#160;<span class="preprocessor">#if VMA_RECORDING_ENABLED</span></div><div class="line"><a name="l13446"></a><span class="lineno">13446</span>&#160;    <span class="keywordflow">if</span>(allocator-&gt;GetRecorder() != VMA_NULL)</div><div class="line"><a name="l13447"></a><span class="lineno">13447</span>&#160;    {</div><div class="line"><a name="l13448"></a><span class="lineno">13448</span>&#160;        allocator-&gt;GetRecorder()-&gt;RecordDestroyImage(</div><div class="line"><a name="l13449"></a><span class="lineno">13449</span>&#160;            allocator-&gt;GetCurrentFrameIndex(),</div><div class="line"><a name="l13450"></a><span class="lineno">13450</span>&#160;            allocation);</div><div class="line"><a name="l13451"></a><span class="lineno">13451</span>&#160;    }</div><div class="line"><a name="l13452"></a><span class="lineno">13452</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l13453"></a><span class="lineno">13453</span>&#160;</div><div class="line"><a name="l13454"></a><span class="lineno">13454</span>&#160;    <span class="keywordflow">if</span>(image != VK_NULL_HANDLE)</div><div class="line"><a name="l13455"></a><span class="lineno">13455</span>&#160;    {</div><div class="line"><a name="l13456"></a><span class="lineno">13456</span>&#160;        (*allocator-&gt;GetVulkanFunctions().vkDestroyImage)(allocator-&gt;m_hDevice, image, allocator-&gt;GetAllocationCallbacks());</div><div class="line"><a name="l13457"></a><span class="lineno">13457</span>&#160;    }</div><div class="line"><a name="l13458"></a><span class="lineno">13458</span>&#160;    <span class="keywordflow">if</span>(allocation != VK_NULL_HANDLE)</div><div class="line"><a name="l13459"></a><span class="lineno">13459</span>&#160;    {</div><div class="line"><a name="l13460"></a><span class="lineno">13460</span>&#160;        allocator-&gt;FreeMemory(allocation);</div><div class="line"><a name="l13461"></a><span class="lineno">13461</span>&#160;    }</div><div class="line"><a name="l13462"></a><span class="lineno">13462</span>&#160;}</div><div class="line"><a name="l13463"></a><span class="lineno">13463</span>&#160;</div><div class="line"><a name="l13464"></a><span class="lineno">13464</span>&#160;<span class="preprocessor">#endif // #ifdef VMA_IMPLEMENTATION</span></div><div class="ttc" id="struct_vma_vulkan_functions_html_a77b7a74082823e865dd6546623468f96"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">VmaVulkanFunctions::vkGetPhysicalDeviceProperties</a></div><div class="ttdeci">PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1446</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a></div><div class="ttdoc">Set this flag if the allocation should have its own memory block. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1759</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a9bc268595cb33f6ec4d519cfce81ff45"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a></div><div class="ttdeci">void vmaUnmapMemory(VmaAllocator allocator, VmaAllocation allocation)</div><div class="ttdoc">Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). </div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_a08230f04ae6ccf8a78150a9e829a7156"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">VmaAllocatorCreateInfo::physicalDevice</a></div><div class="ttdeci">VkPhysicalDevice physicalDevice</div><div class="ttdoc">Vulkan physical device. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1178</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_a08230f04ae6ccf8a78150a9e829a7156"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">VmaAllocatorCreateInfo::physicalDevice</a></div><div class="ttdeci">VkPhysicalDevice physicalDevice</div><div class="ttdoc">Vulkan physical device. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1515</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a6aced90fcc7b39882b6654a740a0b9bb"><div class="ttname"><a href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a></div><div class="ttdeci">VkResult vmaDefragment(VmaAllocator allocator, VmaAllocation *pAllocations, size_t allocationCount, VkBool32 *pAllocationsChanged, const VmaDefragmentationInfo *pDefragmentationInfo, VmaDefragmentationStats *pDefragmentationStats)</div><div class="ttdoc">Compacts memory by moving allocations. </div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a0d0eb0c1102268fa9a476d12ecbe4006"><div class="ttname"><a href="vk__mem__alloc_8h.html#a0d0eb0c1102268fa9a476d12ecbe4006">vmaInvalidateAllocation</a></div><div class="ttdeci">void vmaInvalidateAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size)</div><div class="ttdoc">Invalidates memory of given allocation. </div></div>
 <div class="ttc" id="struct_vma_allocation_html"><div class="ttname"><a href="struct_vma_allocation.html">VmaAllocation</a></div><div class="ttdoc">Represents single memory allocation. </div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_ae8084315a25006271a2edfc3a447519f"><div class="ttname"><a href="struct_vma_vulkan_functions.html#ae8084315a25006271a2edfc3a447519f">VmaVulkanFunctions::vkCreateBuffer</a></div><div class="ttdeci">PFN_vkCreateBuffer vkCreateBuffer</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1163</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a20dd17d69966dbffa054739d6090b85e">VMA_RECORD_FLAG_BITS_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1477</div></div>
+<div class="ttc" id="struct_vma_pool_stats_html_aa0b5cb45cef6f18571cefb03b9a230e7"><div class="ttname"><a href="struct_vma_pool_stats.html#aa0b5cb45cef6f18571cefb03b9a230e7">VmaPoolStats::blockCount</a></div><div class="ttdeci">size_t blockCount</div><div class="ttdoc">Number of VkDeviceMemory blocks allocated for this pool. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2032</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_ae8084315a25006271a2edfc3a447519f"><div class="ttname"><a href="struct_vma_vulkan_functions.html#ae8084315a25006271a2edfc3a447519f">VmaVulkanFunctions::vkCreateBuffer</a></div><div class="ttdeci">PFN_vkCreateBuffer vkCreateBuffer</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1458</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a3104eb30d8122c84dd8541063f145288"><div class="ttname"><a href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vmaFreeStatsString</a></div><div class="ttdeci">void vmaFreeStatsString(VmaAllocator allocator, char *pStatsString)</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a732be855fb4a7c248e6853d928a729af"><div class="ttname"><a href="vk__mem__alloc_8h.html#a732be855fb4a7c248e6853d928a729af">VmaStats</a></div><div class="ttdeci">struct VmaStats VmaStats</div><div class="ttdoc">General statistics from current state of Allocator. </div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1372</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_ab5c1f38dea3a2cf00dc9eb4f57218c49"><div class="ttname"><a href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">VmaVulkanFunctions::vkMapMemory</a></div><div class="ttdeci">PFN_vkMapMemory vkMapMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1157</div></div>
-<div class="ttc" id="struct_vma_allocation_info_html_ae0bfb7dfdf79a76ffefc9a94677a2f67"><div class="ttname"><a href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">VmaAllocationInfo::deviceMemory</a></div><div class="ttdeci">VkDeviceMemory deviceMemory</div><div class="ttdoc">Handle to Vulkan memory object. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1745</div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_a392ea2ecbaff93f91a7c49f735ad4346"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">VmaAllocatorCreateInfo::flags</a></div><div class="ttdeci">VmaAllocatorCreateFlags flags</div><div class="ttdoc">Flags for created allocator. Use VmaAllocatorCreateFlagBits enum. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1175</div></div>
-<div class="ttc" id="struct_vma_defragmentation_info_html_aa7c7304e13c71f604c907196c4e28fbc"><div class="ttname"><a href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc">VmaDefragmentationInfo::maxAllocationsToMove</a></div><div class="ttdeci">uint32_t maxAllocationsToMove</div><div class="ttdoc">Maximum number of allocations that can be moved to different place. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1944</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a></div><div class="ttdoc">Use this flag if you always allocate only buffers and linear images or only optimal images out of thi...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1591</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1716</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_ab5c1f38dea3a2cf00dc9eb4f57218c49"><div class="ttname"><a href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">VmaVulkanFunctions::vkMapMemory</a></div><div class="ttdeci">PFN_vkMapMemory vkMapMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1450</div></div>
+<div class="ttc" id="struct_vma_allocation_info_html_ae0bfb7dfdf79a76ffefc9a94677a2f67"><div class="ttname"><a href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">VmaAllocationInfo::deviceMemory</a></div><div class="ttdeci">VkDeviceMemory deviceMemory</div><div class="ttdoc">Handle to Vulkan memory object. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2132</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_a392ea2ecbaff93f91a7c49f735ad4346"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">VmaAllocatorCreateInfo::flags</a></div><div class="ttdeci">VmaAllocatorCreateFlags flags</div><div class="ttdoc">Flags for created allocator. Use VmaAllocatorCreateFlagBits enum. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1512</div></div>
+<div class="ttc" id="struct_vma_defragmentation_info_html_aa7c7304e13c71f604c907196c4e28fbc"><div class="ttname"><a href="struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc">VmaDefragmentationInfo::maxAllocationsToMove</a></div><div class="ttdeci">uint32_t maxAllocationsToMove</div><div class="ttdoc">Maximum number of allocations that can be moved to different place. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2377</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2">VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT</a></div><div class="ttdoc">Use this flag if you always allocate only buffers and linear images or only optimal images out of thi...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1940</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a1f0c126759fc96ccb6e2d23c101d770c"><div class="ttname"><a href="vk__mem__alloc_8h.html#a1f0c126759fc96ccb6e2d23c101d770c">VMA_RECORDING_ENABLED</a></div><div class="ttdeci">#define VMA_RECORDING_ENABLED</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1489</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a736bd6cbda886f36c891727e73bd4024"><div class="ttname"><a href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024">vmaMakePoolAllocationsLost</a></div><div class="ttdeci">void vmaMakePoolAllocationsLost(VmaAllocator allocator, VmaPool pool, size_t *pLostAllocationCount)</div><div class="ttdoc">Marks all allocations in given pool as lost if they are not used in current frame or VmaPoolCreateInf...</div></div>
-<div class="ttc" id="struct_vma_pool_stats_html_a326807b2de2b0931cee4ed9a5f2e420c"><div class="ttname"><a href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">VmaPoolStats::size</a></div><div class="ttdeci">VkDeviceSize size</div><div class="ttdoc">Total amount of VkDeviceMemory allocated from Vulkan for this pool, in bytes. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1645</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1452</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_acfe6863e160722c2c1bbcf7573fddc4d"><div class="ttname"><a href="vk__mem__alloc_8h.html#acfe6863e160722c2c1bbcf7573fddc4d">VmaAllocatorCreateFlags</a></div><div class="ttdeci">VkFlags VmaAllocatorCreateFlags</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1146</div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html_a7fe8d81a1ad10b2a2faacacee5b15d6d"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">VmaAllocationCreateInfo::preferredFlags</a></div><div class="ttdeci">VkMemoryPropertyFlags preferredFlags</div><div class="ttdoc">Flags that preferably should be set in a memory type chosen for an allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1490</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e">VMA_MEMORY_USAGE_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1399</div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_a6e409087e3be55400d0e4ccbe43c608d"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">VmaAllocatorCreateInfo::pAllocationCallbacks</a></div><div class="ttdeci">const VkAllocationCallbacks * pAllocationCallbacks</div><div class="ttdoc">Custom CPU memory allocation callbacks. Optional. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1187</div></div>
+<div class="ttc" id="struct_vma_pool_stats_html_a326807b2de2b0931cee4ed9a5f2e420c"><div class="ttname"><a href="struct_vma_pool_stats.html#a326807b2de2b0931cee4ed9a5f2e420c">VmaPoolStats::size</a></div><div class="ttdeci">VkDeviceSize size</div><div class="ttdoc">Total amount of VkDeviceMemory allocated from Vulkan for this pool, in bytes. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2013</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1796</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_acfe6863e160722c2c1bbcf7573fddc4d"><div class="ttname"><a href="vk__mem__alloc_8h.html#acfe6863e160722c2c1bbcf7573fddc4d">VmaAllocatorCreateFlags</a></div><div class="ttdeci">VkFlags VmaAllocatorCreateFlags</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1439</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html_a7fe8d81a1ad10b2a2faacacee5b15d6d"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d">VmaAllocationCreateInfo::preferredFlags</a></div><div class="ttdeci">VkMemoryPropertyFlags preferredFlags</div><div class="ttdoc">Flags that preferably should be set in a memory type chosen for an allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1839</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e">VMA_MEMORY_USAGE_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1743</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_a6e409087e3be55400d0e4ccbe43c608d"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">VmaAllocatorCreateInfo::pAllocationCallbacks</a></div><div class="ttdeci">const VkAllocationCallbacks * pAllocationCallbacks</div><div class="ttdoc">Custom CPU memory allocation callbacks. Optional. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1524</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a333b61c1788cb23559177531e6a93ca3"><div class="ttname"><a href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3">vmaCalculateStats</a></div><div class="ttdeci">void vmaCalculateStats(VmaAllocator allocator, VmaStats *pStats)</div><div class="ttdoc">Retrieves statistics from current state of the Allocator. </div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_a3dc197be3227da7338b1643f70db36bd"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">VmaAllocatorCreateInfo::pVulkanFunctions</a></div><div class="ttdeci">const VmaVulkanFunctions * pVulkanFunctions</div><div class="ttdoc">Pointers to Vulkan functions. Can be null if you leave define VMA_STATIC_VULKAN_FUNCTIONS 1...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1240</div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html"><div class="ttname"><a href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></div><div class="ttdoc">Description of a Allocator to be created. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1172</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_a3dc197be3227da7338b1643f70db36bd"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">VmaAllocatorCreateInfo::pVulkanFunctions</a></div><div class="ttdeci">const VmaVulkanFunctions * pVulkanFunctions</div><div class="ttdoc">Pointers to Vulkan functions. Can be null if you leave define VMA_STATIC_VULKAN_FUNCTIONS 1...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1577</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html"><div class="ttname"><a href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></div><div class="ttdoc">Description of a Allocator to be created. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1509</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_aa8d164061c88f22fb1fd3c8f3534bc1d"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa8d164061c88f22fb1fd3c8f3534bc1d">vmaDestroyAllocator</a></div><div class="ttdeci">void vmaDestroyAllocator(VmaAllocator allocator)</div><div class="ttdoc">Destroys allocator object. </div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a></div><div class="ttdeci">VmaAllocationCreateFlagBits</div><div class="ttdoc">Flags to be passed as VmaAllocationCreateInfo::flags. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1403</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a></div><div class="ttdeci">VmaAllocationCreateFlagBits</div><div class="ttdoc">Flags to be passed as VmaAllocationCreateInfo::flags. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1747</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a86dd08aba8633bfa4ad0df2e76481d8b"><div class="ttname"><a href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a></div><div class="ttdeci">void vmaGetAllocationInfo(VmaAllocator allocator, VmaAllocation allocation, VmaAllocationInfo *pAllocationInfo)</div><div class="ttdoc">Returns current information about specified allocation and atomically marks it as used in current fra...</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_a17e9733a5ecd76287d4db6e66f71f50c"><div class="ttname"><a href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">VmaStatInfo::allocationSizeMax</a></div><div class="ttdeci">VkDeviceSize allocationSizeMax</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1305</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a1338d96a128a5ade648b8d934907c637"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637">VmaVulkanFunctions::vkBindImageMemory</a></div><div class="ttdeci">PFN_vkBindImageMemory vkBindImageMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1160</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_a1859d290aca2cd582d8dc25922092669"><div class="ttname"><a href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">VmaStatInfo::unusedBytes</a></div><div class="ttdeci">VkDeviceSize unusedBytes</div><div class="ttdoc">Total number of bytes occupied by unused ranges. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1304</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a9cdcdc1e2b2ea7c571f7d27e30ba6875"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">VmaVulkanFunctions::vkGetImageMemoryRequirements2KHR</a></div><div class="ttdeci">PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1168</div></div>
-<div class="ttc" id="struct_vma_defragmentation_stats_html"><div class="ttname"><a href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a></div><div class="ttdoc">Statistics returned by function vmaDefragment(). </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1948</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_a17e9733a5ecd76287d4db6e66f71f50c"><div class="ttname"><a href="struct_vma_stat_info.html#a17e9733a5ecd76287d4db6e66f71f50c">VmaStatInfo::allocationSizeMax</a></div><div class="ttdeci">VkDeviceSize allocationSizeMax</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1649</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a1338d96a128a5ade648b8d934907c637"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637">VmaVulkanFunctions::vkBindImageMemory</a></div><div class="ttdeci">PFN_vkBindImageMemory vkBindImageMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1455</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_a1859d290aca2cd582d8dc25922092669"><div class="ttname"><a href="struct_vma_stat_info.html#a1859d290aca2cd582d8dc25922092669">VmaStatInfo::unusedBytes</a></div><div class="ttdeci">VkDeviceSize unusedBytes</div><div class="ttdoc">Total number of bytes occupied by unused ranges. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1648</div></div>
+<div class="ttc" id="struct_vma_defragmentation_stats_html"><div class="ttname"><a href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a></div><div class="ttdoc">Statistics returned by function vmaDefragment(). </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2381</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a11f0fbc034fa81a4efedd73d61ce7568"><div class="ttname"><a href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vmaFreeMemory</a></div><div class="ttdeci">void vmaFreeMemory(VmaAllocator allocator, VmaAllocation allocation)</div><div class="ttdoc">Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). </div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_a21ea188dd212b8171cb9ecbed4a2a3a7"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">VmaAllocatorCreateInfo::frameInUseCount</a></div><div class="ttdeci">uint32_t frameInUseCount</div><div class="ttdoc">Maximum number of additional frames that are in use at the same time as current frame. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1204</div></div>
-<div class="ttc" id="struct_vma_stats_html_a2e8f5b3353f2fefef3c27f29e245a1f9"><div class="ttname"><a href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">VmaStats::total</a></div><div class="ttdeci">VmaStatInfo total</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1314</div></div>
-<div class="ttc" id="struct_vma_defragmentation_stats_html_a0113f1877904a5d1ee8f409216ff276b"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b">VmaDefragmentationStats::deviceMemoryBlocksFreed</a></div><div class="ttdeci">uint32_t deviceMemoryBlocksFreed</div><div class="ttdoc">Number of empty VkDeviceMemory objects that have been released to the system. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1956</div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html_add09658ac14fe290ace25470ddd6d41b"><div class="ttname"><a href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">VmaAllocationCreateInfo::flags</a></div><div class="ttdeci">VmaAllocationCreateFlags flags</div><div class="ttdoc">Use VmaAllocationCreateFlagBits enum. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1474</div></div>
-<div class="ttc" id="struct_vma_defragmentation_info_html_acb311c940a777270e67e1b81c5ab6a1d"><div class="ttname"><a href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d">VmaDefragmentationInfo::maxBytesToMove</a></div><div class="ttdeci">VkDeviceSize maxBytesToMove</div><div class="ttdoc">Maximum total numbers of bytes that can be copied while moving allocations to different places...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1939</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a5b92901df89a4194b0d12f6071d4d143"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">VmaVulkanFunctions::vkGetBufferMemoryRequirements</a></div><div class="ttdeci">PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1161</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ab6a6477cda1ce775b30bde96d766203b"><div class="ttname"><a href="vk__mem__alloc_8h.html#ab6a6477cda1ce775b30bde96d766203b">PFN_vmaAllocateDeviceMemoryFunction</a></div><div class="ttdeci">void(VKAPI_PTR * PFN_vmaAllocateDeviceMemoryFunction)(VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</div><div class="ttdoc">Callback function called after successful vkAllocateMemory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1088</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_a21ea188dd212b8171cb9ecbed4a2a3a7"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">VmaAllocatorCreateInfo::frameInUseCount</a></div><div class="ttdeci">uint32_t frameInUseCount</div><div class="ttdoc">Maximum number of additional frames that are in use at the same time as current frame. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1541</div></div>
+<div class="ttc" id="struct_vma_stats_html_a2e8f5b3353f2fefef3c27f29e245a1f9"><div class="ttname"><a href="struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9">VmaStats::total</a></div><div class="ttdeci">VmaStatInfo total</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1658</div></div>
+<div class="ttc" id="struct_vma_defragmentation_stats_html_a0113f1877904a5d1ee8f409216ff276b"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b">VmaDefragmentationStats::deviceMemoryBlocksFreed</a></div><div class="ttdeci">uint32_t deviceMemoryBlocksFreed</div><div class="ttdoc">Number of empty VkDeviceMemory objects that have been released to the system. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2389</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html_add09658ac14fe290ace25470ddd6d41b"><div class="ttname"><a href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">VmaAllocationCreateInfo::flags</a></div><div class="ttdeci">VmaAllocationCreateFlags flags</div><div class="ttdoc">Use VmaAllocationCreateFlagBits enum. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1823</div></div>
+<div class="ttc" id="struct_vma_defragmentation_info_html_acb311c940a777270e67e1b81c5ab6a1d"><div class="ttname"><a href="struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d">VmaDefragmentationInfo::maxBytesToMove</a></div><div class="ttdeci">VkDeviceSize maxBytesToMove</div><div class="ttdoc">Maximum total numbers of bytes that can be copied while moving allocations to different places...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2372</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a5b92901df89a4194b0d12f6071d4d143"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">VmaVulkanFunctions::vkGetBufferMemoryRequirements</a></div><div class="ttdeci">PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1456</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ab6a6477cda1ce775b30bde96d766203b"><div class="ttname"><a href="vk__mem__alloc_8h.html#ab6a6477cda1ce775b30bde96d766203b">PFN_vmaAllocateDeviceMemoryFunction</a></div><div class="ttdeci">void(VKAPI_PTR * PFN_vmaAllocateDeviceMemoryFunction)(VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</div><div class="ttdoc">Callback function called after successful vkAllocateMemory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1381</div></div>
 <div class="ttc" id="struct_vma_allocator_html"><div class="ttname"><a href="struct_vma_allocator.html">VmaAllocator</a></div><div class="ttdoc">Represents main object of this library initialized. </div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_ad924ddd77b04039c88d0c09b0ffcd500"><div class="ttname"><a href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500">VmaAllocatorCreateInfo::device</a></div><div class="ttdeci">VkDevice device</div><div class="ttdoc">Vulkan device. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1181</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_ad924ddd77b04039c88d0c09b0ffcd500"><div class="ttname"><a href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500">VmaAllocatorCreateInfo::device</a></div><div class="ttdeci">VkDevice device</div><div class="ttdoc">Vulkan device. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1518</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a6b0929b914b60cf2d45cac4bf3547470"><div class="ttname"><a href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vmaBindBufferMemory</a></div><div class="ttdeci">VkResult vmaBindBufferMemory(VmaAllocator allocator, VmaAllocation allocation, VkBuffer buffer)</div><div class="ttdoc">Binds buffer to allocation. </div></div>
-<div class="ttc" id="struct_vma_pool_create_info_html"><div class="ttname"><a href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a></div><div class="ttdoc">Describes parameter of created VmaPool. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1599</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec">VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1593</div></div>
-<div class="ttc" id="struct_vma_allocation_info_html_aac76d113a6a5ccbb09fea00fb25fd18f"><div class="ttname"><a href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">VmaAllocationInfo::size</a></div><div class="ttdeci">VkDeviceSize size</div><div class="ttdoc">Size of this allocation, in bytes. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1755</div></div>
+<div class="ttc" id="struct_vma_pool_create_info_html"><div class="ttname"><a href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a></div><div class="ttdoc">Describes parameter of created VmaPool. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1963</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec">VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1957</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_ace2aa4877b16a42b0b7673d4e26000ee"><div class="ttname"><a href="struct_vma_allocator_create_info.html#ace2aa4877b16a42b0b7673d4e26000ee">VmaAllocatorCreateInfo::pRecordSettings</a></div><div class="ttdeci">const VmaRecordSettings * pRecordSettings</div><div class="ttdoc">Parameters for recording of VMA calls. Can be null. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1584</div></div>
+<div class="ttc" id="struct_vma_allocation_info_html_aac76d113a6a5ccbb09fea00fb25fd18f"><div class="ttname"><a href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">VmaAllocationInfo::size</a></div><div class="ttdeci">VkDeviceSize size</div><div class="ttdoc">Size of this allocation, in bytes. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2142</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a8701444752eb5de4464adb5a2b514bca"><div class="ttname"><a href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a></div><div class="ttdeci">void vmaGetMemoryTypeProperties(VmaAllocator allocator, uint32_t memoryTypeIndex, VkMemoryPropertyFlags *pFlags)</div><div class="ttdoc">Given Memory Type Index, returns Property Flags of this memory type. </div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_acc798589736f0becb317fc2196c1d8b9"><div class="ttname"><a href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9">VmaVulkanFunctions::vkUnmapMemory</a></div><div class="ttdeci">PFN_vkUnmapMemory vkUnmapMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1158</div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html_a8259e85c272683434f4abb4ddddffe19"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">VmaAllocationCreateInfo::pUserData</a></div><div class="ttdeci">void * pUserData</div><div class="ttdoc">Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1511</div></div>
-<div class="ttc" id="struct_vma_pool_create_info_html_ad8006fb803185c0a699d30f3e9a865ae"><div class="ttname"><a href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae">VmaPoolCreateInfo::minBlockCount</a></div><div class="ttdeci">size_t minBlockCount</div><div class="ttdoc">Minimum number of blocks to be always allocated in this pool, even if they stay empty. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1615</div></div>
-<div class="ttc" id="struct_vma_pool_stats_html_ad1924eb54fffa45e9e0e65670c8fe5eb"><div class="ttname"><a href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">VmaPoolStats::allocationCount</a></div><div class="ttdeci">size_t allocationCount</div><div class="ttdoc">Number of VmaAllocation objects created from this pool that were not destroyed or lost...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1651</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_acc798589736f0becb317fc2196c1d8b9"><div class="ttname"><a href="struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9">VmaVulkanFunctions::vkUnmapMemory</a></div><div class="ttdeci">PFN_vkUnmapMemory vkUnmapMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1451</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2a8e7ab322e8732654be627c4ea8f36cc7">VMA_RECORD_FLUSH_AFTER_CALL_BIT</a></div><div class="ttdoc">Enables flush after recording every function call. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1475</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html_a8259e85c272683434f4abb4ddddffe19"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">VmaAllocationCreateInfo::pUserData</a></div><div class="ttdeci">void * pUserData</div><div class="ttdoc">Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1860</div></div>
+<div class="ttc" id="struct_vma_pool_create_info_html_ad8006fb803185c0a699d30f3e9a865ae"><div class="ttname"><a href="struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae">VmaPoolCreateInfo::minBlockCount</a></div><div class="ttdeci">size_t minBlockCount</div><div class="ttdoc">Minimum number of blocks to be always allocated in this pool, even if they stay empty. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1983</div></div>
+<div class="ttc" id="struct_vma_pool_stats_html_ad1924eb54fffa45e9e0e65670c8fe5eb"><div class="ttname"><a href="struct_vma_pool_stats.html#ad1924eb54fffa45e9e0e65670c8fe5eb">VmaPoolStats::allocationCount</a></div><div class="ttdeci">size_t allocationCount</div><div class="ttdoc">Number of VmaAllocation objects created from this pool that were not destroyed or lost...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2019</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a97064a1a271b0061ebfc3a079862d0c5"><div class="ttname"><a href="vk__mem__alloc_8h.html#a97064a1a271b0061ebfc3a079862d0c5">VmaVulkanFunctions</a></div><div class="ttdeci">struct VmaVulkanFunctions VmaVulkanFunctions</div><div class="ttdoc">Pointers to some Vulkan functions - a subset used by the library. </div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c">VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1144</div></div>
-<div class="ttc" id="struct_vma_pool_create_info_html_a596fa76b685d3f1f688f84a709a5b319"><div class="ttname"><a href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">VmaPoolCreateInfo::memoryTypeIndex</a></div><div class="ttdeci">uint32_t memoryTypeIndex</div><div class="ttdoc">Vulkan memory type index to allocate this pool from. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1602</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c">VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1437</div></div>
+<div class="ttc" id="struct_vma_pool_create_info_html_a596fa76b685d3f1f688f84a709a5b319"><div class="ttname"><a href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">VmaPoolCreateInfo::memoryTypeIndex</a></div><div class="ttdeci">uint32_t memoryTypeIndex</div><div class="ttdoc">Vulkan memory type index to allocate this pool from. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1966</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_aef15a94b58fbcb0fe706d5720e84a74a"><div class="ttname"><a href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a">vmaFindMemoryTypeIndex</a></div><div class="ttdeci">VkResult vmaFindMemoryTypeIndex(VmaAllocator allocator, uint32_t memoryTypeBits, const VmaAllocationCreateInfo *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)</div><div class="ttdoc">Helps to find memoryTypeIndex, given memoryTypeBits and VmaAllocationCreateInfo. </div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cc"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a></div><div class="ttdeci">VmaMemoryUsage</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1350</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cc"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cc">VmaMemoryUsage</a></div><div class="ttdeci">VmaMemoryUsage</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1694</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a795e6ff02a21d5486c0565f403dd9255"><div class="ttname"><a href="vk__mem__alloc_8h.html#a795e6ff02a21d5486c0565f403dd9255">VmaAllocationInfo</a></div><div class="ttdeci">struct VmaAllocationInfo VmaAllocationInfo</div><div class="ttdoc">Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo(). </div></div>
-<div class="ttc" id="struct_vma_defragmentation_info_html"><div class="ttname"><a href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a></div><div class="ttdoc">Optional configuration parameters to be passed to function vmaDefragment(). </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1934</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_abc34ee6f021f459aff885f3758c435de"><div class="ttname"><a href="vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de">vmaFlushAllocation</a></div><div class="ttdeci">void vmaFlushAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size)</div><div class="ttdoc">Flushes memory of given allocation. </div></div>
+<div class="ttc" id="struct_vma_defragmentation_info_html"><div class="ttname"><a href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a></div><div class="ttdoc">Optional configuration parameters to be passed to function vmaDefragment(). </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2367</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a211706e9348dcee25a843ed4ea69bce7"><div class="ttname"><a href="vk__mem__alloc_8h.html#a211706e9348dcee25a843ed4ea69bce7">VmaPoolCreateInfo</a></div><div class="ttdeci">struct VmaPoolCreateInfo VmaPoolCreateInfo</div><div class="ttdoc">Describes parameter of created VmaPool. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a5485779c8f1948238fc4e92232fa65e1"><div class="ttname"><a href="vk__mem__alloc_8h.html#a5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a></div><div class="ttdeci">void vmaDestroyPool(VmaAllocator allocator, VmaPool pool)</div><div class="ttdoc">Destroys VmaPool object and frees Vulkan device memory. </div></div>
-<div class="ttc" id="struct_vma_defragmentation_stats_html_ab0cb9ac0dbc106c77e384ea676422f28"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28">VmaDefragmentationStats::bytesFreed</a></div><div class="ttdeci">VkDeviceSize bytesFreed</div><div class="ttdoc">Total number of bytes that have been released to the system by freeing empty VkDeviceMemory objects...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1952</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1389</div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html_a3bf940c0271d85d6ba32a4d820075055"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">VmaAllocationCreateInfo::memoryTypeBits</a></div><div class="ttdeci">uint32_t memoryTypeBits</div><div class="ttdoc">Bitmask containing one bit set for every memory type acceptable for this allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1498</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a94fc4f3a605d9880bb3c0ba2c2fc80b2"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2">VmaVulkanFunctions::vkBindBufferMemory</a></div><div class="ttdeci">PFN_vkBindBufferMemory vkBindBufferMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1159</div></div>
+<div class="ttc" id="struct_vma_defragmentation_stats_html_ab0cb9ac0dbc106c77e384ea676422f28"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#ab0cb9ac0dbc106c77e384ea676422f28">VmaDefragmentationStats::bytesFreed</a></div><div class="ttdeci">VkDeviceSize bytesFreed</div><div class="ttdoc">Total number of bytes that have been released to the system by freeing empty VkDeviceMemory objects...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2385</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1733</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html_a3bf940c0271d85d6ba32a4d820075055"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">VmaAllocationCreateInfo::memoryTypeBits</a></div><div class="ttdeci">uint32_t memoryTypeBits</div><div class="ttdoc">Bitmask containing one bit set for every memory type acceptable for this allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1847</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a94fc4f3a605d9880bb3c0ba2c2fc80b2"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2">VmaVulkanFunctions::vkBindBufferMemory</a></div><div class="ttdeci">PFN_vkBindBufferMemory vkBindBufferMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1454</div></div>
 <div class="ttc" id="struct_vma_pool_html"><div class="ttname"><a href="struct_vma_pool.html">VmaPool</a></div><div class="ttdoc">Represents custom memory pool. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ae8bf76997b234ef68aad922616df4153"><div class="ttname"><a href="vk__mem__alloc_8h.html#ae8bf76997b234ef68aad922616df4153">vmaGetPoolStats</a></div><div class="ttdeci">void vmaGetPoolStats(VmaAllocator allocator, VmaPool pool, VmaPoolStats *pPoolStats)</div><div class="ttdoc">Retrieves statistics of existing VmaPool object. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ae67f8573a0cf20f16f0a1eecbca566a0"><div class="ttname"><a href="vk__mem__alloc_8h.html#ae67f8573a0cf20f16f0a1eecbca566a0">VmaDefragmentationInfo</a></div><div class="ttdeci">struct VmaDefragmentationInfo VmaDefragmentationInfo</div><div class="ttdoc">Optional configuration parameters to be passed to function vmaDefragment(). </div></div>
-<div class="ttc" id="struct_vma_stats_html"><div class="ttname"><a href="struct_vma_stats.html">VmaStats</a></div><div class="ttdoc">General statistics from current state of Allocator. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1310</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aef2545dc2e9dd4f29ab9ba6ac6fe2f49"><div class="ttname"><a href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49">PFN_vmaFreeDeviceMemoryFunction</a></div><div class="ttdeci">void(VKAPI_PTR * PFN_vmaFreeDeviceMemoryFunction)(VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</div><div class="ttdoc">Callback function called before vkFreeMemory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1094</div></div>
+<div class="ttc" id="struct_vma_stats_html"><div class="ttname"><a href="struct_vma_stats.html">VmaStats</a></div><div class="ttdoc">General statistics from current state of Allocator. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1654</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aef2545dc2e9dd4f29ab9ba6ac6fe2f49"><div class="ttname"><a href="vk__mem__alloc_8h.html#aef2545dc2e9dd4f29ab9ba6ac6fe2f49">PFN_vmaFreeDeviceMemoryFunction</a></div><div class="ttdeci">void(VKAPI_PTR * PFN_vmaFreeDeviceMemoryFunction)(VmaAllocator allocator, uint32_t memoryType, VkDeviceMemory memory, VkDeviceSize size)</div><div class="ttdoc">Callback function called before vkFreeMemory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1387</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_af9147d31ffc11d62fc187bde283ed14f"><div class="ttname"><a href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f">vmaSetAllocationUserData</a></div><div class="ttdeci">void vmaSetAllocationUserData(VmaAllocator allocator, VmaAllocation allocation, void *pUserData)</div><div class="ttdoc">Sets pUserData in given allocation to new value. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a5c8770ded7c59c8caac6de0c2cb00b50"><div class="ttname"><a href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a></div><div class="ttdeci">VkResult vmaCreatePool(VmaAllocator allocator, const VmaPoolCreateInfo *pCreateInfo, VmaPool *pPool)</div><div class="ttdoc">Allocates Vulkan device memory and creates VmaPool object. </div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7c"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a></div><div class="ttdeci">VmaAllocatorCreateFlagBits</div><div class="ttdoc">Flags for created VmaAllocator. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1115</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7c"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c">VmaAllocatorCreateFlagBits</a></div><div class="ttdeci">VmaAllocatorCreateFlagBits</div><div class="ttdoc">Flags for created VmaAllocator. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1408</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a3d3ca45799923aa5d138e9e5f9eb2da5"><div class="ttname"><a href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vmaBindImageMemory</a></div><div class="ttdeci">VkResult vmaBindImageMemory(VmaAllocator allocator, VmaAllocation allocation, VkImage image)</div><div class="ttdoc">Binds image to allocation. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a810b009a788ee8aac72a25b42ffbe31c"><div class="ttname"><a href="vk__mem__alloc_8h.html#a810b009a788ee8aac72a25b42ffbe31c">VmaStatInfo</a></div><div class="ttdeci">struct VmaStatInfo VmaStatInfo</div><div class="ttdoc">Calculated statistics of memory usage in entire allocator. </div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a></div><div class="ttdoc">Allocator and all objects created from it will not be synchronized internally, so you must guarantee ...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1120</div></div>
-<div class="ttc" id="struct_vma_defragmentation_stats_html_aefeabf130022008eadd75999478af3f9"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">VmaDefragmentationStats::allocationsMoved</a></div><div class="ttdeci">uint32_t allocationsMoved</div><div class="ttdoc">Number of allocations that have been moved to different places. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1954</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_af3929a1a4547c592fc0b0e55ef452828"><div class="ttname"><a href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">VmaRecordFlags</a></div><div class="ttdeci">VkFlags VmaRecordFlags</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1479</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a></div><div class="ttdoc">Allocator and all objects created from it will not be synchronized internally, so you must guarantee ...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1413</div></div>
+<div class="ttc" id="struct_vma_defragmentation_stats_html_aefeabf130022008eadd75999478af3f9"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9">VmaDefragmentationStats::allocationsMoved</a></div><div class="ttdeci">uint32_t allocationsMoved</div><div class="ttdoc">Number of allocations that have been moved to different places. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2387</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ae5c9657d9e94756269145b01c05d16f1"><div class="ttname"><a href="vk__mem__alloc_8h.html#ae5c9657d9e94756269145b01c05d16f1">vmaCreateLostAllocation</a></div><div class="ttdeci">void vmaCreateLostAllocation(VmaAllocator allocator, VmaAllocation *pAllocation)</div><div class="ttdoc">Creates new allocation that is in lost state from the beginning. </div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html_a9166390303ff42d783305bc31c2b6b90"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">VmaAllocationCreateInfo::requiredFlags</a></div><div class="ttdeci">VkMemoryPropertyFlags requiredFlags</div><div class="ttdoc">Flags that must be set in a Memory Type chosen for an allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1485</div></div>
-<div class="ttc" id="struct_vma_pool_stats_html_ab4c8f52dd42ab01998f60f0b6acc722b"><div class="ttname"><a href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">VmaPoolStats::unusedRangeSizeMax</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeMax</div><div class="ttdoc">Size of the largest continuous free memory region. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1661</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html_a9166390303ff42d783305bc31c2b6b90"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90">VmaAllocationCreateInfo::requiredFlags</a></div><div class="ttdeci">VkMemoryPropertyFlags requiredFlags</div><div class="ttdoc">Flags that must be set in a Memory Type chosen for an allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1834</div></div>
+<div class="ttc" id="struct_vma_pool_stats_html_ab4c8f52dd42ab01998f60f0b6acc722b"><div class="ttname"><a href="struct_vma_pool_stats.html#ab4c8f52dd42ab01998f60f0b6acc722b">VmaPoolStats::unusedRangeSizeMax</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeMax</div><div class="ttdoc">Size of the largest continuous free memory region available for new allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2029</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_aa4fee7eb5253377599ef4fd38c93c2a0"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0">vmaBuildStatsString</a></div><div class="ttdeci">void vmaBuildStatsString(VmaAllocator allocator, char **ppStatsString, VkBool32 detailedMap)</div><div class="ttdoc">Builds and returns statistics as string in JSON format. </div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a60d25c33bba06bb8592e6875cbaa9830"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">VmaVulkanFunctions::vkGetPhysicalDeviceMemoryProperties</a></div><div class="ttdeci">PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1154</div></div>
-<div class="ttc" id="struct_vma_stat_info_html"><div class="ttname"><a href="struct_vma_stat_info.html">VmaStatInfo</a></div><div class="ttdoc">Calculated statistics of memory usage in entire allocator. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1293</div></div>
-<div class="ttc" id="struct_vma_pool_create_info_html_aa4265160536cdb9be821b7686c16c676"><div class="ttname"><a href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">VmaPoolCreateInfo::blockSize</a></div><div class="ttdeci">VkDeviceSize blockSize</div><div class="ttdoc">Size of a single VkDeviceMemory block to be allocated as part of this pool, in bytes. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1610</div></div>
-<div class="ttc" id="struct_vma_device_memory_callbacks_html"><div class="ttname"><a href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a></div><div class="ttdoc">Set of callbacks that the library will call for vkAllocateMemory and vkFreeMemory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1107</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a60d25c33bba06bb8592e6875cbaa9830"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">VmaVulkanFunctions::vkGetPhysicalDeviceMemoryProperties</a></div><div class="ttdeci">PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1447</div></div>
+<div class="ttc" id="struct_vma_stat_info_html"><div class="ttname"><a href="struct_vma_stat_info.html">VmaStatInfo</a></div><div class="ttdoc">Calculated statistics of memory usage in entire allocator. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1637</div></div>
+<div class="ttc" id="struct_vma_pool_create_info_html_aa4265160536cdb9be821b7686c16c676"><div class="ttname"><a href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">VmaPoolCreateInfo::blockSize</a></div><div class="ttdeci">VkDeviceSize blockSize</div><div class="ttdoc">Size of a single VkDeviceMemory block to be allocated as part of this pool, in bytes. Optional. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1978</div></div>
+<div class="ttc" id="struct_vma_device_memory_callbacks_html"><div class="ttname"><a href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a></div><div class="ttdoc">Set of callbacks that the library will call for vkAllocateMemory and vkFreeMemory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1400</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ac72ee55598617e8eecca384e746bab51"><div class="ttname"><a href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a></div><div class="ttdeci">VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1459</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_aedeba931324f16589cd2416c0d2dd0d4"><div class="ttname"><a href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">VmaStatInfo::unusedRangeSizeMin</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeMin</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1306</div></div>
-<div class="ttc" id="struct_vma_device_memory_callbacks_html_abe8a3328bbc916f6f712fdb6b299444c"><div class="ttname"><a href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">VmaDeviceMemoryCallbacks::pfnFree</a></div><div class="ttdeci">PFN_vmaFreeDeviceMemoryFunction pfnFree</div><div class="ttdoc">Optional, can be null. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1111</div></div>
-<div class="ttc" id="struct_vma_pool_create_info_html_a8405139f63d078340ae74513a59f5446"><div class="ttname"><a href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">VmaPoolCreateInfo::flags</a></div><div class="ttdeci">VmaPoolCreateFlags flags</div><div class="ttdoc">Use combination of VmaPoolCreateFlagBits. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1605</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1398</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1803</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_aedeba931324f16589cd2416c0d2dd0d4"><div class="ttname"><a href="struct_vma_stat_info.html#aedeba931324f16589cd2416c0d2dd0d4">VmaStatInfo::unusedRangeSizeMin</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeMin</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1650</div></div>
+<div class="ttc" id="struct_vma_device_memory_callbacks_html_abe8a3328bbc916f6f712fdb6b299444c"><div class="ttname"><a href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">VmaDeviceMemoryCallbacks::pfnFree</a></div><div class="ttdeci">PFN_vmaFreeDeviceMemoryFunction pfnFree</div><div class="ttdoc">Optional, can be null. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1404</div></div>
+<div class="ttc" id="struct_vma_pool_create_info_html_a8405139f63d078340ae74513a59f5446"><div class="ttname"><a href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446">VmaPoolCreateInfo::flags</a></div><div class="ttdeci">VmaPoolCreateFlags flags</div><div class="ttdoc">Use combination of VmaPoolCreateFlagBits. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1969</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27">VMA_MEMORY_USAGE_GPU_TO_CPU</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1742</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a5c1093bc32386a8060c37c9f282078a1"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1">VmaVulkanFunctions::vkInvalidateMappedMemoryRanges</a></div><div class="ttdeci">PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1453</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a2e5612d871d64c5624087b837a338c34"><div class="ttname"><a href="vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34">VmaPoolStats</a></div><div class="ttdeci">struct VmaPoolStats VmaPoolStats</div><div class="ttdoc">Describes parameter of existing VmaPool. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a02a94f25679275851a53e82eacbcfc73"><div class="ttname"><a href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73">vmaCreateImage</a></div><div class="ttdeci">VkResult vmaCreateImage(VmaAllocator allocator, const VkImageCreateInfo *pImageCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkImage *pImage, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div><div class="ttdoc">Function similar to vmaCreateBuffer(). </div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html_accb8b06b1f677d858cb9af20705fa910"><div class="ttname"><a href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">VmaAllocationCreateInfo::usage</a></div><div class="ttdeci">VmaMemoryUsage usage</div><div class="ttdoc">Intended usage of memory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1480</div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html"><div class="ttname"><a href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1471</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html_accb8b06b1f677d858cb9af20705fa910"><div class="ttname"><a href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">VmaAllocationCreateInfo::usage</a></div><div class="ttdeci">VmaMemoryUsage usage</div><div class="ttdoc">Intended usage of memory. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1829</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html"><div class="ttname"><a href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1820</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a088da83d8eaf3ce9056d9ea0b981d472"><div class="ttname"><a href="vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472">vmaFindMemoryTypeIndexForImageInfo</a></div><div class="ttdeci">VkResult vmaFindMemoryTypeIndexForImageInfo(VmaAllocator allocator, const VkImageCreateInfo *pImageCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)</div><div class="ttdoc">Helps to find memoryTypeIndex, given VkImageCreateInfo and VmaAllocationCreateInfo. </div></div>
-<div class="ttc" id="struct_vma_stat_info_html_abc4bb7cd611900778464c56e50c970a4"><div class="ttname"><a href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">VmaStatInfo::blockCount</a></div><div class="ttdeci">uint32_t blockCount</div><div class="ttdoc">Number of VkDeviceMemory Vulkan memory blocks allocated. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1296</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a4c658701778564d62034255b5dda91b4"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">VmaVulkanFunctions::vkFreeMemory</a></div><div class="ttdeci">PFN_vkFreeMemory vkFreeMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1156</div></div>
-<div class="ttc" id="struct_vma_pool_create_info_html_ae41142f2834fcdc82baa4883c187b75c"><div class="ttname"><a href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">VmaPoolCreateInfo::maxBlockCount</a></div><div class="ttdeci">size_t maxBlockCount</div><div class="ttdoc">Maximum number of blocks that can be allocated in this pool. Optional. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1623</div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_af1380969b5e1ea4c3184a877892d260e"><div class="ttname"><a href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a></div><div class="ttdeci">const VmaDeviceMemoryCallbacks * pDeviceMemoryCallbacks</div><div class="ttdoc">Informative callbacks for vkAllocateMemory, vkFreeMemory. Optional. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1190</div></div>
-<div class="ttc" id="struct_vma_pool_stats_html_ae4f3546ffa4d1e598b64d8e6134854f4"><div class="ttname"><a href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">VmaPoolStats::unusedRangeCount</a></div><div class="ttdeci">size_t unusedRangeCount</div><div class="ttdoc">Number of continuous memory ranges in the pool not used by any VmaAllocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1654</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a5225e5e11f8376f6a31a1791f3d6e817"><div class="ttname"><a href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a></div><div class="ttdeci">VkFlags VmaAllocationCreateFlags</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1469</div></div>
-<div class="ttc" id="struct_vma_allocation_create_info_html_a6272c0555cfd1fe28bff1afeb6190150"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">VmaAllocationCreateInfo::pool</a></div><div class="ttdeci">VmaPool pool</div><div class="ttdoc">Pool that this allocation should be created in. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1504</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_abc4bb7cd611900778464c56e50c970a4"><div class="ttname"><a href="struct_vma_stat_info.html#abc4bb7cd611900778464c56e50c970a4">VmaStatInfo::blockCount</a></div><div class="ttdeci">uint32_t blockCount</div><div class="ttdoc">Number of VkDeviceMemory Vulkan memory blocks allocated. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1640</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a4c658701778564d62034255b5dda91b4"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">VmaVulkanFunctions::vkFreeMemory</a></div><div class="ttdeci">PFN_vkFreeMemory vkFreeMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1449</div></div>
+<div class="ttc" id="struct_vma_pool_create_info_html_ae41142f2834fcdc82baa4883c187b75c"><div class="ttname"><a href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">VmaPoolCreateInfo::maxBlockCount</a></div><div class="ttdeci">size_t maxBlockCount</div><div class="ttdoc">Maximum number of blocks that can be allocated in this pool. Optional. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1991</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_af1380969b5e1ea4c3184a877892d260e"><div class="ttname"><a href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a></div><div class="ttdeci">const VmaDeviceMemoryCallbacks * pDeviceMemoryCallbacks</div><div class="ttdoc">Informative callbacks for vkAllocateMemory, vkFreeMemory. Optional. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1527</div></div>
+<div class="ttc" id="struct_vma_pool_stats_html_ae4f3546ffa4d1e598b64d8e6134854f4"><div class="ttname"><a href="struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4">VmaPoolStats::unusedRangeCount</a></div><div class="ttdeci">size_t unusedRangeCount</div><div class="ttdoc">Number of continuous memory ranges in the pool not used by any VmaAllocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2022</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a5225e5e11f8376f6a31a1791f3d6e817"><div class="ttname"><a href="vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817">VmaAllocationCreateFlags</a></div><div class="ttdeci">VkFlags VmaAllocationCreateFlags</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1818</div></div>
+<div class="ttc" id="struct_vma_allocation_create_info_html_a6272c0555cfd1fe28bff1afeb6190150"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">VmaAllocationCreateInfo::pool</a></div><div class="ttdeci">VmaPool pool</div><div class="ttdoc">Pool that this allocation should be created in. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1853</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ab88db292a17974f911182543fda52d19"><div class="ttname"><a href="vk__mem__alloc_8h.html#ab88db292a17974f911182543fda52d19">vmaGetMemoryProperties</a></div><div class="ttdeci">void vmaGetMemoryProperties(VmaAllocator allocator, const VkPhysicalDeviceMemoryProperties **ppPhysicalDeviceMemoryProperties)</div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_a31c192aa6cbffa33279f6d9f0c47c44b"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">VmaAllocatorCreateInfo::pHeapSizeLimit</a></div><div class="ttdeci">const VkDeviceSize * pHeapSizeLimit</div><div class="ttdoc">Either null or a pointer to an array of limits on maximum number of bytes that can be allocated out o...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1228</div></div>
-<div class="ttc" id="struct_vma_stats_html_a13e3caf754be79352c42408756309331"><div class="ttname"><a href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">VmaStats::memoryType</a></div><div class="ttdeci">VmaStatInfo memoryType[VK_MAX_MEMORY_TYPES]</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1312</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a></div><div class="ttdoc">Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1439</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_ade8b40bd3139c04aabd2fc538a356fea"><div class="ttname"><a href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">VmaStatInfo::allocationSizeMin</a></div><div class="ttdeci">VkDeviceSize allocationSizeMin</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1305</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_a31c192aa6cbffa33279f6d9f0c47c44b"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">VmaAllocatorCreateInfo::pHeapSizeLimit</a></div><div class="ttdeci">const VkDeviceSize * pHeapSizeLimit</div><div class="ttdoc">Either null or a pointer to an array of limits on maximum number of bytes that can be allocated out o...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1565</div></div>
+<div class="ttc" id="struct_vma_stats_html_a13e3caf754be79352c42408756309331"><div class="ttname"><a href="struct_vma_stats.html#a13e3caf754be79352c42408756309331">VmaStats::memoryType</a></div><div class="ttdeci">VmaStatInfo memoryType[VK_MAX_MEMORY_TYPES]</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1656</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a></div><div class="ttdoc">Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1783</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_ade8b40bd3139c04aabd2fc538a356fea"><div class="ttname"><a href="struct_vma_stat_info.html#ade8b40bd3139c04aabd2fc538a356fea">VmaStatInfo::allocationSizeMin</a></div><div class="ttdeci">VkDeviceSize allocationSizeMin</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1649</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ae790ab9ffaf7667fb8f62523e6897888"><div class="ttname"><a href="vk__mem__alloc_8h.html#ae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a></div><div class="ttdeci">VkResult vmaFindMemoryTypeIndexForBufferInfo(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)</div><div class="ttdoc">Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo. </div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a23ebe70be515b9b5010a1d691200e325"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325">VmaVulkanFunctions::vkCreateImage</a></div><div class="ttdeci">PFN_vkCreateImage vkCreateImage</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1165</div></div>
-<div class="ttc" id="struct_vma_device_memory_callbacks_html_a4f17f7b255101e733b44d5633aceabfb"><div class="ttname"><a href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">VmaDeviceMemoryCallbacks::pfnAllocate</a></div><div class="ttdeci">PFN_vmaAllocateDeviceMemoryFunction pfnAllocate</div><div class="ttdoc">Optional, can be null. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1109</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a7e054606faddb07f0e8556f3ed317d45"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45">VmaVulkanFunctions::vkDestroyBuffer</a></div><div class="ttdeci">PFN_vkDestroyBuffer vkDestroyBuffer</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1164</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a23ebe70be515b9b5010a1d691200e325"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325">VmaVulkanFunctions::vkCreateImage</a></div><div class="ttdeci">PFN_vkCreateImage vkCreateImage</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1460</div></div>
+<div class="ttc" id="struct_vma_record_settings_html_ad8fdcc92119ae7a8c08c1a564c01d63a"><div class="ttname"><a href="struct_vma_record_settings.html#ad8fdcc92119ae7a8c08c1a564c01d63a">VmaRecordSettings::flags</a></div><div class="ttdeci">VmaRecordFlags flags</div><div class="ttdoc">Flags for recording. Use VmaRecordFlagBits enum. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1497</div></div>
+<div class="ttc" id="struct_vma_device_memory_callbacks_html_a4f17f7b255101e733b44d5633aceabfb"><div class="ttname"><a href="struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb">VmaDeviceMemoryCallbacks::pfnAllocate</a></div><div class="ttdeci">PFN_vmaAllocateDeviceMemoryFunction pfnAllocate</div><div class="ttdoc">Optional, can be null. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1402</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a7e054606faddb07f0e8556f3ed317d45"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45">VmaVulkanFunctions::vkDestroyBuffer</a></div><div class="ttdeci">PFN_vkDestroyBuffer vkDestroyBuffer</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1459</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ad5bd1243512d099706de88168992f069"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a></div><div class="ttdeci">VkResult vmaMapMemory(VmaAllocator allocator, VmaAllocation allocation, void **ppData)</div><div class="ttdoc">Maps memory represented by given allocation and returns pointer to it. </div></div>
-<div class="ttc" id="struct_vma_pool_create_info_html_a9437e43ffbb644dbbf7fc4e50cfad6aa"><div class="ttname"><a href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa">VmaPoolCreateInfo::frameInUseCount</a></div><div class="ttdeci">uint32_t frameInUseCount</div><div class="ttdoc">Maximum number of additional frames that are in use at the same time as current frame. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1637</div></div>
+<div class="ttc" id="struct_vma_pool_create_info_html_a9437e43ffbb644dbbf7fc4e50cfad6aa"><div class="ttname"><a href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa">VmaPoolCreateInfo::frameInUseCount</a></div><div class="ttdeci">uint32_t frameInUseCount</div><div class="ttdoc">Maximum number of additional frames that are in use at the same time as current frame. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2005</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a33c322f4c4ad2810f8a9c97a277572f9"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9">VmaVulkanFunctions::vkFlushMappedMemoryRanges</a></div><div class="ttdeci">PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1452</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1814</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a0faa3f9e5fb233d29d1e00390650febb"><div class="ttname"><a href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vmaAllocateMemoryForImage</a></div><div class="ttdeci">VkResult vmaAllocateMemoryForImage(VmaAllocator allocator, VkImage image, const VmaAllocationCreateInfo *pCreateInfo, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div><div class="ttdoc">Function similar to vmaAllocateMemoryForBuffer(). </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ae0f6d1d733dded220d28134da46b4283"><div class="ttname"><a href="vk__mem__alloc_8h.html#ae0f6d1d733dded220d28134da46b4283">VmaAllocatorCreateInfo</a></div><div class="ttdeci">struct VmaAllocatorCreateInfo VmaAllocatorCreateInfo</div><div class="ttdoc">Description of a Allocator to be created. </div></div>
-<div class="ttc" id="struct_vma_allocation_info_html_adc507656149c04de7ed95d0042ba2a13"><div class="ttname"><a href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">VmaAllocationInfo::pUserData</a></div><div class="ttdeci">void * pUserData</div><div class="ttdoc">Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1769</div></div>
-<div class="ttc" id="struct_vma_allocator_create_info_html_a8e4714298e3121cdd8b214a1ae7a637a"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">VmaAllocatorCreateInfo::preferredLargeHeapBlockSize</a></div><div class="ttdeci">VkDeviceSize preferredLargeHeapBlockSize</div><div class="ttdoc">Preferred size of a single VkDeviceMemory block to be allocated from large heaps &gt; 1 GiB...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1184</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_a1081a039964e566c672e7a2347f9e599"><div class="ttname"><a href="struct_vma_stat_info.html#a1081a039964e566c672e7a2347f9e599">VmaStatInfo::allocationSizeAvg</a></div><div class="ttdeci">VkDeviceSize allocationSizeAvg</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1305</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_ab0c6c73837e5a70c749fbd4f6064895a"><div class="ttname"><a href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">VmaStatInfo::usedBytes</a></div><div class="ttdeci">VkDeviceSize usedBytes</div><div class="ttdoc">Total number of bytes occupied by all allocations. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1302</div></div>
+<div class="ttc" id="struct_vma_record_settings_html_a6cb1fdbf6bcb610b68f2010dd629e89d"><div class="ttname"><a href="struct_vma_record_settings.html#a6cb1fdbf6bcb610b68f2010dd629e89d">VmaRecordSettings::pFilePath</a></div><div class="ttdeci">const char * pFilePath</div><div class="ttdoc">Path to the file that should be written by the recording. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1505</div></div>
+<div class="ttc" id="struct_vma_allocation_info_html_adc507656149c04de7ed95d0042ba2a13"><div class="ttname"><a href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">VmaAllocationInfo::pUserData</a></div><div class="ttdeci">void * pUserData</div><div class="ttdoc">Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2156</div></div>
+<div class="ttc" id="struct_vma_allocator_create_info_html_a8e4714298e3121cdd8b214a1ae7a637a"><div class="ttname"><a href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">VmaAllocatorCreateInfo::preferredLargeHeapBlockSize</a></div><div class="ttdeci">VkDeviceSize preferredLargeHeapBlockSize</div><div class="ttdoc">Preferred size of a single VkDeviceMemory block to be allocated from large heaps &gt; 1 GiB...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1521</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_a1081a039964e566c672e7a2347f9e599"><div class="ttname"><a href="struct_vma_stat_info.html#a1081a039964e566c672e7a2347f9e599">VmaStatInfo::allocationSizeAvg</a></div><div class="ttdeci">VkDeviceSize allocationSizeAvg</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1649</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_ab0c6c73837e5a70c749fbd4f6064895a"><div class="ttname"><a href="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">VmaStatInfo::usedBytes</a></div><div class="ttdeci">VkDeviceSize usedBytes</div><div class="ttdoc">Total number of bytes occupied by all allocations. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1646</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a5e2eb68d727cfd4df25702b027b7aa31"><div class="ttname"><a href="vk__mem__alloc_8h.html#a5e2eb68d727cfd4df25702b027b7aa31">VmaDeviceMemoryCallbacks</a></div><div class="ttdeci">struct VmaDeviceMemoryCallbacks VmaDeviceMemoryCallbacks</div><div class="ttdoc">Set of callbacks that the library will call for vkAllocateMemory and vkFreeMemory. </div></div>
-<div class="ttc" id="struct_vma_pool_stats_html"><div class="ttname"><a href="struct_vma_pool_stats.html">VmaPoolStats</a></div><div class="ttdoc">Describes parameter of existing VmaPool. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1642</div></div>
-<div class="ttc" id="struct_vma_allocation_info_html_a4a3c732388dbdc7a23f9365b00825268"><div class="ttname"><a href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">VmaAllocationInfo::offset</a></div><div class="ttdeci">VkDeviceSize offset</div><div class="ttdoc">Offset into deviceMemory object to the beginning of this allocation, in bytes. (deviceMemory, offset) pair is unique to this allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1750</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1467</div></div>
-<div class="ttc" id="struct_vma_defragmentation_stats_html_a36f9d5df2a10ba2a36b16e126d60572d"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">VmaDefragmentationStats::bytesMoved</a></div><div class="ttdeci">VkDeviceSize bytesMoved</div><div class="ttdoc">Total number of bytes that have been copied while moving allocations to different places...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1950</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html"><div class="ttname"><a href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></div><div class="ttdoc">Pointers to some Vulkan functions - a subset used by the library. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1152</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a49329a7f030dafcf82f7b73334c22e98"><div class="ttname"><a href="vk__mem__alloc_8h.html#a49329a7f030dafcf82f7b73334c22e98">vmaCheckCorruption</a></div><div class="ttdeci">VkResult vmaCheckCorruption(VmaAllocator allocator, uint32_t memoryTypeBits)</div><div class="ttdoc">Checks magic number in margins around all allocations in given memory types (in both default and cust...</div></div>
+<div class="ttc" id="struct_vma_pool_stats_html"><div class="ttname"><a href="struct_vma_pool_stats.html">VmaPoolStats</a></div><div class="ttdoc">Describes parameter of existing VmaPool. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2010</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad535935619c7a549bf837e1bb0068f89"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad535935619c7a549bf837e1bb0068f89">vmaCheckPoolCorruption</a></div><div class="ttdeci">VkResult vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool)</div><div class="ttdoc">Checks magic number in margins around all allocations in given memory pool in search for corruptions...</div></div>
+<div class="ttc" id="struct_vma_allocation_info_html_a4a3c732388dbdc7a23f9365b00825268"><div class="ttname"><a href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">VmaAllocationInfo::offset</a></div><div class="ttdeci">VkDeviceSize offset</div><div class="ttdoc">Offset into deviceMemory object to the beginning of this allocation, in bytes. (deviceMemory, offset) pair is unique to this allocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2137</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1816</div></div>
+<div class="ttc" id="struct_vma_defragmentation_stats_html_a36f9d5df2a10ba2a36b16e126d60572d"><div class="ttname"><a href="struct_vma_defragmentation_stats.html#a36f9d5df2a10ba2a36b16e126d60572d">VmaDefragmentationStats::bytesMoved</a></div><div class="ttdeci">VkDeviceSize bytesMoved</div><div class="ttdoc">Total number of bytes that have been copied while moving allocations to different places...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2383</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html"><div class="ttname"><a href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></div><div class="ttdoc">Pointers to some Vulkan functions - a subset used by the library. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1445</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a200692051ddb34240248234f5f4c17bb"><div class="ttname"><a href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a></div><div class="ttdeci">VkResult vmaCreateAllocator(const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)</div><div class="ttdoc">Creates Allocator object. </div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a9d8d1b05d2b1e7e1d9b27f6f585acf9c"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">VmaVulkanFunctions::vkGetBufferMemoryRequirements2KHR</a></div><div class="ttdeci">PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1167</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_ae06129c771bfebfd6468a7f4276502a9"><div class="ttname"><a href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">VmaStatInfo::unusedRangeCount</a></div><div class="ttdeci">uint32_t unusedRangeCount</div><div class="ttdoc">Number of free ranges of memory between allocations. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1300</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1355</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a2770e325ea42e087c1b91fdf46d0292a"><div class="ttname"><a href="vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a">VmaPoolCreateFlags</a></div><div class="ttdeci">VkFlags VmaPoolCreateFlags</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1595</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_ae06129c771bfebfd6468a7f4276502a9"><div class="ttname"><a href="struct_vma_stat_info.html#ae06129c771bfebfd6468a7f4276502a9">VmaStatInfo::unusedRangeCount</a></div><div class="ttdeci">uint32_t unusedRangeCount</div><div class="ttdoc">Number of free ranges of memory between allocations. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1644</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1699</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a2770e325ea42e087c1b91fdf46d0292a"><div class="ttname"><a href="vk__mem__alloc_8h.html#a2770e325ea42e087c1b91fdf46d0292a">VmaPoolCreateFlags</a></div><div class="ttdeci">VkFlags VmaPoolCreateFlags</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1959</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_aecabf7b6e91ea87d0316fa0a9e014fe0"><div class="ttname"><a href="vk__mem__alloc_8h.html#aecabf7b6e91ea87d0316fa0a9e014fe0">vmaGetPhysicalDeviceProperties</a></div><div class="ttdeci">void vmaGetPhysicalDeviceProperties(VmaAllocator allocator, const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_a537741e4d5cdddc1c0ab95ec650afaff"><div class="ttname"><a href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">VmaStatInfo::allocationCount</a></div><div class="ttdeci">uint32_t allocationCount</div><div class="ttdoc">Number of VmaAllocation allocation objects allocated. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1298</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a475f6f49f8debe4d10800592606d53f4"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">VmaVulkanFunctions::vkGetImageMemoryRequirements</a></div><div class="ttdeci">PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1162</div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a90b898227039b1dcb3520f6e91f09ffa"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">VmaVulkanFunctions::vkDestroyImage</a></div><div class="ttdeci">PFN_vkDestroyImage vkDestroyImage</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1166</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a></div><div class="ttdoc">Set this flag to only try to allocate from existing VkDeviceMemory blocks and never create new such b...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1426</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1382</div></div>
-<div class="ttc" id="struct_vma_allocation_info_html_a5eeffbe2d2f30f53370ff14aefbadbe2"><div class="ttname"><a href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">VmaAllocationInfo::pMappedData</a></div><div class="ttdeci">void * pMappedData</div><div class="ttdoc">Pointer to the beginning of this allocation as mapped data. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1764</div></div>
+<div class="ttc" id="struct_vma_record_settings_html"><div class="ttname"><a href="struct_vma_record_settings.html">VmaRecordSettings</a></div><div class="ttdoc">Parameters for recording calls to VMA functions. To be used in VmaAllocatorCreateInfo::pRecordSetting...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1494</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_a537741e4d5cdddc1c0ab95ec650afaff"><div class="ttname"><a href="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">VmaStatInfo::allocationCount</a></div><div class="ttdeci">uint32_t allocationCount</div><div class="ttdoc">Number of VmaAllocation allocation objects allocated. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1642</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a475f6f49f8debe4d10800592606d53f4"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">VmaVulkanFunctions::vkGetImageMemoryRequirements</a></div><div class="ttdeci">PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1457</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a90b898227039b1dcb3520f6e91f09ffa"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">VmaVulkanFunctions::vkDestroyImage</a></div><div class="ttdeci">PFN_vkDestroyImage vkDestroyImage</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1461</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a></div><div class="ttdoc">Set this flag to only try to allocate from existing VkDeviceMemory blocks and never create new such b...</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1770</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"><div class="ttname"><a href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1726</div></div>
+<div class="ttc" id="struct_vma_allocation_info_html_a5eeffbe2d2f30f53370ff14aefbadbe2"><div class="ttname"><a href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">VmaAllocationInfo::pMappedData</a></div><div class="ttdeci">void * pMappedData</div><div class="ttdoc">Pointer to the beginning of this allocation as mapped data. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2151</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ae50d2cb3b4a3bfd4dd40987234e50e7e"><div class="ttname"><a href="vk__mem__alloc_8h.html#ae50d2cb3b4a3bfd4dd40987234e50e7e">vmaDestroyImage</a></div><div class="ttdeci">void vmaDestroyImage(VmaAllocator allocator, VkImage image, VmaAllocation allocation)</div><div class="ttdoc">Destroys Vulkan image and frees allocated memory. </div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a></div><div class="ttdoc">Enables usage of VK_KHR_dedicated_allocation extension. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1142</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a></div><div class="ttdoc">Enables usage of VK_KHR_dedicated_allocation extension. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1435</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ab0f9b06441c840fee560de4a2967f8c9"><div class="ttname"><a href="vk__mem__alloc_8h.html#ab0f9b06441c840fee560de4a2967f8c9">VmaDefragmentationStats</a></div><div class="ttdeci">struct VmaDefragmentationStats VmaDefragmentationStats</div><div class="ttdoc">Statistics returned by function vmaDefragment(). </div></div>
-<div class="ttc" id="struct_vma_vulkan_functions_html_a2943bf99dfd784a0e8f599d987e22e6c"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a2943bf99dfd784a0e8f599d987e22e6c">VmaVulkanFunctions::vkAllocateMemory</a></div><div class="ttdeci">PFN_vkAllocateMemory vkAllocateMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1155</div></div>
-<div class="ttc" id="struct_vma_allocation_info_html"><div class="ttname"><a href="struct_vma_allocation_info.html">VmaAllocationInfo</a></div><div class="ttdoc">Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo(). </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1731</div></div>
+<div class="ttc" id="struct_vma_vulkan_functions_html_a2943bf99dfd784a0e8f599d987e22e6c"><div class="ttname"><a href="struct_vma_vulkan_functions.html#a2943bf99dfd784a0e8f599d987e22e6c">VmaVulkanFunctions::vkAllocateMemory</a></div><div class="ttdeci">PFN_vkAllocateMemory vkAllocateMemory</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1448</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a></div><div class="ttdoc">Enables alternative, linear allocation algorithm in this pool. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1955</div></div>
+<div class="ttc" id="struct_vma_allocation_info_html"><div class="ttname"><a href="struct_vma_allocation_info.html">VmaAllocationInfo</a></div><div class="ttdoc">Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo(). </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2118</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_abf28077dbf82d0908b8acbe8ee8dd9b8"><div class="ttname"><a href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a></div><div class="ttdeci">VkResult vmaAllocateMemory(VmaAllocator allocator, const VkMemoryRequirements *pVkMemoryRequirements, const VmaAllocationCreateInfo *pCreateInfo, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div><div class="ttdoc">General purpose memory allocation. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_ade56bf8dc9f5a5eaddf5f119ed525236"><div class="ttname"><a href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236">vmaSetCurrentFrameIndex</a></div><div class="ttdeci">void vmaSetCurrentFrameIndex(VmaAllocator allocator, uint32_t frameIndex)</div><div class="ttdoc">Sets index of the current frame. </div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a86c44f9950b40d50088ed93a17870a7a"><div class="ttname"><a href="vk__mem__alloc_8h.html#a86c44f9950b40d50088ed93a17870a7a">VmaAllocationCreateInfo</a></div><div class="ttdeci">struct VmaAllocationCreateInfo VmaAllocationCreateInfo</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a7fdf64415b6c3d83c454f28d2c53df7b"><div class="ttname"><a href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer</a></div><div class="ttdeci">VkResult vmaAllocateMemoryForBuffer(VmaAllocator allocator, VkBuffer buffer, const VmaAllocationCreateInfo *pCreateInfo, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_a9a7c45f9c863695d98c83fa5ac940fe7"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a></div><div class="ttdeci">VmaPoolCreateFlagBits</div><div class="ttdoc">Flags to be passed as VmaPoolCreateInfo::flags. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1573</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_a2f9b3452af90c9768a30b7fb6ae194fc"><div class="ttname"><a href="struct_vma_stat_info.html#a2f9b3452af90c9768a30b7fb6ae194fc">VmaStatInfo::unusedRangeSizeAvg</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeAvg</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1306</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a9a7c45f9c863695d98c83fa5ac940fe7"><div class="ttname"><a href="vk__mem__alloc_8h.html#a9a7c45f9c863695d98c83fa5ac940fe7">VmaPoolCreateFlagBits</a></div><div class="ttdeci">VmaPoolCreateFlagBits</div><div class="ttdoc">Flags to be passed as VmaPoolCreateInfo::flags. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1922</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_a2f9b3452af90c9768a30b7fb6ae194fc"><div class="ttname"><a href="struct_vma_stat_info.html#a2f9b3452af90c9768a30b7fb6ae194fc">VmaStatInfo::unusedRangeSizeAvg</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeAvg</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1650</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a43d8ba9673c846f049089a5029d5c73a"><div class="ttname"><a href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a></div><div class="ttdeci">VkBool32 vmaTouchAllocation(VmaAllocator allocator, VmaAllocation allocation)</div><div class="ttdoc">Returns VK_TRUE if allocation is not lost and atomically marks it as used in current frame...</div></div>
-<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1465</div></div>
-<div class="ttc" id="struct_vma_stats_html_a0e6611508c29a187f0fd14ff1a0329c0"><div class="ttname"><a href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">VmaStats::memoryHeap</a></div><div class="ttdeci">VmaStatInfo memoryHeap[VK_MAX_MEMORY_HEAPS]</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1313</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520"><div class="ttname"><a href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a></div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1809</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a4dd2c44642312a147a4e93373a6e64d2"><div class="ttname"><a href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">VmaRecordFlagBits</a></div><div class="ttdeci">VmaRecordFlagBits</div><div class="ttdoc">Flags to be used in VmaRecordSettings::flags. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1469</div></div>
+<div class="ttc" id="struct_vma_stats_html_a0e6611508c29a187f0fd14ff1a0329c0"><div class="ttname"><a href="struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0">VmaStats::memoryHeap</a></div><div class="ttdeci">VmaStatInfo memoryHeap[VK_MAX_MEMORY_HEAPS]</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1657</div></div>
 <div class="ttc" id="vk__mem__alloc_8h_html_a0d9f4e4ba5bf9aab1f1c746387753d77"><div class="ttname"><a href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a></div><div class="ttdeci">void vmaDestroyBuffer(VmaAllocator allocator, VkBuffer buffer, VmaAllocation allocation)</div><div class="ttdoc">Destroys Vulkan buffer and frees allocated memory. </div></div>
-<div class="ttc" id="struct_vma_pool_stats_html_ad7c54874724fce7b06aba526202d82a8"><div class="ttname"><a href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">VmaPoolStats::unusedSize</a></div><div class="ttdeci">VkDeviceSize unusedSize</div><div class="ttdoc">Total number of bytes in the pool not used by any VmaAllocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1648</div></div>
-<div class="ttc" id="struct_vma_stat_info_html_a5ba1a2476c4d39b10f7e2f7ebbb72ac4"><div class="ttname"><a href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">VmaStatInfo::unusedRangeSizeMax</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeMax</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1306</div></div>
-<div class="ttc" id="struct_vma_allocation_info_html_a7f6b0aa58c135e488e6b40a388dad9d5"><div class="ttname"><a href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">VmaAllocationInfo::memoryType</a></div><div class="ttdeci">uint32_t memoryType</div><div class="ttdoc">Memory type index that this allocation was allocated from. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1736</div></div>
+<div class="ttc" id="struct_vma_pool_stats_html_ad7c54874724fce7b06aba526202d82a8"><div class="ttname"><a href="struct_vma_pool_stats.html#ad7c54874724fce7b06aba526202d82a8">VmaPoolStats::unusedSize</a></div><div class="ttdeci">VkDeviceSize unusedSize</div><div class="ttdoc">Total number of bytes in the pool not used by any VmaAllocation. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2016</div></div>
+<div class="ttc" id="struct_vma_stat_info_html_a5ba1a2476c4d39b10f7e2f7ebbb72ac4"><div class="ttname"><a href="struct_vma_stat_info.html#a5ba1a2476c4d39b10f7e2f7ebbb72ac4">VmaStatInfo::unusedRangeSizeMax</a></div><div class="ttdeci">VkDeviceSize unusedRangeSizeMax</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1650</div></div>
+<div class="ttc" id="vk__mem__alloc_8h_html_a0ab61e87ff6365f1d59915eadc37a9f0"><div class="ttname"><a href="vk__mem__alloc_8h.html#a0ab61e87ff6365f1d59915eadc37a9f0">VmaRecordSettings</a></div><div class="ttdeci">struct VmaRecordSettings VmaRecordSettings</div><div class="ttdoc">Parameters for recording calls to VMA functions. To be used in VmaAllocatorCreateInfo::pRecordSetting...</div></div>
+<div class="ttc" id="struct_vma_allocation_info_html_a7f6b0aa58c135e488e6b40a388dad9d5"><div class="ttname"><a href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">VmaAllocationInfo::memoryType</a></div><div class="ttdeci">uint32_t memoryType</div><div class="ttdoc">Memory type index that this allocation was allocated from. </div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:2123</div></div>
 </div><!-- fragment --></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/premake/premake5.lua b/premake/premake5.lua
index 8893601..c6d2b93 100644
--- a/premake/premake5.lua
+++ b/premake/premake5.lua
@@ -12,7 +12,7 @@
 filter "platforms:x64"

 system "Windows"

 architecture "x64"

-includedirs { "../third_party/mathfu-1.1.0/include", "$(VULKAN_SDK)/Include" }

+includedirs { "$(VULKAN_SDK)/Include" }

 libdirs { "$(VULKAN_SDK)/Lib" }

 

 filter "platforms:Linux-x64"

@@ -21,6 +21,7 @@
 includedirs { "$(VULKAN_SDK)/include" }

 libdirs { "$(VULKAN_SDK)/lib" }

 

+

 project "VulkanSample"

 kind "ConsoleApp"

 language "C++"

@@ -57,3 +58,41 @@
 

 filter { "configurations:Release", "platforms:Windows-x64" }

 buildoptions { "/MD" }

+

+

+project "VmaReplay"

+kind "ConsoleApp"

+language "C++"

+location "../build"

+filename ("VmaReplay_" .. _SUFFIX)

+targetdir "../bin"

+objdir "../build/Desktop_%{_SUFFIX}/%{cfg.platform}/%{cfg.buildcfg}"

+floatingpoint "Fast"

+files { "../src/VmaReplay/*.h", "../src/VmaReplay/*.cpp" }

+flags { "NoPCH", "FatalWarnings" }

+characterset "Default"

+

+filter "configurations:Debug"

+defines { "_DEBUG", "DEBUG" }

+flags { }

+targetsuffix ("_Debug_" .. _SUFFIX)

+

+filter "configurations:Release"

+defines { "NDEBUG" }

+optimize "On"

+flags { "LinkTimeOptimization" }

+targetsuffix ("_Release_" .. _SUFFIX)

+

+filter { "platforms:x64" }

+defines { "WIN32", "_CONSOLE", "PROFILE", "_WINDOWS", "_WIN32_WINNT=0x0601" }

+links { "vulkan-1" }

+

+filter { "platforms:Linux-x64" }

+buildoptions { "-std=c++0x" }

+links { "vulkan" }

+

+filter { "configurations:Debug", "platforms:x64" }

+buildoptions { "/MDd" }

+

+filter { "configurations:Release", "platforms:Windows-x64" }

+buildoptions { "/MD" }

diff --git a/src/Common.h b/src/Common.h
index aa8e504..111ccde 100644
--- a/src/Common.h
+++ b/src/Common.h
@@ -5,10 +5,6 @@
 

 #ifdef _WIN32

 

-#define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT

-#include <mathfu/glsl_mappings.h>

-#include <mathfu/constants.h>

-

 #include <iostream>

 #include <fstream>

 #include <vector>

@@ -44,15 +40,159 @@
 template <typename T>

 inline T ceil_div(T x, T y)

 {

-	return (x+y-1) / y;

+    return (x+y-1) / y;

 }

 

 template <typename T>

 static inline T align_up(T val, T align)

 {

-	return (val + align - 1) / align * align;

+    return (val + align - 1) / align * align;

 }

 

+static const float PI = 3.14159265358979323846264338327950288419716939937510582f;

+

+struct vec3

+{

+    float x, y, z;

+

+    vec3() { }

+    vec3(float x, float y, float z) : x(x), y(y), z(z) { }

+

+    float& operator[](uint32_t index) { return *(&x + index); }

+    const float& operator[](uint32_t index) const { return *(&x + index); }

+

+    vec3 operator+(const vec3& rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }

+    vec3 operator-(const vec3& rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }

+    vec3 operator*(float s) const { return vec3(x * s, y * s, z * s); }

+

+    vec3 Normalized() const

+    {

+        return (*this) * (1.f / sqrt(x * x + y * y + z * z));

+    }

+};

+

+inline float Dot(const vec3& lhs, const vec3& rhs)

+{

+    return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;

+}

+inline vec3 Cross(const vec3& lhs, const vec3& rhs)

+{

+    return vec3(

+        lhs.y * rhs.z - lhs.z * rhs.y,

+	    lhs.z * rhs.x - lhs.x * rhs.z,

+	    lhs.x * rhs.y - lhs.y * rhs.x);

+}

+

+struct vec4

+{

+    float x, y, z, w;

+

+    vec4() { }

+    vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }

+    vec4(const vec3& v, float w) : x(v.x), y(v.y), z(v.z), w(w) { }

+

+    float& operator[](uint32_t index) { return *(&x + index); }

+    const float& operator[](uint32_t index) const { return *(&x + index); }

+};

+

+struct mat4

+{

+    union

+    {

+        struct

+        {

+            float _11, _12, _13, _14;

+            float _21, _22, _23, _24;

+            float _31, _32, _33, _34;

+            float _41, _42, _43, _44;

+        };

+        float m[4][4]; // [row][column]

+    };

+

+    mat4() { }

+

+    mat4(

+        float _11, float _12, float _13, float _14,

+        float _21, float _22, float _23, float _24,

+        float _31, float _32, float _33, float _34,

+        float _41, float _42, float _43, float _44) :

+        _11(_11), _12(_12), _13(_13), _14(_14),

+        _21(_21), _22(_22), _23(_23), _24(_24),

+        _31(_31), _32(_32), _33(_33), _34(_34),

+        _41(_41), _42(_42), _43(_43), _44(_44)

+    {

+    }

+

+    mat4(

+        const vec4& row1,

+        const vec4& row2,

+        const vec4& row3,

+        const vec4& row4) :

+        _11(row1.x), _12(row1.y), _13(row1.z), _14(row1.w),

+        _21(row2.x), _22(row2.y), _23(row2.z), _24(row2.w),

+        _31(row3.x), _32(row3.y), _33(row3.z), _34(row3.w),

+        _41(row4.x), _42(row4.y), _43(row4.z), _44(row4.w)

+    {

+    }

+

+    mat4 operator*(const mat4 &rhs) const

+    {

+        return mat4(

+            _11 * rhs._11 + _12 * rhs._21 + _13 * rhs._31 + _14 * rhs._41,

+            _11 * rhs._12 + _12 * rhs._22 + _13 * rhs._32 + _14 * rhs._42,

+            _11 * rhs._13 + _12 * rhs._23 + _13 * rhs._33 + _14 * rhs._43,

+            _11 * rhs._14 + _12 * rhs._24 + _13 * rhs._34 + _14 * rhs._44,

+

+            _21 * rhs._11 + _22 * rhs._21 + _23 * rhs._31 + _24 * rhs._41,

+            _21 * rhs._12 + _22 * rhs._22 + _23 * rhs._32 + _24 * rhs._42,

+            _21 * rhs._13 + _22 * rhs._23 + _23 * rhs._33 + _24 * rhs._43,

+            _21 * rhs._14 + _22 * rhs._24 + _23 * rhs._34 + _24 * rhs._44,

+

+            _31 * rhs._11 + _32 * rhs._21 + _33 * rhs._31 + _34 * rhs._41,

+            _31 * rhs._12 + _32 * rhs._22 + _33 * rhs._32 + _34 * rhs._42,

+            _31 * rhs._13 + _32 * rhs._23 + _33 * rhs._33 + _34 * rhs._43,

+            _31 * rhs._14 + _32 * rhs._24 + _33 * rhs._34 + _34 * rhs._44,

+

+            _41 * rhs._11 + _42 * rhs._21 + _43 * rhs._31 + _44 * rhs._41,

+            _41 * rhs._12 + _42 * rhs._22 + _43 * rhs._32 + _44 * rhs._42,

+            _41 * rhs._13 + _42 * rhs._23 + _43 * rhs._33 + _44 * rhs._43,

+            _41 * rhs._14 + _42 * rhs._24 + _43 * rhs._34 + _44 * rhs._44);

+    }

+

+    static mat4 RotationY(float angle)

+    {

+        const float s = sin(angle), c = cos(angle);

+        return mat4(

+            c,   0.f, -s,  0.f,

+            0.f, 1.f, 0.f, 0.f,

+            s,   0.f, c,   0.f,

+            0.f, 0.f, 0.f, 1.f);

+    }

+

+    static mat4 Perspective(float fovY, float aspectRatio, float zNear, float zFar)

+    {

+        float yScale = 1.0f / tan(fovY * 0.5f);

+        float xScale = yScale / aspectRatio;

+        return mat4(

+            xScale, 0.0f, 0.0f, 0.0f,

+            0.0f, yScale, 0.0f, 0.0f,

+            0.0f, 0.0f, zFar / (zFar - zNear), 1.0f,

+            0.0f, 0.0f, -zNear * zFar / (zFar - zNear), 0.0f);

+    }

+

+    static mat4 LookAt(vec3 at, vec3 eye, vec3 up)

+    {

+        vec3 zAxis = (at - eye).Normalized();

+        vec3 xAxis = Cross(up, zAxis).Normalized();

+        vec3 yAxis = Cross(zAxis, xAxis);

+        return mat4(

+            xAxis.x, yAxis.x, zAxis.x, 0.0f,

+            xAxis.y, yAxis.y, zAxis.y, 0.0f,

+            xAxis.z, yAxis.z, zAxis.z, 0.0f,

+            -Dot(xAxis, eye), -Dot(yAxis, eye), -Dot(zAxis, eye), 1.0f);

+    }

+};

+

 class RandomNumberGenerator

 {

 public:

@@ -66,6 +206,19 @@
     uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }

 };

 

+// Wrapper for RandomNumberGenerator compatible with STL "UniformRandomNumberGenerator" idea.

+struct MyUniformRandomNumberGenerator

+{

+    typedef uint32_t result_type;

+    MyUniformRandomNumberGenerator(RandomNumberGenerator& gen) : m_Gen(gen) { }

+    static uint32_t min() { return 0; }

+    static uint32_t max() { return UINT32_MAX; }

+    uint32_t operator()() { return m_Gen.Generate(); }

+

+private:

+    RandomNumberGenerator& m_Gen;

+};

+

 void ReadFile(std::vector<char>& out, const char* fileName);

 

 enum class CONSOLE_COLOR

diff --git a/src/Tests.cpp b/src/Tests.cpp
index 46b456e..842fba2 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -7,8 +7,26 @@
 

 #ifdef _WIN32

 

+enum CONFIG_TYPE {

+    CONFIG_TYPE_MINIMUM,

+    CONFIG_TYPE_SMALL,

+    CONFIG_TYPE_AVERAGE,

+    CONFIG_TYPE_LARGE,

+    CONFIG_TYPE_MAXIMUM,

+    CONFIG_TYPE_COUNT

+};

+

+static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_SMALL;

+//static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_LARGE;

+

 enum class FREE_ORDER { FORWARD, BACKWARD, RANDOM, COUNT };

 

+static const wchar_t* FREE_ORDER_NAMES[] = {

+    L"FORWARD",

+    L"BACKWARD",

+    L"RANDOM",

+};

+

 struct AllocationSize

 {

     uint32_t Probability;

@@ -101,6 +119,8 @@
 

 static const uint32_t IMAGE_BYTES_PER_PIXEL = 1;

 

+static uint32_t g_FrameIndex = 0;

+

 struct BufferInfo

 {

     VkBuffer Buffer = VK_NULL_HANDLE;

@@ -558,12 +578,12 @@
     return res;

 }

 

-static void SaveAllocatorStatsToFile(VmaAllocator alloc, const wchar_t* filePath)

+static void SaveAllocatorStatsToFile(const wchar_t* filePath)

 {

     char* stats;

-    vmaBuildStatsString(alloc, &stats, VK_TRUE);

+    vmaBuildStatsString(g_hAllocator, &stats, VK_TRUE);

     SaveFile(filePath, stats, strlen(stats));

-    vmaFreeStatsString(alloc, stats);

+    vmaFreeStatsString(g_hAllocator, stats);

 }

 

 struct AllocInfo

@@ -982,7 +1002,7 @@
     for(size_t i = 0; i < allocations.size(); ++i)

         ValidateAllocationData(allocations[i]);

 

-    SaveAllocatorStatsToFile(g_hAllocator, L"Before.csv");

+    SaveAllocatorStatsToFile(L"Before.csv");

 

     {

         std::vector<VmaAllocation> vmaAllocations(allocations.size());

@@ -1033,7 +1053,7 @@
 

             wchar_t fileName[MAX_PATH];

             swprintf(fileName, MAX_PATH, L"After_%02u.csv", defragIndex);

-            SaveAllocatorStatsToFile(g_hAllocator, fileName);

+            SaveAllocatorStatsToFile(fileName);

         }

     }

 

@@ -1322,6 +1342,918 @@
     vmaDestroyAllocator(hAllocator);

 }

 

+#if VMA_DEBUG_MARGIN

+static void TestDebugMargin()

+{

+    if(VMA_DEBUG_MARGIN == 0)

+    {

+        return;

+    }

+

+    VkBufferCreateInfo bufInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+    bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

+    

+    VmaAllocationCreateInfo allocCreateInfo = {};

+    allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;

+

+    // Create few buffers of different size.

+    const size_t BUF_COUNT = 10;

+    BufferInfo buffers[BUF_COUNT];

+    VmaAllocationInfo allocInfo[BUF_COUNT];

+    for(size_t i = 0; i < 10; ++i)

+    {

+        bufInfo.size = (VkDeviceSize)(i + 1) * 64;

+        // Last one will be mapped.

+        allocCreateInfo.flags = (i == BUF_COUNT - 1) ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;

+

+        VkResult res = vmaCreateBuffer(g_hAllocator, &bufInfo, &allocCreateInfo, &buffers[i].Buffer, &buffers[i].Allocation, &allocInfo[i]);

+        assert(res == VK_SUCCESS);

+        // Margin is preserved also at the beginning of a block.

+        assert(allocInfo[i].offset >= VMA_DEBUG_MARGIN);

+

+        if(i == BUF_COUNT - 1)

+        {

+            // Fill with data.

+            assert(allocInfo[i].pMappedData != nullptr);

+            // Uncomment this "+ 1" to overwrite past end of allocation and check corruption detection.

+            memset(allocInfo[i].pMappedData, 0xFF, bufInfo.size /* + 1 */);

+        }

+    }

+

+    // Check if their offsets preserve margin between them.

+    std::sort(allocInfo, allocInfo + BUF_COUNT, [](const VmaAllocationInfo& lhs, const VmaAllocationInfo& rhs) -> bool

+    {

+        if(lhs.deviceMemory != rhs.deviceMemory)

+        {

+            return lhs.deviceMemory < rhs.deviceMemory;

+        }

+        return lhs.offset < rhs.offset;

+    });

+    for(size_t i = 1; i < BUF_COUNT; ++i)

+    {

+        if(allocInfo[i].deviceMemory == allocInfo[i - 1].deviceMemory)

+        {

+            assert(allocInfo[i].offset >= allocInfo[i - 1].offset + VMA_DEBUG_MARGIN);

+        }

+    }

+

+    VkResult res = vmaCheckCorruption(g_hAllocator, UINT32_MAX);

+    assert(res == VK_SUCCESS);

+

+    // Destroy all buffers.

+    for(size_t i = BUF_COUNT; i--; )

+    {

+        vmaDestroyBuffer(g_hAllocator, buffers[i].Buffer, buffers[i].Allocation);

+    }

+}

+#endif

+

+static void TestLinearAllocator()

+{

+    wprintf(L"Test linear allocator\n");

+

+    RandomNumberGenerator rand{645332};

+

+    VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+    sampleBufCreateInfo.size = 1024; // Whatever.

+    sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;

+

+    VmaAllocationCreateInfo sampleAllocCreateInfo = {};

+    sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;

+

+    VmaPoolCreateInfo poolCreateInfo = {};

+    VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &poolCreateInfo.memoryTypeIndex);

+    assert(res == VK_SUCCESS);

+

+    poolCreateInfo.blockSize = 1024 * 300;

+    poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;

+    poolCreateInfo.minBlockCount = poolCreateInfo.maxBlockCount = 1;

+

+    VmaPool pool = nullptr;

+    res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);

+    assert(res == VK_SUCCESS);

+

+    VkBufferCreateInfo bufCreateInfo = sampleBufCreateInfo;

+

+    VmaAllocationCreateInfo allocCreateInfo = {};

+    allocCreateInfo.pool = pool;

+

+    constexpr size_t maxBufCount = 100;

+    std::vector<BufferInfo> bufInfo;

+

+    constexpr VkDeviceSize bufSizeMin = 16;

+    constexpr VkDeviceSize bufSizeMax = 1024;

+    VmaAllocationInfo allocInfo;

+    VkDeviceSize prevOffset = 0;

+

+    // Test one-time free.

+    for(size_t i = 0; i < 2; ++i)

+    {

+        // Allocate number of buffers of varying size that surely fit into this block.

+        VkDeviceSize bufSumSize = 0;

+        for(size_t i = 0; i < maxBufCount; ++i)

+        {

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            assert(i == 0 || allocInfo.offset > prevOffset);

+            bufInfo.push_back(newBufInfo);

+            prevOffset = allocInfo.offset;

+            bufSumSize += bufCreateInfo.size;

+        }

+

+        // Validate pool stats.

+        VmaPoolStats stats;

+        vmaGetPoolStats(g_hAllocator, pool, &stats);

+        assert(stats.size == poolCreateInfo.blockSize);

+        assert(stats.unusedSize = poolCreateInfo.blockSize - bufSumSize);

+        assert(stats.allocationCount == bufInfo.size());

+

+        // Destroy the buffers in random order.

+        while(!bufInfo.empty())

+        {

+            const size_t indexToDestroy = rand.Generate() % bufInfo.size();

+            const BufferInfo& currBufInfo = bufInfo[indexToDestroy];

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.erase(bufInfo.begin() + indexToDestroy);

+        }

+    }

+

+    // Test stack.

+    {

+        // Allocate number of buffers of varying size that surely fit into this block.

+        for(size_t i = 0; i < maxBufCount; ++i)

+        {

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            assert(i == 0 || allocInfo.offset > prevOffset);

+            bufInfo.push_back(newBufInfo);

+            prevOffset = allocInfo.offset;

+        }

+

+        // Destroy few buffers from top of the stack.

+        for(size_t i = 0; i < maxBufCount / 5; ++i)

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+

+        // Create some more

+        for(size_t i = 0; i < maxBufCount / 5; ++i)

+        {

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            assert(i == 0 || allocInfo.offset > prevOffset);

+            bufInfo.push_back(newBufInfo);

+            prevOffset = allocInfo.offset;

+        }

+

+        // Destroy the buffers in reverse order.

+        while(!bufInfo.empty())

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+    }

+

+    // Test ring buffer.

+    {

+        // Allocate number of buffers that surely fit into this block.

+        bufCreateInfo.size = bufSizeMax;

+        for(size_t i = 0; i < maxBufCount; ++i)

+        {

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            assert(i == 0 || allocInfo.offset > prevOffset);

+            bufInfo.push_back(newBufInfo);

+            prevOffset = allocInfo.offset;

+        }

+

+        // Free and allocate new buffers so many times that we make sure we wrap-around at least once.

+        const size_t buffersPerIter = maxBufCount / 10 - 1;

+        const size_t iterCount = poolCreateInfo.blockSize / bufCreateInfo.size / buffersPerIter * 2;

+        for(size_t iter = 0; iter < iterCount; ++iter)

+        {

+            for(size_t bufPerIter = 0; bufPerIter < buffersPerIter; ++bufPerIter)

+            {

+                const BufferInfo& currBufInfo = bufInfo.front();

+                vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+                bufInfo.erase(bufInfo.begin());

+            }

+            for(size_t bufPerIter = 0; bufPerIter < buffersPerIter; ++bufPerIter)

+            {

+                BufferInfo newBufInfo;

+                res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                    &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+                assert(res == VK_SUCCESS);

+                bufInfo.push_back(newBufInfo);

+            }

+        }

+        

+        // Allocate buffers until we reach out-of-memory.

+        uint32_t debugIndex = 0;

+        while(res == VK_SUCCESS)

+        {

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            if(res == VK_SUCCESS)

+            {

+                bufInfo.push_back(newBufInfo);

+            }

+            else

+            {

+                assert(res == VK_ERROR_OUT_OF_DEVICE_MEMORY);

+            }

+            ++debugIndex;

+        }

+

+        // Destroy the buffers in random order.

+        while(!bufInfo.empty())

+        {

+            const size_t indexToDestroy = rand.Generate() % bufInfo.size();

+            const BufferInfo& currBufInfo = bufInfo[indexToDestroy];

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.erase(bufInfo.begin() + indexToDestroy);

+        }

+    }

+

+    // Test double stack.

+    {

+        // Allocate number of buffers of varying size that surely fit into this block, alternate from bottom/top.

+        VkDeviceSize prevOffsetLower = 0;

+        VkDeviceSize prevOffsetUpper = poolCreateInfo.blockSize;

+        for(size_t i = 0; i < maxBufCount; ++i)

+        {

+            const bool upperAddress = (i % 2) != 0;

+            if(upperAddress)

+                allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+            else

+                allocCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            if(upperAddress)

+            {

+                assert(allocInfo.offset < prevOffsetUpper);

+                prevOffsetUpper = allocInfo.offset;

+            }

+            else

+            {

+                assert(allocInfo.offset >= prevOffsetLower);

+                prevOffsetLower = allocInfo.offset;

+            }

+            assert(prevOffsetLower < prevOffsetUpper);

+            bufInfo.push_back(newBufInfo);

+        }

+

+        // Destroy few buffers from top of the stack.

+        for(size_t i = 0; i < maxBufCount / 5; ++i)

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+

+        // Create some more

+        for(size_t i = 0; i < maxBufCount / 5; ++i)

+        {

+            const bool upperAddress = (i % 2) != 0;

+            if(upperAddress)

+                allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+            else

+                allocCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            bufInfo.push_back(newBufInfo);

+        }

+

+        // Destroy the buffers in reverse order.

+        while(!bufInfo.empty())

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+

+        // Create buffers on both sides until we reach out of memory.

+        prevOffsetLower = 0;

+        prevOffsetUpper = poolCreateInfo.blockSize;

+        res = VK_SUCCESS;

+        for(size_t i = 0; res == VK_SUCCESS; ++i)

+        {

+            const bool upperAddress = (i % 2) != 0;

+            if(upperAddress)

+                allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+            else

+                allocCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            if(res == VK_SUCCESS)

+            {

+                if(upperAddress)

+                {

+                    assert(allocInfo.offset < prevOffsetUpper);

+                    prevOffsetUpper = allocInfo.offset;

+                }

+                else

+                {

+                    assert(allocInfo.offset >= prevOffsetLower);

+                    prevOffsetLower = allocInfo.offset;

+                }

+                assert(prevOffsetLower < prevOffsetUpper);

+                bufInfo.push_back(newBufInfo);

+            }

+        }

+

+        // Destroy the buffers in random order.

+        while(!bufInfo.empty())

+        {

+            const size_t indexToDestroy = rand.Generate() % bufInfo.size();

+            const BufferInfo& currBufInfo = bufInfo[indexToDestroy];

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.erase(bufInfo.begin() + indexToDestroy);

+        }

+

+        // Create buffers on upper side only, constant size, until we reach out of memory.

+        prevOffsetUpper = poolCreateInfo.blockSize;

+        res = VK_SUCCESS;

+        allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+        bufCreateInfo.size = bufSizeMax;

+        for(size_t i = 0; res == VK_SUCCESS; ++i)

+        {

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            if(res == VK_SUCCESS)

+            {

+                assert(allocInfo.offset < prevOffsetUpper);

+                prevOffsetUpper = allocInfo.offset;

+                bufInfo.push_back(newBufInfo);

+            }

+        }

+

+        // Destroy the buffers in reverse order.

+        while(!bufInfo.empty())

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+    }

+

+    // Test ring buffer with lost allocations.

+    {

+        // Allocate number of buffers until pool is full.

+        // Notice CAN_BECOME_LOST flag and call to vmaSetCurrentFrameIndex.

+        allocCreateInfo.flags = VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT;

+        res = VK_SUCCESS;

+        for(size_t i = 0; res == VK_SUCCESS; ++i)

+        {

+            vmaSetCurrentFrameIndex(g_hAllocator, ++g_FrameIndex);

+

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            if(res == VK_SUCCESS)

+                bufInfo.push_back(newBufInfo);

+        }

+

+        // Free first half of it.

+        {

+            const size_t buffersToDelete = bufInfo.size() / 2;

+            for(size_t i = 0; i < buffersToDelete; ++i)

+            {

+                vmaDestroyBuffer(g_hAllocator, bufInfo[i].Buffer, bufInfo[i].Allocation);

+            }

+            bufInfo.erase(bufInfo.begin(), bufInfo.begin() + buffersToDelete);

+        }

+

+        // Allocate number of buffers until pool is full again.

+        // This way we make sure ring buffers wraps around, front in in the middle.

+        res = VK_SUCCESS;

+        for(size_t i = 0; res == VK_SUCCESS; ++i)

+        {

+            vmaSetCurrentFrameIndex(g_hAllocator, ++g_FrameIndex);

+

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            if(res == VK_SUCCESS)

+                bufInfo.push_back(newBufInfo);

+        }

+

+        VkDeviceSize firstNewOffset;

+        {

+            vmaSetCurrentFrameIndex(g_hAllocator, ++g_FrameIndex);

+

+            // Allocate a large buffer with CAN_MAKE_OTHER_LOST.

+            allocCreateInfo.flags = VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT;

+            bufCreateInfo.size = bufSizeMax;

+

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            bufInfo.push_back(newBufInfo);

+            firstNewOffset = allocInfo.offset;

+

+            // Make sure at least one buffer from the beginning became lost.

+            vmaGetAllocationInfo(g_hAllocator, bufInfo[0].Allocation, &allocInfo);

+            assert(allocInfo.deviceMemory == VK_NULL_HANDLE);

+        }

+

+        // Allocate more buffers that CAN_MAKE_OTHER_LOST until we wrap-around with this.

+        size_t newCount = 1;

+        for(;;)

+        {

+            vmaSetCurrentFrameIndex(g_hAllocator, ++g_FrameIndex);

+

+            bufCreateInfo.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            bufInfo.push_back(newBufInfo);

+            ++newCount;

+            if(allocInfo.offset < firstNewOffset)

+                break;

+        }

+

+        // Delete buffers that are lost.

+        for(size_t i = bufInfo.size(); i--; )

+        {

+            vmaGetAllocationInfo(g_hAllocator, bufInfo[i].Allocation, &allocInfo);

+            if(allocInfo.deviceMemory == VK_NULL_HANDLE)

+            {

+                vmaDestroyBuffer(g_hAllocator, bufInfo[i].Buffer, bufInfo[i].Allocation);

+                bufInfo.erase(bufInfo.begin() + i);

+            }

+        }

+

+        // Test vmaMakePoolAllocationsLost

+        {

+            vmaSetCurrentFrameIndex(g_hAllocator, ++g_FrameIndex);

+

+            size_t lostAllocCount = SIZE_MAX;

+            vmaMakePoolAllocationsLost(g_hAllocator, pool, &lostAllocCount);

+            assert(lostAllocCount > 0);

+

+            size_t realLostAllocCount = 0;

+            for(size_t i = 0; i < bufInfo.size(); ++i)

+            {

+                vmaGetAllocationInfo(g_hAllocator, bufInfo[i].Allocation, &allocInfo);

+                if(allocInfo.deviceMemory == VK_NULL_HANDLE)

+                    ++realLostAllocCount;

+            }

+            assert(realLostAllocCount == lostAllocCount);

+        }

+

+        // Destroy all the buffers in forward order.

+        for(size_t i = 0; i < bufInfo.size(); ++i)

+            vmaDestroyBuffer(g_hAllocator, bufInfo[i].Buffer, bufInfo[i].Allocation);

+        bufInfo.clear();

+    }

+

+    vmaDestroyPool(g_hAllocator, pool);

+}

+

+static void TestLinearAllocatorMultiBlock()

+{

+    wprintf(L"Test linear allocator multi block\n");

+

+    RandomNumberGenerator rand{345673};

+

+    VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+    sampleBufCreateInfo.size = 1024 * 1024;

+    sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

+

+    VmaAllocationCreateInfo sampleAllocCreateInfo = {};

+    sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;

+

+    VmaPoolCreateInfo poolCreateInfo = {};

+    poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;

+    VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &poolCreateInfo.memoryTypeIndex);

+    assert(res == VK_SUCCESS);

+

+    VmaPool pool = nullptr;

+    res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);

+    assert(res == VK_SUCCESS);

+

+    VkBufferCreateInfo bufCreateInfo = sampleBufCreateInfo;

+

+    VmaAllocationCreateInfo allocCreateInfo = {};

+    allocCreateInfo.pool = pool;

+    

+    std::vector<BufferInfo> bufInfo;

+    VmaAllocationInfo allocInfo;

+

+    // Test one-time free.

+    {

+        // Allocate buffers until we move to a second block.

+        VkDeviceMemory lastMem = VK_NULL_HANDLE;

+        for(uint32_t i = 0; ; ++i)

+        {

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            bufInfo.push_back(newBufInfo);

+            if(lastMem && allocInfo.deviceMemory != lastMem)

+            {

+                break;

+            }

+            lastMem = allocInfo.deviceMemory;

+        }

+

+        assert(bufInfo.size() > 2);

+

+        // Make sure that pool has now two blocks.

+        VmaPoolStats poolStats = {};

+        vmaGetPoolStats(g_hAllocator, pool, &poolStats);

+        assert(poolStats.blockCount == 2);

+

+        // Destroy all the buffers in random order.

+        while(!bufInfo.empty())

+        {

+            const size_t indexToDestroy = rand.Generate() % bufInfo.size();

+            const BufferInfo& currBufInfo = bufInfo[indexToDestroy];

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.erase(bufInfo.begin() + indexToDestroy);

+        }

+

+        // Make sure that pool has now at most one block.

+        vmaGetPoolStats(g_hAllocator, pool, &poolStats);

+        assert(poolStats.blockCount <= 1);

+    }

+

+    // Test stack.

+    {

+        // Allocate buffers until we move to a second block.

+        VkDeviceMemory lastMem = VK_NULL_HANDLE;

+        for(uint32_t i = 0; ; ++i)

+        {

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            bufInfo.push_back(newBufInfo);

+            if(lastMem && allocInfo.deviceMemory != lastMem)

+            {

+                break;

+            }

+            lastMem = allocInfo.deviceMemory;

+        }

+

+        assert(bufInfo.size() > 2);

+

+        // Add few more buffers.

+        for(uint32_t i = 0; i < 5; ++i)

+        {

+            BufferInfo newBufInfo;

+            res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+                &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+            assert(res == VK_SUCCESS);

+            bufInfo.push_back(newBufInfo);

+        }

+

+        // Make sure that pool has now two blocks.

+        VmaPoolStats poolStats = {};

+        vmaGetPoolStats(g_hAllocator, pool, &poolStats);

+        assert(poolStats.blockCount == 2);

+        

+        // Delete half of buffers, LIFO.

+        for(size_t i = 0, countToDelete = bufInfo.size() / 2; i < countToDelete; ++i)

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+

+        // Add one more buffer.

+        BufferInfo newBufInfo;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        // Make sure that pool has now one block.

+        vmaGetPoolStats(g_hAllocator, pool, &poolStats);

+        assert(poolStats.blockCount == 1);

+

+        // Delete all the remaining buffers, LIFO.

+        while(!bufInfo.empty())

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+    }

+

+    vmaDestroyPool(g_hAllocator, pool);

+}

+

+static void ManuallyTestLinearAllocator()

+{

+    VmaStats origStats;

+    vmaCalculateStats(g_hAllocator, &origStats);

+

+    wprintf(L"Manually test linear allocator\n");

+

+    RandomNumberGenerator rand{645332};

+

+    VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+    sampleBufCreateInfo.size = 1024; // Whatever.

+    sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;

+

+    VmaAllocationCreateInfo sampleAllocCreateInfo = {};

+    sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;

+

+    VmaPoolCreateInfo poolCreateInfo = {};

+    VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &poolCreateInfo.memoryTypeIndex);

+    assert(res == VK_SUCCESS);

+

+    poolCreateInfo.blockSize = 10 * 1024;

+    poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;

+    poolCreateInfo.minBlockCount = poolCreateInfo.maxBlockCount = 1;

+

+    VmaPool pool = nullptr;

+    res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);

+    assert(res == VK_SUCCESS);

+

+    VkBufferCreateInfo bufCreateInfo = sampleBufCreateInfo;

+

+    VmaAllocationCreateInfo allocCreateInfo = {};

+    allocCreateInfo.pool = pool;

+

+    std::vector<BufferInfo> bufInfo;

+    VmaAllocationInfo allocInfo;

+    BufferInfo newBufInfo;

+

+    // Test double stack.

+    {

+        /*

+        Lower: Buffer 32 B, Buffer 1024 B, Buffer 32 B

+        Upper: Buffer 16 B, Buffer 1024 B, Buffer 128 B

+

+        Totally:

+        1 block allocated

+        10240 Vulkan bytes

+        6 new allocations

+        2256 bytes in allocations

+        */

+

+        bufCreateInfo.size = 32;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 1024;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 32;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT;

+

+        bufCreateInfo.size = 128;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 1024;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        bufCreateInfo.size = 16;

+        res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,

+            &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo);

+        assert(res == VK_SUCCESS);

+        bufInfo.push_back(newBufInfo);

+

+        VmaStats currStats;

+        vmaCalculateStats(g_hAllocator, &currStats);

+        VmaPoolStats poolStats;

+        vmaGetPoolStats(g_hAllocator, pool, &poolStats);

+

+        char* statsStr = nullptr;

+        vmaBuildStatsString(g_hAllocator, &statsStr, VK_TRUE);

+

+        // PUT BREAKPOINT HERE TO CHECK.

+        // Inspect: currStats versus origStats, poolStats, statsStr.

+        int I = 0;

+

+        vmaFreeStatsString(g_hAllocator, statsStr);

+

+        // Destroy the buffers in reverse order.

+        while(!bufInfo.empty())

+        {

+            const BufferInfo& currBufInfo = bufInfo.back();

+            vmaDestroyBuffer(g_hAllocator, currBufInfo.Buffer, currBufInfo.Allocation);

+            bufInfo.pop_back();

+        }

+    }

+

+    vmaDestroyPool(g_hAllocator, pool);

+}

+

+static void BenchmarkLinearAllocatorCase(bool linear, bool empty, FREE_ORDER freeOrder)

+{

+    RandomNumberGenerator rand{16223};

+

+    const VkDeviceSize bufSizeMin = 32;

+    const VkDeviceSize bufSizeMax = 1024;

+    const size_t maxBufCapacity = 10000;

+    const uint32_t iterationCount = 10;

+

+    VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+    sampleBufCreateInfo.size = bufSizeMax;

+    sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;

+

+    VmaAllocationCreateInfo sampleAllocCreateInfo = {};

+    sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;

+

+    VmaPoolCreateInfo poolCreateInfo = {};

+    VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &poolCreateInfo.memoryTypeIndex);

+    assert(res == VK_SUCCESS);

+

+    poolCreateInfo.blockSize = bufSizeMax * maxBufCapacity;

+    if(linear)

+        poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;

+    poolCreateInfo.minBlockCount = poolCreateInfo.maxBlockCount = 1;

+

+    VmaPool pool = nullptr;

+    res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);

+    assert(res == VK_SUCCESS);

+

+    // Buffer created just to get memory requirements. Never bound to any memory.

+    VkBuffer dummyBuffer = VK_NULL_HANDLE;

+    res = vkCreateBuffer(g_hDevice, &sampleBufCreateInfo, nullptr, &dummyBuffer);

+    assert(res == VK_SUCCESS && dummyBuffer);

+

+    VkMemoryRequirements memReq = {};

+    vkGetBufferMemoryRequirements(g_hDevice, dummyBuffer, &memReq);

+

+    vkDestroyBuffer(g_hDevice, dummyBuffer, nullptr);

+

+    VmaAllocationCreateInfo allocCreateInfo = {};

+    allocCreateInfo.pool = pool;

+

+    VmaAllocation alloc;

+    std::vector<VmaAllocation> baseAllocations;

+

+    if(!empty)

+    {

+        // Make allocations up to half of pool size.

+        VkDeviceSize totalSize = 0;

+        while(totalSize < poolCreateInfo.blockSize / 2)

+        {

+            memReq.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            res = vmaAllocateMemory(g_hAllocator, &memReq, &allocCreateInfo, &alloc, nullptr);

+            assert(res == VK_SUCCESS);

+            baseAllocations.push_back(alloc);

+            totalSize += memReq.size;

+        }

+

+        // Delete half of them, choose randomly.

+        size_t allocsToDelete = baseAllocations.size() / 2;

+        for(size_t i = 0; i < allocsToDelete; ++i)

+        {

+            const size_t index = (size_t)rand.Generate() % baseAllocations.size();

+            vmaFreeMemory(g_hAllocator, baseAllocations[index]);

+            baseAllocations.erase(baseAllocations.begin() + index);

+        }

+    }

+

+    // BENCHMARK

+    const size_t allocCount = maxBufCapacity / 2;

+    std::vector<VmaAllocation> testAllocations;

+    testAllocations.reserve(allocCount);

+    duration allocTotalDuration = duration::zero();

+    duration freeTotalDuration = duration::zero();

+    for(uint32_t iterationIndex = 0; iterationIndex < iterationCount; ++iterationIndex)

+    {

+        // Allocations

+        time_point allocTimeBeg = std::chrono::high_resolution_clock::now();

+        for(size_t i = 0; i < allocCount; ++i)

+        {

+            memReq.size = bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin);

+            res = vmaAllocateMemory(g_hAllocator, &memReq, &allocCreateInfo, &alloc, nullptr);

+            assert(res == VK_SUCCESS);

+            testAllocations.push_back(alloc);

+        }

+        allocTotalDuration += std::chrono::high_resolution_clock::now() - allocTimeBeg;

+

+        // Deallocations

+        switch(freeOrder)

+        {

+        case FREE_ORDER::FORWARD:

+            // Leave testAllocations unchanged.

+            break;

+        case FREE_ORDER::BACKWARD:

+            std::reverse(testAllocations.begin(), testAllocations.end());

+            break;

+        case FREE_ORDER::RANDOM:

+            std::shuffle(testAllocations.begin(), testAllocations.end(), MyUniformRandomNumberGenerator(rand));

+            break;

+        default: assert(0);

+        }

+

+        time_point freeTimeBeg = std::chrono::high_resolution_clock::now();

+        for(size_t i = 0; i < allocCount; ++i)

+            vmaFreeMemory(g_hAllocator, testAllocations[i]);

+        freeTotalDuration += std::chrono::high_resolution_clock::now() - freeTimeBeg;

+

+        testAllocations.clear();

+    }

+

+    // Delete baseAllocations

+    while(!baseAllocations.empty())

+    {

+        vmaFreeMemory(g_hAllocator, baseAllocations.back());

+        baseAllocations.pop_back();

+    }

+

+    vmaDestroyPool(g_hAllocator, pool);

+

+    wprintf(L"    LinearAlgorithm=%u %s FreeOrder=%s: allocations %g s, free %g s\n",

+        linear ? 1 : 0,

+        empty ? L"Empty" : L"Not empty",

+        FREE_ORDER_NAMES[(size_t)freeOrder],

+        ToFloatSeconds(allocTotalDuration),

+        ToFloatSeconds(freeTotalDuration));

+}

+

+static void BenchmarkLinearAllocator()

+{

+    wprintf(L"Benchmark linear allocator\n");

+

+    uint32_t freeOrderCount = 1;

+    if(ConfigType >= CONFIG_TYPE::CONFIG_TYPE_LARGE)

+        freeOrderCount = 3;

+    else if(ConfigType >= CONFIG_TYPE::CONFIG_TYPE_SMALL)

+        freeOrderCount = 2;

+

+    const uint32_t emptyCount = ConfigType >= CONFIG_TYPE::CONFIG_TYPE_SMALL ? 2 : 1;

+

+    for(uint32_t freeOrderIndex = 0; freeOrderIndex < freeOrderCount; ++freeOrderIndex)

+    {

+        FREE_ORDER freeOrder = FREE_ORDER::COUNT;

+        switch(freeOrderIndex)

+        {

+        case 0: freeOrder = FREE_ORDER::BACKWARD; break;

+        case 1: freeOrder = FREE_ORDER::FORWARD; break;

+        case 2: freeOrder = FREE_ORDER::RANDOM; break;

+        default: assert(0);

+        }

+

+        for(uint32_t emptyIndex = 0; emptyIndex < emptyCount; ++emptyIndex)

+        {

+            for(uint32_t linearIndex = 0; linearIndex < 2; ++linearIndex)

+            {

+                BenchmarkLinearAllocatorCase(

+                    linearIndex ? 1 : 0, // linear

+                    emptyIndex ? 0 : 1, // empty

+                    freeOrder); // freeOrder

+            }

+        }

+    }

+}

+

 static void TestPool_SameSize()

 {

     const VkDeviceSize BUF_SIZE = 1024 * 1024;

@@ -1585,9 +2517,118 @@
 

     items.clear();

 

+    ////////////////////////////////////////////////////////////////////////////////

+    // Test for allocation too large for pool

+

+    {

+        VmaAllocationCreateInfo allocCreateInfo = {};

+        allocCreateInfo.pool = pool;

+

+        VkMemoryRequirements memReq;

+        memReq.memoryTypeBits = UINT32_MAX;

+        memReq.alignment = 1;

+        memReq.size = poolCreateInfo.blockSize + 4;

+        

+        VmaAllocation alloc = nullptr;

+        res = vmaAllocateMemory(g_hAllocator, &memReq, &allocCreateInfo, &alloc, nullptr);

+        assert(res == VK_ERROR_OUT_OF_DEVICE_MEMORY && alloc == nullptr);

+    }

+

     vmaDestroyPool(g_hAllocator, pool);

 }

 

+static bool ValidatePattern(const void* pMemory, size_t size, uint8_t pattern)

+{

+    const uint8_t* pBytes = (const uint8_t*)pMemory;

+    for(size_t i = 0; i < size; ++i)

+    {

+        if(pBytes[i] != pattern)

+        {

+            return false;

+        }

+    }

+    return true;

+}

+

+static void TestAllocationsInitialization()

+{

+    VkResult res;

+

+    const size_t BUF_SIZE = 1024;

+

+    // Create pool.

+

+    VkBufferCreateInfo bufInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+    bufInfo.size = BUF_SIZE;

+    bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

+

+    VmaAllocationCreateInfo dummyBufAllocCreateInfo = {};

+    dummyBufAllocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;

+

+    VmaPoolCreateInfo poolCreateInfo = {};

+    poolCreateInfo.blockSize = BUF_SIZE * 10;

+    poolCreateInfo.minBlockCount = 1; // To keep memory alive while pool exists.

+    poolCreateInfo.maxBlockCount = 1;

+    res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &bufInfo, &dummyBufAllocCreateInfo, &poolCreateInfo.memoryTypeIndex);

+    assert(res == VK_SUCCESS);

+

+    VmaAllocationCreateInfo bufAllocCreateInfo = {};

+    res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &bufAllocCreateInfo.pool);

+    assert(res == VK_SUCCESS);

+

+    // Create one persistently mapped buffer to keep memory of this block mapped,

+    // so that pointer to mapped data will remain (more or less...) valid even

+    // after destruction of other allocations.

+    

+    bufAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;

+    VkBuffer firstBuf;

+    VmaAllocation firstAlloc;

+    res = vmaCreateBuffer(g_hAllocator, &bufInfo, &bufAllocCreateInfo, &firstBuf, &firstAlloc, nullptr);

+    assert(res == VK_SUCCESS);

+

+    // Test buffers.

+

+    for(uint32_t i = 0; i < 2; ++i)

+    {

+        const bool persistentlyMapped = i == 0;

+        bufAllocCreateInfo.flags = persistentlyMapped ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0;

+        VkBuffer buf;

+        VmaAllocation alloc;

+        VmaAllocationInfo allocInfo;

+        res = vmaCreateBuffer(g_hAllocator, &bufInfo, &bufAllocCreateInfo, &buf, &alloc, &allocInfo);

+        assert(res == VK_SUCCESS);

+

+        void* pMappedData;

+        if(!persistentlyMapped)

+        {

+            res = vmaMapMemory(g_hAllocator, alloc, &pMappedData);

+            assert(res == VK_SUCCESS);

+        }

+        else

+        {

+            pMappedData = allocInfo.pMappedData;

+        }

+

+        // Validate initialized content

+        bool valid = ValidatePattern(pMappedData, BUF_SIZE, 0xDC);

+        assert(valid);

+

+        if(!persistentlyMapped)

+        {

+            vmaUnmapMemory(g_hAllocator, alloc);

+        }

+

+        vmaDestroyBuffer(g_hAllocator, buf, alloc);

+

+        // Validate freed content

+        valid = ValidatePattern(pMappedData, BUF_SIZE, 0xEF);

+        assert(valid);

+    }

+

+    vmaDestroyBuffer(g_hAllocator, firstBuf, firstAlloc);

+    vmaDestroyPool(g_hAllocator, bufAllocCreateInfo.pool);

+}

+

 static void TestPool_Benchmark(

     PoolTestResult& outResult,

     const PoolTestConfig& config)

@@ -2459,17 +3500,6 @@
     WritePoolTestResult(file, "Code desc", "Test desc", config, result);

 }

 

-enum CONFIG_TYPE {

-    CONFIG_TYPE_MINIMUM,

-    CONFIG_TYPE_SMALL,

-    CONFIG_TYPE_AVERAGE,

-    CONFIG_TYPE_LARGE,

-    CONFIG_TYPE_MAXIMUM,

-    CONFIG_TYPE_COUNT

-};

-

-static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_SMALL;

-//static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_LARGE;

 static const char* CODE_DESCRIPTION = "Foo";

 

 static void PerformMainTests(FILE* file)

@@ -2936,13 +3966,34 @@
 {

     wprintf(L"TESTING:\n");

 

+    if(false)

+    {

+        // # Temporarily insert custom tests here

+TestLinearAllocator();

+ManuallyTestLinearAllocator();

+TestLinearAllocatorMultiBlock();

+BenchmarkLinearAllocator();

+        return;

+    }

+

     // # Simple tests

 

     TestBasics();

+#if VMA_DEBUG_MARGIN

+    TestDebugMargin();

+#else

     TestPool_SameSize();

     TestHeapSizeLimit();

+#endif

+#if VMA_DEBUG_INITIALIZE_ALLOCATIONS

+    TestAllocationsInitialization();

+#endif

     TestMapping();

     TestMappingMultithreaded();

+    TestLinearAllocator();

+    ManuallyTestLinearAllocator();

+    TestLinearAllocatorMultiBlock();

+    BenchmarkLinearAllocator();

     TestDefragmentationSimple();

     TestDefragmentationFull();

 

diff --git a/src/VmaReplay/Common.cpp b/src/VmaReplay/Common.cpp
new file mode 100644
index 0000000..c324245
--- /dev/null
+++ b/src/VmaReplay/Common.cpp
@@ -0,0 +1,670 @@
+#include "Common.h"

+

+////////////////////////////////////////////////////////////////////////////////

+// LineSplit class

+

+bool LineSplit::GetNextLine(StrRange& out)

+{

+    if(m_NextLineBeg < m_NumBytes)

+    {

+        out.beg = m_Data + m_NextLineBeg;

+        size_t currLineEnd = m_NextLineBeg;

+        while(currLineEnd < m_NumBytes && m_Data[currLineEnd] != '\n')

+            ++currLineEnd;

+        out.end = m_Data + currLineEnd;

+        m_NextLineBeg = currLineEnd + 1; // Past '\n'

+        ++m_NextLineIndex;

+        return true;

+    }

+    else

+        return false;

+}

+

+////////////////////////////////////////////////////////////////////////////////

+// CsvSplit class

+

+void CsvSplit::Set(const StrRange& line, size_t maxCount)

+{

+    assert(maxCount <= RANGE_COUNT_MAX);

+    m_Line = line;

+    const size_t strLen = line.length();

+    size_t rangeIndex = 0;

+    size_t charIndex = 0;

+    while(charIndex < strLen && rangeIndex < maxCount)

+    {

+        m_Ranges[rangeIndex * 2] = charIndex;

+        while(charIndex < strLen && (rangeIndex + 1 == maxCount || m_Line.beg[charIndex] != ','))

+            ++charIndex;

+        m_Ranges[rangeIndex * 2 + 1] = charIndex;

+        ++rangeIndex;

+        ++charIndex; // Past ','

+    }

+    m_Count = rangeIndex;

+}

+

+////////////////////////////////////////////////////////////////////////////////

+// class CmdLineParser

+

+bool CmdLineParser::ReadNextArg(std::string *OutArg)

+{

+	if (m_argv != NULL)

+	{

+		if (m_ArgIndex >= (size_t)m_argc) return false;

+

+		*OutArg = m_argv[m_ArgIndex];

+		m_ArgIndex++;

+		return true;

+	}

+	else

+	{

+		if (m_ArgIndex >= m_CmdLineLength) return false;

+		

+		OutArg->clear();

+		bool InsideQuotes = false;

+		while (m_ArgIndex < m_CmdLineLength)

+		{

+			char Ch = m_CmdLine[m_ArgIndex];

+			if (Ch == '\\')

+			{

+				bool FollowedByQuote = false;

+				size_t BackslashCount = 1;

+				size_t TmpIndex = m_ArgIndex + 1;

+				while (TmpIndex < m_CmdLineLength)

+				{

+					char TmpCh = m_CmdLine[TmpIndex];

+					if (TmpCh == '\\')

+					{

+						BackslashCount++;

+						TmpIndex++;

+					}

+					else if (TmpCh == '"')

+					{

+						FollowedByQuote = true;

+						break;

+					}

+					else

+						break;

+				}

+

+				if (FollowedByQuote)

+				{

+					if (BackslashCount % 2 == 0)

+					{

+						for (size_t i = 0; i < BackslashCount / 2; i++)

+							*OutArg += '\\';

+						m_ArgIndex += BackslashCount + 1;

+						InsideQuotes = !InsideQuotes;

+					}

+					else

+					{

+						for (size_t i = 0; i < BackslashCount / 2; i++)

+							*OutArg += '\\';

+						*OutArg += '"';

+						m_ArgIndex += BackslashCount + 1;

+					}

+				}

+				else

+				{

+					for (size_t i = 0; i < BackslashCount; i++)

+						*OutArg += '\\';

+					m_ArgIndex += BackslashCount;

+				}

+			}

+			else if (Ch == '"')

+			{

+				InsideQuotes = !InsideQuotes;

+				m_ArgIndex++;

+			}

+			else if (isspace(Ch))

+			{

+				if (InsideQuotes)

+				{

+					*OutArg += Ch;

+					m_ArgIndex++;

+				}

+				else

+				{

+					m_ArgIndex++;

+					break;

+				}

+			}

+			else

+			{

+				*OutArg += Ch;

+				m_ArgIndex++;

+			}

+		}

+

+		while (m_ArgIndex < m_CmdLineLength && isspace(m_CmdLine[m_ArgIndex]))

+			m_ArgIndex++;

+

+		return true;

+	}

+}

+

+CmdLineParser::SHORT_OPT * CmdLineParser::FindShortOpt(char Opt)

+{

+	for (size_t i = 0; i < m_ShortOpts.size(); i++)

+		if (m_ShortOpts[i].Opt == Opt)

+			return &m_ShortOpts[i];

+	return NULL;

+}

+

+CmdLineParser::LONG_OPT * CmdLineParser::FindLongOpt(const std::string &Opt)

+{

+	for (size_t i = 0; i < m_LongOpts.size(); i++)

+		if (m_LongOpts[i].Opt == Opt)

+			return &m_LongOpts[i];

+	return NULL;

+}

+

+CmdLineParser::CmdLineParser(int argc, char **argv) :

+	m_argv(argv),

+	m_CmdLine(NULL),

+	m_argc(argc),

+	m_CmdLineLength(0),

+	m_ArgIndex(1),

+	m_InsideMultioption(false),

+	m_LastArgIndex(0),

+	m_LastOptId(0)

+{

+	assert(argc > 0);

+	assert(argv != NULL);

+}

+

+CmdLineParser::CmdLineParser(const char *CmdLine) :

+	m_argv(NULL),

+	m_CmdLine(CmdLine),

+	m_argc(0),

+	m_ArgIndex(0),

+	m_InsideMultioption(false),

+	m_LastArgIndex(0),

+	m_LastOptId(0)

+{

+	assert(CmdLine != NULL);

+

+	m_CmdLineLength = strlen(m_CmdLine);

+

+	while (m_ArgIndex < m_CmdLineLength && isspace(m_CmdLine[m_ArgIndex]))

+		m_ArgIndex++;

+}

+

+void CmdLineParser::RegisterOpt(uint32_t Id, char Opt, bool Parameter)

+{

+	assert(Opt != '\0');

+

+	m_ShortOpts.push_back(SHORT_OPT(Id, Opt, Parameter));

+}

+

+void CmdLineParser::RegisterOpt(uint32_t Id, const std::string &Opt, bool Parameter)

+{

+	assert(!Opt.empty());

+	

+	m_LongOpts.push_back(LONG_OPT(Id, Opt, Parameter));

+}

+

+CmdLineParser::RESULT CmdLineParser::ReadNext()

+{

+	if (m_InsideMultioption)

+	{

+		assert(m_LastArgIndex < m_LastArg.length());

+		SHORT_OPT *so = FindShortOpt(m_LastArg[m_LastArgIndex]);

+		if (so == NULL)

+		{

+			m_LastOptId = 0;

+			m_LastParameter.clear();

+			return CmdLineParser::RESULT_ERROR;

+		}

+		if (so->Parameter)

+		{

+			if (m_LastArg.length() == m_LastArgIndex+1)

+			{

+				if (!ReadNextArg(&m_LastParameter))

+				{

+					m_LastOptId = 0;

+					m_LastParameter.clear();

+					return CmdLineParser::RESULT_ERROR;

+				}

+				m_InsideMultioption = false;

+				m_LastOptId = so->Id;

+				return CmdLineParser::RESULT_OPT;

+			}

+			else if (m_LastArg[m_LastArgIndex+1] == '=')

+			{

+				m_InsideMultioption = false;

+				m_LastParameter = m_LastArg.substr(m_LastArgIndex+2);

+				m_LastOptId = so->Id;

+				return CmdLineParser::RESULT_OPT;

+			}

+			else

+			{

+				m_InsideMultioption = false;

+				m_LastParameter = m_LastArg.substr(m_LastArgIndex+1);

+				m_LastOptId = so->Id;

+				return CmdLineParser::RESULT_OPT;

+			}

+		}

+		else

+		{

+			if (m_LastArg.length() == m_LastArgIndex+1)

+			{

+				m_InsideMultioption = false;

+				m_LastParameter.clear();

+				m_LastOptId = so->Id;

+				return CmdLineParser::RESULT_OPT;

+			}

+			else

+			{

+				m_LastArgIndex++;

+

+				m_LastParameter.clear();

+				m_LastOptId = so->Id;

+				return CmdLineParser::RESULT_OPT;

+			}

+		}

+	}

+	else

+	{

+		if (!ReadNextArg(&m_LastArg))

+		{

+			m_LastParameter.clear();

+			m_LastOptId = 0;

+			return CmdLineParser::RESULT_END;

+		}

+		

+		if (!m_LastArg.empty() && m_LastArg[0] == '-')

+		{

+			if (m_LastArg.length() > 1 && m_LastArg[1] == '-')

+			{

+				size_t EqualIndex = m_LastArg.find('=', 2);

+				if (EqualIndex != std::string::npos)

+				{

+					LONG_OPT *lo = FindLongOpt(m_LastArg.substr(2, EqualIndex-2));

+					if (lo == NULL || lo->Parameter == false)

+					{

+						m_LastOptId = 0;

+						m_LastParameter.clear();

+						return CmdLineParser::RESULT_ERROR;

+					}

+					m_LastParameter = m_LastArg.substr(EqualIndex+1);

+					m_LastOptId = lo->Id;

+					return CmdLineParser::RESULT_OPT;

+				}

+				else

+				{

+					LONG_OPT *lo = FindLongOpt(m_LastArg.substr(2));

+					if (lo == NULL)

+					{

+						m_LastOptId = 0;

+						m_LastParameter.clear();

+						return CmdLineParser::RESULT_ERROR;

+					}

+					if (lo->Parameter)

+					{

+						if (!ReadNextArg(&m_LastParameter))

+						{

+							m_LastOptId = 0;

+							m_LastParameter.clear();

+							return CmdLineParser::RESULT_ERROR;

+						}

+					}

+					else

+						m_LastParameter.clear();

+					m_LastOptId = lo->Id;

+					return CmdLineParser::RESULT_OPT;

+				}

+			}

+			else

+			{

+				if (m_LastArg.length() < 2)

+				{

+					m_LastOptId = 0;

+					m_LastParameter.clear();

+					return CmdLineParser::RESULT_ERROR;

+				}

+				SHORT_OPT *so = FindShortOpt(m_LastArg[1]);

+				if (so == NULL)

+				{

+					m_LastOptId = 0;

+					m_LastParameter.clear();

+					return CmdLineParser::RESULT_ERROR;

+				}

+				if (so->Parameter)

+				{

+					if (m_LastArg.length() == 2)

+					{

+						if (!ReadNextArg(&m_LastParameter))

+						{

+							m_LastOptId = 0;

+							m_LastParameter.clear();

+							return CmdLineParser::RESULT_ERROR;

+						}

+						m_LastOptId = so->Id;

+						return CmdLineParser::RESULT_OPT;

+					}

+					else if (m_LastArg[2] == '=')

+					{

+						m_LastParameter = m_LastArg.substr(3);

+						m_LastOptId = so->Id;

+						return CmdLineParser::RESULT_OPT;

+					}

+					else

+					{

+						m_LastParameter = m_LastArg.substr(2);

+						m_LastOptId = so->Id;

+						return CmdLineParser::RESULT_OPT;

+					}

+				}

+				else

+				{

+					if (m_LastArg.length() == 2)

+					{

+						m_LastParameter.clear();

+						m_LastOptId = so->Id;

+						return CmdLineParser::RESULT_OPT;

+					}

+					else

+					{

+						m_InsideMultioption = true;

+						m_LastArgIndex = 2;

+

+						m_LastParameter.clear();

+						m_LastOptId = so->Id;

+						return CmdLineParser::RESULT_OPT;

+					}

+				}

+			}

+		}

+		else if (!m_LastArg.empty() && m_LastArg[0] == '/')

+		{

+			size_t EqualIndex = m_LastArg.find('=', 1);

+			if (EqualIndex != std::string::npos)

+			{

+				if (EqualIndex == 2)

+				{

+					SHORT_OPT *so = FindShortOpt(m_LastArg[1]);

+					if (so != NULL)

+					{

+						if (so->Parameter == false)	

+						{

+							m_LastOptId = 0;

+							m_LastParameter.clear();

+							return CmdLineParser::RESULT_ERROR;

+						}

+						m_LastParameter = m_LastArg.substr(EqualIndex+1);

+						m_LastOptId = so->Id;

+						return CmdLineParser::RESULT_OPT;

+					}

+				}

+				LONG_OPT *lo = FindLongOpt(m_LastArg.substr(1, EqualIndex-1));

+				if (lo == NULL || lo->Parameter == false)

+				{

+					m_LastOptId = 0;

+					m_LastParameter.clear();

+					return CmdLineParser::RESULT_ERROR;

+				}

+				m_LastParameter = m_LastArg.substr(EqualIndex+1);

+				m_LastOptId = lo->Id;

+				return CmdLineParser::RESULT_OPT;

+			}

+			else

+			{

+				if (m_LastArg.length() == 2)

+				{

+					SHORT_OPT *so = FindShortOpt(m_LastArg[1]);

+					if (so != NULL)

+					{

+						if (so->Parameter)

+						{

+							if (!ReadNextArg(&m_LastParameter))

+							{

+								m_LastOptId = 0;

+								m_LastParameter.clear();

+								return CmdLineParser::RESULT_ERROR;

+							}

+						}

+						else

+							m_LastParameter.clear();

+						m_LastOptId = so->Id;

+						return CmdLineParser::RESULT_OPT;

+					}

+				}

+				LONG_OPT *lo = FindLongOpt(m_LastArg.substr(1));

+				if (lo == NULL)

+				{

+					m_LastOptId = 0;

+					m_LastParameter.clear();

+					return CmdLineParser::RESULT_ERROR;

+				}

+				if (lo->Parameter)

+				{

+					if (!ReadNextArg(&m_LastParameter))

+					{

+						m_LastOptId = 0;

+						m_LastParameter.clear();

+						return CmdLineParser::RESULT_ERROR;

+					}

+				}

+				else

+					m_LastParameter.clear();

+				m_LastOptId = lo->Id;

+				return CmdLineParser::RESULT_OPT;

+			}

+		}

+		else

+		{

+			m_LastOptId = 0;

+			m_LastParameter = m_LastArg;

+			return CmdLineParser::RESULT_PARAMETER;

+		}

+	}

+}

+

+uint32_t CmdLineParser::GetOptId()

+{

+	return m_LastOptId;

+}

+

+const std::string & CmdLineParser::GetParameter()

+{

+	return m_LastParameter;

+}

+

+////////////////////////////////////////////////////////////////////////////////

+// Glolals

+

+/*

+

+void SetConsoleColor(CONSOLE_COLOR color)

+{

+    WORD attr = 0;

+    switch(color)

+    {

+    case CONSOLE_COLOR::INFO:

+        attr = FOREGROUND_INTENSITY;;

+        break;

+    case CONSOLE_COLOR::NORMAL:

+        attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;

+        break;

+    case CONSOLE_COLOR::WARNING:

+        attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;

+        break;

+    case CONSOLE_COLOR::ERROR_:

+        attr = FOREGROUND_RED | FOREGROUND_INTENSITY;

+        break;

+    default:

+        assert(0);

+    }

+

+    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

+    SetConsoleTextAttribute(out, attr);

+}

+

+void PrintMessage(CONSOLE_COLOR color, const char* msg)

+{

+    if(color != CONSOLE_COLOR::NORMAL)

+        SetConsoleColor(color);

+    

+    printf("%s\n", msg);

+    

+    if (color != CONSOLE_COLOR::NORMAL)

+        SetConsoleColor(CONSOLE_COLOR::NORMAL);

+}

+

+void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg)

+{

+    if(color != CONSOLE_COLOR::NORMAL)

+        SetConsoleColor(color);

+    

+    wprintf(L"%s\n", msg);

+    

+    if (color != CONSOLE_COLOR::NORMAL)

+        SetConsoleColor(CONSOLE_COLOR::NORMAL);

+}

+

+static const size_t CONSOLE_SMALL_BUF_SIZE = 256;

+

+void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList)

+{

+	size_t dstLen = (size_t)::_vscprintf(format, argList);

+	if(dstLen)

+	{

+		bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;

+		char smallBuf[CONSOLE_SMALL_BUF_SIZE];

+		std::vector<char> bigBuf(useSmallBuf ? 0 : dstLen + 1);

+		char* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();

+		::vsprintf_s(bufPtr, dstLen + 1, format, argList);

+		PrintMessage(color, bufPtr);

+	}

+}

+

+void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList)

+{

+	size_t dstLen = (size_t)::_vcwprintf(format, argList);

+	if(dstLen)

+	{

+		bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;

+		wchar_t smallBuf[CONSOLE_SMALL_BUF_SIZE];

+		std::vector<wchar_t> bigBuf(useSmallBuf ? 0 : dstLen + 1);

+		wchar_t* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();

+		::vswprintf_s(bufPtr, dstLen + 1, format, argList);

+		PrintMessage(color, bufPtr);

+	}

+}

+

+void PrintMessageF(CONSOLE_COLOR color, const char* format, ...)

+{

+	va_list argList;

+	va_start(argList, format);

+	PrintMessageV(color, format, argList);

+	va_end(argList);

+}

+

+void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...)

+{

+	va_list argList;

+	va_start(argList, format);

+	PrintMessageV(color, format, argList);

+	va_end(argList);

+}

+

+void PrintWarningF(const char* format, ...)

+{

+	va_list argList;

+	va_start(argList, format);

+	PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);

+	va_end(argList);

+}

+

+void PrintWarningF(const wchar_t* format, ...)

+{

+	va_list argList;

+	va_start(argList, format);

+	PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);

+	va_end(argList);

+}

+

+void PrintErrorF(const char* format, ...)

+{

+	va_list argList;

+	va_start(argList, format);

+	PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);

+	va_end(argList);

+}

+

+void PrintErrorF(const wchar_t* format, ...)

+{

+	va_list argList;

+	va_start(argList, format);

+	PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);

+	va_end(argList);

+}

+*/

+

+void SecondsToFriendlyStr(float seconds, std::string& out)

+{

+    if(seconds == 0.f)

+    {

+        out = "0";

+        return;

+    }

+

+    if (seconds < 0.f)

+	{

+		out = "-";

+        seconds = -seconds;

+	}

+	else

+	{

+		out.clear();

+	}

+

+	char s[32];

+

+    // #.### ns

+    if(seconds < 1e-6)

+    {

+        sprintf_s(s, "%.3f ns", seconds * 1e9);

+        out += s;

+    }

+    // #.### us

+    else if(seconds < 1e-3)

+    {

+        sprintf_s(s, "%.3f us", seconds * 1e6);

+        out += s;

+    }

+    // #.### ms

+    else if(seconds < 1.f)

+    {

+        sprintf_s(s, "%.3f ms", seconds * 1e3);

+        out += s;

+    }

+    // #.### s

+    else if(seconds < 60.f)

+    {

+        sprintf_s(s, "%.3f s", seconds);

+        out += s;

+    }

+    else

+    {

+	    uint64_t seconds_u = (uint64_t)seconds;

+	    // "#:## min"

+	    if (seconds_u < 3600)

+	    {

+		    uint64_t minutes = seconds_u / 60;

+		    seconds_u -= minutes * 60;

+            sprintf_s(s, "%llu:%02llu min", minutes, seconds_u);

+            out += s;

+	    }

+	    // "#:##:## h"

+	    else

+	    {

+		    uint64_t minutes = seconds_u / 60;

+            seconds_u -= minutes * 60;

+		    uint64_t hours = minutes / 60;

+		    minutes -= hours * 60;

+            sprintf_s(s, "%llu:%02llu:%02llu h", hours, minutes, seconds_u);

+            out += s;

+	    }

+    }

+}

diff --git a/src/VmaReplay/Common.h b/src/VmaReplay/Common.h
new file mode 100644
index 0000000..28b5bbc
--- /dev/null
+++ b/src/VmaReplay/Common.h
@@ -0,0 +1,391 @@
+#pragma once

+

+#include "VmaUsage.h"

+

+#include <iostream>

+#include <fstream>

+#include <vector>

+#include <memory>

+#include <algorithm>

+#include <numeric>

+#include <array>

+#include <type_traits>

+#include <utility>

+#include <chrono>

+#include <string>

+#include <limits>

+

+#include <cassert>

+#include <cstdlib>

+#include <cstdio>

+#include <cstdarg>

+

+typedef std::chrono::high_resolution_clock::time_point time_point;

+typedef std::chrono::high_resolution_clock::duration duration;

+

+inline float ToFloatSeconds(duration d)

+{

+    return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();

+}

+

+void SecondsToFriendlyStr(float seconds, std::string& out);

+

+template <typename T>

+T ceil_div(T x, T y)

+{

+    return (x+y-1) / y;

+}

+

+template <typename T>

+inline T align_up(T val, T align)

+{

+    return (val + align - 1) / align * align;

+}

+

+struct StrRange

+{

+    const char* beg;

+    const char* end;

+

+    StrRange() { }

+    StrRange(const char* beg, const char* end) : beg(beg), end(end) { }

+    explicit StrRange(const char* sz) : beg(sz), end(sz + strlen(sz)) { }

+    explicit StrRange(const std::string& s) : beg(s.data()), end(s.data() + s.length()) { }

+

+    size_t length() const { return end - beg; }

+    void to_str(std::string& out) const { out.assign(beg, end); }

+};

+

+inline bool StrRangeEq(const StrRange& lhs, const char* rhsSz)

+{

+    const size_t rhsLen = strlen(rhsSz);

+    return rhsLen == lhs.length() &&

+        memcmp(lhs.beg, rhsSz, rhsLen) == 0;

+}

+

+inline bool StrRangeToUint(const StrRange& s, uint32_t& out)

+{

+    char* end = (char*)s.end;

+    out = (uint32_t)strtoul(s.beg, &end, 10);

+    return end == s.end;

+}

+inline bool StrRangeToUint(const StrRange& s, uint64_t& out)

+{

+    char* end = (char*)s.end;

+    out = (uint64_t)strtoull(s.beg, &end, 10);

+    return end == s.end;

+}

+inline bool StrRangeToPtr(const StrRange& s, uint64_t& out)

+{

+    char* end = (char*)s.end;

+    out = (uint64_t)strtoull(s.beg, &end, 16);

+    return end == s.end;

+}

+inline bool StrRangeToFloat(const StrRange& s, float& out)

+{

+    char* end = (char*)s.end;

+    out = strtof(s.beg, &end);

+    return end == s.end;

+}

+inline bool StrRangeToBool(const StrRange& s, bool& out)

+{

+    if(s.end - s.beg == 1)

+    {

+        if(*s.beg == '1')

+        {

+            out = true;

+        }

+        else if(*s.beg == '0')

+        {

+            out = false;

+        }

+        else

+        {

+            return false;

+        }

+    }

+    else

+    {

+        return false;

+    }

+

+    return true;

+}

+

+class LineSplit

+{

+public:

+    LineSplit(const char* data, size_t numBytes) :

+        m_Data(data),

+        m_NumBytes(numBytes),

+        m_NextLineBeg(0),

+        m_NextLineIndex(0)

+    {

+    }

+

+    bool GetNextLine(StrRange& out);

+    size_t GetNextLineIndex() const { return m_NextLineIndex; }

+

+private:

+    const char* const m_Data;

+    const size_t m_NumBytes;

+    size_t m_NextLineBeg;

+    size_t m_NextLineIndex;

+};

+

+class CsvSplit

+{

+public:

+    static const size_t RANGE_COUNT_MAX = 32;

+

+    void Set(const StrRange& line, size_t maxCount = RANGE_COUNT_MAX);

+

+    const StrRange& GetLine() const { return m_Line; }

+

+    size_t GetCount() const { return m_Count; }

+    StrRange GetRange(size_t index) const 

+    {

+        return StrRange {

+            m_Line.beg + m_Ranges[index * 2],

+            m_Line.beg + m_Ranges[index * 2 + 1] };

+    }

+

+private:

+    StrRange m_Line = { nullptr, nullptr };

+    size_t m_Count = 0;

+    size_t m_Ranges[RANGE_COUNT_MAX * 2]; // Pairs of begin-end.

+};

+

+class CmdLineParser

+{

+public:

+	enum RESULT

+	{

+		RESULT_OPT,

+		RESULT_PARAMETER,

+		RESULT_END,

+		RESULT_ERROR,

+	};

+

+	CmdLineParser(int argc, char **argv);

+	CmdLineParser(const char *CmdLine);

+	

+    void RegisterOpt(uint32_t Id, char Opt, bool Parameter);

+	void RegisterOpt(uint32_t Id, const std::string &Opt, bool Parameter);

+	

+    RESULT ReadNext();

+	uint32_t GetOptId();

+	const std::string & GetParameter();

+

+private:

+	struct SHORT_OPT

+	{

+		uint32_t Id;

+		char Opt;

+		bool Parameter;

+

+		SHORT_OPT(uint32_t Id, char Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }

+	};

+

+	struct LONG_OPT

+	{

+		uint32_t Id;

+		std::string Opt;

+		bool Parameter;

+

+		LONG_OPT(uint32_t Id, std::string Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }

+	};

+

+	char **m_argv;

+	const char *m_CmdLine;

+	int m_argc;

+	size_t m_CmdLineLength;

+	size_t m_ArgIndex;

+

+	bool ReadNextArg(std::string *OutArg);

+

+	std::vector<SHORT_OPT> m_ShortOpts;

+	std::vector<LONG_OPT> m_LongOpts;

+

+	SHORT_OPT * FindShortOpt(char Opt);

+	LONG_OPT * FindLongOpt(const std::string &Opt);

+

+	bool m_InsideMultioption;

+	std::string m_LastArg;

+	size_t m_LastArgIndex;

+	uint32_t m_LastOptId;

+	std::string m_LastParameter;

+};

+

+/*

+Parses and stores a sequence of ranges.

+

+Upper range is inclusive.

+

+Examples:

+

+    "1" -> [ {1, 1} ]

+    "1,10" -> [ {1, 1}, {10, 10} ]

+    "2-6" -> [ {2, 6} ]

+    "-8" -> [ {MIN, 8} ]

+    "12-" -> [ {12, MAX} ]

+    "1-10,12,15-" -> [ {1, 10}, {12, 12}, {15, MAX} ]

+

+TODO: Optimize it: Do sorting and merging while parsing. Do binary search while

+reading.

+*/

+template<typename T>

+class RangeSequence

+{

+public:

+    typedef std::pair<T, T> RangeType;

+

+    void Clear() { m_Ranges.clear(); }

+    bool Parse(const StrRange& str);

+

+    bool IsEmpty() const { return m_Ranges.empty(); }

+    size_t GetCount() const { return m_Ranges.size(); }

+    const RangeType* GetRanges() const { return m_Ranges.data(); }

+

+    bool Includes(T number) const;

+    

+private:

+    std::vector<RangeType> m_Ranges;

+};

+

+template<typename T>

+bool RangeSequence<T>::Parse(const StrRange& str)

+{

+    m_Ranges.clear();

+

+    StrRange currRange = { str.beg, str.beg };

+    while(currRange.beg < str.end)

+    {

+        currRange.end = currRange.beg + 1;

+        // Find next ',' or the end.

+        while(currRange.end < str.end && *currRange.end != ',')

+        {

+            ++currRange.end;

+        }

+

+        // Find '-' within this range.

+        const char* hyphenPos = currRange.beg;

+        while(hyphenPos < currRange.end && *hyphenPos != '-')

+        {

+            ++hyphenPos;

+        }

+

+        // No hyphen - single number like '10'.

+        if(hyphenPos == currRange.end)

+        {

+            RangeType range;

+            if(!StrRangeToUint(currRange, range.first))

+            {

+                return false;

+            }

+            range.second = range.first;

+            m_Ranges.push_back(range);

+        }

+        // Hyphen at the end, like '10-'.

+        else if(hyphenPos + 1 == currRange.end)

+        {

+            const StrRange numberRange = { currRange.beg, hyphenPos };

+            RangeType range;

+            if(!StrRangeToUint(numberRange, range.first))

+            {

+                return false;

+            }

+            range.second = std::numeric_limits<T>::max();

+            m_Ranges.push_back(range);

+        }

+        // Hyphen at the beginning, like "-10".

+        else if(hyphenPos == currRange.beg)

+        {

+            const StrRange numberRange = { currRange.beg + 1, currRange.end };

+            RangeType range;

+            range.first = std::numeric_limits<T>::min();

+            if(!StrRangeToUint(numberRange, range.second))

+            {

+                return false;

+            }

+            m_Ranges.push_back(range);

+        }

+        // Hyphen in the middle, like "1-10".

+        else

+        {

+            const StrRange numberRange1 = { currRange.beg, hyphenPos };

+            const StrRange numberRange2 = { hyphenPos + 1, currRange.end };

+            RangeType range;

+            if(!StrRangeToUint(numberRange1, range.first) ||

+                !StrRangeToUint(numberRange2, range.second) ||

+                range.second < range.first)

+            {

+                return false;

+            }

+            m_Ranges.push_back(range);

+        }

+

+        // Skip ','

+        currRange.beg = currRange.end + 1;

+    }

+

+    return true;

+}

+

+template<typename T>

+bool RangeSequence<T>::Includes(T number) const

+{

+    for(const auto& it : m_Ranges)

+    {

+        if(number >= it.first && number <= it.second)

+        {

+            return true;

+        }

+    }

+    return false;

+}

+

+/*

+class RandomNumberGenerator

+{

+public:

+    RandomNumberGenerator() : m_Value{GetTickCount()} {}

+    RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }

+    void Seed(uint32_t seed) { m_Value = seed; }

+    uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }

+

+private:

+    uint32_t m_Value;

+    uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }

+};

+

+enum class CONSOLE_COLOR

+{

+    INFO,

+    NORMAL,

+    WARNING,

+    ERROR_,

+    COUNT

+};

+

+void SetConsoleColor(CONSOLE_COLOR color);

+

+void PrintMessage(CONSOLE_COLOR color, const char* msg);

+void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);

+

+inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }

+inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }

+inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }

+inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }

+inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }

+inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }

+

+void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);

+void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);

+void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);

+void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);

+void PrintWarningF(const char* format, ...);

+void PrintWarningF(const wchar_t* format, ...);

+void PrintErrorF(const char* format, ...);

+void PrintErrorF(const wchar_t* format, ...);

+*/

diff --git a/src/VmaReplay/VmaReplay.cpp b/src/VmaReplay/VmaReplay.cpp
new file mode 100644
index 0000000..9635b03
--- /dev/null
+++ b/src/VmaReplay/VmaReplay.cpp
@@ -0,0 +1,3000 @@
+//

+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.

+//

+// Permission is hereby granted, free of charge, to any person obtaining a copy

+// of this software and associated documentation files (the "Software"), to deal

+// in the Software without restriction, including without limitation the rights

+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

+// copies of the Software, and to permit persons to whom the Software is

+// furnished to do so, subject to the following conditions:

+//

+// The above copyright notice and this permission notice shall be included in

+// all copies or substantial portions of the Software.

+//

+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN

+// THE SOFTWARE.

+//

+

+#include "VmaUsage.h"

+#include "Common.h"

+#include <unordered_map>

+

+static const int RESULT_EXCEPTION          = -1000;

+static const int RESULT_ERROR_COMMAND_LINE = -1;

+static const int RESULT_ERROR_SOURCE_FILE  = -2;

+static const int RESULT_ERROR_FORMAT       = -3;

+static const int RESULT_ERROR_VULKAN       = -4;

+

+enum CMD_LINE_OPT

+{

+    CMD_LINE_OPT_VERBOSITY,

+    CMD_LINE_OPT_ITERATIONS,

+    CMD_LINE_OPT_LINES,

+    CMD_LINE_OPT_PHYSICAL_DEVICE,

+    CMD_LINE_OPT_USER_DATA,

+    CMD_LINE_OPT_VK_KHR_DEDICATED_ALLOCATION,

+    CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION,

+    CMD_LINE_OPT_MEM_STATS,

+    CMD_LINE_OPT_DUMP_STATS_AFTER_LINE,

+    CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE,

+};

+

+static enum class VERBOSITY

+{

+    MINIMUM = 0,

+    DEFAULT,

+    MAXIMUM,

+    COUNT,

+} g_Verbosity = VERBOSITY::DEFAULT;

+

+enum class VULKAN_EXTENSION_REQUEST

+{

+    DISABLED,

+    ENABLED,

+    DEFAULT

+};

+

+enum class OBJECT_TYPE { BUFFER, IMAGE };

+

+enum class VMA_FUNCTION

+{

+    CreatePool,

+    DestroyPool,

+    SetAllocationUserData,

+    CreateBuffer,

+    DestroyBuffer,

+    CreateImage,

+    DestroyImage,

+    FreeMemory,

+    CreateLostAllocation,

+    AllocateMemory,

+    AllocateMemoryForBuffer,

+    AllocateMemoryForImage,

+    MapMemory,

+    UnmapMemory,

+    FlushAllocation,

+    InvalidateAllocation,

+    TouchAllocation,

+    GetAllocationInfo,

+    MakePoolAllocationsLost,

+    Count

+};

+static const char* VMA_FUNCTION_NAMES[] = {

+    "vmaCreatePool",

+    "vmaDestroyPool",

+    "vmaSetAllocationUserData",

+    "vmaCreateBuffer",

+    "vmaDestroyBuffer",

+    "vmaCreateImage",

+    "vmaDestroyImage",

+    "vmaFreeMemory",

+    "vmaCreateLostAllocation",

+    "vmaAllocateMemory",

+    "vmaAllocateMemoryForBuffer",

+    "vmaAllocateMemoryForImage",

+    "vmaMapMemory",

+    "vmaUnmapMemory",

+    "vmaFlushAllocation",

+    "vmaInvalidateAllocation",

+    "vmaTouchAllocation",

+    "vmaGetAllocationInfo",

+    "vmaMakePoolAllocationsLost",

+};

+static_assert(

+    _countof(VMA_FUNCTION_NAMES) == (size_t)VMA_FUNCTION::Count,

+    "VMA_FUNCTION_NAMES array doesn't match VMA_FUNCTION enum.");

+

+// Set this to false to disable deleting leaked VmaAllocation, VmaPool objects

+// and let VMA report asserts about them.

+static const bool CLEANUP_LEAKED_OBJECTS = true;

+

+static std::string g_FilePath;

+// Most significant 16 bits are major version, least significant 16 bits are minor version.

+static uint32_t g_FileVersion;

+

+inline uint32_t MakeVersion(uint32_t major, uint32_t minor) { return (major << 16) | minor; }

+inline uint32_t GetVersionMajor(uint32_t version) { return version >> 16; }

+inline uint32_t GetVersionMinor(uint32_t version) { return version & 0xFFFF; }

+

+static size_t g_IterationCount = 1;

+static uint32_t g_PhysicalDeviceIndex = 0;

+static RangeSequence<size_t> g_LineRanges;

+static bool g_UserDataEnabled = true;

+static bool g_MemStatsEnabled = false;

+VULKAN_EXTENSION_REQUEST g_VK_KHR_dedicated_allocation_request = VULKAN_EXTENSION_REQUEST::DEFAULT;

+VULKAN_EXTENSION_REQUEST g_VK_LAYER_LUNARG_standard_validation = VULKAN_EXTENSION_REQUEST::DEFAULT;

+

+struct StatsAfterLineEntry

+{

+    size_t line;

+    bool detailed;

+

+    bool operator<(const StatsAfterLineEntry& rhs) const { return line < rhs.line; }

+    bool operator==(const StatsAfterLineEntry& rhs) const { return line == rhs.line; }

+};

+static std::vector<StatsAfterLineEntry> g_DumpStatsAfterLine;

+static size_t g_DumpStatsAfterLineNextIndex = 0;

+

+static bool ValidateFileVersion()

+{

+    if(GetVersionMajor(g_FileVersion) == 1 &&

+        GetVersionMinor(g_FileVersion) <= 3)

+    {

+        return true;

+    }

+

+    return false;

+}

+

+static bool ParseFileVersion(const StrRange& s)

+{

+    CsvSplit csvSplit;

+    csvSplit.Set(s, 2);

+    uint32_t major, minor;

+    if(csvSplit.GetCount() == 2 &&

+        StrRangeToUint(csvSplit.GetRange(0), major) &&

+        StrRangeToUint(csvSplit.GetRange(1), minor))

+    {

+        g_FileVersion = (major << 16) | minor;

+        return true;

+    }

+    else

+    {

+        return false;

+    }

+}

+

+////////////////////////////////////////////////////////////////////////////////

+// class Statistics

+

+class Statistics

+{

+public:

+    static uint32_t BufferUsageToClass(uint32_t usage);

+    static uint32_t ImageUsageToClass(uint32_t usage);

+

+    Statistics();

+    void Init(uint32_t memHeapCount, uint32_t memTypeCount);

+    void PrintMemStats() const;

+

+    const size_t* GetFunctionCallCount() const { return m_FunctionCallCount; }

+    size_t GetImageCreationCount(uint32_t imgClass) const { return m_ImageCreationCount[imgClass]; }

+    size_t GetLinearImageCreationCount() const { return m_LinearImageCreationCount; }

+    size_t GetBufferCreationCount(uint32_t bufClass) const { return m_BufferCreationCount[bufClass]; }

+    size_t GetAllocationCreationCount() const { return m_AllocationCreationCount; }

+    size_t GetPoolCreationCount() const { return m_PoolCreationCount; }

+

+    void RegisterFunctionCall(VMA_FUNCTION func);

+    void RegisterCreateImage(uint32_t usage, uint32_t tiling);

+    void RegisterCreateBuffer(uint32_t usage);

+    void RegisterCreatePool();

+    void RegisterCreateAllocation();

+

+    void UpdateMemStats(const VmaStats& currStats);

+

+private:

+    uint32_t m_MemHeapCount = 0;

+    uint32_t m_MemTypeCount = 0;

+

+    size_t m_FunctionCallCount[(size_t)VMA_FUNCTION::Count] = {};

+    size_t m_ImageCreationCount[4] = { };

+    size_t m_LinearImageCreationCount = 0;

+    size_t m_BufferCreationCount[4] = { };

+    size_t m_AllocationCreationCount = 0; // Also includes buffers and images, and lost allocations.

+    size_t m_PoolCreationCount = 0;

+    

+    // Structure similar to VmaStatInfo, but not the same.

+    struct MemStatInfo

+    {

+        uint32_t blockCount;

+        uint32_t allocationCount;

+        uint32_t unusedRangeCount;

+        VkDeviceSize usedBytes;

+        VkDeviceSize unusedBytes;

+        VkDeviceSize totalBytes;

+    };

+    struct MemStats

+    {

+        MemStatInfo memoryType[VK_MAX_MEMORY_TYPES];

+        MemStatInfo memoryHeap[VK_MAX_MEMORY_HEAPS];

+        MemStatInfo total;

+    } m_PeakMemStats;

+

+    void UpdateMemStatInfo(MemStatInfo& inoutPeakInfo, const VmaStatInfo& currInfo);

+    static void PrintMemStatInfo(const MemStatInfo& info);

+};

+

+uint32_t Statistics::BufferUsageToClass(uint32_t usage)

+{

+    // Buffer is used as source of data for fixed-function stage of graphics pipeline.

+    // It's indirect, vertex, or index buffer.

+    if ((usage & (VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT |

+        VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |

+        VK_BUFFER_USAGE_INDEX_BUFFER_BIT)) != 0)

+    {

+        return 0;

+    }

+    // Buffer is accessed by shaders for load/store/atomic.

+    // Aka "UAV"

+    else if ((usage & (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |

+        VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) != 0)

+    {

+        return 1;

+    }

+    // Buffer is accessed by shaders for reading uniform data.

+    // Aka "constant buffer"

+    else if ((usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |

+    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) != 0)

+    {

+        return 2;

+    }

+    // Any other type of buffer.

+    // Notice that VK_BUFFER_USAGE_TRANSFER_SRC_BIT and VK_BUFFER_USAGE_TRANSFER_DST_BIT

+    // flags are intentionally ignored.

+    else

+    {

+        return 3;

+    }

+}

+

+uint32_t Statistics::ImageUsageToClass(uint32_t usage)

+{

+    // Image is used as depth/stencil "texture/surface".

+    if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)

+    {

+        return 0;

+    }

+    // Image is used as other type of attachment.

+    // Aka "render target"

+    else if ((usage & (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |

+        VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |

+        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) != 0)

+    {

+        return 1;

+    }

+    // Image is accessed by shaders for sampling.

+    // Aka "texture"

+    else if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)

+    {

+        return 2;

+    }

+    // Any other type of image.

+    // Notice that VK_IMAGE_USAGE_TRANSFER_SRC_BIT and VK_IMAGE_USAGE_TRANSFER_DST_BIT

+    // flags are intentionally ignored.

+    else

+    {

+        return 3;

+    }

+}

+

+Statistics::Statistics()

+{

+    ZeroMemory(&m_PeakMemStats, sizeof(m_PeakMemStats));

+}

+

+void Statistics::Init(uint32_t memHeapCount, uint32_t memTypeCount)

+{

+    m_MemHeapCount = memHeapCount;

+    m_MemTypeCount = memTypeCount;

+}

+

+void Statistics::PrintMemStats() const

+{

+    printf("Memory statistics:\n");

+

+    printf("    Total:\n");

+    PrintMemStatInfo(m_PeakMemStats.total);

+

+    for(uint32_t i = 0; i < m_MemHeapCount; ++i)

+    {

+        const MemStatInfo& info = m_PeakMemStats.memoryHeap[i];

+        if(info.blockCount > 0 || info.totalBytes > 0)

+        {

+            printf("    Heap %u:\n", i);

+            PrintMemStatInfo(info);

+        }

+    }

+

+    for(uint32_t i = 0; i < m_MemTypeCount; ++i)

+    {

+        const MemStatInfo& info = m_PeakMemStats.memoryType[i];

+        if(info.blockCount > 0 || info.totalBytes > 0)

+        {

+            printf("    Type %u:\n", i);

+            PrintMemStatInfo(info);

+        }

+    }

+}

+

+void Statistics::RegisterFunctionCall(VMA_FUNCTION func)

+{

+    ++m_FunctionCallCount[(size_t)func];

+}

+

+void Statistics::RegisterCreateImage(uint32_t usage, uint32_t tiling)

+{

+    if(tiling == VK_IMAGE_TILING_LINEAR)

+        ++m_LinearImageCreationCount;

+    else

+    {

+        const uint32_t imgClass = ImageUsageToClass(usage);

+        ++m_ImageCreationCount[imgClass];

+    }

+

+    ++m_AllocationCreationCount;

+}

+

+void Statistics::RegisterCreateBuffer(uint32_t usage)

+{

+    const uint32_t bufClass = BufferUsageToClass(usage);

+    ++m_BufferCreationCount[bufClass];

+

+    ++m_AllocationCreationCount;

+}

+

+void Statistics::RegisterCreatePool()

+{

+    ++m_PoolCreationCount;

+}

+

+void Statistics::RegisterCreateAllocation()

+{

+    ++m_AllocationCreationCount;

+}

+

+void Statistics::UpdateMemStats(const VmaStats& currStats)

+{

+    UpdateMemStatInfo(m_PeakMemStats.total, currStats.total);

+    

+    for(uint32_t i = 0; i < m_MemHeapCount; ++i)

+    {

+        UpdateMemStatInfo(m_PeakMemStats.memoryHeap[i], currStats.memoryHeap[i]);

+    }

+

+    for(uint32_t i = 0; i < m_MemTypeCount; ++i)

+    {

+        UpdateMemStatInfo(m_PeakMemStats.memoryType[i], currStats.memoryType[i]);

+    }

+}

+

+void Statistics::UpdateMemStatInfo(MemStatInfo& inoutPeakInfo, const VmaStatInfo& currInfo)

+{

+#define SET_PEAK(inoutDst, src) \

+    if((src) > (inoutDst)) \

+    { \

+        (inoutDst) = (src); \

+    }

+

+    SET_PEAK(inoutPeakInfo.blockCount, currInfo.blockCount);

+    SET_PEAK(inoutPeakInfo.allocationCount, currInfo.allocationCount);

+    SET_PEAK(inoutPeakInfo.unusedRangeCount, currInfo.unusedRangeCount);

+    SET_PEAK(inoutPeakInfo.usedBytes, currInfo.usedBytes);

+    SET_PEAK(inoutPeakInfo.unusedBytes, currInfo.unusedBytes);

+    SET_PEAK(inoutPeakInfo.totalBytes, currInfo.usedBytes + currInfo.unusedBytes);

+

+#undef SET_PEAK

+}

+

+void Statistics::PrintMemStatInfo(const MemStatInfo& info)

+{

+    printf("        Peak blocks %u, allocations %u, unused ranges %u\n",

+        info.blockCount,

+        info.allocationCount,

+        info.unusedRangeCount);

+    printf("        Peak total bytes %llu, used bytes %llu, unused bytes %llu\n",

+        info.totalBytes,

+        info.usedBytes,

+        info.unusedBytes);

+}

+

+////////////////////////////////////////////////////////////////////////////////

+// class ConfigurationParser

+

+class ConfigurationParser

+{

+public:

+    ConfigurationParser();

+    

+    bool Parse(LineSplit& lineSplit);

+

+    void Compare(

+        const VkPhysicalDeviceProperties& currDevProps,

+        const VkPhysicalDeviceMemoryProperties& currMemProps,

+        bool currDedicatedAllocationExtensionEnabled);

+

+private:

+    enum class OPTION

+    {

+        PhysicalDevice_apiVersion,

+        PhysicalDevice_driverVersion,

+        PhysicalDevice_vendorID,

+        PhysicalDevice_deviceID,

+        PhysicalDevice_deviceType,

+        PhysicalDevice_deviceName,

+        PhysicalDeviceLimits_maxMemoryAllocationCount,

+        PhysicalDeviceLimits_bufferImageGranularity,

+        PhysicalDeviceLimits_nonCoherentAtomSize,

+        Extension_VK_KHR_dedicated_allocation,

+        Macro_VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,

+        Macro_VMA_DEBUG_ALIGNMENT,

+        Macro_VMA_DEBUG_MARGIN,

+        Macro_VMA_DEBUG_INITIALIZE_ALLOCATIONS,

+        Macro_VMA_DEBUG_DETECT_CORRUPTION,

+        Macro_VMA_DEBUG_GLOBAL_MUTEX,

+        Macro_VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,

+        Macro_VMA_SMALL_HEAP_MAX_SIZE,

+        Macro_VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,

+        Count

+    };

+

+    std::vector<bool> m_OptionSet;

+    std::vector<std::string> m_OptionValue;

+    VkPhysicalDeviceMemoryProperties m_MemProps;

+

+    bool m_WarningHeaderPrinted = false;

+

+    void SetOption(

+        size_t lineNumber,

+        OPTION option,

+        const StrRange& str);

+    void EnsureWarningHeader();

+    void CompareOption(VERBOSITY minVerbosity, const char* name,

+        OPTION option, uint32_t currValue);

+    void CompareOption(VERBOSITY minVerbosity, const char* name,

+        OPTION option, uint64_t currValue);

+    void CompareOption(VERBOSITY minVerbosity, const char* name,

+        OPTION option, bool currValue);

+    void CompareOption(VERBOSITY minVerbosity, const char* name,

+        OPTION option, const char* currValue);

+    void CompareMemProps(

+        const VkPhysicalDeviceMemoryProperties& currMemProps);

+};

+

+ConfigurationParser::ConfigurationParser() :

+    m_OptionSet((size_t)OPTION::Count),

+    m_OptionValue((size_t)OPTION::Count)

+{

+    ZeroMemory(&m_MemProps, sizeof(m_MemProps));

+}

+

+bool ConfigurationParser::Parse(LineSplit& lineSplit)

+{

+    for(auto& it : m_OptionSet)

+    {

+        it = false;

+    }

+    for(auto& it : m_OptionValue)

+    {

+        it.clear();

+    }

+

+    StrRange line;

+

+    if(!lineSplit.GetNextLine(line) && !StrRangeEq(line, "Config,Begin"))

+    {

+        return false;

+    }

+

+    CsvSplit csvSplit;

+    while(lineSplit.GetNextLine(line))

+    {

+        if(StrRangeEq(line, "Config,End"))

+        {

+            break;

+        }

+

+        const size_t currLineNumber = lineSplit.GetNextLineIndex();

+

+        csvSplit.Set(line);

+        if(csvSplit.GetCount() == 0)

+        {

+            return false;

+        }

+

+        const StrRange optionName = csvSplit.GetRange(0);

+        if(StrRangeEq(optionName, "PhysicalDevice"))

+        {

+            if(csvSplit.GetCount() >= 3)

+            {

+                const StrRange subOptionName = csvSplit.GetRange(1);

+                if(StrRangeEq(subOptionName, "apiVersion"))

+                    SetOption(currLineNumber, OPTION::PhysicalDevice_apiVersion, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "driverVersion"))

+                    SetOption(currLineNumber, OPTION::PhysicalDevice_driverVersion, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "vendorID"))

+                    SetOption(currLineNumber, OPTION::PhysicalDevice_vendorID, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "deviceID"))

+                    SetOption(currLineNumber, OPTION::PhysicalDevice_deviceID, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "deviceType"))

+                    SetOption(currLineNumber, OPTION::PhysicalDevice_deviceType, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "deviceName"))

+                    SetOption(currLineNumber, OPTION::PhysicalDevice_deviceName, StrRange(csvSplit.GetRange(2).beg, line.end));

+                else

+                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);

+            }

+            else

+                printf("Line %zu: Too few columns.\n", currLineNumber);

+        }

+        else if(StrRangeEq(optionName, "PhysicalDeviceLimits"))

+        {

+            if(csvSplit.GetCount() >= 3)

+            {

+                const StrRange subOptionName = csvSplit.GetRange(1);

+                if(StrRangeEq(subOptionName, "maxMemoryAllocationCount"))

+                    SetOption(currLineNumber, OPTION::PhysicalDeviceLimits_maxMemoryAllocationCount, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "bufferImageGranularity"))

+                    SetOption(currLineNumber, OPTION::PhysicalDeviceLimits_bufferImageGranularity, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "nonCoherentAtomSize"))

+                    SetOption(currLineNumber, OPTION::PhysicalDeviceLimits_nonCoherentAtomSize, csvSplit.GetRange(2));

+                else

+                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);

+            }

+            else

+                printf("Line %zu: Too few columns.\n", currLineNumber);

+        }

+        else if(StrRangeEq(optionName, "Extension"))

+        {

+            if(csvSplit.GetCount() >= 3)

+            {

+                const StrRange subOptionName = csvSplit.GetRange(1);

+                if(StrRangeEq(subOptionName, "VK_KHR_dedicated_allocation"))

+                    SetOption(currLineNumber, OPTION::Extension_VK_KHR_dedicated_allocation, csvSplit.GetRange(2));

+                else

+                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);

+            }

+            else

+                printf("Line %zu: Too few columns.\n", currLineNumber);

+        }

+        else if(StrRangeEq(optionName, "Macro"))

+        {

+            if(csvSplit.GetCount() >= 3)

+            {

+                const StrRange subOptionName = csvSplit.GetRange(1);

+                if(StrRangeEq(subOptionName, "VMA_DEBUG_ALWAYS_DEDICATED_MEMORY"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_ALWAYS_DEDICATED_MEMORY, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_DEBUG_ALIGNMENT"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_ALIGNMENT, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_DEBUG_MARGIN"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_MARGIN, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_DEBUG_INITIALIZE_ALLOCATIONS"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_INITIALIZE_ALLOCATIONS, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_DEBUG_DETECT_CORRUPTION"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_DETECT_CORRUPTION, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_DEBUG_GLOBAL_MUTEX"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_GLOBAL_MUTEX, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_SMALL_HEAP_MAX_SIZE"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_SMALL_HEAP_MAX_SIZE, csvSplit.GetRange(2));

+                else if(StrRangeEq(subOptionName, "VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE"))

+                    SetOption(currLineNumber, OPTION::Macro_VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE, csvSplit.GetRange(2));

+                else

+                    printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);

+            }

+            else

+                printf("Line %zu: Too few columns.\n", currLineNumber);

+        }

+        else if(StrRangeEq(optionName, "PhysicalDeviceMemory"))

+        {

+            uint32_t value = 0;

+            if(csvSplit.GetCount() == 3 && StrRangeEq(csvSplit.GetRange(1), "HeapCount") &&

+                StrRangeToUint(csvSplit.GetRange(2), value))

+            {

+                m_MemProps.memoryHeapCount = value;

+            }

+            else if(csvSplit.GetCount() == 3 && StrRangeEq(csvSplit.GetRange(1), "TypeCount") &&

+                StrRangeToUint(csvSplit.GetRange(2), value))

+            {

+                m_MemProps.memoryTypeCount = value;

+            }

+            else if(csvSplit.GetCount() == 5 && StrRangeEq(csvSplit.GetRange(1), "Heap") &&

+                StrRangeToUint(csvSplit.GetRange(2), value) &&

+                value < m_MemProps.memoryHeapCount)

+            {

+                if(StrRangeEq(csvSplit.GetRange(3), "size") &&

+                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryHeaps[value].size))

+                {

+                     // Parsed.

+                }

+                else if(StrRangeEq(csvSplit.GetRange(3), "flags") &&

+                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryHeaps[value].flags))

+                {

+                     // Parsed.

+                }

+                else

+                    printf("Line %zu: Invalid configuration option.\n", currLineNumber);

+            }

+            else if(csvSplit.GetCount() == 5 && StrRangeEq(csvSplit.GetRange(1), "Type") &&

+                StrRangeToUint(csvSplit.GetRange(2), value) &&

+                value < m_MemProps.memoryTypeCount)

+            {

+                if(StrRangeEq(csvSplit.GetRange(3), "heapIndex") &&

+                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryTypes[value].heapIndex))

+                {

+                     // Parsed.

+                }

+                else if(StrRangeEq(csvSplit.GetRange(3), "propertyFlags") &&

+                    StrRangeToUint(csvSplit.GetRange(4), m_MemProps.memoryTypes[value].propertyFlags))

+                {

+                     // Parsed.

+                }

+                else

+                    printf("Line %zu: Invalid configuration option.\n", currLineNumber);

+            }

+            else

+                printf("Line %zu: Invalid configuration option.\n", currLineNumber);

+        }

+        else

+            printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);

+    }

+

+    return true;

+}

+

+void ConfigurationParser::Compare(

+    const VkPhysicalDeviceProperties& currDevProps,

+    const VkPhysicalDeviceMemoryProperties& currMemProps,

+    bool currDedicatedAllocationExtensionEnabled)

+{

+    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice apiVersion",

+        OPTION::PhysicalDevice_apiVersion, currDevProps.apiVersion);

+    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice driverVersion",

+        OPTION::PhysicalDevice_driverVersion, currDevProps.driverVersion);

+    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice vendorID",

+        OPTION::PhysicalDevice_vendorID, currDevProps.vendorID);

+    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice deviceID",

+        OPTION::PhysicalDevice_deviceID, currDevProps.deviceID);

+    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice deviceType",

+        OPTION::PhysicalDevice_deviceType, (uint32_t)currDevProps.deviceType);

+    CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice deviceName",

+        OPTION::PhysicalDevice_deviceName, currDevProps.deviceName);

+

+    CompareOption(VERBOSITY::DEFAULT, "PhysicalDeviceLimits maxMemoryAllocationCount",

+        OPTION::PhysicalDeviceLimits_maxMemoryAllocationCount, currDevProps.limits.maxMemoryAllocationCount);

+    CompareOption(VERBOSITY::DEFAULT, "PhysicalDeviceLimits bufferImageGranularity",

+        OPTION::PhysicalDeviceLimits_bufferImageGranularity, currDevProps.limits.bufferImageGranularity);

+    CompareOption(VERBOSITY::DEFAULT, "PhysicalDeviceLimits nonCoherentAtomSize",

+        OPTION::PhysicalDeviceLimits_nonCoherentAtomSize, currDevProps.limits.nonCoherentAtomSize);

+    CompareOption(VERBOSITY::DEFAULT, "Extension VK_KHR_dedicated_allocation",

+        OPTION::Extension_VK_KHR_dedicated_allocation, currDedicatedAllocationExtensionEnabled);

+

+    CompareMemProps(currMemProps);

+}

+

+void ConfigurationParser::SetOption(

+    size_t lineNumber,

+    OPTION option,

+    const StrRange& str)

+{

+    if(m_OptionSet[(size_t)option])

+    {

+        printf("Line %zu: Option already specified.\n" ,lineNumber);

+    }

+

+    m_OptionSet[(size_t)option] = true;

+

+    std::string val;

+    str.to_str(val);

+    m_OptionValue[(size_t)option] = std::move(val);

+}

+

+void ConfigurationParser::EnsureWarningHeader()

+{

+    if(!m_WarningHeaderPrinted)

+    {

+        printf("WARNING: Following configuration parameters don't match:\n");

+        m_WarningHeaderPrinted = true;

+    }

+}

+

+void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,

+    OPTION option, uint32_t currValue)

+{

+    if(m_OptionSet[(size_t)option] &&

+        g_Verbosity >= minVerbosity)

+    {

+        uint32_t origValue;

+        if(StrRangeToUint(StrRange(m_OptionValue[(size_t)option]), origValue))

+        {

+            if(origValue != currValue)

+            {

+                EnsureWarningHeader();

+                printf("    %s: original %u, current %u\n", name, origValue, currValue);

+            }

+        }

+    }

+}

+

+void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,

+    OPTION option, uint64_t currValue)

+{

+    if(m_OptionSet[(size_t)option] &&

+        g_Verbosity >= minVerbosity)

+    {

+        uint64_t origValue;

+        if(StrRangeToUint(StrRange(m_OptionValue[(size_t)option]), origValue))

+        {

+            if(origValue != currValue)

+            {

+                EnsureWarningHeader();

+                printf("    %s: original %llu, current %llu\n", name, origValue, currValue);

+            }

+        }

+    }

+}

+

+void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,

+    OPTION option, bool currValue)

+{

+    if(m_OptionSet[(size_t)option] &&

+        g_Verbosity >= minVerbosity)

+    {

+        bool origValue;

+        if(StrRangeToBool(StrRange(m_OptionValue[(size_t)option]), origValue))

+        {

+            if(origValue != currValue)

+            {

+                EnsureWarningHeader();

+                printf("    %s: original %u, current %u\n", name,

+                    origValue ? 1 : 0,

+                    currValue ? 1 : 0);

+            }

+        }

+    }

+}

+

+void ConfigurationParser::CompareOption(VERBOSITY minVerbosity, const char* name,

+    OPTION option, const char* currValue)

+{

+    if(m_OptionSet[(size_t)option] &&

+        g_Verbosity >= minVerbosity)

+    {

+        const std::string& origValue = m_OptionValue[(size_t)option];

+        if(origValue != currValue)

+        {

+            EnsureWarningHeader();

+            printf("    %s: original \"%s\", current \"%s\"\n", name, origValue.c_str(), currValue);

+        }

+    }

+}

+

+void ConfigurationParser::CompareMemProps(

+    const VkPhysicalDeviceMemoryProperties& currMemProps)

+{

+    if(g_Verbosity < VERBOSITY::DEFAULT)

+    {

+        return;

+    }

+

+    bool memoryMatch =

+        currMemProps.memoryHeapCount == m_MemProps.memoryHeapCount &&

+        currMemProps.memoryTypeCount == m_MemProps.memoryTypeCount;

+

+    for(uint32_t i = 0; memoryMatch && i < currMemProps.memoryHeapCount; ++i)

+    {

+        memoryMatch =

+            currMemProps.memoryHeaps[i].flags == m_MemProps.memoryHeaps[i].flags;

+    }

+    for(uint32_t i = 0; memoryMatch && i < currMemProps.memoryTypeCount; ++i)

+    {

+        memoryMatch =

+            currMemProps.memoryTypes[i].heapIndex == m_MemProps.memoryTypes[i].heapIndex &&

+            currMemProps.memoryTypes[i].propertyFlags == m_MemProps.memoryTypes[i].propertyFlags;

+    }

+

+    if(memoryMatch && g_Verbosity == VERBOSITY::MAXIMUM)

+    {

+        bool memorySizeMatch = true;

+        for(uint32_t i = 0; memorySizeMatch && i < currMemProps.memoryHeapCount; ++i)

+        {

+            memorySizeMatch =

+                currMemProps.memoryHeaps[i].size == m_MemProps.memoryHeaps[i].size;

+        }

+

+        if(!memorySizeMatch)

+        {

+            printf("WARNING: Sizes of original memory heaps are different from current ones.\n");

+        }

+    }

+    else

+    {

+        printf("WARNING: Layout of original memory heaps and types is different from current one.\n");

+    }

+}

+

+////////////////////////////////////////////////////////////////////////////////

+// class Player

+

+static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_LUNARG_standard_validation";

+

+static bool g_MemoryAliasingWarningEnabled = true;

+

+static VKAPI_ATTR VkBool32 VKAPI_CALL MyDebugReportCallback(

+    VkDebugReportFlagsEXT flags,

+    VkDebugReportObjectTypeEXT objectType,

+    uint64_t object,

+    size_t location,

+    int32_t messageCode,

+    const char* pLayerPrefix,

+    const char* pMessage,

+    void* pUserData)

+{

+    // "Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug."

+    if(!g_MemoryAliasingWarningEnabled && flags == VK_DEBUG_REPORT_WARNING_BIT_EXT &&

+        (strstr(pMessage, " is aliased with non-linear ") || strstr(pMessage, " is aliased with linear ")))

+    {

+        return VK_FALSE;

+    }

+

+    // Ignoring because when VK_KHR_dedicated_allocation extension is enabled,

+    // vkGetBufferMemoryRequirements2KHR function is used instead, while Validation

+    // Layer seems to be unaware of it.

+    if (strstr(pMessage, "but vkGetBufferMemoryRequirements() has not been called on that buffer") != nullptr)

+    {

+        return VK_FALSE;

+    }

+    if (strstr(pMessage, "but vkGetImageMemoryRequirements() has not been called on that image") != nullptr)

+    {

+        return VK_FALSE;

+    }

+    

+    /*

+    "Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used."

+    Ignoring because we map entire VkDeviceMemory blocks, where different types of

+    images and buffers may end up together, especially on GPUs with unified memory

+    like Intel.

+    */

+    if(strstr(pMessage, "Mapping an image with layout") != nullptr &&

+        strstr(pMessage, "can result in undefined behavior if this memory is used by the device") != nullptr)

+    {

+        return VK_FALSE;

+    }

+

+    printf("%s \xBA %s\n", pLayerPrefix, pMessage);

+

+    return VK_FALSE;

+}

+

+static bool IsLayerSupported(const VkLayerProperties* pProps, size_t propCount, const char* pLayerName)

+{

+    const VkLayerProperties* propsEnd = pProps + propCount;

+    return std::find_if(

+        pProps,

+        propsEnd,

+        [pLayerName](const VkLayerProperties& prop) -> bool {

+            return strcmp(pLayerName, prop.layerName) == 0;

+        }) != propsEnd;

+}

+

+static const size_t FIRST_PARAM_INDEX = 4;

+

+static void InitVulkanFeatures(

+    VkPhysicalDeviceFeatures& outFeatures,

+    const VkPhysicalDeviceFeatures& supportedFeatures)

+{

+    ZeroMemory(&outFeatures, sizeof(outFeatures));

+

+    // Enable something what may interact with memory/buffer/image support.

+

+    outFeatures.fullDrawIndexUint32 = supportedFeatures.fullDrawIndexUint32;

+    outFeatures.imageCubeArray = supportedFeatures.imageCubeArray;

+    outFeatures.geometryShader = supportedFeatures.geometryShader;

+    outFeatures.tessellationShader = supportedFeatures.tessellationShader;

+    outFeatures.multiDrawIndirect = supportedFeatures.multiDrawIndirect;

+    outFeatures.textureCompressionETC2 = supportedFeatures.textureCompressionETC2;

+    outFeatures.textureCompressionASTC_LDR = supportedFeatures.textureCompressionASTC_LDR;

+    outFeatures.textureCompressionBC = supportedFeatures.textureCompressionBC;

+}

+

+class Player

+{

+public:

+    Player();

+    int Init();

+    ~Player();

+

+    void ApplyConfig(ConfigurationParser& configParser);

+    void ExecuteLine(size_t lineNumber, const StrRange& line);

+    void DumpStats(const char* fileNameFormat, size_t lineNumber, bool detailed);

+

+    void PrintStats();

+

+private:

+    static const size_t MAX_WARNINGS_TO_SHOW = 64;

+

+    size_t m_WarningCount = 0;

+    bool m_AllocateForBufferImageWarningIssued = false;

+

+    VkInstance m_VulkanInstance = VK_NULL_HANDLE;

+    VkPhysicalDevice m_PhysicalDevice = VK_NULL_HANDLE;

+    uint32_t m_GraphicsQueueFamilyIndex = UINT_MAX;

+    VkDevice m_Device = VK_NULL_HANDLE;

+    VmaAllocator m_Allocator = VK_NULL_HANDLE;

+    bool m_DedicatedAllocationEnabled = false;

+    const VkPhysicalDeviceProperties* m_DevProps = nullptr;

+    const VkPhysicalDeviceMemoryProperties* m_MemProps = nullptr;

+

+    PFN_vkCreateDebugReportCallbackEXT m_pvkCreateDebugReportCallbackEXT;

+    PFN_vkDebugReportMessageEXT m_pvkDebugReportMessageEXT;

+    PFN_vkDestroyDebugReportCallbackEXT m_pvkDestroyDebugReportCallbackEXT;

+    VkDebugReportCallbackEXT m_hCallback;

+

+    uint32_t m_VmaFrameIndex = 0;

+

+    // Any of these handles null can mean it was created in original but couldn't be created now.

+    struct Pool

+    {

+        VmaPool pool;

+    };

+    struct Allocation

+    {

+        uint32_t allocationFlags;

+        VmaAllocation allocation;

+        VkBuffer buffer;

+        VkImage image;

+    };

+    std::unordered_map<uint64_t, Pool> m_Pools;

+    std::unordered_map<uint64_t, Allocation> m_Allocations;

+

+    struct Thread

+    {

+        uint32_t callCount;

+    };

+    std::unordered_map<uint32_t, Thread> m_Threads;

+

+    // Copy of column [1] from previously parsed line.

+    std::string m_LastLineTimeStr;

+    Statistics m_Stats;

+

+    std::vector<char> m_UserDataTmpStr;

+

+    void Destroy(const Allocation& alloc);

+

+    // Finds VmaPool bu original pointer.

+    // If origPool = null, returns true and outPool = null.

+    // If failed, prints warning, returns false and outPool = null.

+    bool FindPool(size_t lineNumber, uint64_t origPool, VmaPool& outPool);

+    // If allocation with that origPtr already exists, prints warning and replaces it.

+    void AddAllocation(size_t lineNumber, uint64_t origPtr, VkResult res, const char* functionName, Allocation&& allocDesc);

+

+    // Increments warning counter. Returns true if warning message should be printed.

+    bool IssueWarning();

+

+    int InitVulkan();

+    void FinalizeVulkan();

+    void RegisterDebugCallbacks();

+

+    // If parmeter count doesn't match, issues warning and returns false.

+    bool ValidateFunctionParameterCount(size_t lineNumber, const CsvSplit& csvSplit, size_t expectedParamCount, bool lastUnbound);

+

+    // If failed, prints warning, returns false, and sets allocCreateInfo.pUserData to null.

+    bool PrepareUserData(size_t lineNumber, uint32_t allocCreateFlags, const StrRange& userDataColumn, const StrRange& wholeLine, void*& outUserData);

+

+    void UpdateMemStats();

+

+    void ExecuteCreatePool(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteDestroyPool(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteSetAllocationUserData(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteDestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyBuffer); DestroyAllocation(lineNumber, csvSplit); }

+    void ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteDestroyImage(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyImage); DestroyAllocation(lineNumber, csvSplit); }

+    void ExecuteFreeMemory(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemory); DestroyAllocation(lineNumber, csvSplit); }

+    void ExecuteCreateLostAllocation(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteAllocateMemory(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteAllocateMemoryForBufferOrImage(size_t lineNumber, const CsvSplit& csvSplit, OBJECT_TYPE objType);

+    void ExecuteMapMemory(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteUnmapMemory(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteFlushAllocation(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteInvalidateAllocation(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteTouchAllocation(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteGetAllocationInfo(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteMakePoolAllocationsLost(size_t lineNumber, const CsvSplit& csvSplit);

+

+    void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit);

+};

+

+Player::Player()

+{

+}

+

+int Player::Init()

+{

+    int result = InitVulkan();

+    

+    if(result == 0)

+    {

+        m_Stats.Init(m_MemProps->memoryHeapCount, m_MemProps->memoryTypeCount);

+        UpdateMemStats();

+    }

+    

+    return result;

+}

+

+Player::~Player()

+{

+    FinalizeVulkan();

+

+    if(g_Verbosity < VERBOSITY::MAXIMUM && m_WarningCount > MAX_WARNINGS_TO_SHOW)

+        printf("WARNING: %zu more warnings not shown.\n", m_WarningCount - MAX_WARNINGS_TO_SHOW);

+}

+

+void Player::ApplyConfig(ConfigurationParser& configParser)

+{

+    configParser.Compare(*m_DevProps, *m_MemProps, m_DedicatedAllocationEnabled);

+}

+

+void Player::ExecuteLine(size_t lineNumber, const StrRange& line)

+{

+    CsvSplit csvSplit;

+    csvSplit.Set(line);

+

+    if(csvSplit.GetCount() >= FIRST_PARAM_INDEX)

+    {

+        // Check thread ID.

+        uint32_t threadId;

+        if(StrRangeToUint(csvSplit.GetRange(0), threadId))

+        {

+            const auto it = m_Threads.find(threadId);

+            if(it != m_Threads.end())

+            {

+                ++it->second.callCount;

+            }

+            else

+            {

+                Thread threadInfo{};

+                threadInfo.callCount = 1;

+                m_Threads[threadId] = threadInfo;

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Incorrect thread ID.\n", lineNumber);

+            }

+        }

+

+        // Save time.

+        csvSplit.GetRange(1).to_str(m_LastLineTimeStr);

+

+        // Update VMA current frame index.

+        StrRange frameIndexStr = csvSplit.GetRange(2);

+        uint32_t frameIndex;

+        if(StrRangeToUint(frameIndexStr, frameIndex))

+        {

+            if(frameIndex != m_VmaFrameIndex)

+            {

+                vmaSetCurrentFrameIndex(m_Allocator, frameIndex);

+                m_VmaFrameIndex = frameIndex;

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Incorrect frame index.\n", lineNumber);

+            }

+        }

+

+        StrRange functionName = csvSplit.GetRange(3);

+

+        if(StrRangeEq(functionName, "vmaCreateAllocator"))

+        {

+            if(ValidateFunctionParameterCount(lineNumber, csvSplit, 0, false))

+            {

+                // Nothing.

+            }

+        }

+        else if(StrRangeEq(functionName, "vmaDestroyAllocator"))

+        {

+            if(ValidateFunctionParameterCount(lineNumber, csvSplit, 0, false))

+            {

+                // Nothing.

+            }

+        }

+        else if(StrRangeEq(functionName, "vmaCreatePool"))

+            ExecuteCreatePool(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaDestroyPool"))

+            ExecuteDestroyPool(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaSetAllocationUserData"))

+            ExecuteSetAllocationUserData(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaCreateBuffer"))

+            ExecuteCreateBuffer(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaDestroyBuffer"))

+            ExecuteDestroyBuffer(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaCreateImage"))

+            ExecuteCreateImage(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaDestroyImage"))

+            ExecuteDestroyImage(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaFreeMemory"))

+            ExecuteFreeMemory(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaCreateLostAllocation"))

+            ExecuteCreateLostAllocation(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaAllocateMemory"))

+            ExecuteAllocateMemory(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaAllocateMemoryForBuffer"))

+            ExecuteAllocateMemoryForBufferOrImage(lineNumber, csvSplit, OBJECT_TYPE::BUFFER);

+        else if(StrRangeEq(functionName, "vmaAllocateMemoryForImage"))

+            ExecuteAllocateMemoryForBufferOrImage(lineNumber, csvSplit, OBJECT_TYPE::IMAGE);

+        else if(StrRangeEq(functionName, "vmaMapMemory"))

+            ExecuteMapMemory(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaUnmapMemory"))

+            ExecuteUnmapMemory(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaFlushAllocation"))

+            ExecuteFlushAllocation(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaInvalidateAllocation"))

+            ExecuteInvalidateAllocation(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaTouchAllocation"))

+            ExecuteTouchAllocation(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaGetAllocationInfo"))

+            ExecuteGetAllocationInfo(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, "vmaMakePoolAllocationsLost"))

+            ExecuteMakePoolAllocationsLost(lineNumber, csvSplit);

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Unknown function.\n", lineNumber);

+            }

+        }

+    }

+    else

+    {

+        if(IssueWarning())

+        {

+            printf("Line %zu: Too few columns.\n", lineNumber);

+        }

+    }

+}

+

+void Player::DumpStats(const char* fileNameFormat, size_t lineNumber, bool detailed)

+{

+    char* pStatsString = nullptr;

+    vmaBuildStatsString(m_Allocator, &pStatsString, detailed ? VK_TRUE : VK_FALSE);

+

+    char fileName[MAX_PATH];

+    sprintf_s(fileName, fileNameFormat, lineNumber);

+

+    FILE* file = nullptr;

+    errno_t err = fopen_s(&file, fileName, "wb");

+    if(err == 0)

+    {

+        fwrite(pStatsString, 1, strlen(pStatsString), file);

+        fclose(file);

+    }

+    else

+    {

+        printf("ERROR: Failed to write file: %s\n", fileName);

+    }

+

+    vmaFreeStatsString(m_Allocator, pStatsString);

+}

+

+void Player::Destroy(const Allocation& alloc)

+{

+    if(alloc.buffer)

+    {

+        assert(alloc.image == VK_NULL_HANDLE);

+        vmaDestroyBuffer(m_Allocator, alloc.buffer, alloc.allocation);

+    }

+    else if(alloc.image)

+    {

+        vmaDestroyImage(m_Allocator, alloc.image, alloc.allocation);

+    }

+    else

+        vmaFreeMemory(m_Allocator, alloc.allocation);

+}

+

+bool Player::FindPool(size_t lineNumber, uint64_t origPool, VmaPool& outPool)

+{

+    outPool = VK_NULL_HANDLE;

+

+    if(origPool != 0)

+    {

+        const auto poolIt = m_Pools.find(origPool);

+        if(poolIt != m_Pools.end())

+        {

+            outPool = poolIt->second.pool;

+            return true;

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Pool %llX not found.\n", lineNumber, origPool);

+            }

+        }

+    }

+

+    return true;

+}

+

+void Player::AddAllocation(size_t lineNumber, uint64_t origPtr, VkResult res, const char* functionName, Allocation&& allocDesc)

+{

+    if(origPtr)

+    {

+        if(res == VK_SUCCESS)

+        {

+            // Originally succeeded, currently succeeded.

+            // Just save pointer (done below).

+        }

+        else

+        {

+            // Originally succeeded, currently failed.

+            // Print warning. Save null pointer.

+            if(IssueWarning())

+            {

+                printf("Line %zu: %s failed (%d), while originally succeeded.\n", lineNumber, functionName, res);

+            }

+        }

+

+        const auto existingIt = m_Allocations.find(origPtr);

+        if(existingIt != m_Allocations.end())

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Allocation %llX already exists.\n", lineNumber, origPtr);

+            }

+        }

+        m_Allocations[origPtr] = std::move(allocDesc);

+    }

+    else

+    {

+        if(res == VK_SUCCESS)

+        {

+            // Originally failed, currently succeeded.

+            // Print warning, destroy the object.

+            if(IssueWarning())

+            {

+                printf("Line %zu: %s succeeded, originally failed.\n", lineNumber, functionName);

+            }

+

+            Destroy(allocDesc);

+        }

+        else

+        {

+            // Originally failed, currently failed.

+            // Print warning.

+            if(IssueWarning())

+            {

+                printf("Line %zu: %s failed (%d), originally also failed.\n", lineNumber, functionName, res);

+            }

+        }

+    }

+}

+

+bool Player::IssueWarning()

+{

+    if(g_Verbosity < VERBOSITY::MAXIMUM)

+    {

+        return m_WarningCount++ < MAX_WARNINGS_TO_SHOW;

+    }

+    else

+    {

+        ++m_WarningCount;

+        return true;

+    }

+}

+

+int Player::InitVulkan()

+{

+    if(g_Verbosity == VERBOSITY::MAXIMUM)

+    {

+        printf("Initializing Vulkan...\n");

+    }

+

+    uint32_t instanceLayerPropCount = 0;

+    VkResult res = vkEnumerateInstanceLayerProperties(&instanceLayerPropCount, nullptr);

+    assert(res == VK_SUCCESS);

+

+    std::vector<VkLayerProperties> instanceLayerProps(instanceLayerPropCount);

+    if(instanceLayerPropCount > 0)

+    {

+        res = vkEnumerateInstanceLayerProperties(&instanceLayerPropCount, instanceLayerProps.data());

+        assert(res == VK_SUCCESS);

+    }

+

+    const bool validationLayersAvailable =

+        IsLayerSupported(instanceLayerProps.data(), instanceLayerProps.size(), VALIDATION_LAYER_NAME);

+

+    bool validationLayersEnabled = false;

+    switch(g_VK_LAYER_LUNARG_standard_validation)

+    {

+    case VULKAN_EXTENSION_REQUEST::DISABLED:

+        break;

+    case VULKAN_EXTENSION_REQUEST::DEFAULT:

+        validationLayersEnabled = validationLayersAvailable;

+        break;

+    case VULKAN_EXTENSION_REQUEST::ENABLED:

+        validationLayersEnabled = validationLayersAvailable;

+        if(!validationLayersAvailable)

+        {

+            printf("WARNING: %s layer cannot be enabled.\n", VALIDATION_LAYER_NAME);

+        }

+        break;

+    default: assert(0);

+    }

+

+    std::vector<const char*> instanceExtensions;

+    //instanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);

+    //instanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);

+

+    std::vector<const char*> instanceLayers;

+    if(validationLayersEnabled)

+    {

+        instanceLayers.push_back(VALIDATION_LAYER_NAME);

+        instanceExtensions.push_back("VK_EXT_debug_report");

+    }

+

+    VkApplicationInfo appInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO };

+    appInfo.pApplicationName = "VmaReplay";

+    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);

+    appInfo.pEngineName = "Vulkan Memory Allocator";

+    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);

+    appInfo.apiVersion = VK_API_VERSION_1_0;

+

+    VkInstanceCreateInfo instInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };

+    instInfo.pApplicationInfo = &appInfo;

+    instInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size();

+    instInfo.ppEnabledExtensionNames = instanceExtensions.data();

+    instInfo.enabledLayerCount = (uint32_t)instanceLayers.size();

+    instInfo.ppEnabledLayerNames = instanceLayers.data();

+

+    res = vkCreateInstance(&instInfo, NULL, &m_VulkanInstance);

+    if(res != VK_SUCCESS)

+    {

+        printf("ERROR: vkCreateInstance failed (%d)\n", res);

+        return RESULT_ERROR_VULKAN;

+    }

+

+    if(validationLayersEnabled)

+    {

+        RegisterDebugCallbacks();

+    }

+

+    // Find physical device

+

+    uint32_t physicalDeviceCount = 0;

+    res = vkEnumeratePhysicalDevices(m_VulkanInstance, &physicalDeviceCount, nullptr);

+    assert(res == VK_SUCCESS);

+    if(physicalDeviceCount == 0)

+    {

+        printf("ERROR: No Vulkan physical devices found.\n");

+        return RESULT_ERROR_VULKAN;

+    }

+

+    std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);

+    res = vkEnumeratePhysicalDevices(m_VulkanInstance, &physicalDeviceCount, physicalDevices.data());

+    assert(res == VK_SUCCESS);

+

+    if(g_PhysicalDeviceIndex >= physicalDeviceCount)

+    {

+        printf("ERROR: Incorrect Vulkan physical device index %u. System has %u physical devices.\n",

+            g_PhysicalDeviceIndex,

+            physicalDeviceCount);

+        return RESULT_ERROR_VULKAN;

+    }

+

+    m_PhysicalDevice = physicalDevices[0];

+

+    // Find queue family index

+

+    uint32_t queueFamilyCount = 0;

+    vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &queueFamilyCount, nullptr);

+    if(queueFamilyCount)

+    {

+        std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);

+        vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &queueFamilyCount, queueFamilies.data());

+        for(uint32_t i = 0; i < queueFamilyCount; ++i)

+        {

+            if(queueFamilies[i].queueCount > 0 &&

+                (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)

+            {

+                m_GraphicsQueueFamilyIndex = i;

+                break;

+            }

+        }

+    }

+    if(m_GraphicsQueueFamilyIndex == UINT_MAX)

+    {

+        printf("ERROR: Couldn't find graphics queue.\n");

+        return RESULT_ERROR_VULKAN;

+    }

+

+    VkPhysicalDeviceFeatures supportedFeatures;

+    vkGetPhysicalDeviceFeatures(m_PhysicalDevice, &supportedFeatures);

+

+    // Create logical device

+

+    const float queuePriority = 1.f;

+

+    VkDeviceQueueCreateInfo deviceQueueCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };

+    deviceQueueCreateInfo.queueFamilyIndex = m_GraphicsQueueFamilyIndex;

+    deviceQueueCreateInfo.queueCount = 1;

+    deviceQueueCreateInfo.pQueuePriorities = &queuePriority;

+

+    // Enable something what may interact with memory/buffer/image support.

+    VkPhysicalDeviceFeatures enabledFeatures;

+    InitVulkanFeatures(enabledFeatures, supportedFeatures);

+

+    bool VK_KHR_get_memory_requirements2_available = false;

+    bool VK_KHR_dedicated_allocation_available = false;

+

+    // Determine list of device extensions to enable.

+    std::vector<const char*> enabledDeviceExtensions;

+    //enabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);

+    {

+        uint32_t propertyCount = 0;

+        res = vkEnumerateDeviceExtensionProperties(m_PhysicalDevice, nullptr, &propertyCount, nullptr);

+        assert(res == VK_SUCCESS);

+

+        if(propertyCount)

+        {

+            std::vector<VkExtensionProperties> properties{propertyCount};

+            res = vkEnumerateDeviceExtensionProperties(m_PhysicalDevice, nullptr, &propertyCount, properties.data());

+            assert(res == VK_SUCCESS);

+

+            for(uint32_t i = 0; i < propertyCount; ++i)

+            {

+                if(strcmp(properties[i].extensionName, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME) == 0)

+                {

+                    VK_KHR_get_memory_requirements2_available = true;

+                }

+                else if(strcmp(properties[i].extensionName, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0)

+                {

+                    VK_KHR_dedicated_allocation_available = true;

+                }

+            }

+        }

+    }

+

+    const bool dedicatedAllocationAvailable =

+        VK_KHR_get_memory_requirements2_available && VK_KHR_dedicated_allocation_available;

+

+    switch(g_VK_KHR_dedicated_allocation_request)

+    {

+    case VULKAN_EXTENSION_REQUEST::DISABLED:

+        break;

+    case VULKAN_EXTENSION_REQUEST::DEFAULT:

+        m_DedicatedAllocationEnabled = dedicatedAllocationAvailable;

+        break;

+    case VULKAN_EXTENSION_REQUEST::ENABLED:

+        m_DedicatedAllocationEnabled = dedicatedAllocationAvailable;

+        if(!dedicatedAllocationAvailable)

+        {

+            printf("WARNING: VK_KHR_dedicated_allocation extension cannot be enabled.\n");

+        }

+        break;

+    default: assert(0);

+    }

+

+    if(m_DedicatedAllocationEnabled)

+    {

+        enabledDeviceExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);

+        enabledDeviceExtensions.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);

+    }

+

+    VkDeviceCreateInfo deviceCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };

+    deviceCreateInfo.enabledExtensionCount = (uint32_t)enabledDeviceExtensions.size();

+    deviceCreateInfo.ppEnabledExtensionNames = !enabledDeviceExtensions.empty() ? enabledDeviceExtensions.data() : nullptr;

+    deviceCreateInfo.queueCreateInfoCount = 1;

+    deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;

+    deviceCreateInfo.pEnabledFeatures = &enabledFeatures;

+

+    res = vkCreateDevice(m_PhysicalDevice, &deviceCreateInfo, nullptr, &m_Device);

+    if(res != VK_SUCCESS)

+    {

+        printf("ERROR: vkCreateDevice failed (%d)\n", res);

+        return RESULT_ERROR_VULKAN;

+    }

+

+    // Create memory allocator

+

+    VmaAllocatorCreateInfo allocatorInfo = {};

+    allocatorInfo.physicalDevice = m_PhysicalDevice;

+    allocatorInfo.device = m_Device;

+    allocatorInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;

+

+    if(m_DedicatedAllocationEnabled)

+    {

+        allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;

+    }

+

+    res = vmaCreateAllocator(&allocatorInfo, &m_Allocator);

+    if(res != VK_SUCCESS)

+    {

+        printf("ERROR: vmaCreateAllocator failed (%d)\n", res);

+        return RESULT_ERROR_VULKAN;

+    }

+

+    vmaGetPhysicalDeviceProperties(m_Allocator, &m_DevProps);

+    vmaGetMemoryProperties(m_Allocator, &m_MemProps);

+

+    return 0;

+}

+

+void Player::FinalizeVulkan()

+{

+    if(!m_Allocations.empty())

+    {

+        printf("WARNING: Allocations not destroyed: %zu.\n", m_Allocations.size());

+

+        if(CLEANUP_LEAKED_OBJECTS)

+        {

+            for(const auto it : m_Allocations)

+            {

+                Destroy(it.second);

+            }

+        }

+

+        m_Allocations.clear();

+    }

+

+    if(!m_Pools.empty())

+    {

+        printf("WARNING: Custom pools not destroyed: %zu.\n", m_Pools.size());

+

+        if(CLEANUP_LEAKED_OBJECTS)

+        {

+            for(const auto it : m_Pools)

+            {

+                vmaDestroyPool(m_Allocator, it.second.pool);

+            }

+        }

+

+        m_Pools.clear();

+    }

+

+    vkDeviceWaitIdle(m_Device);

+

+    if(m_Allocator != VK_NULL_HANDLE)

+    {

+        vmaDestroyAllocator(m_Allocator);

+        m_Allocator = nullptr;

+    }

+

+    if(m_Device != VK_NULL_HANDLE)

+    {

+        vkDestroyDevice(m_Device, nullptr);

+        m_Device = nullptr;

+    }

+

+    if(m_pvkDestroyDebugReportCallbackEXT && m_hCallback != VK_NULL_HANDLE)

+    {

+        m_pvkDestroyDebugReportCallbackEXT(m_VulkanInstance, m_hCallback, nullptr);

+        m_hCallback = VK_NULL_HANDLE;

+    }

+

+    if(m_VulkanInstance != VK_NULL_HANDLE)

+    {

+        vkDestroyInstance(m_VulkanInstance, NULL);

+        m_VulkanInstance = VK_NULL_HANDLE;

+    }

+}

+

+void Player::RegisterDebugCallbacks()

+{

+    m_pvkCreateDebugReportCallbackEXT =

+        reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>

+            (vkGetInstanceProcAddr(m_VulkanInstance, "vkCreateDebugReportCallbackEXT"));

+    m_pvkDebugReportMessageEXT =

+        reinterpret_cast<PFN_vkDebugReportMessageEXT>

+            (vkGetInstanceProcAddr(m_VulkanInstance, "vkDebugReportMessageEXT"));

+    m_pvkDestroyDebugReportCallbackEXT =

+        reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>

+            (vkGetInstanceProcAddr(m_VulkanInstance, "vkDestroyDebugReportCallbackEXT"));

+    assert(m_pvkCreateDebugReportCallbackEXT);

+    assert(m_pvkDebugReportMessageEXT);

+    assert(m_pvkDestroyDebugReportCallbackEXT);

+

+    VkDebugReportCallbackCreateInfoEXT callbackCreateInfo = { VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT };

+    callbackCreateInfo.flags = //VK_DEBUG_REPORT_INFORMATION_BIT_EXT |

+        VK_DEBUG_REPORT_ERROR_BIT_EXT |

+        VK_DEBUG_REPORT_WARNING_BIT_EXT |

+        VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT /*|

+        VK_DEBUG_REPORT_DEBUG_BIT_EXT*/;

+    callbackCreateInfo.pfnCallback = &MyDebugReportCallback;

+

+    VkResult res = m_pvkCreateDebugReportCallbackEXT(m_VulkanInstance, &callbackCreateInfo, nullptr, &m_hCallback);

+    assert(res == VK_SUCCESS);

+}

+

+void Player::PrintStats()

+{

+    if(g_Verbosity == VERBOSITY::MINIMUM)

+    {

+        return;

+    }

+

+    printf("Statistics:\n");

+    if(m_Stats.GetAllocationCreationCount() > 0)

+    {

+        printf("    Total allocations created: %zu\n", m_Stats.GetAllocationCreationCount());

+    }

+

+    // Buffers

+    const size_t bufferCreationCount =

+        m_Stats.GetBufferCreationCount(0) +

+        m_Stats.GetBufferCreationCount(1) +

+        m_Stats.GetBufferCreationCount(2) +

+        m_Stats.GetBufferCreationCount(3);

+    if(bufferCreationCount > 0)

+    {

+        printf("    Total buffers created: %zu\n", bufferCreationCount);

+        if(g_Verbosity == VERBOSITY::MAXIMUM)

+        {

+            printf("        Class 0 (indirect/vertex/index): %zu\n", m_Stats.GetBufferCreationCount(0));

+            printf("        Class 1 (storage): %zu\n", m_Stats.GetBufferCreationCount(1));

+            printf("        Class 2 (uniform): %zu\n", m_Stats.GetBufferCreationCount(2));

+            printf("        Class 3 (other): %zu\n", m_Stats.GetBufferCreationCount(3));

+        }

+    }

+    

+    // Images

+    const size_t imageCreationCount =

+        m_Stats.GetImageCreationCount(0) +

+        m_Stats.GetImageCreationCount(1) +

+        m_Stats.GetImageCreationCount(2) +

+        m_Stats.GetImageCreationCount(3) +

+        m_Stats.GetLinearImageCreationCount();

+    if(imageCreationCount > 0)

+    {

+        printf("    Total images created: %zu\n", imageCreationCount);

+        if(g_Verbosity == VERBOSITY::MAXIMUM)

+        {

+            printf("        Class 0 (depth/stencil): %zu\n", m_Stats.GetImageCreationCount(0));

+            printf("        Class 1 (attachment): %zu\n", m_Stats.GetImageCreationCount(1));

+            printf("        Class 2 (sampled): %zu\n", m_Stats.GetImageCreationCount(2));

+            printf("        Class 3 (other): %zu\n", m_Stats.GetImageCreationCount(3));

+            if(m_Stats.GetLinearImageCreationCount() > 0)

+            {

+                printf("        LINEAR tiling: %zu\n", m_Stats.GetLinearImageCreationCount());

+            }

+        }

+    }

+    

+    if(m_Stats.GetPoolCreationCount() > 0)

+    {

+        printf("    Total custom pools created: %zu\n", m_Stats.GetPoolCreationCount());

+    }

+

+    float lastTime;

+    if(!m_LastLineTimeStr.empty() && StrRangeToFloat(StrRange(m_LastLineTimeStr), lastTime))

+    {

+        std::string origTimeStr;

+        SecondsToFriendlyStr(lastTime, origTimeStr);

+        printf("    Original recording time: %s\n", origTimeStr.c_str());

+    }

+

+    // Thread statistics.

+    const size_t threadCount = m_Threads.size();

+    if(threadCount > 1)

+    {

+        uint32_t threadCallCountMax = 0;

+        uint32_t threadCallCountSum = 0;

+        for(const auto& it : m_Threads)

+        {

+            threadCallCountMax = std::max(threadCallCountMax, it.second.callCount);

+            threadCallCountSum += it.second.callCount;

+        }

+        printf("    Threads making calls to VMA: %zu\n", threadCount);

+        printf("        %.2f%% calls from most active thread.\n",

+            (float)threadCallCountMax * 100.f / (float)threadCallCountSum);

+    }

+    else

+    {

+        printf("    VMA used from only one thread.\n");

+    }

+

+    // Function call count

+    if(g_Verbosity == VERBOSITY::MAXIMUM)

+    {

+        printf("    Function call count:\n");

+        const size_t* const functionCallCount = m_Stats.GetFunctionCallCount();

+        for(size_t i = 0; i < (size_t)VMA_FUNCTION::Count; ++i)

+        {

+            if(functionCallCount[i] > 0)

+            {

+                printf("        %s %zu\n", VMA_FUNCTION_NAMES[i], functionCallCount[i]);

+            }

+        }

+    }

+

+    if(g_MemStatsEnabled)

+    {

+        m_Stats.PrintMemStats();

+    }

+}

+

+bool Player::ValidateFunctionParameterCount(size_t lineNumber, const CsvSplit& csvSplit, size_t expectedParamCount, bool lastUnbound)

+{

+    bool ok;

+    if(lastUnbound)

+        ok = csvSplit.GetCount() >= FIRST_PARAM_INDEX + expectedParamCount - 1;

+    else

+        ok = csvSplit.GetCount() == FIRST_PARAM_INDEX + expectedParamCount;

+

+    if(!ok)

+    {

+        if(IssueWarning())

+        {

+            printf("Line %zu: Incorrect number of function parameters.\n", lineNumber);

+        }

+    }

+

+    return ok;

+}

+

+bool Player::PrepareUserData(size_t lineNumber, uint32_t allocCreateFlags, const StrRange& userDataColumn, const StrRange& wholeLine, void*& outUserData)

+{

+    if(!g_UserDataEnabled)

+    {

+        outUserData = nullptr;

+        return true;

+    }

+

+    // String

+    if((allocCreateFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0)

+    {

+        const size_t len = wholeLine.end - userDataColumn.beg;

+        m_UserDataTmpStr.resize(len + 1);

+        memcpy(m_UserDataTmpStr.data(), userDataColumn.beg, len);

+        m_UserDataTmpStr[len] = '\0';

+        outUserData = m_UserDataTmpStr.data();

+        return true;

+    }

+    // Pointer

+    else

+    {

+        uint64_t pUserData = 0;

+        if(StrRangeToPtr(userDataColumn, pUserData))

+        {

+            outUserData = (void*)(uintptr_t)pUserData;

+            return true;

+        }

+    }

+

+    if(IssueWarning())

+    {

+        printf("Line %zu: Invalid pUserData.\n", lineNumber);

+    }

+    outUserData = 0;

+    return false;

+}

+

+void Player::UpdateMemStats()

+{

+    if(!g_MemStatsEnabled)

+    {

+        return;

+    }

+

+    VmaStats stats;

+    vmaCalculateStats(m_Allocator, &stats);

+    m_Stats.UpdateMemStats(stats);

+}

+

+void Player::ExecuteCreatePool(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreatePool);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 7, false))

+    {

+        VmaPoolCreateInfo poolCreateInfo = {};

+        uint64_t origPtr = 0;

+

+        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), poolCreateInfo.memoryTypeIndex) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), poolCreateInfo.flags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), poolCreateInfo.blockSize) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), poolCreateInfo.minBlockCount) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), poolCreateInfo.maxBlockCount) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), poolCreateInfo.frameInUseCount) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), origPtr))

+        {

+            m_Stats.RegisterCreatePool();

+

+            Pool poolDesc = {};

+            VkResult res = vmaCreatePool(m_Allocator, &poolCreateInfo, &poolDesc.pool);

+

+            if(origPtr)

+            {

+                if(res == VK_SUCCESS)

+                {

+                    // Originally succeeded, currently succeeded.

+                    // Just save pointer (done below).

+                }

+                else

+                {

+                    // Originally succeeded, currently failed.

+                    // Print warning. Save null pointer.

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: vmaCreatePool failed (%d), while originally succeeded.\n", lineNumber, res);

+                    }

+               }

+

+                const auto existingIt = m_Pools.find(origPtr);

+                if(existingIt != m_Pools.end())

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Pool %llX already exists.\n", lineNumber, origPtr);

+                    }

+                }

+                m_Pools[origPtr] = poolDesc;

+            }

+            else

+            {

+                if(res == VK_SUCCESS)

+                {

+                    // Originally failed, currently succeeded.

+                    // Print warning, destroy the pool.

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: vmaCreatePool succeeded, originally failed.\n", lineNumber);

+                    }

+

+                    vmaDestroyPool(m_Allocator, poolDesc.pool);

+                }

+                else

+                {

+                    // Originally failed, currently failed.

+                    // Print warning.

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: vmaCreatePool failed (%d), originally also failed.\n", lineNumber, res);

+                    }

+                }

+            }

+

+            UpdateMemStats();

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaCreatePool.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteDestroyPool(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyPool);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origPtr = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            if(origPtr != 0)

+            {

+                const auto it = m_Pools.find(origPtr);

+                if(it != m_Pools.end())

+                {

+                    vmaDestroyPool(m_Allocator, it->second.pool);

+                    UpdateMemStats();

+                    m_Pools.erase(it);

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Pool %llX not found.\n", lineNumber, origPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaDestroyPool.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteSetAllocationUserData(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::SetAllocationUserData);

+

+    if(!g_UserDataEnabled)

+    {

+        return;

+    }

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 2, true))

+    {

+        uint64_t origPtr = 0;

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            const auto it = m_Allocations.find(origPtr);

+            if(it != m_Allocations.end())

+            {

+                void* pUserData = nullptr;

+                if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 1)

+                {

+                    PrepareUserData(

+                        lineNumber,

+                        it->second.allocationFlags,

+                        csvSplit.GetRange(FIRST_PARAM_INDEX + 1),

+                        csvSplit.GetLine(),

+                        pUserData);

+                }

+

+                vmaSetAllocationUserData(m_Allocator, it->second.allocation, pUserData);

+            }

+            else

+            {

+                if(IssueWarning())

+                {

+                    printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaSetAllocationUserData.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreateBuffer);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 12, true))

+    {

+        VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };

+        VmaAllocationCreateInfo allocCreateInfo = {};

+        uint64_t origPool = 0;

+        uint64_t origPtr = 0;

+

+        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), bufCreateInfo.flags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), bufCreateInfo.size) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), bufCreateInfo.usage) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), (uint32_t&)bufCreateInfo.sharingMode) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), allocCreateInfo.flags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), (uint32_t&)allocCreateInfo.usage) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), allocCreateInfo.requiredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), allocCreateInfo.preferredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), allocCreateInfo.memoryTypeBits) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), origPool) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 10), origPtr))

+        {

+            FindPool(lineNumber, origPool, allocCreateInfo.pool);

+

+            if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 11)

+            {

+                PrepareUserData(

+                    lineNumber,

+                    allocCreateInfo.flags,

+                    csvSplit.GetRange(FIRST_PARAM_INDEX + 11),

+                    csvSplit.GetLine(),

+                    allocCreateInfo.pUserData);

+            }

+

+            m_Stats.RegisterCreateBuffer(bufCreateInfo.usage);

+

+            Allocation allocDesc = { };

+            allocDesc.allocationFlags = allocCreateInfo.flags;

+            VkResult res = vmaCreateBuffer(m_Allocator, &bufCreateInfo, &allocCreateInfo, &allocDesc.buffer, &allocDesc.allocation, nullptr);

+            UpdateMemStats();

+            AddAllocation(lineNumber, origPtr, res, "vmaCreateBuffer", std::move(allocDesc));

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaCreateBuffer.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origAllocPtr = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origAllocPtr))

+        {

+            if(origAllocPtr != 0)

+            {

+                const auto it = m_Allocations.find(origAllocPtr);

+                if(it != m_Allocations.end())

+                {

+                    Destroy(it->second);

+                    UpdateMemStats();

+                    m_Allocations.erase(it);

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origAllocPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaDestroyBuffer.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreateImage);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 21, true))

+    {

+        VkImageCreateInfo imageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };

+        VmaAllocationCreateInfo allocCreateInfo = {};

+        uint64_t origPool = 0;

+        uint64_t origPtr = 0;

+

+        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), imageCreateInfo.flags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), (uint32_t&)imageCreateInfo.imageType) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), (uint32_t&)imageCreateInfo.format) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), imageCreateInfo.extent.width) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), imageCreateInfo.extent.height) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), imageCreateInfo.extent.depth) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), imageCreateInfo.mipLevels) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), imageCreateInfo.arrayLayers) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), (uint32_t&)imageCreateInfo.samples) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), (uint32_t&)imageCreateInfo.tiling) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 10), imageCreateInfo.usage) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 11), (uint32_t&)imageCreateInfo.sharingMode) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 12), (uint32_t&)imageCreateInfo.initialLayout) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 13), allocCreateInfo.flags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 14), (uint32_t&)allocCreateInfo.usage) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 15), allocCreateInfo.requiredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 16), allocCreateInfo.preferredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 17), allocCreateInfo.memoryTypeBits) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 18), origPool) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 19), origPtr))

+        {

+            FindPool(lineNumber, origPool, allocCreateInfo.pool);

+

+            if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 20)

+            {

+                PrepareUserData(

+                    lineNumber,

+                    allocCreateInfo.flags,

+                    csvSplit.GetRange(FIRST_PARAM_INDEX + 20),

+                    csvSplit.GetLine(),

+                    allocCreateInfo.pUserData);

+            }

+

+            m_Stats.RegisterCreateImage(imageCreateInfo.usage, imageCreateInfo.tiling);

+

+            Allocation allocDesc = {};

+            allocDesc.allocationFlags = allocCreateInfo.flags;

+            VkResult res = vmaCreateImage(m_Allocator, &imageCreateInfo, &allocCreateInfo, &allocDesc.image, &allocDesc.allocation, nullptr);

+            UpdateMemStats();

+            AddAllocation(lineNumber, origPtr, res, "vmaCreateImage", std::move(allocDesc));

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaCreateImage.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteCreateLostAllocation(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreateLostAllocation);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origPtr = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            Allocation allocDesc = {};

+            vmaCreateLostAllocation(m_Allocator, &allocDesc.allocation);

+            UpdateMemStats();

+            m_Stats.RegisterCreateAllocation();

+

+            AddAllocation(lineNumber, origPtr, VK_SUCCESS, "vmaCreateLostAllocation", std::move(allocDesc));

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaCreateLostAllocation.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteAllocateMemory(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemory);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 11, true))

+    {

+        VkMemoryRequirements memReq = {};

+        VmaAllocationCreateInfo allocCreateInfo = {};

+        uint64_t origPool = 0;

+        uint64_t origPtr = 0;

+

+        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), memReq.size) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), memReq.alignment) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), memReq.memoryTypeBits) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), allocCreateInfo.flags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), (uint32_t&)allocCreateInfo.usage) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), allocCreateInfo.requiredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), allocCreateInfo.preferredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), allocCreateInfo.memoryTypeBits) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), origPool) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), origPtr))

+        {

+            FindPool(lineNumber, origPool, allocCreateInfo.pool);

+

+            if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 10)

+            {

+                PrepareUserData(

+                    lineNumber,

+                    allocCreateInfo.flags,

+                    csvSplit.GetRange(FIRST_PARAM_INDEX + 10),

+                    csvSplit.GetLine(),

+                    allocCreateInfo.pUserData);

+            }

+

+            UpdateMemStats();

+            m_Stats.RegisterCreateAllocation();

+

+            Allocation allocDesc = {};

+            allocDesc.allocationFlags = allocCreateInfo.flags;

+            VkResult res = vmaAllocateMemory(m_Allocator, &memReq, &allocCreateInfo, &allocDesc.allocation, nullptr);

+            AddAllocation(lineNumber, origPtr, res, "vmaAllocateMemory", std::move(allocDesc));

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaAllocateMemory.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteAllocateMemoryForBufferOrImage(size_t lineNumber, const CsvSplit& csvSplit, OBJECT_TYPE objType)

+{

+    switch(objType)

+    {

+    case OBJECT_TYPE::BUFFER:

+        m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemoryForBuffer);

+        break;

+    case OBJECT_TYPE::IMAGE:

+        m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemoryForImage);

+        break;

+    default: assert(0);

+    }

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 13, true))

+    {

+        VkMemoryRequirements memReq = {};

+        VmaAllocationCreateInfo allocCreateInfo = {};

+        bool requiresDedicatedAllocation = false;

+        bool prefersDedicatedAllocation = false;

+        uint64_t origPool = 0;

+        uint64_t origPtr = 0;

+

+        if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), memReq.size) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), memReq.alignment) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), memReq.memoryTypeBits) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), allocCreateInfo.flags) &&

+            StrRangeToBool(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), requiresDedicatedAllocation) &&

+            StrRangeToBool(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), prefersDedicatedAllocation) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), (uint32_t&)allocCreateInfo.usage) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), allocCreateInfo.requiredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), allocCreateInfo.preferredFlags) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), allocCreateInfo.memoryTypeBits) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 10), origPool) &&

+            StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 11), origPtr))

+        {

+            FindPool(lineNumber, origPool, allocCreateInfo.pool);

+

+            if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 12)

+            {

+                PrepareUserData(

+                    lineNumber,

+                    allocCreateInfo.flags,

+                    csvSplit.GetRange(FIRST_PARAM_INDEX + 12),

+                    csvSplit.GetLine(),

+                    allocCreateInfo.pUserData);

+            }

+

+            if(requiresDedicatedAllocation || prefersDedicatedAllocation)

+            {

+                allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;

+            }

+

+            if(!m_AllocateForBufferImageWarningIssued)

+            {

+                if(IssueWarning())

+                {

+                    printf("Line %zu: vmaAllocateMemoryForBuffer or vmaAllocateMemoryForImage cannot be replayed accurately. Using vmaCreateAllocation instead.\n", lineNumber);

+                }

+                m_AllocateForBufferImageWarningIssued = true;

+            }

+

+            UpdateMemStats();

+            m_Stats.RegisterCreateAllocation();

+

+            Allocation allocDesc = {};

+            allocDesc.allocationFlags = allocCreateInfo.flags;

+            VkResult res = vmaAllocateMemory(m_Allocator, &memReq, &allocCreateInfo, &allocDesc.allocation, nullptr);

+            AddAllocation(lineNumber, origPtr, res, "vmaAllocateMemory (called as vmaAllocateMemoryForBuffer or vmaAllocateMemoryForImage)", std::move(allocDesc));

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaAllocateMemoryForBuffer or vmaAllocateMemoryForImage.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteMapMemory(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::MapMemory);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origPtr = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            if(origPtr != 0)

+            {

+                const auto it = m_Allocations.find(origPtr);

+                if(it != m_Allocations.end())

+                {

+                    if(it->second.allocation)

+                    {

+                        void* pData;

+                        VkResult res = vmaMapMemory(m_Allocator, it->second.allocation, &pData);

+                        if(res != VK_SUCCESS)

+                        {

+                            printf("Line %zu: vmaMapMemory failed (%d)\n", lineNumber, res);

+                        }

+                    }

+                    else

+                    {

+                        if(IssueWarning())

+                        {

+                            printf("Line %zu: Cannot call vmaMapMemory - allocation is null.\n", lineNumber);

+                        }

+                    }

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaMapMemory.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteUnmapMemory(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::UnmapMemory);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origPtr = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            if(origPtr != 0)

+            {

+                const auto it = m_Allocations.find(origPtr);

+                if(it != m_Allocations.end())

+                {

+                    if(it->second.allocation)

+                    {

+                        vmaUnmapMemory(m_Allocator, it->second.allocation);

+                    }

+                    else

+                    {

+                        if(IssueWarning())

+                        {

+                            printf("Line %zu: Cannot call vmaUnmapMemory - allocation is null.\n", lineNumber);

+                        }

+                    }

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaMapMemory.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteFlushAllocation(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::FlushAllocation);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 3, false))

+    {

+        uint64_t origPtr = 0;

+        uint64_t offset = 0;

+        uint64_t size = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), offset) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), size))

+        {

+            if(origPtr != 0)

+            {

+                const auto it = m_Allocations.find(origPtr);

+                if(it != m_Allocations.end())

+                {

+                    if(it->second.allocation)

+                    {

+                        vmaFlushAllocation(m_Allocator, it->second.allocation, offset, size);

+                    }

+                    else

+                    {

+                        if(IssueWarning())

+                        {

+                            printf("Line %zu: Cannot call vmaFlushAllocation - allocation is null.\n", lineNumber);

+                        }

+                    }

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaFlushAllocation.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteInvalidateAllocation(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::InvalidateAllocation);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 3, false))

+    {

+        uint64_t origPtr = 0;

+        uint64_t offset = 0;

+        uint64_t size = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), offset) &&

+            StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), size))

+        {

+            if(origPtr != 0)

+            {

+                const auto it = m_Allocations.find(origPtr);

+                if(it != m_Allocations.end())

+                {

+                    if(it->second.allocation)

+                    {

+                        vmaInvalidateAllocation(m_Allocator, it->second.allocation, offset, size);

+                    }

+                    else

+                    {

+                        if(IssueWarning())

+                        {

+                            printf("Line %zu: Cannot call vmaInvalidateAllocation - allocation is null.\n", lineNumber);

+                        }

+                    }

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaInvalidateAllocation.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteTouchAllocation(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::TouchAllocation);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origPtr = 0;

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            const auto it = m_Allocations.find(origPtr);

+            if(it != m_Allocations.end())

+            {

+                if(it->second.allocation)

+                {

+                    vmaTouchAllocation(m_Allocator, it->second.allocation);

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Cannot call vmaTouchAllocation - allocation is null.\n", lineNumber);

+                    }

+                }

+            }

+            else

+            {

+                if(IssueWarning())

+                {

+                    printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaTouchAllocation.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteGetAllocationInfo(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::GetAllocationInfo);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origPtr = 0;

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            const auto it = m_Allocations.find(origPtr);

+            if(it != m_Allocations.end())

+            {

+                if(it->second.allocation)

+                {

+                    VmaAllocationInfo allocInfo;

+                    vmaGetAllocationInfo(m_Allocator, it->second.allocation, &allocInfo);

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Cannot call vmaGetAllocationInfo - allocation is null.\n", lineNumber);

+                    }

+                }

+            }

+            else

+            {

+                if(IssueWarning())

+                {

+                    printf("Line %zu: Allocation %llX not found.\n", lineNumber, origPtr);

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaGetAllocationInfo.\n", lineNumber);

+            }

+        }

+    }

+}

+

+void Player::ExecuteMakePoolAllocationsLost(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::MakePoolAllocationsLost);

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))

+    {

+        uint64_t origPtr = 0;

+

+        if(StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX), origPtr))

+        {

+            if(origPtr != 0)

+            {

+                const auto it = m_Pools.find(origPtr);

+                if(it != m_Pools.end())

+                {

+                    vmaMakePoolAllocationsLost(m_Allocator, it->second.pool, nullptr);

+                    UpdateMemStats();

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Pool %llX not found.\n", lineNumber, origPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaMakePoolAllocationsLost.\n", lineNumber);

+            }

+        }

+    }

+}

+

+////////////////////////////////////////////////////////////////////////////////

+// Main functions

+

+static void PrintCommandLineSyntax()

+{

+    printf(

+        "Command line syntax:\n"

+        "    VmaReplay [Options] <SrcFile.csv>\n"

+        "Available options:\n"

+        "    -v <Number> - Verbosity level:\n"

+        "        0 - Minimum verbosity. Prints only warnings and errors.\n"

+        "        1 - Default verbosity. Prints important messages and statistics.\n"

+        "        2 - Maximum verbosity. Prints a lot of information.\n"

+        "    -i <Number> - Repeat playback given number of times (iterations)\n"

+        "        Default is 1. Vulkan is reinitialized with every iteration.\n"

+        "    --MemStats <Value> - 0 to disable or 1 to enable memory statistics.\n"

+        "        Default is 0. Enabling it may negatively impact playback performance.\n"

+        "    --DumpStatsAfterLine <Line> - Dump VMA statistics to JSON file after specified source file line finishes execution.\n"

+        "        File is written to current directory with name: VmaReplay_Line####.json.\n"

+        "        This parameter can be repeated.\n"

+        "    --DumpDetailedStatsAfterLine <Line> - Like command above, but includes detailed map.\n"

+        "    --Lines <Ranges> - Replay only limited set of lines from file\n"

+        "        Ranges is comma-separated list of ranges, e.g. \"-10,15,18-25,31-\".\n"

+        "    --PhysicalDevice <Index> - Choice of Vulkan physical device. Default: 0.\n"

+        "    --UserData <Value> - 0 to disable or 1 to enable setting pUserData during playback.\n"

+        "        Default is 1. Affects both creation of buffers and images, as well as calls to vmaSetAllocationUserData.\n"

+        "    --VK_LAYER_LUNARG_standard_validation <Value> - 0 to disable or 1 to enable validation layers.\n"

+        "        By default the layers are silently enabled if available.\n"

+        "    --VK_KHR_dedicated_allocation <Value> - 0 to disable or 1 to enable this extension.\n"

+        "        By default the extension is silently enabled if available.\n"

+    );

+}

+

+static int ProcessFile(size_t iterationIndex, const char* data, size_t numBytes, duration& outDuration)

+{

+    outDuration = duration::max();

+

+    const bool useLineRanges = !g_LineRanges.IsEmpty();

+    const bool useDumpStatsAfterLine = !g_DumpStatsAfterLine.empty();

+

+    LineSplit lineSplit(data, numBytes);

+    StrRange line;

+

+    if(!lineSplit.GetNextLine(line) ||

+        !StrRangeEq(line, "Vulkan Memory Allocator,Calls recording"))

+    {

+        printf("ERROR: Incorrect file format.\n");

+        return RESULT_ERROR_FORMAT;

+    }

+

+    if(!lineSplit.GetNextLine(line) || !ParseFileVersion(line) || !ValidateFileVersion())

+    {

+        printf("ERROR: Incorrect file format version.\n");

+        return RESULT_ERROR_FORMAT;

+    }

+

+    if(g_Verbosity == VERBOSITY::MAXIMUM)

+    {

+        printf("Format version: %u,%u\n",

+            GetVersionMajor(g_FileVersion),

+            GetVersionMinor(g_FileVersion));

+    }

+

+    // Parse configuration

+    const bool configEnabled = g_FileVersion >= MakeVersion(1, 3);

+    ConfigurationParser configParser;

+    if(configEnabled)

+    {

+        if(!configParser.Parse(lineSplit))

+        {

+            return RESULT_ERROR_FORMAT;

+        }

+    }

+

+    Player player;

+    int result = player.Init();

+

+    if(configEnabled)

+    {

+        player.ApplyConfig(configParser);

+    }

+

+    size_t executedLineCount = 0;

+    if(result == 0)

+    {

+        if(g_Verbosity > VERBOSITY::MINIMUM)

+        {

+            if(useLineRanges)

+            {

+                printf("Playing #%zu (limited range of lines)...\n", iterationIndex + 1);

+            }

+            else

+            {

+                printf("Playing #%zu...\n", iterationIndex + 1);

+            }

+        }

+

+        const time_point timeBeg = std::chrono::high_resolution_clock::now();

+

+        while(lineSplit.GetNextLine(line))

+        {

+            const size_t currLineNumber = lineSplit.GetNextLineIndex();

+

+            bool execute = true;

+            if(useLineRanges)

+            {

+                execute = g_LineRanges.Includes(currLineNumber);

+            }

+

+            if(execute)

+            {

+                player.ExecuteLine(currLineNumber, line);

+                ++executedLineCount;

+            }

+

+            while(useDumpStatsAfterLine &&

+                g_DumpStatsAfterLineNextIndex < g_DumpStatsAfterLine.size() &&

+                currLineNumber >= g_DumpStatsAfterLine[g_DumpStatsAfterLineNextIndex].line)

+            {

+                const size_t requestedLine = g_DumpStatsAfterLine[g_DumpStatsAfterLineNextIndex].line;

+                const bool detailed = g_DumpStatsAfterLine[g_DumpStatsAfterLineNextIndex].detailed;

+                

+                if(g_Verbosity == VERBOSITY::MAXIMUM)

+                {

+                    printf("Dumping %sstats after line %zu actual line %zu...\n",

+                        detailed ? "detailed " : "",

+                        requestedLine,

+                        currLineNumber);

+                }

+

+                player.DumpStats("VmaReplay_Line%04zu.json", requestedLine, detailed);

+                

+                ++g_DumpStatsAfterLineNextIndex;

+            }

+        }

+

+        const duration playDuration = std::chrono::high_resolution_clock::now() - timeBeg;

+        outDuration = playDuration;

+

+        // End stats.

+        if(g_Verbosity > VERBOSITY::MINIMUM)

+        {

+            std::string playDurationStr;

+            SecondsToFriendlyStr(ToFloatSeconds(playDuration), playDurationStr);

+

+            printf("Done.\n");

+            printf("Playback took: %s\n", playDurationStr.c_str());

+        }

+        if(g_Verbosity == VERBOSITY::MAXIMUM)

+        {

+            printf("File lines: %zu\n", lineSplit.GetNextLineIndex());

+            printf("Executed %zu file lines\n", executedLineCount);

+        }

+

+        player.PrintStats();

+    }

+

+    return result;

+}

+

+static int ProcessFile()

+{

+    if(g_Verbosity > VERBOSITY::MINIMUM)

+    {

+        printf("Loading file \"%s\"...\n", g_FilePath.c_str());

+    }

+    int result = 0;

+

+    FILE* file = nullptr;

+    const errno_t err = fopen_s(&file, g_FilePath.c_str(), "rb");

+    if(err == 0)

+    {

+        _fseeki64(file, 0, SEEK_END);

+        const size_t fileSize = (size_t)_ftelli64(file);

+        _fseeki64(file, 0, SEEK_SET);

+

+        if(fileSize > 0)

+        {

+            std::vector<char> fileContents(fileSize);

+            fread(fileContents.data(), 1, fileSize, file);

+

+            // Begin stats.

+            if(g_Verbosity == VERBOSITY::MAXIMUM)

+            {

+                printf("File size: %zu B\n", fileSize);

+            }

+

+            duration durationSum = duration::zero();

+            for(size_t i = 0; i < g_IterationCount; ++i)

+            {

+                duration currDuration;

+                ProcessFile(i, fileContents.data(), fileContents.size(), currDuration);

+                durationSum += currDuration;

+            }

+

+            if(g_IterationCount > 1)

+            {

+                std::string playDurationStr;

+                SecondsToFriendlyStr(ToFloatSeconds(durationSum / g_IterationCount), playDurationStr);

+                printf("Average playback time from %zu iterations: %s\n", g_IterationCount, playDurationStr.c_str());

+            }

+        }

+        else

+        {

+            printf("ERROR: Source file is empty.\n");

+            result = RESULT_ERROR_SOURCE_FILE;

+        }

+

+        fclose(file);

+    }

+    else

+    {

+        printf("ERROR: Couldn't open file (%i).\n", err);

+        result = RESULT_ERROR_SOURCE_FILE;

+    }

+

+    return result;

+}

+

+static int main2(int argc, char** argv)

+{

+    CmdLineParser cmdLineParser(argc, argv);

+

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_VERBOSITY, 'v', true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_ITERATIONS, 'i', true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_LINES, "Lines", true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_PHYSICAL_DEVICE, "PhysicalDevice", true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_USER_DATA, "UserData", true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_VK_KHR_DEDICATED_ALLOCATION, "VK_KHR_dedicated_allocation", true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION, VALIDATION_LAYER_NAME, true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_MEM_STATS, "MemStats", true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_DUMP_STATS_AFTER_LINE, "DumpStatsAfterLine", true);

+    cmdLineParser.RegisterOpt(CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE, "DumpDetailedStatsAfterLine", true);

+

+    CmdLineParser::RESULT res;

+    while((res = cmdLineParser.ReadNext()) != CmdLineParser::RESULT_END)

+    {

+        switch(res)

+        {

+        case CmdLineParser::RESULT_OPT:

+            switch(cmdLineParser.GetOptId())

+            {

+            case CMD_LINE_OPT_VERBOSITY:

+                {

+                    uint32_t verbosityVal = UINT32_MAX;

+                    if(StrRangeToUint(StrRange(cmdLineParser.GetParameter()), verbosityVal) &&

+                        verbosityVal < (uint32_t)VERBOSITY::COUNT)

+                    {

+                        g_Verbosity = (VERBOSITY)verbosityVal;

+                    }

+                    else

+                    {

+                        PrintCommandLineSyntax();

+                        return RESULT_ERROR_COMMAND_LINE;

+                    }

+                }

+                break;

+            case CMD_LINE_OPT_ITERATIONS:

+                if(!StrRangeToUint(StrRange(cmdLineParser.GetParameter()), g_IterationCount))

+                {

+                    PrintCommandLineSyntax();

+                    return RESULT_ERROR_COMMAND_LINE;

+                }

+                break;

+            case CMD_LINE_OPT_LINES:

+                if(!g_LineRanges.Parse(StrRange(cmdLineParser.GetParameter())))

+                {

+                    PrintCommandLineSyntax();

+                    return RESULT_ERROR_COMMAND_LINE;

+                }

+                break;

+            case CMD_LINE_OPT_PHYSICAL_DEVICE:

+                if(!StrRangeToUint(StrRange(cmdLineParser.GetParameter()), g_PhysicalDeviceIndex))

+                {

+                    PrintCommandLineSyntax();

+                    return RESULT_ERROR_COMMAND_LINE;

+                }

+                break;

+            case CMD_LINE_OPT_USER_DATA:

+                if(!StrRangeToBool(StrRange(cmdLineParser.GetParameter()), g_UserDataEnabled))

+                {

+                    PrintCommandLineSyntax();

+                    return RESULT_ERROR_COMMAND_LINE;

+                }

+                break;

+            case CMD_LINE_OPT_VK_KHR_DEDICATED_ALLOCATION:

+                {

+                    bool newValue;

+                    if(StrRangeToBool(StrRange(cmdLineParser.GetParameter()), newValue))

+                    {

+                        g_VK_KHR_dedicated_allocation_request = newValue ?

+                            VULKAN_EXTENSION_REQUEST::ENABLED :

+                            VULKAN_EXTENSION_REQUEST::DISABLED;

+                    }

+                    else

+                    {

+                        PrintCommandLineSyntax();

+                        return RESULT_ERROR_COMMAND_LINE;

+                    }

+                }

+                break;

+            case CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION:

+                {

+                    bool newValue;

+                    if(StrRangeToBool(StrRange(cmdLineParser.GetParameter()), newValue))

+                    {

+                        g_VK_LAYER_LUNARG_standard_validation = newValue ?

+                            VULKAN_EXTENSION_REQUEST::ENABLED :

+                            VULKAN_EXTENSION_REQUEST::DISABLED;

+                    }

+                    else

+                    {

+                        PrintCommandLineSyntax();

+                        return RESULT_ERROR_COMMAND_LINE;

+                    }

+                }

+                break;

+            case CMD_LINE_OPT_MEM_STATS:

+                if(!StrRangeToBool(StrRange(cmdLineParser.GetParameter()), g_MemStatsEnabled))

+                {

+                    PrintCommandLineSyntax();

+                    return RESULT_ERROR_COMMAND_LINE;

+                }

+                break;

+            case CMD_LINE_OPT_DUMP_STATS_AFTER_LINE:

+            case CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE:

+                {

+                    size_t line;

+                    if(StrRangeToUint(StrRange(cmdLineParser.GetParameter()), line))

+                    {

+                        const bool detailed =

+                            cmdLineParser.GetOptId() == CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE;

+                        g_DumpStatsAfterLine.push_back({line, detailed});

+                    }

+                    else

+                    {

+                        PrintCommandLineSyntax();

+                        return RESULT_ERROR_COMMAND_LINE;

+                    }

+                }

+                break;

+            default:

+                assert(0);

+            }

+            break;

+        case CmdLineParser::RESULT_PARAMETER:

+            if(g_FilePath.empty())

+            {

+                g_FilePath = cmdLineParser.GetParameter();

+            }

+            else

+            {

+                PrintCommandLineSyntax();

+                return RESULT_ERROR_COMMAND_LINE;

+            }

+            break;

+        case CmdLineParser::RESULT_ERROR:

+            PrintCommandLineSyntax();

+            return RESULT_ERROR_COMMAND_LINE;

+            break;

+        default:

+            assert(0);

+        }

+    }

+

+    // Postprocess command line parameters.

+

+    if(g_FilePath.empty())

+    {

+        PrintCommandLineSyntax();

+        return RESULT_ERROR_COMMAND_LINE;

+    }

+

+    // Sort g_DumpStatsAfterLine and make unique.

+    std::sort(g_DumpStatsAfterLine.begin(), g_DumpStatsAfterLine.end());

+    g_DumpStatsAfterLine.erase(

+        std::unique(g_DumpStatsAfterLine.begin(), g_DumpStatsAfterLine.end()),

+        g_DumpStatsAfterLine.end());

+

+    return ProcessFile();

+}

+

+int main(int argc, char** argv)

+{

+    try

+    {

+        return main2(argc, argv);

+    }

+    catch(const std::exception& e)

+    {

+        printf("ERROR: %s\n", e.what());

+        return RESULT_EXCEPTION;

+    }

+    catch(...)

+    {

+        printf("UNKNOWN ERROR\n");

+        return RESULT_EXCEPTION;

+    }

+}

diff --git a/src/VmaReplay/VmaUsage.cpp b/src/VmaReplay/VmaUsage.cpp
new file mode 100644
index 0000000..d2d035b
--- /dev/null
+++ b/src/VmaReplay/VmaUsage.cpp
@@ -0,0 +1,2 @@
+#define VMA_IMPLEMENTATION

+#include "VmaUsage.h"

diff --git a/src/VmaReplay/VmaUsage.h b/src/VmaReplay/VmaUsage.h
new file mode 100644
index 0000000..182132b
--- /dev/null
+++ b/src/VmaReplay/VmaUsage.h
@@ -0,0 +1,27 @@
+#pragma once

+

+#define NOMINMAX

+#define WIN32_LEAN_AND_MEAN

+#include <Windows.h>

+#define VK_USE_PLATFORM_WIN32_KHR

+

+#include <vulkan/vulkan.h>

+

+//#define VMA_USE_STL_CONTAINERS 1

+

+//#define VMA_HEAVY_ASSERT(expr) assert(expr)

+

+//#define VMA_DEDICATED_ALLOCATION 0

+

+//#define VMA_DEBUG_MARGIN 16

+//#define VMA_DEBUG_DETECT_CORRUPTION 1

+//#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1

+

+#pragma warning(push, 4)

+#pragma warning(disable: 4127) // conditional expression is constant

+#pragma warning(disable: 4100) // unreferenced formal parameter

+#pragma warning(disable: 4189) // local variable is initialized but not referenced

+

+#include "../vk_mem_alloc.h"

+

+#pragma warning(pop)

diff --git a/src/VmaUsage.h b/src/VmaUsage.h
index 70c8849..a85bf9e 100644
--- a/src/VmaUsage.h
+++ b/src/VmaUsage.h
@@ -16,9 +16,14 @@
 include all public interface declarations. Example:

 */

 

+//#define VMA_HEAVY_ASSERT(expr) assert(expr)

 //#define VMA_USE_STL_CONTAINERS 1

-

-//#define VMA_HEAVY_ASSERT(expr)

+//#define VMA_DEDICATED_ALLOCATION 0

+//#define VMA_DEBUG_MARGIN 16

+//#define VMA_DEBUG_DETECT_CORRUPTION 1

+//#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1

+//#define VMA_RECORDING_ENABLED 0

+//#define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY 256

 

 #pragma warning(push, 4)

 #pragma warning(disable: 4127) // conditional expression is constant

diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp
index d3937b7..d33861e 100644
--- a/src/VulkanSample.cpp
+++ b/src/VulkanSample.cpp
@@ -190,6 +190,18 @@
     {

         return VK_FALSE;

     }

+

+    /*

+    "Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used."

+    Ignoring because we map entire VkDeviceMemory blocks, where different types of

+    images and buffers may end up together, especially on GPUs with unified memory

+    like Intel.

+    */

+    if(strstr(pMessage, "Mapping an image with layout") != nullptr &&

+        strstr(pMessage, "can result in undefined behavior if this memory is used by the device") != nullptr)

+    {

+        return VK_FALSE;

+    }

     

     switch(flags)

     {

@@ -573,7 +585,7 @@
 

 struct UniformBufferObject

 {

-    mathfu::vec4_packed ModelViewProj[4];

+    mat4 ModelViewProj;

 };

 

 static void RegisterDebugCallbacks()

@@ -1573,18 +1585,16 @@
         VK_PIPELINE_BIND_POINT_GRAPHICS,

         g_hPipeline);

 

-    mathfu::mat4 view = mathfu::mat4::LookAt(

-        mathfu::kZeros3f,

-        mathfu::vec3(0.f, -2.f, 4.f),

-        mathfu::kAxisY3f);

-    mathfu::mat4 proj = mathfu::mat4::Perspective(

+    mat4 view = mat4::LookAt(

+        vec3(0.f, 0.f, 0.f),

+        vec3(0.f, -2.f, 4.f),

+        vec3(0.f, 1.f, 0.f));

+    mat4 proj = mat4::Perspective(

         1.0471975511966f, // 60 degrees

         (float)g_Extent.width / (float)g_Extent.height,

         0.1f,

-        1000.f,

-        -1.f);

-    //proj[1][1] *= -1.f;

-    mathfu::mat4 viewProj = proj * view;

+        1000.f);

+    mat4 viewProj = view * proj;

 

     vkCmdBindDescriptorSets(

         hCommandBuffer,

@@ -1596,17 +1606,11 @@
         0,

         nullptr);

 

-    float rotationAngle = (float)GetTickCount() * 0.001f * (float)M_PI * 0.2f;

-    mathfu::mat3 model_3 = mathfu::mat3::RotationY(rotationAngle);

-    mathfu::mat4 model_4 = mathfu::mat4(

-        model_3(0, 0), model_3(0, 1), model_3(0, 2), 0.f,

-        model_3(1, 0), model_3(1, 1), model_3(1, 2), 0.f,

-        model_3(2, 0), model_3(2, 1), model_3(2, 2), 0.f,

-        0.f, 0.f, 0.f, 1.f);

-    mathfu::mat4 modelViewProj = viewProj * model_4;

+    float rotationAngle = (float)GetTickCount() * 0.001f * (float)PI * 0.2f;

+    mat4 model = mat4::RotationY(rotationAngle);

 

     UniformBufferObject ubo = {};

-    modelViewProj.Pack(ubo.ModelViewProj);

+    ubo.ModelViewProj = model * viewProj;

     vkCmdPushConstants(hCommandBuffer, g_hPipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(UniformBufferObject), &ubo);

 

     VkBuffer vertexBuffers[] = { g_hVertexBuffer };

diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index b621fe7..2975335 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -29,7 +29,7 @@
 

 /** \mainpage Vulkan Memory Allocator

 

-<b>Version 2.0.0</b> (2018-03-19)

+<b>Version 2.1.0-beta.1</b> (2018-08-27)

 

 Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved. \n

 License: MIT

@@ -55,6 +55,11 @@
     - [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable)

   - \subpage custom_memory_pools

     - [Choosing memory type index](@ref custom_memory_pools_MemTypeIndex)

+    - [Linear allocation algorithm](@ref linear_algorithm)

+      - [Free-at-once](@ref linear_algorithm_free_at_once)

+      - [Stack](@ref linear_algorithm_stack)

+      - [Double stack](@ref linear_algorithm_double_stack)

+      - [Ring buffer](@ref linear_algorithm_ring_buffer)

   - \subpage defragmentation

   - \subpage lost_allocations

   - \subpage statistics

@@ -63,6 +68,11 @@
   - \subpage allocation_annotation

     - [Allocation user data](@ref allocation_user_data)

     - [Allocation names](@ref allocation_names)

+  - \subpage debugging_memory_usage

+    - [Memory initialization](@ref debugging_memory_usage_initialization)

+    - [Margins](@ref debugging_memory_usage_margins)

+    - [Corruption detection](@ref debugging_memory_usage_corruption_detection)

+  - \subpage record_and_replay

 - \subpage usage_patterns

   - [Simple patterns](@ref usage_patterns_simple)

   - [Advanced patterns](@ref usage_patterns_advanced)

@@ -74,6 +84,7 @@
   - \subpage vk_khr_dedicated_allocation

 - \subpage general_considerations

   - [Thread safety](@ref general_considerations_thread_safety)

+  - [Validation layer warnings](@ref general_considerations_validation_layer_warnings)

   - [Allocation algorithm](@ref general_considerations_allocation_algorithm)

   - [Features not supported](@ref general_considerations_features_not_supported)

 

@@ -112,6 +123,13 @@
 

 It may be a good idea to create dedicated CPP file just for this purpose.

 

+Please note that this library includes header `<vulkan/vulkan.h>`, which in turn

+includes `<windows.h>` on Windows. If you need some specific macros defined

+before including these headers (like `NOMINMAX`, `WIN32_LEAN_AND_MEAN`, or

+`WINVER` for Windows, `VK_USE_PLATFORM_WIN32_KHR` for Vulkan), you must define

+them before every `#include` of this library.

+

+

 \section quick_start_initialization Initialization

 

 At program startup:

@@ -294,7 +312,7 @@
 They are safer and more convenient to use than standard Vulkan functions.

 You can map an allocation multiple times simultaneously - mapping is reference-counted internally.

 You can also map different allocations simultaneously regardless of whether they use the same `VkDeviceMemory` block.

-They way it's implemented is that the library always maps entire memory block, not just region of the allocation.

+The way it's implemented is that the library always maps entire memory block, not just region of the allocation.

 For further details, see description of vmaMapMemory() function.

 Example:

 

@@ -308,7 +326,7 @@
 ConstantBuffer constantBufferData;

 

 VmaAllocator allocator;

-VmaBuffer constantBuffer;

+VkBuffer constantBuffer;

 VmaAllocation constantBufferAllocation;

 

 // You can map and fill your buffer using following code:

@@ -319,6 +337,16 @@
 vmaUnmapMemory(allocator, constantBufferAllocation);

 \endcode

 

+When mapping, you may see a warning from Vulkan validation layer similar to this one:

+

+<i>Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.</i>

+

+It happens because the library maps entire `VkDeviceMemory` block, where different

+types of images and buffers may end up together, especially on GPUs with unified memory like Intel.

+You can safely ignore it if you are sure you access only memory of the intended

+object that you wanted to map.

+

+

 \section memory_mapping_persistently_mapped_memory Persistently mapped memory

 

 Kepping your memory persistently mapped is generally OK in Vulkan.

@@ -366,31 +394,23 @@
 Memory in Vulkan doesn't need to be unmapped before using it on GPU,

 but unless a memory types has `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` flag set,

 you need to manually invalidate cache before reading of mapped pointer

-using function `vkvkInvalidateMappedMemoryRanges()`

-and flush cache after writing to mapped pointer

-using function `vkFlushMappedMemoryRanges()`.

-Example:

+and flush cache after writing to mapped pointer.

+Vulkan provides following functions for this purpose `vkFlushMappedMemoryRanges()`,

+`vkInvalidateMappedMemoryRanges()`, but this library provides more convenient

+functions that refer to given allocation object: vmaFlushAllocation(),

+vmaInvalidateAllocation().

 

-\code

-memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData));

+Regions of memory specified for flush/invalidate must be aligned to

+`VkPhysicalDeviceLimits::nonCoherentAtomSize`. This is automatically ensured by the library.

+In any memory type that is `HOST_VISIBLE` but not `HOST_COHERENT`, all allocations

+within blocks are aligned to this value, so their offsets are always multiply of

+`nonCoherentAtomSize` and two different allocations never share same "line" of this size.

 

-VkMemoryPropertyFlags memFlags;

-vmaGetMemoryTypeProperties(allocator, allocInfo.memoryType, &memFlags);

-if((memFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)

-{

-    VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };

-    memRange.memory = allocInfo.deviceMemory;

-    memRange.offset = allocInfo.offset;

-    memRange.size   = allocInfo.size;

-    vkFlushMappedMemoryRanges(device, 1, &memRange);

-}

-\endcode

-

-Please note that memory allocated with #VMA_MEMORY_USAGE_CPU_ONLY is guaranteed to be host coherent.

+Please note that memory allocated with #VMA_MEMORY_USAGE_CPU_ONLY is guaranteed to be `HOST_COHERENT`.

 

 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.

+currently provide `HOST_COHERENT` flag on all memory types that are

+`HOST_VISIBLE`, so on this platform you may not need to bother.

 

 \section memory_mapping_finding_if_memory_mappable Finding out if memory is mappable

 

@@ -411,6 +431,7 @@
 

 VmaAllocationCreateInfo allocCreateInfo = {};

 allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;

+allocCreateInfo.preferredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

 

 VkBuffer buf;

 VmaAllocation alloc;

@@ -488,7 +509,7 @@
 -# Fill VmaPoolCreateInfo structure.

 -# Call vmaCreatePool() to obtain #VmaPool handle.

 -# When making an allocation, set VmaAllocationCreateInfo::pool to this handle.

-   You don't need to specify any other parameters of this structure, like usage.

+   You don't need to specify any other parameters of this structure, like `usage`.

 

 Example:

 

@@ -556,6 +577,94 @@
 - VmaAllocationCreateInfo: You don't need to pass same parameters. Fill only `pool` member.

   Other members are ignored anyway.

 

+\section linear_algorithm Linear allocation algorithm

+

+Each Vulkan memory block managed by this library has accompanying metadata that

+keeps track of used and unused regions. By default, the metadata structure and

+algorithm tries to find best place for new allocations among free regions to

+optimize memory usage. This way you can allocate and free objects in any order.

+

+![Default allocation algorithm](../gfx/Linear_allocator_1_algo_default.png)

+

+Sometimes there is a need to use simpler, linear allocation algorithm. You can

+create custom pool that uses such algorithm by adding flag

+#VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT to VmaPoolCreateInfo::flags while creating

+#VmaPool object. Then an alternative metadata management is used. It always

+creates new allocations after last one and doesn't reuse free regions after

+allocations freed in the middle. It results in better allocation performance and

+less memory consumed by metadata.

+

+![Linear allocation algorithm](../gfx/Linear_allocator_2_algo_linear.png)

+

+With this one flag, you can create a custom pool that can be used in many ways:

+free-at-once, stack, double stack, and ring buffer. See below for details.

+

+\subsection linear_algorithm_free_at_once Free-at-once

+

+In a pool that uses linear algorithm, you still need to free all the allocations

+individually, e.g. by using vmaFreeMemory() or vmaDestroyBuffer(). You can free

+them in any order. New allocations are always made after last one - free space

+in the middle is not reused. However, when you release all the allocation and

+the pool becomes empty, allocation starts from the beginning again. This way you

+can use linear algorithm to speed up creation of allocations that you are going

+to release all at once.

+

+![Free-at-once](../gfx/Linear_allocator_3_free_at_once.png)

+

+This mode is also available for pools created with VmaPoolCreateInfo::maxBlockCount

+value that allows multiple memory blocks.

+

+\subsection linear_algorithm_stack Stack

+

+When you free an allocation that was created last, its space can be reused.

+Thanks to this, if you always release allocations in the order opposite to their

+creation (LIFO - Last In First Out), you can achieve behavior of a stack.

+

+![Stack](../gfx/Linear_allocator_4_stack.png)

+

+This mode is also available for pools created with VmaPoolCreateInfo::maxBlockCount

+value that allows multiple memory blocks.

+

+\subsection linear_algorithm_double_stack Double stack

+

+The space reserved by a custom pool with linear algorithm may be used by two

+stacks:

+

+- First, default one, growing up from offset 0.

+- Second, "upper" one, growing down from the end towards lower offsets.

+

+To make allocation from upper stack, add flag #VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT

+to VmaAllocationCreateInfo::flags.

+

+![Double stack](../gfx/Linear_allocator_7_double_stack.png)

+

+Double stack is available only in pools with one memory block -

+VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined.

+

+When the two stacks' ends meet so there is not enough space between them for a

+new allocation, such allocation fails with usual

+`VK_ERROR_OUT_OF_DEVICE_MEMORY` error.

+

+\subsection linear_algorithm_ring_buffer Ring buffer

+

+When you free some allocations from the beginning and there is not enough free space

+for a new one at the end of a pool, allocator's "cursor" wraps around to the

+beginning and starts allocation there. Thanks to this, if you always release

+allocations in the same order as you created them (FIFO - First In First Out),

+you can achieve behavior of a ring buffer / queue.

+

+![Ring buffer](../gfx/Linear_allocator_5_ring_buffer.png)

+

+Pools with linear algorithm support [lost allocations](@ref lost_allocations) when used as ring buffer.

+If there is not enough free space for a new allocation, but existing allocations

+from the front of the queue can become lost, they become lost and the allocation

+succeeds.

+

+![Ring buffer with lost allocations](../gfx/Linear_allocator_6_ring_buffer_lost.png)

+

+Ring buffer is available only in pools with one memory block -

+VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined.

+

 

 \page defragmentation Defragmentation

 

@@ -685,6 +794,15 @@
 Allocations that have been "touched" in current frame or VmaPoolCreateInfo::frameInUseCount frames back

 cannot become lost.

 

+<b>Q: Can I touch allocation that cannot become lost?</b>

+

+Yes, although it has no visible effect.

+Calls to vmaGetAllocationInfo() and vmaTouchAllocation() update last use frame index

+also for allocations that cannot become lost, but the only way to observe it is to dump

+internal allocator state using vmaBuildStatsString().

+You can use this feature for debugging purposes to explicitly mark allocations that you use

+in current frame and then analyze JSON dump to see for how long each allocation stays unused.

+

 

 \page statistics Statistics

 

@@ -808,8 +926,154 @@
 That string is also printed in JSON report created by vmaBuildStatsString().

 

 

+\page debugging_memory_usage Debugging incorrect memory usage

+

+If you suspect a bug with memory usage, like usage of uninitialized memory or

+memory being overwritten out of bounds of an allocation,

+you can use debug features of this library to verify this.

+

+\section debugging_memory_usage_initialization Memory initialization

+

+If you experience a bug with incorrect and nondeterministic data in your program and you suspect uninitialized memory to be used,

+you can enable automatic memory initialization to verify this.

+To do it, define macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to 1.

+

+\code

+#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1

+#include "vk_mem_alloc.h"

+\endcode

+

+It makes memory of all new allocations initialized to bit pattern `0xDCDCDCDC`.

+Before an allocation is destroyed, its memory is filled with bit pattern `0xEFEFEFEF`.

+Memory is automatically mapped and unmapped if necessary.

+

+If you find these values while debugging your program, good chances are that you incorrectly

+read Vulkan memory that is allocated but not initialized, or already freed, respectively.

+

+Memory initialization works only with memory types that are `HOST_VISIBLE`.

+It works also with dedicated allocations.

+It doesn't work with allocations created with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag,

+as they cannot be mapped.

+

+\section debugging_memory_usage_margins Margins

+

+By default, allocations are laid out in memory blocks next to each other if possible

+(considering required alignment, `bufferImageGranularity`, and `nonCoherentAtomSize`).

+

+![Allocations without margin](../gfx/Margins_1.png)

+

+Define macro `VMA_DEBUG_MARGIN` to some non-zero value (e.g. 16) to enforce specified

+number of bytes as a margin before and after every allocation.

+

+\code

+#define VMA_DEBUG_MARGIN 16

+#include "vk_mem_alloc.h"

+\endcode

+

+![Allocations with margin](../gfx/Margins_2.png)

+

+If your bug goes away after enabling margins, it means it may be caused by memory

+being overwritten outside of allocation boundaries. It is not 100% certain though.

+Change in application behavior may also be caused by different order and distribution

+of allocations across memory blocks after margins are applied.

+

+The margin is applied also before first and after last allocation in a block.

+It may occur only once between two adjacent allocations.

+

+Margins work with all types of memory.

+

+Margin is applied only to allocations made out of memory blocks and not to dedicated

+allocations, which have their own memory block of specific size.

+It is thus not applied to allocations made using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag

+or those automatically decided to put into dedicated allocations, e.g. due to its

+large size or recommended by VK_KHR_dedicated_allocation extension.

+

+Margins appear in [JSON dump](@ref statistics_json_dump) as part of free space.

+

+Note that enabling margins increases memory usage and fragmentation.

+

+\section debugging_memory_usage_corruption_detection Corruption detection

+

+You can additionally define macro `VMA_DEBUG_DETECT_CORRUPTION` to 1 to enable validation

+of contents of the margins.

+

+\code

+#define VMA_DEBUG_MARGIN 16

+#define VMA_DEBUG_DETECT_CORRUPTION 1

+#include "vk_mem_alloc.h"

+\endcode

+

+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.

+

+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`.

+

+

+\page record_and_replay Record and replay

+

+\section record_and_replay_introduction Introduction

+

+While using the library, sequence of calls to its functions together with their

+parameters can be recorded to a file and later replayed using standalone player

+application. It can be useful to:

+

+- Test correctness - check if same sequence of calls will not cause crash or

+  failures on a target platform.

+- Gather statistics - see number of allocations, peak memory usage, number of

+  calls etc.

+- Benchmark performance - see how much time it takes to replay the whole

+  sequence.

+

+\section record_and_replay_usage Usage

+

+<b>To record sequence of calls to a file:</b> Fill in

+VmaAllocatorCreateInfo::pRecordSettings member while creating #VmaAllocator

+object. File is opened and written during whole lifetime of the allocator.

+

+<b>To replay file:</b> Use VmaReplay - standalone command-line program.

+Precompiled binary can be found in "bin" directory.

+Its source can be found in "src/VmaReplay" directory.

+Its project is generated by Premake.

+Command line syntax is printed when the program is launched without parameters.

+Basic usage:

+

+    VmaReplay.exe MyRecording.csv

+

+<b>Documentation of file format</b> can be found in file: "docs/Recording file format.md".

+It's a human-readable, text file in CSV format (Comma Separated Values).

+

+\section record_and_replay_additional_considerations Additional considerations

+

+- Replaying file that was recorded on a different GPU (with different parameters

+  like `bufferImageGranularity`, `nonCoherentAtomSize`, and especially different

+  set of memory heaps and types) may give different performance and memory usage

+  results, as well as issue some warnings and errors.

+- Current implementation of recording in VMA, as well as VmaReplay application, is

+  coded and tested only on Windows. Inclusion of recording code is driven by

+  `VMA_RECORDING_ENABLED` macro. Support for other platforms should be easy to

+  add. Contributions are welcomed.

+- Currently calls to vmaDefragment() function are not recorded.

+

+

 \page usage_patterns Recommended usage patterns

 

+See also slides from talk:

+[Sawicki, Adam. Advanced Graphics Techniques Tutorial: Memory management in Vulkan and DX12. Game Developers Conference, 2018](https://www.gdcvault.com/play/1025458/Advanced-Graphics-Techniques-Tutorial-New)

+

+

 \section usage_patterns_simple Simple patterns

 

 \subsection usage_patterns_simple_render_targets Render targets

@@ -864,7 +1128,7 @@
 This is a more complex situation. Different solutions are possible,

 and the best one depends on specific GPU type, but you can use this simple approach for the start.

 Prefer to write to such resource sequentially (e.g. using `memcpy`).

-Don't perform random access or any reads from it, as it may be very slow.

+Don't perform random access or any reads from it on CPU, as it may be very slow.

 

 \subsection usage_patterns_readback Readback

 

@@ -884,7 +1148,7 @@
 by detecting it in Vulkan.

 To do it, call `vkGetPhysicalDeviceProperties()`, inspect

 `VkPhysicalDeviceProperties::deviceType` and look for `VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU`.

-When you find it, you can assume that memory is unified and all memory types are equally fast

+When you find it, you can assume that memory is unified and all memory types are comparably fast

 to access from GPU, regardless of `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`.

 

 You can then sum up sizes of all available memory heaps and treat them as useful for

@@ -908,7 +1172,7 @@
 Some general recommendations:

 

 - On integrated graphics use (2) or (3) to avoid unnecesary time and memory overhead

-  related to using a second copy.

+  related to using a second copy and making transfer.

 - For small resources (e.g. constant buffers) use (2).

   Discrete AMD cards have special 256 MiB pool of video memory that is directly mappable.

   Even if the resource ends up in system memory, its data may be cached on GPU after first

@@ -928,7 +1192,7 @@
 You should take some measurements to decide which option is faster in case of your specific

 resource.

 

-If you don't want to specialize your code for specific types of GPUs, yon can still make

+If you don't want to specialize your code for specific types of GPUs, you can still make

 an simple optimization for cases when your resource ends up in mappable memory to use it

 directly in this case instead of creating CPU-side staging copy.

 For details see [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable).

@@ -1044,6 +1308,23 @@
   threads at the same time if you pass the same #VmaAllocation object to these

   functions.

 

+\section general_considerations_validation_layer_warnings Validation layer warnings

+

+When using this library, you can meet following types of warnings issued by

+Vulkan validation layer. They don't necessarily indicate a bug, so you may need

+to just ignore them.

+

+- *vkBindBufferMemory(): Binding memory to buffer 0xeb8e4 but vkGetBufferMemoryRequirements() has not been called on that buffer.*

+  - It happens when VK_KHR_dedicated_allocation extension is enabled.

+    `vkGetBufferMemoryRequirements2KHR` function is used instead, while validation layer seems to be unaware of it.

+- *Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.*

+  - It happens when you map a buffer or image, because the library maps entire

+    `VkDeviceMemory` block, where different types of images and buffers may end

+    up together, especially on GPUs with unified memory like Intel.

+- *Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug.*

+  - It happens when you use lost allocations, and a new image or buffer is

+    created in place of an existing object that bacame lost.

+

 \section general_considerations_allocation_algorithm Allocation algorithm

 

 The library uses following algorithm for allocation, in order:

@@ -1065,7 +1346,11 @@
 Features deliberately excluded from the scope of this library:

 

 - Data transfer - issuing commands that transfer data between buffers or images, any usage of

-  `VkCommandList` or `VkCommandQueue` and related synchronization is responsibility of the user.

+  `VkCommandList` or `VkQueue` and related synchronization is responsibility of the user.

+- Allocations for imported/exported external memory. They tend to require

+  explicit memory type index and dedicated allocation anyway, so they don't

+  interact with main features of this library. Such special purpose allocations

+  should be made manually, using `vkCreateBuffer()` and `vkAllocateMemory()`.

 - Support for any programming languages other than C/C++.

   Bindings to other languages are welcomed as external projects.

 

@@ -1073,6 +1358,14 @@
 

 #include <vulkan/vulkan.h>

 

+#if !defined(VMA_DEDICATED_ALLOCATION)

+    #if VK_KHR_get_memory_requirements2 && VK_KHR_dedicated_allocation

+        #define VMA_DEDICATED_ALLOCATION 1

+    #else

+        #define VMA_DEDICATED_ALLOCATION 0

+    #endif

+#endif

+

 /** \struct VmaAllocator

 \brief Represents main object of this library initialized.

 

@@ -1156,6 +1449,8 @@
     PFN_vkFreeMemory vkFreeMemory;

     PFN_vkMapMemory vkMapMemory;

     PFN_vkUnmapMemory vkUnmapMemory;

+    PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;

+    PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;

     PFN_vkBindBufferMemory vkBindBufferMemory;

     PFN_vkBindImageMemory vkBindImageMemory;

     PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;

@@ -1164,10 +1459,52 @@
     PFN_vkDestroyBuffer vkDestroyBuffer;

     PFN_vkCreateImage vkCreateImage;

     PFN_vkDestroyImage vkDestroyImage;

+#if VMA_DEDICATED_ALLOCATION

     PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;

     PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;

+#endif

 } VmaVulkanFunctions;

 

+/// Flags to be used in VmaRecordSettings::flags.

+typedef enum VmaRecordFlagBits {

+    /** \brief Enables flush after recording every function call.

+

+    Enable it if you expect your application to crash, which may leave recording file truncated.

+    It may degrade performance though.

+    */

+    VMA_RECORD_FLUSH_AFTER_CALL_BIT = 0x00000001,

+    

+    VMA_RECORD_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF

+} VmaRecordFlagBits;

+typedef VkFlags VmaRecordFlags;

+

+/*

+Define this macro to 0/1 to disable/enable support for recording functionality,

+available through VmaAllocatorCreateInfo::pRecordSettings.

+*/

+#ifndef VMA_RECORDING_ENABLED

+    #ifdef _WIN32

+        #define VMA_RECORDING_ENABLED 1

+    #else

+        #define VMA_RECORDING_ENABLED 0

+    #endif

+#endif

+

+/// Parameters for recording calls to VMA functions. To be used in VmaAllocatorCreateInfo::pRecordSettings.

+typedef struct VmaRecordSettings

+{

+    /// Flags for recording. Use #VmaRecordFlagBits enum.

+    VmaRecordFlags flags;

+    /** \brief Path to the file that should be written by the recording.

+

+    Suggested extension: "csv".

+    If the file already exists, it will be overwritten.

+    It will be opened for the whole time #VmaAllocator object is alive.

+    If opening this file fails, creation of the whole allocator object fails.

+    */

+    const char* pFilePath;

+} VmaRecordSettings;

+

 /// Description of a Allocator to be created.

 typedef struct VmaAllocatorCreateInfo

 {

@@ -1238,6 +1575,13 @@
     e.g. fetched using `vkGetInstanceProcAddr()` and `vkGetDeviceProcAddr()`.

     */

     const VmaVulkanFunctions* pVulkanFunctions;

+    /** \brief Parameters for recording of VMA calls. Can be null.

+

+    If not null, it enables recording of calls to VMA functions to a file.

+    If support for recording is not enabled using `VMA_RECORDING_ENABLED` macro,

+    creation of the allocator object fails with `VK_ERROR_FEATURE_NOT_PRESENT`.

+    */

+    const VmaRecordSettings* pRecordSettings;

 } VmaAllocatorCreateInfo;

 

 /// Creates Allocator object.

@@ -1363,7 +1707,7 @@
     - Resources written and read by device, e.g. images used as attachments.

     - Resources transferred from host once (immutable) or infrequently and read by

       device multiple times, e.g. textures to be sampled, vertex buffers, uniform

-      (constant) buffers, and majority of other types of resources used by device.

+      (constant) buffers, and majority of other types of resources used on GPU.

 

     Allocation may still end up in `HOST_VISIBLE` memory on some implementations.

     In such case, you are free to map it.

@@ -1372,9 +1716,9 @@
     VMA_MEMORY_USAGE_GPU_ONLY = 1,

     /** Memory will be mappable on host.

     It usually means CPU (system) memory.

-    Resources created in this pool may still be accessible to the device, but access to them can be slower.

     Guarantees to be `HOST_VISIBLE` and `HOST_COHERENT`.

-    CPU read may be uncached.

+    CPU access is typically uncached. Writes may be write-combined.

+    Resources created in this pool may still be accessible to the device, but access to them can be slow.

     It is roughly equivalent of `D3D12_HEAP_TYPE_UPLOAD`.

 

     Usage: Staging copy of resources used as transfer source.

@@ -1382,7 +1726,7 @@
     VMA_MEMORY_USAGE_CPU_ONLY = 2,

     /**

     Memory that is both mappable on host (guarantees to be `HOST_VISIBLE`) and preferably fast to access by GPU.

-    CPU reads may be uncached and very slow.

+    CPU access is typically uncached. Writes may be write-combined.

 

     Usage: Resources written frequently by host (dynamic), read by device. E.g. textures, vertex buffers, uniform buffers updated every frame or every draw call.

     */

@@ -1463,6 +1807,11 @@
     freed together with the allocation. It is also used in vmaBuildStatsString().

     */

     VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = 0x00000020,

+    /** Allocation will be created from upper stack in a double stack pool.

+

+    This flag is only allowed for custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT flag.

+    */

+    VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = 0x00000040,

 

     VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF

 } VmaAllocationCreateFlagBits;

@@ -1573,7 +1922,7 @@
 typedef enum VmaPoolCreateFlagBits {

     /** \brief Use this flag if you always allocate only buffers and linear images or only optimal images out of this pool and so Buffer-Image Granularity can be ignored.

 

-    This is na optional optimization flag.

+    This is an optional optimization flag.

 

     If you always allocate using vmaCreateBuffer(), vmaCreateImage(),

     vmaAllocateMemoryForBuffer(), then you don't need to use it because allocator

@@ -1590,6 +1939,21 @@
     */

     VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002,

 

+    /** \brief Enables alternative, linear allocation algorithm in this pool.

+

+Specify this flag to enable linear allocation algorithm, which always creates

+new allocations after last one and doesn't reuse space from allocations freed in

+between. It trades memory consumption for simplified algorithm and data

+structure, which has better performance and uses less memory for metadata.

+

+By using this flag, you can achieve behavior of free-at-once, stack,

+ring buffer, and double stack. For details, see documentation chapter

+\ref linear_algorithm.

+

+When using this flag, you must specify VmaPoolCreateInfo::maxBlockCount == 1 (or 0 for default).

+*/

+    VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004,

+

     VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF

 } VmaPoolCreateFlagBits;

 typedef VkFlags VmaPoolCreateFlags;

@@ -1603,22 +1967,26 @@
     /** \brief Use combination of #VmaPoolCreateFlagBits.

     */

     VmaPoolCreateFlags flags;

-    /** \brief Size of a single `VkDeviceMemory` block to be allocated as part of this pool, in bytes.

+    /** \brief Size of a single `VkDeviceMemory` block to be allocated as part of this pool, in bytes. Optional.

 

-    Optional. Leave 0 to use default.

+    Specify nonzero to set explicit, constant size of memory blocks used by this

+    pool.

+

+    Leave 0 to use default and let the library manage block sizes automatically.

+    Sizes of particular blocks may vary.

     */

     VkDeviceSize blockSize;

     /** \brief Minimum number of blocks to be always allocated in this pool, even if they stay empty.

 

-    Set to 0 to have no preallocated blocks and let the pool be completely empty.

+    Set to 0 to have no preallocated blocks and allow the pool be completely empty.

     */

     size_t minBlockCount;

     /** \brief Maximum number of blocks that can be allocated in this pool. Optional.

 

-    Optional. Set to 0 to use `SIZE_MAX`, which means no limit.

+    Set to 0 to use default, which is `SIZE_MAX`, which means no limit.

     

-    Set to same value as minBlockCount to have fixed amount of memory allocated

-    throuout whole lifetime of this pool.

+    Set to same value as VmaPoolCreateInfo::minBlockCount to have fixed amount of memory allocated

+    throughout whole lifetime of this pool.

     */

     size_t maxBlockCount;

     /** \brief Maximum number of additional frames that are in use at the same time as current frame.

@@ -1652,13 +2020,16 @@
     /** \brief Number of continuous memory ranges in the pool not used by any #VmaAllocation.

     */

     size_t unusedRangeCount;

-    /** \brief Size of the largest continuous free memory region.

+    /** \brief Size of the largest continuous free memory region available for new allocation.

 

     Making a new allocation of that size is not guaranteed to succeed because of

     possible additional margin required to respect alignment and buffer/image

     granularity.

     */

     VkDeviceSize unusedRangeSizeMax;

+    /** \brief Number of `VkDeviceMemory` blocks allocated for this pool.

+    */

+    size_t blockCount;

 } VmaPoolStats;

 

 /** \brief Allocates Vulkan device memory and creates #VmaPool object.

@@ -1700,6 +2071,22 @@
     VmaPool pool,

     size_t* pLostAllocationCount);

 

+/** \brief Checks magic number in margins around all allocations in given memory pool in search for corruptions.

+

+Corruption detection is enabled only when `VMA_DEBUG_DETECT_CORRUPTION` macro is defined to nonzero,

+`VMA_DEBUG_MARGIN` is defined to nonzero and the pool is created in memory type that is

+`HOST_VISIBLE` and `HOST_COHERENT`. For more information, see [Corruption detection](@ref debugging_memory_usage_corruption_detection).

+

+Possible return values:

+

+- `VK_ERROR_FEATURE_NOT_PRESENT` - corruption detection is not enabled for specified pool.

+- `VK_SUCCESS` - corruption detection has been performed and succeeded.

+- `VK_ERROR_VALIDATION_FAILED_EXT` - corruption detection has been performed and found memory corruptions around one of the allocations.

+  `VMA_ASSERT` is also fired in that case.

+- Other value: Error returned by Vulkan, e.g. memory mapping failure.

+*/

+VkResult vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool);

+

 /** \struct VmaAllocation

 \brief Represents single memory allocation.

 

@@ -1930,6 +2317,52 @@
     VmaAllocator allocator,

     VmaAllocation allocation);

 

+/** \brief Flushes memory of given allocation.

+

+Calls `vkFlushMappedMemoryRanges()` for memory associated with given range of given allocation.

+

+- `offset` must be relative to the beginning of allocation.

+- `size` can be `VK_WHOLE_SIZE`. It means all memory from `offset` the the end of given allocation.

+- `offset` and `size` don't have to be aligned.

+  They are internally rounded down/up to multiply of `nonCoherentAtomSize`.

+- If `size` is 0, this call is ignored.

+- If memory type that the `allocation` belongs to is not `HOST_VISIBLE` or it is `HOST_COHERENT`,

+  this call is ignored.

+*/

+void vmaFlushAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size);

+

+/** \brief Invalidates memory of given allocation.

+

+Calls `vkInvalidateMappedMemoryRanges()` for memory associated with given range of given allocation.

+

+- `offset` must be relative to the beginning of allocation.

+- `size` can be `VK_WHOLE_SIZE`. It means all memory from `offset` the the end of given allocation.

+- `offset` and `size` don't have to be aligned.

+  They are internally rounded down/up to multiply of `nonCoherentAtomSize`.

+- If `size` is 0, this call is ignored.

+- If memory type that the `allocation` belongs to is not `HOST_VISIBLE` or it is `HOST_COHERENT`,

+  this call is ignored.

+*/

+void vmaInvalidateAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size);

+

+/** \brief Checks magic number in margins around all allocations in given memory types (in both default and custom pools) in search for corruptions.

+

+@param memoryTypeBits Bit mask, where each bit set means that a memory type with that index should be checked.

+

+Corruption detection is enabled only when `VMA_DEBUG_DETECT_CORRUPTION` macro is defined to nonzero,

+`VMA_DEBUG_MARGIN` is defined to nonzero and only for memory types that are

+`HOST_VISIBLE` and `HOST_COHERENT`. For more information, see [Corruption detection](@ref debugging_memory_usage_corruption_detection).

+

+Possible return values:

+

+- `VK_ERROR_FEATURE_NOT_PRESENT` - corruption detection is not enabled for any of specified memory types.

+- `VK_SUCCESS` - corruption detection has been performed and succeeded.

+- `VK_ERROR_VALIDATION_FAILED_EXT` - corruption detection has been performed and found memory corruptions around one of the allocations.

+  `VMA_ASSERT` is also fired in that case.

+- Other value: Error returned by Vulkan, e.g. memory mapping failure.

+*/

+VkResult vmaCheckCorruption(VmaAllocator allocator, uint32_t memoryTypeBits);

+

 /** \brief Optional configuration parameters to be passed to function vmaDefragment(). */

 typedef struct VmaDefragmentationInfo {

     /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places.

@@ -1971,10 +2404,14 @@
 allocations are considered nonmovable in this call. Basic rules:

 

 - Only allocations made in memory types that have

-  `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag can be compacted. You may pass other

-  allocations but it makes no sense - these will never be moved.

-- You may pass allocations made with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT but

-  it makes no sense - they will never be moved.

+  `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` and `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT`

+  flags can be compacted. You may pass other allocations but it makes no sense -

+  these will never be moved.

+- Custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT flag are not

+  defragmented. Allocations passed to this function that come from such pools

+  are ignored.

+- Allocations created with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT or

+  created as dedicated allocations for any other reason are also ignored.

 - Both allocations made with or without #VMA_ALLOCATION_CREATE_MAPPED_BIT

   flag can be compacted. If not persistently mapped, memory will be mapped

   temporarily inside this function if needed.

@@ -2162,7 +2599,7 @@
 #endif // AMD_VULKAN_MEMORY_ALLOCATOR_H

 

 // For Visual Studio IntelliSense.

-#ifdef __INTELLISENSE__

+#if defined(__cplusplus) && defined(__INTELLISENSE__)

 #define VMA_IMPLEMENTATION

 #endif

 

@@ -2229,10 +2666,6 @@
 #include <mutex> // for std::mutex

 #include <atomic> // for std::atomic

 

-#if !defined(_WIN32) && !defined(__APPLE__)

-    #include <malloc.h> // for aligned_alloc()

-#endif

-

 #ifndef VMA_NULL

    // Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.

    #define VMA_NULL   nullptr

@@ -2255,6 +2688,11 @@
 }

 #endif

 

+// If your compiler is not compatible with C++11 and definition of

+// aligned_alloc() function is missing, uncommeting following line may help:

+

+//#include <malloc.h>

+

 // Normal assert to check for programmer's errors, especially in Debug configuration.

 #ifndef VMA_ASSERT

    #ifdef _DEBUG

@@ -2322,32 +2760,32 @@
 

 // Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString.

 #if VMA_STATS_STRING_ENABLED

-   static inline void VmaUint32ToStr(char* outStr, size_t strLen, uint32_t num)

-   {

-       snprintf(outStr, strLen, "%u", static_cast<unsigned int>(num));

-   }

-   static inline void VmaUint64ToStr(char* outStr, size_t strLen, uint64_t num)

-   {

-       snprintf(outStr, strLen, "%llu", static_cast<unsigned long long>(num));

-   }

-   static inline void VmaPtrToStr(char* outStr, size_t strLen, const void* ptr)

-   {

-       snprintf(outStr, strLen, "%p", ptr);

-   }

+    static inline void VmaUint32ToStr(char* outStr, size_t strLen, uint32_t num)

+    {

+        snprintf(outStr, strLen, "%u", static_cast<unsigned int>(num));

+    }

+    static inline void VmaUint64ToStr(char* outStr, size_t strLen, uint64_t num)

+    {

+        snprintf(outStr, strLen, "%llu", static_cast<unsigned long long>(num));

+    }

+    static inline void VmaPtrToStr(char* outStr, size_t strLen, const void* ptr)

+    {

+        snprintf(outStr, strLen, "%p", ptr);

+    }

 #endif

 

 #ifndef VMA_MUTEX

-   class VmaMutex

-   {

-   public:

-       VmaMutex() { }

-       ~VmaMutex() { }

-       void Lock() { m_Mutex.lock(); }

-       void Unlock() { m_Mutex.unlock(); }

-   private:

-       std::mutex m_Mutex;

-   };

-   #define VMA_MUTEX VmaMutex

+    class VmaMutex

+    {

+    public:

+        VmaMutex() { }

+        ~VmaMutex() { }

+        void Lock() { m_Mutex.lock(); }

+        void Unlock() { m_Mutex.unlock(); }

+    private:

+        std::mutex m_Mutex;

+    };

+    #define VMA_MUTEX VmaMutex

 #endif

 

 /*

@@ -2363,59 +2801,76 @@
 #endif

 

 #ifndef VMA_BEST_FIT

-   /**

-   Main parameter for function assessing how good is a free suballocation for a new

-   allocation request.

-

-   - Set to 1 to use Best-Fit algorithm - prefer smaller blocks, as close to the

-     size of requested allocations as possible.

-   - Set to 0 to use Worst-Fit algorithm - prefer larger blocks, as large as

-     possible.

-

-   Experiments in special testing environment showed that Best-Fit algorithm is

-   better.

-   */

-   #define VMA_BEST_FIT (1)

+    /**

+    Main parameter for function assessing how good is a free suballocation for a new

+    allocation request.

+    

+    - Set to 1 to use Best-Fit algorithm - prefer smaller blocks, as close to the

+      size of requested allocations as possible.

+    - Set to 0 to use Worst-Fit algorithm - prefer larger blocks, as large as

+      possible.

+    

+    Experiments in special testing environment showed that Best-Fit algorithm is

+    better.

+    */

+    #define VMA_BEST_FIT (1)

 #endif

 

 #ifndef VMA_DEBUG_ALWAYS_DEDICATED_MEMORY

-   /**

-   Every allocation will have its own memory block.

-   Define to 1 for debugging purposes only.

-   */

-   #define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0)

+    /**

+    Every allocation will have its own memory block.

+    Define to 1 for debugging purposes only.

+    */

+    #define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0)

 #endif

 

 #ifndef VMA_DEBUG_ALIGNMENT

-   /**

-   Minimum alignment of all suballocations, in bytes.

-   Set to more than 1 for debugging purposes only. Must be power of two.

-   */

-   #define VMA_DEBUG_ALIGNMENT (1)

+    /**

+    Minimum alignment of all allocations, in bytes.

+    Set to more than 1 for debugging purposes only. Must be power of two.

+    */

+    #define VMA_DEBUG_ALIGNMENT (1)

 #endif

 

 #ifndef VMA_DEBUG_MARGIN

-   /**

-   Minimum margin between suballocations, in bytes.

-   Set nonzero for debugging purposes only.

-   */

-   #define VMA_DEBUG_MARGIN (0)

+    /**

+    Minimum margin before and after every allocation, in bytes.

+    Set nonzero for debugging purposes only.

+    */

+    #define VMA_DEBUG_MARGIN (0)

+#endif

+

+#ifndef VMA_DEBUG_INITIALIZE_ALLOCATIONS

+    /**

+    Define this macro to 1 to automatically fill new allocations and destroyed

+    allocations with some bit pattern.

+    */

+    #define VMA_DEBUG_INITIALIZE_ALLOCATIONS (0)

+#endif

+

+#ifndef VMA_DEBUG_DETECT_CORRUPTION

+    /**

+    Define this macro to 1 together with non-zero value of VMA_DEBUG_MARGIN to

+    enable writing magic value to the margin before and after every allocation and

+    validating it, so that memory corruptions (out-of-bounds writes) are detected.

+    */

+    #define VMA_DEBUG_DETECT_CORRUPTION (0)

 #endif

 

 #ifndef VMA_DEBUG_GLOBAL_MUTEX

-   /**

-   Set this to 1 for debugging purposes only, to enable single mutex protecting all

-   entry calls to the library. Can be useful for debugging multithreading issues.

-   */

-   #define VMA_DEBUG_GLOBAL_MUTEX (0)

+    /**

+    Set this to 1 for debugging purposes only, to enable single mutex protecting all

+    entry calls to the library. Can be useful for debugging multithreading issues.

+    */

+    #define VMA_DEBUG_GLOBAL_MUTEX (0)

 #endif

 

 #ifndef VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY

-   /**

-   Minimum value for VkPhysicalDeviceLimits::bufferImageGranularity.

-   Set to more than 1 for debugging purposes only. Must be power of two.

-   */

-   #define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1)

+    /**

+    Minimum value for VkPhysicalDeviceLimits::bufferImageGranularity.

+    Set to more than 1 for debugging purposes only. Must be power of two.

+    */

+    #define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1)

 #endif

 

 #ifndef VMA_SMALL_HEAP_MAX_SIZE

@@ -2428,8 +2883,21 @@
    #define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256ull * 1024 * 1024)

 #endif

 

+#ifndef VMA_CLASS_NO_COPY

+    #define VMA_CLASS_NO_COPY(className) \

+        private: \

+            className(const className&) = delete; \

+            className& operator=(const className&) = delete;

+#endif

+

 static const uint32_t VMA_FRAME_INDEX_LOST = UINT32_MAX;

 

+// Decimal 2139416166, float NaN, little-endian binary 66 E6 84 7F.

+static const uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666;

+

+static const uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED   = 0xDC;

+static const uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF;

+

 /*******************************************************************************

 END OF CONFIGURATION

 */

@@ -2455,6 +2923,13 @@
 {

 	return (val + align - 1) / align * align;

 }

+// Aligns given value down to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 8.

+// Use types like uint32_t, uint64_t as T.

+template <typename T>

+static inline T VmaAlignDown(T val, T align)

+{

+    return val / align * align;

+}

 

 // Division with mathematical rounding to nearest number.

 template <typename T>

@@ -2463,6 +2938,11 @@
 	return (x + (y / (T)2)) / y;

 }

 

+static inline bool VmaStrIsEmpty(const char* pStr)

+{

+    return pStr == VMA_NULL || *pStr == '\0';

+}

+

 #ifndef VMA_SORT

 

 template<typename Iterator, typename Compare>

@@ -2576,9 +3056,34 @@
     }

 }

 

+static void VmaWriteMagicValue(void* pData, VkDeviceSize offset)

+{

+    uint32_t* pDst = (uint32_t*)((char*)pData + offset);

+    const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);

+    for(size_t i = 0; i < numberCount; ++i, ++pDst)

+    {

+        *pDst = VMA_CORRUPTION_DETECTION_MAGIC_VALUE;

+    }

+}

+

+static bool VmaValidateMagicValue(const void* pData, VkDeviceSize offset)

+{

+    const uint32_t* pSrc = (const uint32_t*)((const char*)pData + offset);

+    const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);

+    for(size_t i = 0; i < numberCount; ++i, ++pSrc)

+    {

+        if(*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE)

+        {

+            return false;

+        }

+    }

+    return true;

+}

+

 // Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope).

 struct VmaMutexLock

 {

+    VMA_CLASS_NO_COPY(VmaMutexLock)

 public:

     VmaMutexLock(VMA_MUTEX& mutex, bool useMutex) :

         m_pMutex(useMutex ? &mutex : VMA_NULL)

@@ -2620,23 +3125,23 @@
 Returned value is the found element, if present in the collection or place where

 new element with value (key) should be inserted.

 */

-template <typename IterT, typename KeyT, typename CmpT>

-static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, CmpT cmp)

+template <typename CmpLess, typename IterT, typename KeyT>

+static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, CmpLess cmp)

 {

-   size_t down = 0, up = (end - beg);

-   while(down < up)

-   {

-      const size_t mid = (down + up) / 2;

-      if(cmp(*(beg+mid), key))

-      {

-         down = mid + 1;

-      }

-      else

-      {

-         up = mid;

-      }

-   }

-   return beg + down;

+    size_t down = 0, up = (end - beg);

+    while(down < up)

+    {

+        const size_t mid = (down + up) / 2;

+        if(cmp(*(beg+mid), key))

+        {

+            down = mid + 1;

+        }

+        else

+        {

+            up = mid;

+        }

+    }

+    return beg + down;

 }

 

 ////////////////////////////////////////////////////////////////////////////////

@@ -3004,23 +3509,18 @@
     return false;

 }

 

-template<typename CmpLess, typename VectorT>

-size_t VmaVectorFindSorted(const VectorT& vector, const typename VectorT::value_type& value)

+template<typename CmpLess, typename IterT, typename KeyT>

+IterT VmaVectorFindSorted(const IterT& beg, const IterT& end, const KeyT& value)

 {

     CmpLess comparator;

-    typename VectorT::iterator it = VmaBinaryFindFirstNotLess(

-        vector.data(),

-        vector.data() + vector.size(),

-        value,

-        comparator);

-    if(it != vector.size() && !comparator(*it, value) && !comparator(value, *it))

+    typename IterT it = VmaBinaryFindFirstNotLess<CmpLess, IterT, KeyT>(

+        beg, end, value, comparator);

+    if(it == end ||

+        !comparator(*it, value) && !comparator(value, *it))

     {

-        return it - vector.begin();

+        return it;

     }

-    else

-    {

-        return vector.size();

-    }

+    return end;

 }

 

 ////////////////////////////////////////////////////////////////////////////////

@@ -3034,6 +3534,7 @@
 template<typename T>

 class VmaPoolAllocator

 {

+    VMA_CLASS_NO_COPY(VmaPoolAllocator)

 public:

     VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, size_t itemsPerBlock);

     ~VmaPoolAllocator();

@@ -3166,6 +3667,7 @@
 template<typename T>

 class VmaRawList

 {

+    VMA_CLASS_NO_COPY(VmaRawList)

 public:

     typedef VmaListItem<T> ItemType;

 

@@ -3204,10 +3706,6 @@
     ItemType* m_pFront;

     ItemType* m_pBack;

     size_t m_Count;

-

-    // Declared not defined, to block copy constructor and assignment operator.

-    VmaRawList(const VmaRawList<T>& src);

-    VmaRawList<T>& operator=(const VmaRawList<T>& rhs);

 };

 

 template<typename T>

@@ -3436,6 +3934,7 @@
 template<typename T, typename AllocatorT>

 class VmaList

 {

+    VMA_CLASS_NO_COPY(VmaList)

 public:

     class iterator

     {

@@ -3725,8 +4224,11 @@
 

 class VmaDeviceMemoryBlock;

 

+enum VMA_CACHE_OPERATION { VMA_CACHE_FLUSH, VMA_CACHE_INVALIDATE };

+

 struct VmaAllocation_T

 {

+    VMA_CLASS_NO_COPY(VmaAllocation_T)

 private:

     static const uint8_t MAP_COUNT_FLAG_PERSISTENT_MAP = 0x80;

 

@@ -3753,6 +4255,10 @@
         m_MapCount(0),

         m_Flags(userDataString ? (uint8_t)FLAG_USER_DATA_STRING : 0)

     {

+#if VMA_STATS_STRING_ENABLED

+        m_CreationFrameIndex = currentFrameIndex;

+        m_BufferImageUsage = 0;

+#endif

     }

 

     ~VmaAllocation_T()

@@ -3879,6 +4385,19 @@
     VkResult DedicatedAllocMap(VmaAllocator hAllocator, void** ppData);

     void DedicatedAllocUnmap(VmaAllocator hAllocator);

 

+#if VMA_STATS_STRING_ENABLED

+    uint32_t GetCreationFrameIndex() const { return m_CreationFrameIndex; }

+    uint32_t GetBufferImageUsage() const { return m_BufferImageUsage; }

+

+    void InitBufferImageUsage(uint32_t bufferImageUsage)

+    {

+        VMA_ASSERT(m_BufferImageUsage == 0);

+        m_BufferImageUsage = bufferImageUsage;

+    }

+

+    void PrintParameters(class VmaJsonWriter& json) const;

+#endif

+

 private:

     VkDeviceSize m_Alignment;

     VkDeviceSize m_Size;

@@ -3916,6 +4435,11 @@
         DedicatedAllocation m_DedicatedAllocation;

     };

 

+#if VMA_STATS_STRING_ENABLED

+    uint32_t m_CreationFrameIndex;

+    uint32_t m_BufferImageUsage; // 0 if unknown.

+#endif

+

     void FreeUserDataString(VmaAllocator hAllocator);

 };

 

@@ -3931,6 +4455,22 @@
     VmaSuballocationType type;

 };

 

+// Comparator for offsets.

+struct VmaSuballocationOffsetLess

+{

+    bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const

+    {

+        return lhs.offset < rhs.offset;

+    }

+};

+struct VmaSuballocationOffsetGreater

+{

+    bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const

+    {

+        return lhs.offset > rhs.offset;

+    }

+};

+

 typedef VmaList< VmaSuballocation, VmaStlAllocator<VmaSuballocation> > VmaSuballocationList;

 

 // Cost of one additional allocation lost, as equivalent in bytes.

@@ -3970,62 +4510,133 @@
 class VmaBlockMetadata

 {

 public:

-    VmaBlockMetadata(VmaAllocator hAllocator);

-    ~VmaBlockMetadata();

-    void Init(VkDeviceSize size);

+    VmaBlockMetadata() : m_Size(0) { }

+    virtual ~VmaBlockMetadata() { }

+    virtual void Init(VkDeviceSize size) { m_Size = size; }

 

     // Validates all data structures inside this object. If not valid, returns false.

-    bool Validate() const;

+    virtual bool Validate() const = 0;

     VkDeviceSize GetSize() const { return m_Size; }

-    size_t GetAllocationCount() const { return m_Suballocations.size() - m_FreeCount; }

-    VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; }

-    VkDeviceSize GetUnusedRangeSizeMax() const;

+    virtual size_t GetAllocationCount() const = 0;

+    virtual VkDeviceSize GetSumFreeSize() const = 0;

+    virtual VkDeviceSize GetUnusedRangeSizeMax() const = 0;

     // Returns true if this block is empty - contains only single free suballocation.

-    bool IsEmpty() const;

+    virtual bool IsEmpty() const = 0;

 

-    void CalcAllocationStatInfo(VmaStatInfo& outInfo) const;

-    void AddPoolStats(VmaPoolStats& inoutStats) const;

+    virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const = 0;

+    // Shouldn't modify blockCount.

+    virtual void AddPoolStats(VmaPoolStats& inoutStats) const = 0;

 

 #if VMA_STATS_STRING_ENABLED

-    void PrintDetailedMap(class VmaJsonWriter& json) const;

+    virtual void PrintDetailedMap(class VmaJsonWriter& json) const = 0;

 #endif

 

-    // Creates trivial request for case when block is empty.

-    void CreateFirstAllocationRequest(VmaAllocationRequest* pAllocationRequest);

-

     // Tries to find a place for suballocation with given parameters inside this block.

     // If succeeded, fills pAllocationRequest and returns true.

     // If failed, returns false.

-    bool CreateAllocationRequest(

+    virtual bool CreateAllocationRequest(

         uint32_t currentFrameIndex,

         uint32_t frameInUseCount,

         VkDeviceSize bufferImageGranularity,

         VkDeviceSize allocSize,

         VkDeviceSize allocAlignment,

+        bool upperAddress,

+        VmaSuballocationType allocType,

+        bool canMakeOtherLost,

+        VmaAllocationRequest* pAllocationRequest) = 0;

+

+    virtual bool MakeRequestedAllocationsLost(

+        uint32_t currentFrameIndex,

+        uint32_t frameInUseCount,

+        VmaAllocationRequest* pAllocationRequest) = 0;

+

+    virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) = 0;

+

+    virtual VkResult CheckCorruption(const void* pBlockData) = 0;

+

+    // Makes actual allocation based on request. Request must already be checked and valid.

+    virtual void Alloc(

+        const VmaAllocationRequest& request,

+        VmaSuballocationType type,

+        VkDeviceSize allocSize,

+        bool upperAddress,

+        VmaAllocation hAllocation) = 0;

+

+    // Frees suballocation assigned to given memory region.

+    virtual void Free(const VmaAllocation allocation) = 0;

+    virtual void FreeAtOffset(VkDeviceSize offset) = 0;

+

+protected:

+#if VMA_STATS_STRING_ENABLED

+    void PrintDetailedMap_Begin(class VmaJsonWriter& json,

+        VkDeviceSize unusedBytes,

+        size_t allocationCount,

+        size_t unusedRangeCount) const;

+    void PrintDetailedMap_Allocation(class VmaJsonWriter& json,

+        VkDeviceSize offset,

+        VmaAllocation hAllocation) const;

+    void PrintDetailedMap_UnusedRange(class VmaJsonWriter& json,

+        VkDeviceSize offset,

+        VkDeviceSize size) const;

+    void PrintDetailedMap_End(class VmaJsonWriter& json) const;

+#endif

+

+private:

+    VkDeviceSize m_Size;

+};

+

+class VmaBlockMetadata_Generic : public VmaBlockMetadata

+{

+    VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic)

+public:

+    VmaBlockMetadata_Generic(VmaAllocator hAllocator);

+    virtual ~VmaBlockMetadata_Generic();

+    virtual void Init(VkDeviceSize size);

+

+    virtual bool Validate() const;

+    virtual size_t GetAllocationCount() const { return m_Suballocations.size() - m_FreeCount; }

+    virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; }

+    virtual VkDeviceSize GetUnusedRangeSizeMax() const;

+    virtual bool IsEmpty() const;

+

+    virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const;

+    virtual void AddPoolStats(VmaPoolStats& inoutStats) const;

+

+#if VMA_STATS_STRING_ENABLED

+    virtual void PrintDetailedMap(class VmaJsonWriter& json) const;

+#endif

+

+    virtual bool CreateAllocationRequest(

+        uint32_t currentFrameIndex,

+        uint32_t frameInUseCount,

+        VkDeviceSize bufferImageGranularity,

+        VkDeviceSize allocSize,

+        VkDeviceSize allocAlignment,

+        bool upperAddress,

         VmaSuballocationType allocType,

         bool canMakeOtherLost,

         VmaAllocationRequest* pAllocationRequest);

 

-    bool MakeRequestedAllocationsLost(

+    virtual bool MakeRequestedAllocationsLost(

         uint32_t currentFrameIndex,

         uint32_t frameInUseCount,

         VmaAllocationRequest* pAllocationRequest);

 

-    uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);

+    virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);

 

-    // Makes actual allocation based on request. Request must already be checked and valid.

-    void Alloc(

+    virtual VkResult CheckCorruption(const void* pBlockData);

+

+    virtual void Alloc(

         const VmaAllocationRequest& request,

         VmaSuballocationType type,

         VkDeviceSize allocSize,

+        bool upperAddress,

         VmaAllocation hAllocation);

 

-    // Frees suballocation assigned to given memory region.

-    void Free(const VmaAllocation allocation);

-    void FreeAtOffset(VkDeviceSize offset);

+    virtual void Free(const VmaAllocation allocation);

+    virtual void FreeAtOffset(VkDeviceSize offset);

 

 private:

-    VkDeviceSize m_Size;

     uint32_t m_FreeCount;

     VkDeviceSize m_SumFreeSize;

     VmaSuballocationList m_Suballocations;

@@ -4065,6 +4676,182 @@
 };

 

 /*

+Allocations and their references in internal data structure look like this:

+

+if(m_2ndVectorMode == SECOND_VECTOR_EMPTY):

+

+        0 +-------+

+          |       |

+          |       |

+          |       |

+          +-------+

+          | Alloc |  1st[m_1stNullItemsBeginCount]

+          +-------+

+          | Alloc |  1st[m_1stNullItemsBeginCount + 1]

+          +-------+

+          |  ...  |

+          +-------+

+          | Alloc |  1st[1st.size() - 1]

+          +-------+

+          |       |

+          |       |

+          |       |

+GetSize() +-------+

+

+if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER):

+

+        0 +-------+

+          | Alloc |  2nd[0]

+          +-------+

+          | Alloc |  2nd[1]

+          +-------+

+          |  ...  |

+          +-------+

+          | Alloc |  2nd[2nd.size() - 1]

+          +-------+

+          |       |

+          |       |

+          |       |

+          +-------+

+          | Alloc |  1st[m_1stNullItemsBeginCount]

+          +-------+

+          | Alloc |  1st[m_1stNullItemsBeginCount + 1]

+          +-------+

+          |  ...  |

+          +-------+

+          | Alloc |  1st[1st.size() - 1]

+          +-------+

+          |       |

+GetSize() +-------+

+

+if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK):

+

+        0 +-------+

+          |       |

+          |       |

+          |       |

+          +-------+

+          | Alloc |  1st[m_1stNullItemsBeginCount]

+          +-------+

+          | Alloc |  1st[m_1stNullItemsBeginCount + 1]

+          +-------+

+          |  ...  |

+          +-------+

+          | Alloc |  1st[1st.size() - 1]

+          +-------+

+          |       |

+          |       |

+          |       |

+          +-------+

+          | Alloc |  2nd[2nd.size() - 1]

+          +-------+

+          |  ...  |

+          +-------+

+          | Alloc |  2nd[1]

+          +-------+

+          | Alloc |  2nd[0]

+GetSize() +-------+

+

+*/

+class VmaBlockMetadata_Linear : public VmaBlockMetadata

+{

+    VMA_CLASS_NO_COPY(VmaBlockMetadata_Linear)

+public:

+    VmaBlockMetadata_Linear(VmaAllocator hAllocator);

+    virtual ~VmaBlockMetadata_Linear();

+    virtual void Init(VkDeviceSize size);

+

+    virtual bool Validate() const;

+    virtual size_t GetAllocationCount() const;

+    virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; }

+    virtual VkDeviceSize GetUnusedRangeSizeMax() const;

+    virtual bool IsEmpty() const { return GetAllocationCount() == 0; }

+

+    virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const;

+    virtual void AddPoolStats(VmaPoolStats& inoutStats) const;

+

+#if VMA_STATS_STRING_ENABLED

+    virtual void PrintDetailedMap(class VmaJsonWriter& json) const;

+#endif

+

+    virtual bool CreateAllocationRequest(

+        uint32_t currentFrameIndex,

+        uint32_t frameInUseCount,

+        VkDeviceSize bufferImageGranularity,

+        VkDeviceSize allocSize,

+        VkDeviceSize allocAlignment,

+        bool upperAddress,

+        VmaSuballocationType allocType,

+        bool canMakeOtherLost,

+        VmaAllocationRequest* pAllocationRequest);

+

+    virtual bool MakeRequestedAllocationsLost(

+        uint32_t currentFrameIndex,

+        uint32_t frameInUseCount,

+        VmaAllocationRequest* pAllocationRequest);

+

+    virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);

+

+    virtual VkResult CheckCorruption(const void* pBlockData);

+

+    virtual void Alloc(

+        const VmaAllocationRequest& request,

+        VmaSuballocationType type,

+        VkDeviceSize allocSize,

+        bool upperAddress,

+        VmaAllocation hAllocation);

+

+    virtual void Free(const VmaAllocation allocation);

+    virtual void FreeAtOffset(VkDeviceSize offset);

+

+private:

+    /*

+    There are two suballocation vectors, used in ping-pong way.

+    The one with index m_1stVectorIndex is called 1st.

+    The one with index (m_1stVectorIndex ^ 1) is called 2nd.

+    2nd can be non-empty only when 1st is not empty.

+    When 2nd is not empty, m_2ndVectorMode indicates its mode of operation.

+    */

+    typedef VmaVector< VmaSuballocation, VmaStlAllocator<VmaSuballocation> > SuballocationVectorType;

+

+    enum SECOND_VECTOR_MODE

+    {

+        SECOND_VECTOR_EMPTY,

+        /*

+        Suballocations in 2nd vector are created later than the ones in 1st, but they

+        all have smaller offset.

+        */

+        SECOND_VECTOR_RING_BUFFER,

+        /*

+        Suballocations in 2nd vector are upper side of double stack.

+        They all have offsets higher than those in 1st vector.

+        Top of this stack means smaller offsets, but higher indices in this vector.

+        */

+        SECOND_VECTOR_DOUBLE_STACK,

+    };

+

+    VkDeviceSize m_SumFreeSize;

+    SuballocationVectorType m_Suballocations0, m_Suballocations1;

+    uint32_t m_1stVectorIndex;

+    SECOND_VECTOR_MODE m_2ndVectorMode;

+

+    SuballocationVectorType& AccessSuballocations1st() { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; }

+    SuballocationVectorType& AccessSuballocations2nd() { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; }

+    const SuballocationVectorType& AccessSuballocations1st() const { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; }

+    const SuballocationVectorType& AccessSuballocations2nd() const { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; }

+    

+    // Number of items in 1st vector with hAllocation = null at the beginning.

+    size_t m_1stNullItemsBeginCount;

+    // Number of other items in 1st vector with hAllocation = null somewhere in the middle.

+    size_t m_1stNullItemsMiddleCount;

+    // Number of items in 2nd vector with hAllocation = null.

+    size_t m_2ndNullItemsCount;

+

+    bool ShouldCompact1st() const;

+    void CleanupAfterFree();

+};

+

+/*

 Represents a single block of device memory (`VkDeviceMemory`) with all the

 data about its regions (aka suballocations, #VmaAllocation), assigned and free.

 

@@ -4072,8 +4859,9 @@
 */

 class VmaDeviceMemoryBlock

 {

+    VMA_CLASS_NO_COPY(VmaDeviceMemoryBlock)

 public:

-    VmaBlockMetadata m_Metadata;

+    VmaBlockMetadata* m_pMetadata;

 

     VmaDeviceMemoryBlock(VmaAllocator hAllocator);

 

@@ -4085,23 +4873,32 @@
 

     // Always call after construction.

     void Init(

+        VmaAllocator hAllocator,

         uint32_t newMemoryTypeIndex,

         VkDeviceMemory newMemory,

-        VkDeviceSize newSize);

+        VkDeviceSize newSize,

+        uint32_t id,

+        bool linearAlgorithm);

     // Always call before destruction.

     void Destroy(VmaAllocator allocator);

     

     VkDeviceMemory GetDeviceMemory() const { return m_hMemory; }

     uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }

+    uint32_t GetId() const { return m_Id; }

     void* GetMappedData() const { return m_pMappedData; }

 

     // Validates all data structures inside this object. If not valid, returns false.

     bool Validate() const;

 

+    VkResult CheckCorruption(VmaAllocator hAllocator);

+

     // ppData can be null.

     VkResult Map(VmaAllocator hAllocator, uint32_t count, void** ppData);

     void Unmap(VmaAllocator hAllocator, uint32_t count);

 

+    VkResult WriteMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize);

+    VkResult ValidateMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize);

+

     VkResult BindBufferMemory(

         const VmaAllocator hAllocator,

         const VmaAllocation hAllocation,

@@ -4113,6 +4910,7 @@
 

 private:

     uint32_t m_MemoryTypeIndex;

+    uint32_t m_Id;

     VkDeviceMemory m_hMemory;

 

     // Protects access to m_hMemory so it's not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.

@@ -4140,6 +4938,8 @@
 */

 struct VmaBlockVector

 {

+    VMA_CLASS_NO_COPY(VmaBlockVector)

+public:

     VmaBlockVector(

         VmaAllocator hAllocator,

         uint32_t memoryTypeIndex,

@@ -4148,7 +4948,9 @@
         size_t maxBlockCount,

         VkDeviceSize bufferImageGranularity,

         uint32_t frameInUseCount,

-        bool isCustomPool);

+        bool isCustomPool,

+        bool explicitBlockSize,

+        bool linearAlgorithm);

     ~VmaBlockVector();

 

     VkResult CreateMinBlocks();

@@ -4157,15 +4959,18 @@
     VkDeviceSize GetPreferredBlockSize() const { return m_PreferredBlockSize; }

     VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; }

     uint32_t GetFrameInUseCount() const { return m_FrameInUseCount; }

+    bool UsesLinearAlgorithm() const { return m_LinearAlgorithm; }

 

     void GetPoolStats(VmaPoolStats* pStats);

 

     bool IsEmpty() const { return m_Blocks.empty(); }

+    bool IsCorruptionDetectionEnabled() const;

 

     VkResult Allocate(

         VmaPool hCurrentPool,

         uint32_t currentFrameIndex,

-        const VkMemoryRequirements& vkMemReq,

+        VkDeviceSize size,

+        VkDeviceSize alignment,

         const VmaAllocationCreateInfo& createInfo,

         VmaSuballocationType suballocType,

         VmaAllocation* pAllocation);

@@ -4183,6 +4988,7 @@
     void MakePoolAllocationsLost(

         uint32_t currentFrameIndex,

         size_t* pLostAllocationCount);

+    VkResult CheckCorruption();

 

     VmaDefragmentator* EnsureDefragmentator(

         VmaAllocator hAllocator,

@@ -4206,16 +5012,19 @@
     const VkDeviceSize m_BufferImageGranularity;

     const uint32_t m_FrameInUseCount;

     const bool m_IsCustomPool;

+    const bool m_ExplicitBlockSize;

+    const bool m_LinearAlgorithm;

+    bool m_HasEmptyBlock;

     VMA_MUTEX m_Mutex;

     // Incrementally sorted by sumFreeSize, ascending.

     VmaVector< VmaDeviceMemoryBlock*, VmaStlAllocator<VmaDeviceMemoryBlock*> > m_Blocks;

     /* There can be at most one allocation that is completely empty - a

     hysteresis to avoid pessimistic case of alternating creation and destruction

     of a VkDeviceMemory. */

-    bool m_HasEmptyBlock;

     VmaDefragmentator* m_pDefragmentator;

+    uint32_t m_NextBlockId;

 

-    size_t CalcMaxBlockSize() const;

+    VkDeviceSize CalcMaxBlockSize() const;

 

     // Finds and removes given block from vector.

     void Remove(VmaDeviceMemoryBlock* pBlock);

@@ -4224,29 +5033,48 @@
     // after this call.

     void IncrementallySortBlocks();

 

+    // To be used only without CAN_MAKE_OTHER_LOST flag.

+    VkResult AllocateFromBlock(

+        VmaDeviceMemoryBlock* pBlock,

+        VmaPool hCurrentPool,

+        uint32_t currentFrameIndex,

+        VkDeviceSize size,

+        VkDeviceSize alignment,

+        VmaAllocationCreateFlags allocFlags,

+        void* pUserData,

+        VmaSuballocationType suballocType,

+        VmaAllocation* pAllocation);

+

     VkResult CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex);

 };

 

 struct VmaPool_T

 {

+    VMA_CLASS_NO_COPY(VmaPool_T)

 public:

     VmaBlockVector m_BlockVector;

 

-    // Takes ownership.

     VmaPool_T(

         VmaAllocator hAllocator,

-        const VmaPoolCreateInfo& createInfo);

+        const VmaPoolCreateInfo& createInfo,

+        VkDeviceSize preferredBlockSize);

     ~VmaPool_T();

 

-    VmaBlockVector& GetBlockVector() { return m_BlockVector; }

+    uint32_t GetId() const { return m_Id; }

+    void SetId(uint32_t id) { VMA_ASSERT(m_Id == 0); m_Id = id; }

 

 #if VMA_STATS_STRING_ENABLED

     //void PrintDetailedMap(class VmaStringBuilder& sb);

 #endif

+

+private:

+    uint32_t m_Id;

 };

 

 class VmaDefragmentator

 {

+    VMA_CLASS_NO_COPY(VmaDefragmentator)

+private:

     const VmaAllocator m_hAllocator;

     VmaBlockVector* const m_pBlockVector;

     uint32_t m_CurrentFrameIndex;

@@ -4292,7 +5120,7 @@
 

         void CalcHasNonMovableAllocations()

         {

-            const size_t blockAllocCount = m_pBlock->m_Metadata.GetAllocationCount();

+            const size_t blockAllocCount = m_pBlock->m_pMetadata->GetAllocationCount();

             const size_t defragmentAllocCount = m_Allocations.size();

             m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount;

         }

@@ -4336,7 +5164,7 @@
             {

                 return false;

             }

-            if(pLhsBlockInfo->m_pBlock->m_Metadata.GetSumFreeSize() < pRhsBlockInfo->m_pBlock->m_Metadata.GetSumFreeSize())

+            if(pLhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize() < pRhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize())

             {

                 return true;

             }

@@ -4373,9 +5201,111 @@
         uint32_t maxAllocationsToMove);

 };

 

+#if VMA_RECORDING_ENABLED

+

+class VmaRecorder

+{

+public:

+    VmaRecorder();

+    VkResult Init(const VmaRecordSettings& settings, bool useMutex);

+    void WriteConfiguration(

+        const VkPhysicalDeviceProperties& devProps,

+        const VkPhysicalDeviceMemoryProperties& memProps,

+        bool dedicatedAllocationExtensionEnabled);

+    ~VmaRecorder();

+

+    void RecordCreateAllocator(uint32_t frameIndex);

+    void RecordDestroyAllocator(uint32_t frameIndex);

+    void RecordCreatePool(uint32_t frameIndex,

+        const VmaPoolCreateInfo& createInfo,

+        VmaPool pool);

+    void RecordDestroyPool(uint32_t frameIndex, VmaPool pool);

+    void RecordAllocateMemory(uint32_t frameIndex,

+        const VkMemoryRequirements& vkMemReq,

+        const VmaAllocationCreateInfo& createInfo,

+        VmaAllocation allocation);

+    void RecordAllocateMemoryForBuffer(uint32_t frameIndex,

+        const VkMemoryRequirements& vkMemReq,

+        bool requiresDedicatedAllocation,

+        bool prefersDedicatedAllocation,

+        const VmaAllocationCreateInfo& createInfo,

+        VmaAllocation allocation);

+    void RecordAllocateMemoryForImage(uint32_t frameIndex,

+        const VkMemoryRequirements& vkMemReq,

+        bool requiresDedicatedAllocation,

+        bool prefersDedicatedAllocation,

+        const VmaAllocationCreateInfo& createInfo,

+        VmaAllocation allocation);

+    void RecordFreeMemory(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordSetAllocationUserData(uint32_t frameIndex,

+        VmaAllocation allocation,

+        const void* pUserData);

+    void RecordCreateLostAllocation(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordMapMemory(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordUnmapMemory(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordFlushAllocation(uint32_t frameIndex,

+        VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size);

+    void RecordInvalidateAllocation(uint32_t frameIndex,

+        VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size);

+    void RecordCreateBuffer(uint32_t frameIndex,

+        const VkBufferCreateInfo& bufCreateInfo,

+        const VmaAllocationCreateInfo& allocCreateInfo,

+        VmaAllocation allocation);

+    void RecordCreateImage(uint32_t frameIndex,

+        const VkImageCreateInfo& imageCreateInfo,

+        const VmaAllocationCreateInfo& allocCreateInfo,

+        VmaAllocation allocation);

+    void RecordDestroyBuffer(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordDestroyImage(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordTouchAllocation(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordGetAllocationInfo(uint32_t frameIndex,

+        VmaAllocation allocation);

+    void RecordMakePoolAllocationsLost(uint32_t frameIndex,

+        VmaPool pool);

+

+private:

+    struct CallParams

+    {

+        uint32_t threadId;

+        double time;

+    };

+

+    class UserDataString

+    {

+    public:

+        UserDataString(VmaAllocationCreateFlags allocFlags, const void* pUserData);

+        const char* GetString() const { return m_Str; }

+

+    private:

+        char m_PtrStr[17];

+        const char* m_Str;

+    };

+

+    bool m_UseMutex;

+    VmaRecordFlags m_Flags;

+    FILE* m_File;

+    VMA_MUTEX m_FileMutex;

+    int64_t m_Freq;

+    int64_t m_StartCounter;

+

+    void GetBasicParams(CallParams& outParams);

+    void Flush();

+};

+

+#endif // #if VMA_RECORDING_ENABLED

+

 // Main allocator object.

 struct VmaAllocator_T

 {

+    VMA_CLASS_NO_COPY(VmaAllocator_T)

+public:

     bool m_UseMutex;

     bool m_UseKhrDedicatedAllocation;

     VkDevice m_hDevice;

@@ -4399,6 +5329,7 @@
     VMA_MUTEX m_DedicatedAllocationsMutex[VK_MAX_MEMORY_TYPES];

 

     VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo);

+    VkResult Init(const VmaAllocatorCreateInfo* pCreateInfo);

     ~VmaAllocator_T();

 

     const VkAllocationCallbacks* GetAllocationCallbacks() const

@@ -4425,6 +5356,28 @@
         VMA_ASSERT(memTypeIndex < m_MemProps.memoryTypeCount);

         return m_MemProps.memoryTypes[memTypeIndex].heapIndex;

     }

+    // True when specific memory type is HOST_VISIBLE but not HOST_COHERENT.

+    bool IsMemoryTypeNonCoherent(uint32_t memTypeIndex) const

+    {

+        return (m_MemProps.memoryTypes[memTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) ==

+            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

+    }

+    // Minimum alignment for all allocations in specific memory type.

+    VkDeviceSize GetMemoryTypeMinAlignment(uint32_t memTypeIndex) const

+    {

+        return IsMemoryTypeNonCoherent(memTypeIndex) ?

+            VMA_MAX((VkDeviceSize)VMA_DEBUG_ALIGNMENT, m_PhysicalDeviceProperties.limits.nonCoherentAtomSize) :

+            (VkDeviceSize)VMA_DEBUG_ALIGNMENT;

+    }

+

+    bool IsIntegratedGpu() const

+    {

+        return m_PhysicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;

+    }

+

+#if VMA_RECORDING_ENABLED

+    VmaRecorder* GetRecorder() const { return m_pRecorder; }

+#endif

 

     void GetBufferMemoryRequirements(

         VkBuffer hBuffer,

@@ -4472,10 +5425,13 @@
     void GetPoolStats(VmaPool pool, VmaPoolStats* pPoolStats);

 

     void SetCurrentFrameIndex(uint32_t frameIndex);

+    uint32_t GetCurrentFrameIndex() const { return m_CurrentFrameIndex.load(); }

 

     void MakePoolAllocationsLost(

         VmaPool hPool,

         size_t* pLostAllocationCount);

+    VkResult CheckPoolCorruption(VmaPool hPool);

+    VkResult CheckCorruption(uint32_t memoryTypeBits);

 

     void CreateLostAllocation(VmaAllocation* pAllocation);

 

@@ -4488,6 +5444,13 @@
     VkResult BindBufferMemory(VmaAllocation hAllocation, VkBuffer hBuffer);

     VkResult BindImageMemory(VmaAllocation hAllocation, VkImage hImage);

 

+    void FlushOrInvalidateAllocation(

+        VmaAllocation hAllocation,

+        VkDeviceSize offset, VkDeviceSize size,

+        VMA_CACHE_OPERATION op);

+

+    void FillAllocation(const VmaAllocation hAllocation, uint8_t pattern);

+

 private:

     VkDeviceSize m_PreferredLargeHeapBlockSize;

 

@@ -4497,15 +5460,21 @@
     VMA_MUTEX m_PoolsMutex;

     // Protected by m_PoolsMutex. Sorted by pointer value.

     VmaVector<VmaPool, VmaStlAllocator<VmaPool> > m_Pools;

+    uint32_t m_NextPoolId;

 

     VmaVulkanFunctions m_VulkanFunctions;

 

+#if VMA_RECORDING_ENABLED

+    VmaRecorder* m_pRecorder;

+#endif

+

     void ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunctions);

 

     VkDeviceSize CalcPreferredBlockSize(uint32_t memTypeIndex);

 

     VkResult AllocateMemoryOfType(

-        const VkMemoryRequirements& vkMemReq,

+        VkDeviceSize size,

+        VkDeviceSize alignment,

         bool dedicatedAllocation,

         VkBuffer dedicatedBuffer,

         VkImage dedicatedImage,

@@ -4640,6 +5609,7 @@
 

 class VmaJsonWriter

 {

+    VMA_CLASS_NO_COPY(VmaJsonWriter)

 public:

     VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb);

     ~VmaJsonWriter();

@@ -4778,7 +5748,7 @@
     for(size_t i = 0; i < strLen; ++i)

     {

         char ch = pStr[i];

-        if(ch == '\'')

+        if(ch == '\\')

         {

             m_SB.Add("\\\\");

         }

@@ -5086,6 +6056,56 @@
     }

 }

 

+#if VMA_STATS_STRING_ENABLED

+

+// Correspond to values of enum VmaSuballocationType.

+static const char* VMA_SUBALLOCATION_TYPE_NAMES[] = {

+    "FREE",

+    "UNKNOWN",

+    "BUFFER",

+    "IMAGE_UNKNOWN",

+    "IMAGE_LINEAR",

+    "IMAGE_OPTIMAL",

+};

+

+void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const

+{

+    json.WriteString("Type");

+    json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[m_SuballocationType]);

+

+    json.WriteString("Size");

+    json.WriteNumber(m_Size);

+

+    if(m_pUserData != VMA_NULL)

+    {

+        json.WriteString("UserData");

+        if(IsUserDataString())

+        {

+            json.WriteString((const char*)m_pUserData);

+        }

+        else

+        {

+            json.BeginString();

+            json.ContinueString_Pointer(m_pUserData);

+            json.EndString();

+        }

+    }

+

+    json.WriteString("CreationFrameIndex");

+    json.WriteNumber(m_CreationFrameIndex);

+

+    json.WriteString("LastUseFrameIndex");

+    json.WriteNumber(GetLastUseFrameIndex());

+

+    if(m_BufferImageUsage != 0)

+    {

+        json.WriteString("Usage");

+        json.WriteNumber(m_BufferImageUsage);

+    }

+}

+

+#endif

+

 void VmaAllocation_T::FreeUserDataString(VmaAllocator hAllocator)

 {

     VMA_ASSERT(IsUserDataString());

@@ -5186,16 +6206,6 @@
 

 #if VMA_STATS_STRING_ENABLED

 

-// Correspond to values of enum VmaSuballocationType.

-static const char* VMA_SUBALLOCATION_TYPE_NAMES[] = {

-    "FREE",

-    "UNKNOWN",

-    "BUFFER",

-    "IMAGE_UNKNOWN",

-    "IMAGE_LINEAR",

-    "IMAGE_OPTIMAL",

-};

-

 static void VmaPrintStatInfo(VmaJsonWriter& json, const VmaStatInfo& stat)

 {

     json.BeginObject();

@@ -5262,11 +6272,79 @@
     }

 };

 

+

 ////////////////////////////////////////////////////////////////////////////////

 // class VmaBlockMetadata

 

-VmaBlockMetadata::VmaBlockMetadata(VmaAllocator hAllocator) :

-    m_Size(0),

+#if VMA_STATS_STRING_ENABLED

+

+void VmaBlockMetadata::PrintDetailedMap_Begin(class VmaJsonWriter& json,

+    VkDeviceSize unusedBytes,

+    size_t allocationCount,

+    size_t unusedRangeCount) const

+{

+    json.BeginObject();

+

+    json.WriteString("TotalBytes");

+    json.WriteNumber(GetSize());

+

+    json.WriteString("UnusedBytes");

+    json.WriteNumber(unusedBytes);

+

+    json.WriteString("Allocations");

+    json.WriteNumber((uint64_t)allocationCount);

+

+    json.WriteString("UnusedRanges");

+    json.WriteNumber((uint64_t)unusedRangeCount);

+

+    json.WriteString("Suballocations");

+    json.BeginArray();

+}

+

+void VmaBlockMetadata::PrintDetailedMap_Allocation(class VmaJsonWriter& json,

+    VkDeviceSize offset,

+    VmaAllocation hAllocation) const

+{

+    json.BeginObject(true);

+        

+    json.WriteString("Offset");

+    json.WriteNumber(offset);

+

+    hAllocation->PrintParameters(json);

+

+    json.EndObject();

+}

+

+void VmaBlockMetadata::PrintDetailedMap_UnusedRange(class VmaJsonWriter& json,

+    VkDeviceSize offset,

+    VkDeviceSize size) const

+{

+    json.BeginObject(true);

+        

+    json.WriteString("Offset");

+    json.WriteNumber(offset);

+

+    json.WriteString("Type");

+    json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[VMA_SUBALLOCATION_TYPE_FREE]);

+

+    json.WriteString("Size");

+    json.WriteNumber(size);

+

+    json.EndObject();

+}

+

+void VmaBlockMetadata::PrintDetailedMap_End(class VmaJsonWriter& json) const

+{

+    json.EndArray();

+    json.EndObject();

+}

+

+#endif // #if VMA_STATS_STRING_ENABLED

+

+////////////////////////////////////////////////////////////////////////////////

+// class VmaBlockMetadata_Generic

+

+VmaBlockMetadata_Generic::VmaBlockMetadata_Generic(VmaAllocator hAllocator) :

     m_FreeCount(0),

     m_SumFreeSize(0),

     m_Suballocations(VmaStlAllocator<VmaSuballocation>(hAllocator->GetAllocationCallbacks())),

@@ -5274,13 +6352,13 @@
 {

 }

 

-VmaBlockMetadata::~VmaBlockMetadata()

+VmaBlockMetadata_Generic::~VmaBlockMetadata_Generic()

 {

 }

 

-void VmaBlockMetadata::Init(VkDeviceSize size)

+void VmaBlockMetadata_Generic::Init(VkDeviceSize size)

 {

-    m_Size = size;

+    VmaBlockMetadata::Init(size);

     m_FreeCount = 1;

     m_SumFreeSize = size;

 

@@ -5296,14 +6374,14 @@
     m_FreeSuballocationsBySize.push_back(suballocItem);

 }

 

-bool VmaBlockMetadata::Validate() const

+bool VmaBlockMetadata_Generic::Validate() const

 {

     if(m_Suballocations.empty())

     {

         return false;

     }

     

-    // Expected offset of new suballocation as calculates from previous ones.

+    // Expected offset of new suballocation as calculated from previous ones.

     VkDeviceSize calculatedOffset = 0;

     // Expected number of free suballocations as calculated from traversing their list.

     uint32_t calculatedFreeCount = 0;

@@ -5312,7 +6390,7 @@
     // Expected number of free suballocations that should be registered in

     // m_FreeSuballocationsBySize calculated from traversing their list.

     size_t freeSuballocationsToRegister = 0;

-    // True if previous visisted suballocation was free.

+    // True if previous visited suballocation was free.

     bool prevFree = false;

 

     for(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();

@@ -5347,6 +6425,12 @@
             {

                 ++freeSuballocationsToRegister;

             }

+

+            // Margin required between allocations - every free space must be at least that large.

+            if(subAlloc.size < VMA_DEBUG_MARGIN)

+            {

+                return false;

+            }

         }

         else

         {

@@ -5358,6 +6442,12 @@
             {

                 return false;

             }

+

+            // Margin required between allocations - previous allocation must be free.

+            if(VMA_DEBUG_MARGIN > 0 && !prevFree)

+            {

+                return false;

+            }

         }

 

         calculatedOffset += subAlloc.size;

@@ -5392,7 +6482,7 @@
 

     // Check if totals match calculacted values.

     if(!ValidateFreeSuballocationList() ||

-        (calculatedOffset != m_Size) ||

+        (calculatedOffset != GetSize()) ||

         (calculatedSumFreeSize != m_SumFreeSize) ||

         (calculatedFreeCount != m_FreeCount))

     {

@@ -5402,7 +6492,7 @@
     return true;

 }

 

-VkDeviceSize VmaBlockMetadata::GetUnusedRangeSizeMax() const

+VkDeviceSize VmaBlockMetadata_Generic::GetUnusedRangeSizeMax() const

 {

     if(!m_FreeSuballocationsBySize.empty())

     {

@@ -5414,12 +6504,12 @@
     }

 }

 

-bool VmaBlockMetadata::IsEmpty() const

+bool VmaBlockMetadata_Generic::IsEmpty() const

 {

     return (m_Suballocations.size() == 1) && (m_FreeCount == 1);

 }

 

-void VmaBlockMetadata::CalcAllocationStatInfo(VmaStatInfo& outInfo) const

+void VmaBlockMetadata_Generic::CalcAllocationStatInfo(VmaStatInfo& outInfo) const

 {

     outInfo.blockCount = 1;

 

@@ -5428,7 +6518,7 @@
     outInfo.unusedRangeCount = m_FreeCount;

     

     outInfo.unusedBytes = m_SumFreeSize;

-    outInfo.usedBytes = m_Size - outInfo.unusedBytes;

+    outInfo.usedBytes = GetSize() - outInfo.unusedBytes;

 

     outInfo.allocationSizeMin = UINT64_MAX;

     outInfo.allocationSizeMax = 0;

@@ -5453,11 +6543,11 @@
     }

 }

 

-void VmaBlockMetadata::AddPoolStats(VmaPoolStats& inoutStats) const

+void VmaBlockMetadata_Generic::AddPoolStats(VmaPoolStats& inoutStats) const

 {

     const uint32_t rangeCount = (uint32_t)m_Suballocations.size();

 

-    inoutStats.size += m_Size;

+    inoutStats.size += GetSize();

     inoutStats.unusedSize += m_SumFreeSize;

     inoutStats.allocationCount += rangeCount - m_FreeCount;

     inoutStats.unusedRangeCount += m_FreeCount;

@@ -5466,64 +6556,29 @@
 

 #if VMA_STATS_STRING_ENABLED

 

-void VmaBlockMetadata::PrintDetailedMap(class VmaJsonWriter& json) const

+void VmaBlockMetadata_Generic::PrintDetailedMap(class VmaJsonWriter& json) const

 {

-    json.BeginObject();

+    PrintDetailedMap_Begin(json,

+        m_SumFreeSize, // unusedBytes

+        m_Suballocations.size() - (size_t)m_FreeCount, // allocationCount

+        m_FreeCount); // unusedRangeCount

 

-    json.WriteString("TotalBytes");

-    json.WriteNumber(m_Size);

-

-    json.WriteString("UnusedBytes");

-    json.WriteNumber(m_SumFreeSize);

-

-    json.WriteString("Allocations");

-    json.WriteNumber((uint64_t)m_Suballocations.size() - m_FreeCount);

-

-    json.WriteString("UnusedRanges");

-    json.WriteNumber(m_FreeCount);

-

-    json.WriteString("Suballocations");

-    json.BeginArray();

     size_t i = 0;

     for(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();

         suballocItem != m_Suballocations.cend();

         ++suballocItem, ++i)

     {

-        json.BeginObject(true);

-        

-        json.WriteString("Type");

-        json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[suballocItem->type]);

-

-        json.WriteString("Size");

-        json.WriteNumber(suballocItem->size);

-

-        json.WriteString("Offset");

-        json.WriteNumber(suballocItem->offset);

-

-        if(suballocItem->type != VMA_SUBALLOCATION_TYPE_FREE)

+        if(suballocItem->type == VMA_SUBALLOCATION_TYPE_FREE)

         {

-            const void* pUserData = suballocItem->hAllocation->GetUserData();

-            if(pUserData != VMA_NULL)

-            {

-                json.WriteString("UserData");

-                if(suballocItem->hAllocation->IsUserDataString())

-                {

-                    json.WriteString((const char*)pUserData);

-                }

-                else

-                {

-                    json.BeginString();

-                    json.ContinueString_Pointer(pUserData);

-                    json.EndString();

-                }

-            }

+            PrintDetailedMap_UnusedRange(json, suballocItem->offset, suballocItem->size);

         }

-

-        json.EndObject();

+        else

+        {

+            PrintDetailedMap_Allocation(json, suballocItem->offset, suballocItem->hAllocation);

+        }

     }

-    json.EndArray();

 

-    json.EndObject();

+    PrintDetailedMap_End(json);

 }

 

 #endif // #if VMA_STATS_STRING_ENABLED

@@ -5538,33 +6593,25 @@
 */

 //static const uint32_t MAX_SUITABLE_SUBALLOCATIONS_TO_CHECK = 8;

 

-void VmaBlockMetadata::CreateFirstAllocationRequest(VmaAllocationRequest* pAllocationRequest)

-{

-    VMA_ASSERT(IsEmpty());

-    pAllocationRequest->offset = 0;

-    pAllocationRequest->sumFreeSize = m_SumFreeSize;

-    pAllocationRequest->sumItemSize = 0;

-    pAllocationRequest->item = m_Suballocations.begin();

-    pAllocationRequest->itemsToMakeLostCount = 0;

-}

-

-bool VmaBlockMetadata::CreateAllocationRequest(

+bool VmaBlockMetadata_Generic::CreateAllocationRequest(

     uint32_t currentFrameIndex,

     uint32_t frameInUseCount,

     VkDeviceSize bufferImageGranularity,

     VkDeviceSize allocSize,

     VkDeviceSize allocAlignment,

+    bool upperAddress,

     VmaSuballocationType allocType,

     bool canMakeOtherLost,

     VmaAllocationRequest* pAllocationRequest)

 {

     VMA_ASSERT(allocSize > 0);

+    VMA_ASSERT(!upperAddress);

     VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);

     VMA_ASSERT(pAllocationRequest != VMA_NULL);

     VMA_HEAVY_ASSERT(Validate());

 

     // There is not enough total free space in this block to fullfill the request: Early return.

-    if(canMakeOtherLost == false && m_SumFreeSize < allocSize)

+    if(canMakeOtherLost == false && m_SumFreeSize < allocSize + 2 * VMA_DEBUG_MARGIN)

     {

         return false;

     }

@@ -5575,11 +6622,11 @@
     {

         if(VMA_BEST_FIT)

         {

-            // Find first free suballocation with size not less than allocSize.

+            // Find first free suballocation with size not less than allocSize + 2 * VMA_DEBUG_MARGIN.

             VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess(

                 m_FreeSuballocationsBySize.data(),

                 m_FreeSuballocationsBySize.data() + freeSuballocCount,

-                allocSize,

+                allocSize + 2 * VMA_DEBUG_MARGIN,

                 VmaSuballocationItemSizeLess());

             size_t index = it - m_FreeSuballocationsBySize.data();

             for(; index < freeSuballocCount; ++index)

@@ -5677,7 +6724,7 @@
     return false;

 }

 

-bool VmaBlockMetadata::MakeRequestedAllocationsLost(

+bool VmaBlockMetadata_Generic::MakeRequestedAllocationsLost(

     uint32_t currentFrameIndex,

     uint32_t frameInUseCount,

     VmaAllocationRequest* pAllocationRequest)

@@ -5709,7 +6756,7 @@
     return true;

 }

 

-uint32_t VmaBlockMetadata::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)

+uint32_t VmaBlockMetadata_Generic::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)

 {

     uint32_t lostAllocationCount = 0;

     for(VmaSuballocationList::iterator it = m_Suballocations.begin();

@@ -5727,12 +6774,38 @@
     return lostAllocationCount;

 }

 

-void VmaBlockMetadata::Alloc(

+VkResult VmaBlockMetadata_Generic::CheckCorruption(const void* pBlockData)

+{

+    for(VmaSuballocationList::iterator it = m_Suballocations.begin();

+        it != m_Suballocations.end();

+        ++it)

+    {

+        if(it->type != VMA_SUBALLOCATION_TYPE_FREE)

+        {

+            if(!VmaValidateMagicValue(pBlockData, it->offset - VMA_DEBUG_MARGIN))

+            {

+                VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!");

+                return VK_ERROR_VALIDATION_FAILED_EXT;

+            }

+            if(!VmaValidateMagicValue(pBlockData, it->offset + it->size))

+            {

+                VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!");

+                return VK_ERROR_VALIDATION_FAILED_EXT;

+            }

+        }

+    }

+

+    return VK_SUCCESS;

+}

+

+void VmaBlockMetadata_Generic::Alloc(

     const VmaAllocationRequest& request,

     VmaSuballocationType type,

     VkDeviceSize allocSize,

+    bool upperAddress,

     VmaAllocation hAllocation)

 {

+    VMA_ASSERT(!upperAddress);

     VMA_ASSERT(request.item != m_Suballocations.end());

     VmaSuballocation& suballoc = *request.item;

     // Given suballocation is a free block.

@@ -5791,7 +6864,7 @@
     m_SumFreeSize -= allocSize;

 }

 

-void VmaBlockMetadata::Free(const VmaAllocation allocation)

+void VmaBlockMetadata_Generic::Free(const VmaAllocation allocation)

 {

     for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();

         suballocItem != m_Suballocations.end();

@@ -5808,7 +6881,7 @@
     VMA_ASSERT(0 && "Not found!");

 }

 

-void VmaBlockMetadata::FreeAtOffset(VkDeviceSize offset)

+void VmaBlockMetadata_Generic::FreeAtOffset(VkDeviceSize offset)

 {

     for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();

         suballocItem != m_Suballocations.end();

@@ -5824,7 +6897,7 @@
     VMA_ASSERT(0 && "Not found!");

 }

 

-bool VmaBlockMetadata::ValidateFreeSuballocationList() const

+bool VmaBlockMetadata_Generic::ValidateFreeSuballocationList() const

 {

     VkDeviceSize lastSize = 0;

     for(size_t i = 0, count = m_FreeSuballocationsBySize.size(); i < count; ++i)

@@ -5852,7 +6925,7 @@
     return true;

 }

 

-bool VmaBlockMetadata::CheckAllocation(

+bool VmaBlockMetadata_Generic::CheckAllocation(

     uint32_t currentFrameIndex,

     uint32_t frameInUseCount,

     VkDeviceSize bufferImageGranularity,

@@ -5896,7 +6969,7 @@
         }

 

         // Remaining size is too small for this request: Early return.

-        if(m_Size - suballocItem->offset < allocSize)

+        if(GetSize() - suballocItem->offset < allocSize)

         {

             return false;

         }

@@ -5905,14 +6978,13 @@
         *pOffset = suballocItem->offset;

     

         // Apply VMA_DEBUG_MARGIN at the beginning.

-        if((VMA_DEBUG_MARGIN > 0) && suballocItem != m_Suballocations.cbegin())

+        if(VMA_DEBUG_MARGIN > 0)

         {

             *pOffset += VMA_DEBUG_MARGIN;

         }

     

         // Apply alignment.

-        const VkDeviceSize alignment = VMA_MAX(allocAlignment, static_cast<VkDeviceSize>(VMA_DEBUG_ALIGNMENT));

-        *pOffset = VmaAlignUp(*pOffset, alignment);

+        *pOffset = VmaAlignUp(*pOffset, allocAlignment);

 

         // Check previous suballocations for BufferImageGranularity conflicts.

         // Make bigger alignment if necessary.

@@ -5952,15 +7024,12 @@
         // Calculate padding at the beginning based on current offset.

         const VkDeviceSize paddingBegin = *pOffset - suballocItem->offset;

 

-        // Calculate required margin at the end if this is not last suballocation.

-        VmaSuballocationList::const_iterator next = suballocItem;

-        ++next;

-        const VkDeviceSize requiredEndMargin =

-            (next != m_Suballocations.cend()) ? VMA_DEBUG_MARGIN : 0;

+        // Calculate required margin at the end.

+        const VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN;

 

         const VkDeviceSize totalSize = paddingBegin + allocSize + requiredEndMargin;

         // Another early return check.

-        if(suballocItem->offset + totalSize > m_Size)

+        if(suballocItem->offset + totalSize > GetSize())

         {

             return false;

         }

@@ -6052,14 +7121,13 @@
         *pOffset = suballoc.offset;

     

         // Apply VMA_DEBUG_MARGIN at the beginning.

-        if((VMA_DEBUG_MARGIN > 0) && suballocItem != m_Suballocations.cbegin())

+        if(VMA_DEBUG_MARGIN > 0)

         {

             *pOffset += VMA_DEBUG_MARGIN;

         }

     

         // Apply alignment.

-        const VkDeviceSize alignment = VMA_MAX(allocAlignment, static_cast<VkDeviceSize>(VMA_DEBUG_ALIGNMENT));

-        *pOffset = VmaAlignUp(*pOffset, alignment);

+        *pOffset = VmaAlignUp(*pOffset, allocAlignment);

     

         // Check previous suballocations for BufferImageGranularity conflicts.

         // Make bigger alignment if necessary.

@@ -6092,11 +7160,8 @@
         // Calculate padding at the beginning based on current offset.

         const VkDeviceSize paddingBegin = *pOffset - suballoc.offset;

 

-        // Calculate required margin at the end if this is not last suballocation.

-        VmaSuballocationList::const_iterator next = suballocItem;

-        ++next;

-        const VkDeviceSize requiredEndMargin =

-            (next != m_Suballocations.cend()) ? VMA_DEBUG_MARGIN : 0;

+        // Calculate required margin at the end.

+        const VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN;

 

         // Fail if requested size plus margin before and after is bigger than size of this suballocation.

         if(paddingBegin + allocSize + requiredEndMargin > suballoc.size)

@@ -6134,7 +7199,7 @@
     return true;

 }

 

-void VmaBlockMetadata::MergeFreeWithNext(VmaSuballocationList::iterator item)

+void VmaBlockMetadata_Generic::MergeFreeWithNext(VmaSuballocationList::iterator item)

 {

     VMA_ASSERT(item != m_Suballocations.end());

     VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);

@@ -6149,7 +7214,7 @@
     m_Suballocations.erase(nextItem);

 }

 

-VmaSuballocationList::iterator VmaBlockMetadata::FreeSuballocation(VmaSuballocationList::iterator suballocItem)

+VmaSuballocationList::iterator VmaBlockMetadata_Generic::FreeSuballocation(VmaSuballocationList::iterator suballocItem)

 {

     // Change this suballocation to be marked as free.

     VmaSuballocation& suballoc = *suballocItem;

@@ -6201,7 +7266,7 @@
     }

 }

 

-void VmaBlockMetadata::RegisterFreeSuballocation(VmaSuballocationList::iterator item)

+void VmaBlockMetadata_Generic::RegisterFreeSuballocation(VmaSuballocationList::iterator item)

 {

     VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);

     VMA_ASSERT(item->size > 0);

@@ -6226,7 +7291,7 @@
 }

 

 

-void VmaBlockMetadata::UnregisterFreeSuballocation(VmaSuballocationList::iterator item)

+void VmaBlockMetadata_Generic::UnregisterFreeSuballocation(VmaSuballocationList::iterator item)

 {

     VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);

     VMA_ASSERT(item->size > 0);

@@ -6260,11 +7325,1764 @@
 }

 

 ////////////////////////////////////////////////////////////////////////////////

+// class VmaBlockMetadata_Linear

+

+VmaBlockMetadata_Linear::VmaBlockMetadata_Linear(VmaAllocator hAllocator) :

+    m_SumFreeSize(0),

+    m_Suballocations0(VmaStlAllocator<VmaSuballocation>(hAllocator->GetAllocationCallbacks())),

+    m_Suballocations1(VmaStlAllocator<VmaSuballocation>(hAllocator->GetAllocationCallbacks())),

+    m_1stVectorIndex(0),

+    m_2ndVectorMode(SECOND_VECTOR_EMPTY),

+    m_1stNullItemsBeginCount(0),

+    m_1stNullItemsMiddleCount(0),

+    m_2ndNullItemsCount(0)

+{

+}

+

+VmaBlockMetadata_Linear::~VmaBlockMetadata_Linear()

+{

+}

+

+void VmaBlockMetadata_Linear::Init(VkDeviceSize size)

+{

+    VmaBlockMetadata::Init(size);

+    m_SumFreeSize = size;

+}

+

+bool VmaBlockMetadata_Linear::Validate() const

+{

+    const SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+

+    if(suballocations2nd.empty() != (m_2ndVectorMode == SECOND_VECTOR_EMPTY))

+    {

+        return false;

+    }

+    if(suballocations1st.empty() && !suballocations2nd.empty() &&

+        m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+    {

+        return false;

+    }

+    if(!suballocations1st.empty())

+    {

+        // Null item at the beginning should be accounted into m_1stNullItemsBeginCount.

+        if(suballocations1st[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE)

+        {

+            return false;

+        }

+        // Null item at the end should be just pop_back().

+        if(suballocations1st.back().hAllocation == VK_NULL_HANDLE)

+        {

+            return false;

+        }

+    }

+    if(!suballocations2nd.empty())

+    {

+        // Null item at the end should be just pop_back().

+        if(suballocations2nd.back().hAllocation == VK_NULL_HANDLE)

+        {

+            return false;

+        }

+    }

+

+    if(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount > suballocations1st.size())

+    {

+        return false;

+    }

+    if(m_2ndNullItemsCount > suballocations2nd.size())

+    {

+        return false;

+    }

+

+    VkDeviceSize sumUsedSize = 0;

+    const size_t suballoc1stCount = suballocations1st.size();

+    VkDeviceSize offset = VMA_DEBUG_MARGIN;

+

+    if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+    {

+        const size_t suballoc2ndCount = suballocations2nd.size();

+        size_t nullItem2ndCount = 0;

+        for(size_t i = 0; i < suballoc2ndCount; ++i)

+        {

+            const VmaSuballocation& suballoc = suballocations2nd[i];

+            const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);

+

+            if(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))

+            {

+                return false;

+            }

+            if(suballoc.offset < offset)

+            {

+                return false;

+            }

+

+            if(!currFree)

+            {

+                if(suballoc.hAllocation->GetOffset() != suballoc.offset)

+                {

+                    return false;

+                }

+                if(suballoc.hAllocation->GetSize() != suballoc.size)

+                {

+                    return false;

+                }

+                sumUsedSize += suballoc.size;

+            }

+            else

+            {

+                ++nullItem2ndCount;

+            }

+

+            offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;

+        }

+

+        if(nullItem2ndCount != m_2ndNullItemsCount)

+        {

+            return false;

+        }

+    }

+

+    for(size_t i = 0; i < m_1stNullItemsBeginCount; ++i)

+    {

+        const VmaSuballocation& suballoc = suballocations1st[i];

+        if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE ||

+            suballoc.hAllocation != VK_NULL_HANDLE)

+        {

+            return false;

+        }

+    }

+

+    size_t nullItem1stCount = m_1stNullItemsBeginCount;

+

+    for(size_t i = m_1stNullItemsBeginCount; i < suballoc1stCount; ++i)

+    {

+        const VmaSuballocation& suballoc = suballocations1st[i];

+        const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);

+

+        if(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))

+        {

+            return false;

+        }

+        if(suballoc.offset < offset)

+        {

+            return false;

+        }

+        if(i < m_1stNullItemsBeginCount && !currFree)

+        {

+            return false;

+        }

+

+        if(!currFree)

+        {

+            if(suballoc.hAllocation->GetOffset() != suballoc.offset)

+            {

+                return false;

+            }

+            if(suballoc.hAllocation->GetSize() != suballoc.size)

+            {

+                return false;

+            }

+            sumUsedSize += suballoc.size;

+        }

+        else

+        {

+            ++nullItem1stCount;

+        }

+

+        offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;

+    }

+    if(nullItem1stCount != m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount)

+    {

+        return false;

+    }

+

+    if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+    {

+        const size_t suballoc2ndCount = suballocations2nd.size();

+        size_t nullItem2ndCount = 0;

+        for(size_t i = suballoc2ndCount; i--; )

+        {

+            const VmaSuballocation& suballoc = suballocations2nd[i];

+            const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);

+

+            if(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))

+            {

+                return false;

+            }

+            if(suballoc.offset < offset)

+            {

+                return false;

+            }

+

+            if(!currFree)

+            {

+                if(suballoc.hAllocation->GetOffset() != suballoc.offset)

+                {

+                    return false;

+                }

+                if(suballoc.hAllocation->GetSize() != suballoc.size)

+                {

+                    return false;

+                }

+                sumUsedSize += suballoc.size;

+            }

+            else

+            {

+                ++nullItem2ndCount;

+            }

+

+            offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;

+        }

+

+        if(nullItem2ndCount != m_2ndNullItemsCount)

+        {

+            return false;

+        }

+    }

+

+    if(offset > GetSize())

+    {

+        return false;

+    }

+    if(m_SumFreeSize != GetSize() - sumUsedSize)

+    {

+        return false;

+    }

+

+    return true;

+}

+

+size_t VmaBlockMetadata_Linear::GetAllocationCount() const

+{

+    return AccessSuballocations1st().size() - (m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount) +

+        AccessSuballocations2nd().size() - m_2ndNullItemsCount;

+}

+

+VkDeviceSize VmaBlockMetadata_Linear::GetUnusedRangeSizeMax() const

+{

+    const VkDeviceSize size = GetSize();

+

+    /*

+    We don't consider gaps inside allocation vectors with freed allocations because

+    they are not suitable for reuse in linear allocator. We consider only space that

+    is available for new allocations.

+    */

+    if(IsEmpty())

+    {

+        return size;

+    }

+    

+    const SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+

+    switch(m_2ndVectorMode)

+    {

+    case SECOND_VECTOR_EMPTY:

+        /*

+        Available space is after end of 1st, as well as before beginning of 1st (which

+        whould make it a ring buffer).

+        */

+        {

+            const size_t suballocations1stCount = suballocations1st.size();

+            VMA_ASSERT(suballocations1stCount > m_1stNullItemsBeginCount);

+            const VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount];

+            const VmaSuballocation& lastSuballoc  = suballocations1st[suballocations1stCount - 1];

+            return VMA_MAX(

+                firstSuballoc.offset,

+                size - (lastSuballoc.offset + lastSuballoc.size));

+        }

+        break;

+

+    case SECOND_VECTOR_RING_BUFFER:

+        /*

+        Available space is only between end of 2nd and beginning of 1st.

+        */

+        {

+            const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+            const VmaSuballocation& lastSuballoc2nd = suballocations2nd.back();

+            const VmaSuballocation& firstSuballoc1st = suballocations1st[m_1stNullItemsBeginCount];

+            return firstSuballoc1st.offset - (lastSuballoc2nd.offset + lastSuballoc2nd.size);

+        }

+        break;

+

+    case SECOND_VECTOR_DOUBLE_STACK:

+        /*

+        Available space is only between end of 1st and top of 2nd.

+        */

+        {

+            const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+            const VmaSuballocation& topSuballoc2nd = suballocations2nd.back();

+            const VmaSuballocation& lastSuballoc1st = suballocations1st.back();

+            return topSuballoc2nd.offset - (lastSuballoc1st.offset + lastSuballoc1st.size);

+        }

+        break;

+

+    default:

+        VMA_ASSERT(0);

+        return 0;

+    }

+}

+

+void VmaBlockMetadata_Linear::CalcAllocationStatInfo(VmaStatInfo& outInfo) const

+{

+    const VkDeviceSize size = GetSize();

+    const SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+    const size_t suballoc1stCount = suballocations1st.size();

+    const size_t suballoc2ndCount = suballocations2nd.size();

+

+    outInfo.blockCount = 1;

+    outInfo.allocationCount = (uint32_t)GetAllocationCount();

+    outInfo.unusedRangeCount = 0;

+    outInfo.usedBytes = 0;

+    outInfo.allocationSizeMin = UINT64_MAX;

+    outInfo.allocationSizeMax = 0;

+    outInfo.unusedRangeSizeMin = UINT64_MAX;

+    outInfo.unusedRangeSizeMax = 0;

+

+    VkDeviceSize lastOffset = 0;

+

+    if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+    {

+        const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;

+        size_t nextAlloc2ndIndex = 0;

+        while(lastOffset < freeSpace2ndTo1stEnd)

+        {

+            // Find next non-null allocation or move nextAllocIndex to the end.

+            while(nextAlloc2ndIndex < suballoc2ndCount &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                ++nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex < suballoc2ndCount)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                    ++outInfo.unusedRangeCount;

+                    outInfo.unusedBytes += unusedRangeSize;

+                    outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize);

+                    outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize);

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                outInfo.usedBytes += suballoc.size;

+                outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size);

+                outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size);

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                ++nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                // There is free space from lastOffset to freeSpace2ndTo1stEnd.

+                if(lastOffset < freeSpace2ndTo1stEnd)

+                {

+                    const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;

+                    ++outInfo.unusedRangeCount;

+                    outInfo.unusedBytes += unusedRangeSize;

+                    outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize);

+                    outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize);

+               }

+

+                // End of loop.

+                lastOffset = freeSpace2ndTo1stEnd;

+            }

+        }

+    }

+

+    size_t nextAlloc1stIndex = m_1stNullItemsBeginCount;

+    const VkDeviceSize freeSpace1stTo2ndEnd =

+        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;

+    while(lastOffset < freeSpace1stTo2ndEnd)

+    {

+        // Find next non-null allocation or move nextAllocIndex to the end.

+        while(nextAlloc1stIndex < suballoc1stCount &&

+            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)

+        {

+            ++nextAlloc1stIndex;

+        }

+

+        // Found non-null allocation.

+        if(nextAlloc1stIndex < suballoc1stCount)

+        {

+            const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];

+            

+            // 1. Process free space before this allocation.

+            if(lastOffset < suballoc.offset)

+            {

+                // There is free space from lastOffset to suballoc.offset.

+                const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                ++outInfo.unusedRangeCount;

+                outInfo.unusedBytes += unusedRangeSize;

+                outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize);

+                outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize);

+            }

+            

+            // 2. Process this allocation.

+            // There is allocation with suballoc.offset, suballoc.size.

+            outInfo.usedBytes += suballoc.size;

+            outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size);

+            outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size);

+            

+            // 3. Prepare for next iteration.

+            lastOffset = suballoc.offset + suballoc.size;

+            ++nextAlloc1stIndex;

+        }

+        // We are at the end.

+        else

+        {

+            // There is free space from lastOffset to freeSpace1stTo2ndEnd.

+            if(lastOffset < freeSpace1stTo2ndEnd)

+            {

+                const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;

+                ++outInfo.unusedRangeCount;

+                outInfo.unusedBytes += unusedRangeSize;

+                outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize);

+                outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize);

+           }

+

+            // End of loop.

+            lastOffset = freeSpace1stTo2ndEnd;

+        }

+    }

+

+    if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+    {

+        size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;

+        while(lastOffset < size)

+        {

+            // Find next non-null allocation or move nextAllocIndex to the end.

+            while(nextAlloc2ndIndex != SIZE_MAX &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                --nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex != SIZE_MAX)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                    ++outInfo.unusedRangeCount;

+                    outInfo.unusedBytes += unusedRangeSize;

+                    outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize);

+                    outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize);

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                outInfo.usedBytes += suballoc.size;

+                outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size);

+                outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size);

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                --nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                // There is free space from lastOffset to size.

+                if(lastOffset < size)

+                {

+                    const VkDeviceSize unusedRangeSize = size - lastOffset;

+                    ++outInfo.unusedRangeCount;

+                    outInfo.unusedBytes += unusedRangeSize;

+                    outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize);

+                    outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize);

+               }

+

+                // End of loop.

+                lastOffset = size;

+            }

+        }

+    }

+

+    outInfo.unusedBytes = size - outInfo.usedBytes;

+}

+

+void VmaBlockMetadata_Linear::AddPoolStats(VmaPoolStats& inoutStats) const

+{

+    const SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+    const VkDeviceSize size = GetSize();

+    const size_t suballoc1stCount = suballocations1st.size();

+    const size_t suballoc2ndCount = suballocations2nd.size();

+

+    inoutStats.size += size;

+

+    VkDeviceSize lastOffset = 0;

+

+    if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+    {

+        const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;

+        size_t nextAlloc2ndIndex = m_1stNullItemsBeginCount;

+        while(lastOffset < freeSpace2ndTo1stEnd)

+        {

+            // Find next non-null allocation or move nextAlloc2ndIndex to the end.

+            while(nextAlloc2ndIndex < suballoc2ndCount &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                ++nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex < suballoc2ndCount)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                    inoutStats.unusedSize += unusedRangeSize;

+                    ++inoutStats.unusedRangeCount;

+                    inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize);

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                ++inoutStats.allocationCount;

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                ++nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                if(lastOffset < freeSpace2ndTo1stEnd)

+                {

+                    // There is free space from lastOffset to freeSpace2ndTo1stEnd.

+                    const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;

+                    inoutStats.unusedSize += unusedRangeSize;

+                    ++inoutStats.unusedRangeCount;

+                    inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize);

+                }

+

+                // End of loop.

+                lastOffset = freeSpace2ndTo1stEnd;

+            }

+        }

+    }

+

+    size_t nextAlloc1stIndex = m_1stNullItemsBeginCount;

+    const VkDeviceSize freeSpace1stTo2ndEnd =

+        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;

+    while(lastOffset < freeSpace1stTo2ndEnd)

+    {

+        // Find next non-null allocation or move nextAllocIndex to the end.

+        while(nextAlloc1stIndex < suballoc1stCount &&

+            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)

+        {

+            ++nextAlloc1stIndex;

+        }

+

+        // Found non-null allocation.

+        if(nextAlloc1stIndex < suballoc1stCount)

+        {

+            const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];

+            

+            // 1. Process free space before this allocation.

+            if(lastOffset < suballoc.offset)

+            {

+                // There is free space from lastOffset to suballoc.offset.

+                const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                inoutStats.unusedSize += unusedRangeSize;

+                ++inoutStats.unusedRangeCount;

+                inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize);

+            }

+            

+            // 2. Process this allocation.

+            // There is allocation with suballoc.offset, suballoc.size.

+            ++inoutStats.allocationCount;

+            

+            // 3. Prepare for next iteration.

+            lastOffset = suballoc.offset + suballoc.size;

+            ++nextAlloc1stIndex;

+        }

+        // We are at the end.

+        else

+        {

+            if(lastOffset < freeSpace1stTo2ndEnd)

+            {

+                // There is free space from lastOffset to freeSpace1stTo2ndEnd.

+                const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;

+                inoutStats.unusedSize += unusedRangeSize;

+                ++inoutStats.unusedRangeCount;

+                inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize);

+            }

+

+            // End of loop.

+            lastOffset = freeSpace1stTo2ndEnd;

+        }

+    }

+

+    if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+    {

+        size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;

+        while(lastOffset < size)

+        {

+            // Find next non-null allocation or move nextAlloc2ndIndex to the end.

+            while(nextAlloc2ndIndex != SIZE_MAX &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                --nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex != SIZE_MAX)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                    inoutStats.unusedSize += unusedRangeSize;

+                    ++inoutStats.unusedRangeCount;

+                    inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize);

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                ++inoutStats.allocationCount;

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                --nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                if(lastOffset < size)

+                {

+                    // There is free space from lastOffset to size.

+                    const VkDeviceSize unusedRangeSize = size - lastOffset;

+                    inoutStats.unusedSize += unusedRangeSize;

+                    ++inoutStats.unusedRangeCount;

+                    inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize);

+                }

+

+                // End of loop.

+                lastOffset = size;

+            }

+        }

+    }

+}

+

+#if VMA_STATS_STRING_ENABLED

+void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json) const

+{

+    const VkDeviceSize size = GetSize();

+    const SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+    const size_t suballoc1stCount = suballocations1st.size();

+    const size_t suballoc2ndCount = suballocations2nd.size();

+

+    // FIRST PASS

+

+    size_t unusedRangeCount = 0;

+    VkDeviceSize usedBytes = 0;

+

+    VkDeviceSize lastOffset = 0;

+

+    size_t alloc2ndCount = 0;

+    if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+    {

+        const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;

+        size_t nextAlloc2ndIndex = 0;

+        while(lastOffset < freeSpace2ndTo1stEnd)

+        {

+            // Find next non-null allocation or move nextAlloc2ndIndex to the end.

+            while(nextAlloc2ndIndex < suballoc2ndCount &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                ++nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex < suballoc2ndCount)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    ++unusedRangeCount;

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                ++alloc2ndCount;

+                usedBytes += suballoc.size;

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                ++nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                if(lastOffset < freeSpace2ndTo1stEnd)

+                {

+                    // There is free space from lastOffset to freeSpace2ndTo1stEnd.

+                    ++unusedRangeCount;

+                }

+

+                // End of loop.

+                lastOffset = freeSpace2ndTo1stEnd;

+            }

+        }

+    }

+

+    size_t nextAlloc1stIndex = m_1stNullItemsBeginCount;

+    size_t alloc1stCount = 0;

+    const VkDeviceSize freeSpace1stTo2ndEnd =

+        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;

+    while(lastOffset < freeSpace1stTo2ndEnd)

+    {

+        // Find next non-null allocation or move nextAllocIndex to the end.

+        while(nextAlloc1stIndex < suballoc1stCount &&

+            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)

+        {

+            ++nextAlloc1stIndex;

+        }

+

+        // Found non-null allocation.

+        if(nextAlloc1stIndex < suballoc1stCount)

+        {

+            const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];

+            

+            // 1. Process free space before this allocation.

+            if(lastOffset < suballoc.offset)

+            {

+                // There is free space from lastOffset to suballoc.offset.

+                ++unusedRangeCount;

+            }

+            

+            // 2. Process this allocation.

+            // There is allocation with suballoc.offset, suballoc.size.

+            ++alloc1stCount;

+            usedBytes += suballoc.size;

+            

+            // 3. Prepare for next iteration.

+            lastOffset = suballoc.offset + suballoc.size;

+            ++nextAlloc1stIndex;

+        }

+        // We are at the end.

+        else

+        {

+            if(lastOffset < size)

+            {

+                // There is free space from lastOffset to freeSpace1stTo2ndEnd.

+                ++unusedRangeCount;

+            }

+

+            // End of loop.

+            lastOffset = freeSpace1stTo2ndEnd;

+        }

+    }

+

+    if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+    {

+        size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;

+        while(lastOffset < size)

+        {

+            // Find next non-null allocation or move nextAlloc2ndIndex to the end.

+            while(nextAlloc2ndIndex != SIZE_MAX &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                --nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex != SIZE_MAX)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    ++unusedRangeCount;

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                ++alloc2ndCount;

+                usedBytes += suballoc.size;

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                --nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                if(lastOffset < size)

+                {

+                    // There is free space from lastOffset to size.

+                    ++unusedRangeCount;

+                }

+

+                // End of loop.

+                lastOffset = size;

+            }

+        }

+    }

+

+    const VkDeviceSize unusedBytes = size - usedBytes;

+    PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount);

+

+    // SECOND PASS

+    lastOffset = 0;

+

+    if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+    {

+        const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;

+        size_t nextAlloc2ndIndex = 0;

+        while(lastOffset < freeSpace2ndTo1stEnd)

+        {

+            // Find next non-null allocation or move nextAlloc2ndIndex to the end.

+            while(nextAlloc2ndIndex < suballoc2ndCount &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                ++nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex < suballoc2ndCount)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation);

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                ++nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                if(lastOffset < freeSpace2ndTo1stEnd)

+                {

+                    // There is free space from lastOffset to freeSpace2ndTo1stEnd.

+                    const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;

+                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);

+                }

+

+                // End of loop.

+                lastOffset = freeSpace2ndTo1stEnd;

+            }

+        }

+    }

+

+    nextAlloc1stIndex = m_1stNullItemsBeginCount;

+    while(lastOffset < freeSpace1stTo2ndEnd)

+    {

+        // Find next non-null allocation or move nextAllocIndex to the end.

+        while(nextAlloc1stIndex < suballoc1stCount &&

+            suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE)

+        {

+            ++nextAlloc1stIndex;

+        }

+

+        // Found non-null allocation.

+        if(nextAlloc1stIndex < suballoc1stCount)

+        {

+            const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];

+            

+            // 1. Process free space before this allocation.

+            if(lastOffset < suballoc.offset)

+            {

+                // There is free space from lastOffset to suballoc.offset.

+                const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);

+            }

+            

+            // 2. Process this allocation.

+            // There is allocation with suballoc.offset, suballoc.size.

+            PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation);

+            

+            // 3. Prepare for next iteration.

+            lastOffset = suballoc.offset + suballoc.size;

+            ++nextAlloc1stIndex;

+        }

+        // We are at the end.

+        else

+        {

+            if(lastOffset < freeSpace1stTo2ndEnd)

+            {

+                // There is free space from lastOffset to freeSpace1stTo2ndEnd.

+                const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;

+                PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);

+            }

+

+            // End of loop.

+            lastOffset = freeSpace1stTo2ndEnd;

+        }

+    }

+

+    if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+    {

+        size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;

+        while(lastOffset < size)

+        {

+            // Find next non-null allocation or move nextAlloc2ndIndex to the end.

+            while(nextAlloc2ndIndex != SIZE_MAX &&

+                suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE)

+            {

+                --nextAlloc2ndIndex;

+            }

+

+            // Found non-null allocation.

+            if(nextAlloc2ndIndex != SIZE_MAX)

+            {

+                const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];

+            

+                // 1. Process free space before this allocation.

+                if(lastOffset < suballoc.offset)

+                {

+                    // There is free space from lastOffset to suballoc.offset.

+                    const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;

+                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);

+                }

+            

+                // 2. Process this allocation.

+                // There is allocation with suballoc.offset, suballoc.size.

+                PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation);

+            

+                // 3. Prepare for next iteration.

+                lastOffset = suballoc.offset + suballoc.size;

+                --nextAlloc2ndIndex;

+            }

+            // We are at the end.

+            else

+            {

+                if(lastOffset < size)

+                {

+                    // There is free space from lastOffset to size.

+                    const VkDeviceSize unusedRangeSize = size - lastOffset;

+                    PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);

+                }

+

+                // End of loop.

+                lastOffset = size;

+            }

+        }

+    }

+

+    PrintDetailedMap_End(json);

+}

+#endif // #if VMA_STATS_STRING_ENABLED

+

+bool VmaBlockMetadata_Linear::CreateAllocationRequest(

+    uint32_t currentFrameIndex,

+    uint32_t frameInUseCount,

+    VkDeviceSize bufferImageGranularity,

+    VkDeviceSize allocSize,

+    VkDeviceSize allocAlignment,

+    bool upperAddress,

+    VmaSuballocationType allocType,

+    bool canMakeOtherLost,

+    VmaAllocationRequest* pAllocationRequest)

+{

+    VMA_ASSERT(allocSize > 0);

+    VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);

+    VMA_ASSERT(pAllocationRequest != VMA_NULL);

+    VMA_HEAVY_ASSERT(Validate());

+

+    const VkDeviceSize size = GetSize();

+    SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+

+    if(upperAddress)

+    {

+        if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+        {

+            VMA_ASSERT(0 && "Trying to use pool with linear algorithm as double stack, while it is already being used as ring buffer.");

+            return false;

+        }

+

+        // Try to allocate before 2nd.back(), or end of block if 2nd.empty().

+        if(allocSize > size)

+        {

+            return false;

+        }

+        VkDeviceSize resultBaseOffset = size - allocSize;

+        if(!suballocations2nd.empty())

+        {

+            const VmaSuballocation& lastSuballoc = suballocations2nd.back();

+            resultBaseOffset = lastSuballoc.offset - allocSize;

+            if(allocSize > lastSuballoc.offset)

+            {

+                return false;

+            }

+        }

+

+        // Start from offset equal to end of free space.

+        VkDeviceSize resultOffset = resultBaseOffset;

+

+        // Apply VMA_DEBUG_MARGIN at the end.

+        if(VMA_DEBUG_MARGIN > 0)

+        {

+            if(resultOffset < VMA_DEBUG_MARGIN)

+            {

+                return false;

+            }

+            resultOffset -= VMA_DEBUG_MARGIN;

+        }

+

+        // Apply alignment.

+        resultOffset = VmaAlignDown(resultOffset, allocAlignment);

+

+        // Check next suballocations from 2nd for BufferImageGranularity conflicts.

+        // Make bigger alignment if necessary.

+        if(bufferImageGranularity > 1 && !suballocations2nd.empty())

+        {

+            bool bufferImageGranularityConflict = false;

+            for(size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; )

+            {

+                const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex];

+                if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))

+                {

+                    if(VmaIsBufferImageGranularityConflict(nextSuballoc.type, allocType))

+                    {

+                        bufferImageGranularityConflict = true;

+                        break;

+                    }

+                }

+                else

+                    // Already on previous page.

+                    break;

+            }

+            if(bufferImageGranularityConflict)

+            {

+                resultOffset = VmaAlignDown(resultOffset, bufferImageGranularity);

+            }

+        }

+

+        // There is enough free space.

+        const VkDeviceSize endOf1st = !suballocations1st.empty() ?

+            suballocations1st.back().offset + suballocations1st.back().size :

+            0;

+        if(endOf1st + VMA_DEBUG_MARGIN <= resultOffset)

+        {

+            // Check previous suballocations for BufferImageGranularity conflicts.

+            // If conflict exists, allocation cannot be made here.

+            if(bufferImageGranularity > 1)

+            {

+                for(size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; )

+                {

+                    const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex];

+                    if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))

+                    {

+                        if(VmaIsBufferImageGranularityConflict(allocType, prevSuballoc.type))

+                        {

+                            return false;

+                        }

+                    }

+                    else

+                    {

+                        // Already on next page.

+                        break;

+                    }

+                }

+            }

+

+            // All tests passed: Success.

+            pAllocationRequest->offset = resultOffset;

+            pAllocationRequest->sumFreeSize = resultBaseOffset + allocSize - endOf1st;

+            pAllocationRequest->sumItemSize = 0;

+            // pAllocationRequest->item unused.

+            pAllocationRequest->itemsToMakeLostCount = 0;

+            return true;

+        }

+    }

+    else // !upperAddress

+    {

+        if(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+        {

+            // Try to allocate at the end of 1st vector.

+

+            VkDeviceSize resultBaseOffset = 0;

+            if(!suballocations1st.empty())

+            {

+                const VmaSuballocation& lastSuballoc = suballocations1st.back();

+                resultBaseOffset = lastSuballoc.offset + lastSuballoc.size;

+            }

+

+            // Start from offset equal to beginning of free space.

+            VkDeviceSize resultOffset = resultBaseOffset;

+

+            // Apply VMA_DEBUG_MARGIN at the beginning.

+            if(VMA_DEBUG_MARGIN > 0)

+            {

+                resultOffset += VMA_DEBUG_MARGIN;

+            }

+

+            // Apply alignment.

+            resultOffset = VmaAlignUp(resultOffset, allocAlignment);

+

+            // Check previous suballocations for BufferImageGranularity conflicts.

+            // Make bigger alignment if necessary.

+            if(bufferImageGranularity > 1 && !suballocations1st.empty())

+            {

+                bool bufferImageGranularityConflict = false;

+                for(size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; )

+                {

+                    const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex];

+                    if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))

+                    {

+                        if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))

+                        {

+                            bufferImageGranularityConflict = true;

+                            break;

+                        }

+                    }

+                    else

+                        // Already on previous page.

+                        break;

+                }

+                if(bufferImageGranularityConflict)

+                {

+                    resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity);

+                }

+            }

+

+            const VkDeviceSize freeSpaceEnd = m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ?

+                suballocations2nd.back().offset : size;

+

+            // There is enough free space at the end after alignment.

+            if(resultOffset + allocSize + VMA_DEBUG_MARGIN <= freeSpaceEnd)

+            {

+                // Check next suballocations for BufferImageGranularity conflicts.

+                // If conflict exists, allocation cannot be made here.

+                if(bufferImageGranularity > 1 && m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+                {

+                    for(size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; )

+                    {

+                        const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex];

+                        if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))

+                        {

+                            if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))

+                            {

+                                return false;

+                            }

+                        }

+                        else

+                        {

+                            // Already on previous page.

+                            break;

+                        }

+                    }

+                }

+

+                // All tests passed: Success.

+                pAllocationRequest->offset = resultOffset;

+                pAllocationRequest->sumFreeSize = freeSpaceEnd - resultBaseOffset;

+                pAllocationRequest->sumItemSize = 0;

+                // pAllocationRequest->item unused.

+                pAllocationRequest->itemsToMakeLostCount = 0;

+                return true;

+            }

+        }

+

+        // Wrap-around to end of 2nd vector. Try to allocate there, watching for the

+        // beginning of 1st vector as the end of free space.

+        if(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+        {

+            VMA_ASSERT(!suballocations1st.empty());

+

+            VkDeviceSize resultBaseOffset = 0;

+            if(!suballocations2nd.empty())

+            {

+                const VmaSuballocation& lastSuballoc = suballocations2nd.back();

+                resultBaseOffset = lastSuballoc.offset + lastSuballoc.size;

+            }

+

+            // Start from offset equal to beginning of free space.

+            VkDeviceSize resultOffset = resultBaseOffset;

+

+            // Apply VMA_DEBUG_MARGIN at the beginning.

+            if(VMA_DEBUG_MARGIN > 0)

+            {

+                resultOffset += VMA_DEBUG_MARGIN;

+            }

+

+            // Apply alignment.

+            resultOffset = VmaAlignUp(resultOffset, allocAlignment);

+

+            // Check previous suballocations for BufferImageGranularity conflicts.

+            // Make bigger alignment if necessary.

+            if(bufferImageGranularity > 1 && !suballocations2nd.empty())

+            {

+                bool bufferImageGranularityConflict = false;

+                for(size_t prevSuballocIndex = suballocations2nd.size(); prevSuballocIndex--; )

+                {

+                    const VmaSuballocation& prevSuballoc = suballocations2nd[prevSuballocIndex];

+                    if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))

+                    {

+                        if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))

+                        {

+                            bufferImageGranularityConflict = true;

+                            break;

+                        }

+                    }

+                    else

+                        // Already on previous page.

+                        break;

+                }

+                if(bufferImageGranularityConflict)

+                {

+                    resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity);

+                }

+            }

+

+            pAllocationRequest->itemsToMakeLostCount = 0;

+            pAllocationRequest->sumItemSize = 0;

+            size_t index1st = m_1stNullItemsBeginCount;

+

+            if(canMakeOtherLost)

+            {

+                while(index1st < suballocations1st.size() &&

+                    resultOffset + allocSize + VMA_DEBUG_MARGIN > suballocations1st[index1st].offset)

+                {

+                    // Next colliding allocation at the beginning of 1st vector found. Try to make it lost.

+                    const VmaSuballocation& suballoc = suballocations1st[index1st];

+                    if(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE)

+                    {

+                        // No problem.

+                    }

+                    else

+                    {

+                        VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE);

+                        if(suballoc.hAllocation->CanBecomeLost() &&

+                            suballoc.hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex)

+                        {

+                            ++pAllocationRequest->itemsToMakeLostCount;

+                            pAllocationRequest->sumItemSize += suballoc.size;

+                        }

+                        else

+                        {

+                            return false;

+                        }

+                    }

+                    ++index1st;

+                }

+

+                // Check next suballocations for BufferImageGranularity conflicts.

+                // If conflict exists, we must mark more allocations lost or fail.

+                if(bufferImageGranularity > 1)

+                {

+                    while(index1st < suballocations1st.size())

+                    {

+                        const VmaSuballocation& suballoc = suballocations1st[index1st];

+                        if(VmaBlocksOnSamePage(resultOffset, allocSize, suballoc.offset, bufferImageGranularity))

+                        {

+                            if(suballoc.hAllocation != VK_NULL_HANDLE)

+                            {

+                                // Not checking actual VmaIsBufferImageGranularityConflict(allocType, suballoc.type).

+                                if(suballoc.hAllocation->CanBecomeLost() &&

+                                    suballoc.hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex)

+                                {

+                                    ++pAllocationRequest->itemsToMakeLostCount;

+                                    pAllocationRequest->sumItemSize += suballoc.size;

+                                }

+                                else

+                                {

+                                    return false;

+                                }

+                            }

+                        }

+                        else

+                        {

+                            // Already on next page.

+                            break;

+                        }

+                        ++index1st;

+                    }

+                }

+            }

+

+            // There is enough free space at the end after alignment.

+            if(index1st == suballocations1st.size() && resultOffset + allocSize + VMA_DEBUG_MARGIN < size ||

+                index1st < suballocations1st.size() && resultOffset + allocSize + VMA_DEBUG_MARGIN <= suballocations1st[index1st].offset)

+            {

+                // Check next suballocations for BufferImageGranularity conflicts.

+                // If conflict exists, allocation cannot be made here.

+                if(bufferImageGranularity > 1)

+                {

+                    for(size_t nextSuballocIndex = index1st;

+                        nextSuballocIndex < suballocations1st.size();

+                        nextSuballocIndex++)

+                    {

+                        const VmaSuballocation& nextSuballoc = suballocations1st[nextSuballocIndex];

+                        if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))

+                        {

+                            if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))

+                            {

+                                return false;

+                            }

+                        }

+                        else

+                        {

+                            // Already on next page.

+                            break;

+                        }

+                    }

+                }

+

+                // All tests passed: Success.

+                pAllocationRequest->offset = resultOffset;

+                pAllocationRequest->sumFreeSize =

+                    (index1st < suballocations1st.size() ? suballocations1st[index1st].offset : size)

+                    - resultBaseOffset

+                    - pAllocationRequest->sumItemSize;

+                // pAllocationRequest->item unused.

+                return true;

+            }

+        }

+    }

+

+    return false;

+}

+

+bool VmaBlockMetadata_Linear::MakeRequestedAllocationsLost(

+    uint32_t currentFrameIndex,

+    uint32_t frameInUseCount,

+    VmaAllocationRequest* pAllocationRequest)

+{

+    if(pAllocationRequest->itemsToMakeLostCount == 0)

+    {

+        return true;

+    }

+

+    VMA_ASSERT(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER);

+    

+    SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    size_t index1st = m_1stNullItemsBeginCount;

+    size_t madeLostCount = 0;

+    while(madeLostCount < pAllocationRequest->itemsToMakeLostCount)

+    {

+        VMA_ASSERT(index1st < suballocations1st.size());

+        VmaSuballocation& suballoc = suballocations1st[index1st];

+        if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)

+        {

+            VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE);

+            VMA_ASSERT(suballoc.hAllocation->CanBecomeLost());

+            if(suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount))

+            {

+                suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;

+                suballoc.hAllocation = VK_NULL_HANDLE;

+                m_SumFreeSize += suballoc.size;

+                ++m_1stNullItemsMiddleCount;

+                ++madeLostCount;

+            }

+            else

+            {

+                return false;

+            }

+        }

+        ++index1st;

+    }

+

+    CleanupAfterFree();

+    //VMA_HEAVY_ASSERT(Validate()); // Already called by ClanupAfterFree().

+    

+    return true;

+}

+

+uint32_t VmaBlockMetadata_Linear::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount)

+{

+    uint32_t lostAllocationCount = 0;

+    

+    SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    for(size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i)

+    {

+        VmaSuballocation& suballoc = suballocations1st[i];

+        if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE &&

+            suballoc.hAllocation->CanBecomeLost() &&

+            suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount))

+        {

+            suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;

+            suballoc.hAllocation = VK_NULL_HANDLE;

+            ++m_1stNullItemsMiddleCount;

+            m_SumFreeSize += suballoc.size;

+            ++lostAllocationCount;

+        }

+    }

+

+    SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+    for(size_t i = 0, count = suballocations2nd.size(); i < count; ++i)

+    {

+        VmaSuballocation& suballoc = suballocations2nd[i];

+        if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE &&

+            suballoc.hAllocation->CanBecomeLost() &&

+            suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount))

+        {

+            suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;

+            suballoc.hAllocation = VK_NULL_HANDLE;

+            ++m_2ndNullItemsCount;

+            ++lostAllocationCount;

+        }

+    }

+

+    if(lostAllocationCount)

+    {

+        CleanupAfterFree();

+    }

+

+    return lostAllocationCount;

+}

+

+VkResult VmaBlockMetadata_Linear::CheckCorruption(const void* pBlockData)

+{

+    SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    for(size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i)

+    {

+        const VmaSuballocation& suballoc = suballocations1st[i];

+        if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)

+        {

+            if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN))

+            {

+                VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!");

+                return VK_ERROR_VALIDATION_FAILED_EXT;

+            }

+            if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size))

+            {

+                VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!");

+                return VK_ERROR_VALIDATION_FAILED_EXT;

+            }

+        }

+    }

+

+    SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+    for(size_t i = 0, count = suballocations2nd.size(); i < count; ++i)

+    {

+        const VmaSuballocation& suballoc = suballocations2nd[i];

+        if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)

+        {

+            if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN))

+            {

+                VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!");

+                return VK_ERROR_VALIDATION_FAILED_EXT;

+            }

+            if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size))

+            {

+                VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!");

+                return VK_ERROR_VALIDATION_FAILED_EXT;

+            }

+        }

+    }

+

+    return VK_SUCCESS;

+}

+

+void VmaBlockMetadata_Linear::Alloc(

+    const VmaAllocationRequest& request,

+    VmaSuballocationType type,

+    VkDeviceSize allocSize,

+    bool upperAddress,

+    VmaAllocation hAllocation)

+{

+    const VmaSuballocation newSuballoc = { request.offset, allocSize, hAllocation, type };

+

+    if(upperAddress)

+    {

+        VMA_ASSERT(m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER &&

+            "CRITICAL ERROR: Trying to use linear allocator as double stack while it was already used as ring buffer.");

+        SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+        suballocations2nd.push_back(newSuballoc);

+        m_2ndVectorMode = SECOND_VECTOR_DOUBLE_STACK;

+    }

+    else

+    {

+        SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+

+        // First allocation.

+        if(suballocations1st.empty())

+        {

+            suballocations1st.push_back(newSuballoc);

+        }

+        else

+        {

+            // New allocation at the end of 1st vector.

+            if(request.offset >= suballocations1st.back().offset + suballocations1st.back().size)

+            {

+                // Check if it fits before the end of the block.

+                VMA_ASSERT(request.offset + allocSize <= GetSize());

+                suballocations1st.push_back(newSuballoc);

+            }

+            // New allocation at the end of 2-part ring buffer, so before first allocation from 1st vector.

+            else if(request.offset + allocSize <= suballocations1st[m_1stNullItemsBeginCount].offset)

+            {

+                SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+

+                switch(m_2ndVectorMode)

+                {

+                case SECOND_VECTOR_EMPTY:

+                    // First allocation from second part ring buffer.

+                    VMA_ASSERT(suballocations2nd.empty());

+                    m_2ndVectorMode = SECOND_VECTOR_RING_BUFFER;

+                    break;

+                case SECOND_VECTOR_RING_BUFFER:

+                    // 2-part ring buffer is already started.

+                    VMA_ASSERT(!suballocations2nd.empty());

+                    break;

+                case SECOND_VECTOR_DOUBLE_STACK:

+                    VMA_ASSERT(0 && "CRITICAL ERROR: Trying to use linear allocator as ring buffer while it was already used as double stack.");

+                    break;

+                default:

+                    VMA_ASSERT(0);

+                }

+

+                suballocations2nd.push_back(newSuballoc);

+            }

+            else

+            {

+                VMA_ASSERT(0 && "CRITICAL INTERNAL ERROR.");

+            }

+        }

+    }

+

+    m_SumFreeSize -= newSuballoc.size;

+}

+

+void VmaBlockMetadata_Linear::Free(const VmaAllocation allocation)

+{

+    FreeAtOffset(allocation->GetOffset());

+}

+

+void VmaBlockMetadata_Linear::FreeAtOffset(VkDeviceSize offset)

+{

+    SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+

+    if(!suballocations1st.empty())

+    {

+        // First allocation: Mark it as next empty at the beginning.

+        VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount];

+        if(firstSuballoc.offset == offset)

+        {

+            firstSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;

+            firstSuballoc.hAllocation = VK_NULL_HANDLE;

+            m_SumFreeSize += firstSuballoc.size;

+            ++m_1stNullItemsBeginCount;

+            CleanupAfterFree();

+            return;

+        }

+    }

+

+    // Last allocation in 2-part ring buffer or top of upper stack (same logic).

+    if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ||

+        m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)

+    {

+        VmaSuballocation& lastSuballoc = suballocations2nd.back();

+        if(lastSuballoc.offset == offset)

+        {

+            m_SumFreeSize += lastSuballoc.size;

+            suballocations2nd.pop_back();

+            CleanupAfterFree();

+            return;

+        }

+    }

+    // Last allocation in 1st vector.

+    else if(m_2ndVectorMode == SECOND_VECTOR_EMPTY)

+    {

+        VmaSuballocation& lastSuballoc = suballocations1st.back();

+        if(lastSuballoc.offset == offset)

+        {

+            m_SumFreeSize += lastSuballoc.size;

+            suballocations1st.pop_back();

+            CleanupAfterFree();

+            return;

+        }

+    }

+

+    // Item from the middle of 1st vector.

+    {

+        VmaSuballocation refSuballoc;

+        refSuballoc.offset = offset;

+        // Rest of members stays uninitialized intentionally for better performance.

+        SuballocationVectorType::iterator it = VmaVectorFindSorted<VmaSuballocationOffsetLess>(

+            suballocations1st.begin() + m_1stNullItemsBeginCount,

+            suballocations1st.end(),

+            refSuballoc);

+        if(it != suballocations1st.end())

+        {

+            it->type = VMA_SUBALLOCATION_TYPE_FREE;

+            it->hAllocation = VK_NULL_HANDLE;

+            ++m_1stNullItemsMiddleCount;

+            m_SumFreeSize += it->size;

+            CleanupAfterFree();

+            return;

+        }

+    }

+

+    if(m_2ndVectorMode != SECOND_VECTOR_EMPTY)

+    {

+        // Item from the middle of 2nd vector.

+        VmaSuballocation refSuballoc;

+        refSuballoc.offset = offset;

+        // Rest of members stays uninitialized intentionally for better performance.

+        SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ?

+            VmaVectorFindSorted<VmaSuballocationOffsetLess>(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc) :

+            VmaVectorFindSorted<VmaSuballocationOffsetGreater>(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc);

+        if(it != suballocations2nd.end())

+        {

+            it->type = VMA_SUBALLOCATION_TYPE_FREE;

+            it->hAllocation = VK_NULL_HANDLE;

+            ++m_2ndNullItemsCount;

+            m_SumFreeSize += it->size;

+            CleanupAfterFree();

+            return;

+        }

+    }

+

+    VMA_ASSERT(0 && "Allocation to free not found in linear allocator!");

+}

+

+bool VmaBlockMetadata_Linear::ShouldCompact1st() const

+{

+    const size_t nullItemCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount;

+    const size_t suballocCount = AccessSuballocations1st().size();

+    return suballocCount > 32 && nullItemCount * 2 >= (suballocCount - nullItemCount) * 3;

+}

+

+void VmaBlockMetadata_Linear::CleanupAfterFree()

+{

+    SuballocationVectorType& suballocations1st = AccessSuballocations1st();

+    SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();

+

+    if(IsEmpty())

+    {

+        suballocations1st.clear();

+        suballocations2nd.clear();

+        m_1stNullItemsBeginCount = 0;

+        m_1stNullItemsMiddleCount = 0;

+        m_2ndNullItemsCount = 0;

+        m_2ndVectorMode = SECOND_VECTOR_EMPTY;

+    }

+    else

+    {

+        const size_t suballoc1stCount = suballocations1st.size();

+        const size_t nullItem1stCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount;

+        VMA_ASSERT(nullItem1stCount <= suballoc1stCount);

+

+        // Find more null items at the beginning of 1st vector.

+        while(m_1stNullItemsBeginCount < suballoc1stCount &&

+            suballocations1st[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE)

+        {

+            ++m_1stNullItemsBeginCount;

+            --m_1stNullItemsMiddleCount;

+        }

+

+        // Find more null items at the end of 1st vector.

+        while(m_1stNullItemsMiddleCount > 0 &&

+            suballocations1st.back().hAllocation == VK_NULL_HANDLE)

+        {

+            --m_1stNullItemsMiddleCount;

+            suballocations1st.pop_back();

+        }

+

+        // Find more null items at the end of 2nd vector.

+        while(m_2ndNullItemsCount > 0 &&

+            suballocations2nd.back().hAllocation == VK_NULL_HANDLE)

+        {

+            --m_2ndNullItemsCount;

+            suballocations2nd.pop_back();

+        }

+

+        if(ShouldCompact1st())

+        {

+            const size_t nonNullItemCount = suballoc1stCount - nullItem1stCount;

+            size_t srcIndex = m_1stNullItemsBeginCount;

+            for(size_t dstIndex = 0; dstIndex < nonNullItemCount; ++dstIndex)

+            {

+                while(suballocations1st[srcIndex].hAllocation == VK_NULL_HANDLE)

+                {

+                    ++srcIndex;

+                }

+                if(dstIndex != srcIndex)

+                {

+                    suballocations1st[dstIndex] = suballocations1st[srcIndex];

+                }

+                ++srcIndex;

+            }

+            suballocations1st.resize(nonNullItemCount);

+            m_1stNullItemsBeginCount = 0;

+            m_1stNullItemsMiddleCount = 0;

+        }

+

+        // 2nd vector became empty.

+        if(suballocations2nd.empty())

+        {

+            m_2ndVectorMode = SECOND_VECTOR_EMPTY;

+        }

+

+        // 1st vector became empty.

+        if(suballocations1st.size() - m_1stNullItemsBeginCount == 0)

+        {

+            suballocations1st.clear();

+            m_1stNullItemsBeginCount = 0;

+

+            if(!suballocations2nd.empty() && m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)

+            {

+                // Swap 1st with 2nd. Now 2nd is empty.

+                m_2ndVectorMode = SECOND_VECTOR_EMPTY;

+                m_1stNullItemsMiddleCount = m_2ndNullItemsCount;

+                while(m_1stNullItemsBeginCount < suballocations2nd.size() &&

+                    suballocations2nd[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE)

+                {

+                    ++m_1stNullItemsBeginCount;

+                    --m_1stNullItemsMiddleCount;

+                }

+                m_2ndNullItemsCount = 0;

+                m_1stVectorIndex ^= 1;

+            }

+        }

+    }

+

+    VMA_HEAVY_ASSERT(Validate());

+}

+

+

+////////////////////////////////////////////////////////////////////////////////

 // class VmaDeviceMemoryBlock

 

 VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) :

-    m_Metadata(hAllocator),

+    m_pMetadata(VMA_NULL),

     m_MemoryTypeIndex(UINT32_MAX),

+    m_Id(0),

     m_hMemory(VK_NULL_HANDLE),

     m_MapCount(0),

     m_pMappedData(VMA_NULL)

@@ -6272,38 +9090,69 @@
 }

 

 void VmaDeviceMemoryBlock::Init(

+    VmaAllocator hAllocator,

     uint32_t newMemoryTypeIndex,

     VkDeviceMemory newMemory,

-    VkDeviceSize newSize)

+    VkDeviceSize newSize,

+    uint32_t id,

+    bool linearAlgorithm)

 {

     VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);

 

     m_MemoryTypeIndex = newMemoryTypeIndex;

+    m_Id = id;

     m_hMemory = newMemory;

 

-    m_Metadata.Init(newSize);

+    if(linearAlgorithm)

+    {

+        m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Linear)(hAllocator);

+    }

+    else

+    {

+        m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Generic)(hAllocator);

+    }

+    m_pMetadata->Init(newSize);

 }

 

 void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator)

 {

     // This is the most important assert in the entire library.

     // Hitting it means you have some memory leak - unreleased VmaAllocation objects.

-    VMA_ASSERT(m_Metadata.IsEmpty() && "Some allocations were not freed before destruction of this memory block!");

-    

+    VMA_ASSERT(m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!");

+

     VMA_ASSERT(m_hMemory != VK_NULL_HANDLE);

-    allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_Metadata.GetSize(), m_hMemory);

+    allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_pMetadata->GetSize(), m_hMemory);

     m_hMemory = VK_NULL_HANDLE;

+

+    vma_delete(allocator, m_pMetadata);

+    m_pMetadata = VMA_NULL;

 }

 

 bool VmaDeviceMemoryBlock::Validate() const

 {

     if((m_hMemory == VK_NULL_HANDLE) ||

-        (m_Metadata.GetSize() == 0))

+        (m_pMetadata->GetSize() == 0))

     {

         return false;

     }

     

-    return m_Metadata.Validate();

+    return m_pMetadata->Validate();

+}

+

+VkResult VmaDeviceMemoryBlock::CheckCorruption(VmaAllocator hAllocator)

+{

+    void* pData = nullptr;

+    VkResult res = Map(hAllocator, 1, &pData);

+    if(res != VK_SUCCESS)

+    {

+        return res;

+    }

+

+    res = m_pMetadata->CheckCorruption(pData);

+

+    Unmap(hAllocator, 1);

+

+    return res;

 }

 

 VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void** ppData)

@@ -6368,6 +9217,52 @@
     }

 }

 

+VkResult VmaDeviceMemoryBlock::WriteMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize)

+{

+    VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION);

+    VMA_ASSERT(allocOffset >= VMA_DEBUG_MARGIN);

+

+    void* pData;

+    VkResult res = Map(hAllocator, 1, &pData);

+    if(res != VK_SUCCESS)

+    {

+        return res;

+    }

+

+    VmaWriteMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN);

+    VmaWriteMagicValue(pData, allocOffset + allocSize);

+

+    Unmap(hAllocator, 1);

+

+    return VK_SUCCESS;

+}

+

+VkResult VmaDeviceMemoryBlock::ValidateMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize)

+{

+    VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION);

+    VMA_ASSERT(allocOffset >= VMA_DEBUG_MARGIN);

+

+    void* pData;

+    VkResult res = Map(hAllocator, 1, &pData);

+    if(res != VK_SUCCESS)

+    {

+        return res;

+    }

+

+    if(!VmaValidateMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN))

+    {

+        VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE FREED ALLOCATION!");

+    }

+    else if(!VmaValidateMagicValue(pData, allocOffset + allocSize))

+    {

+        VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER FREED ALLOCATION!");

+    }

+

+    Unmap(hAllocator, 1);

+

+    return VK_SUCCESS;

+}

+

 VkResult VmaDeviceMemoryBlock::BindBufferMemory(

     const VmaAllocator hAllocator,

     const VmaAllocation hAllocation,

@@ -6431,16 +9326,20 @@
 

 VmaPool_T::VmaPool_T(

     VmaAllocator hAllocator,

-    const VmaPoolCreateInfo& createInfo) :

+    const VmaPoolCreateInfo& createInfo,

+    VkDeviceSize preferredBlockSize) :

     m_BlockVector(

         hAllocator,

         createInfo.memoryTypeIndex,

-        createInfo.blockSize,

+        createInfo.blockSize != 0 ? createInfo.blockSize : preferredBlockSize,

         createInfo.minBlockCount,

         createInfo.maxBlockCount,

         (createInfo.flags & VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT) != 0 ? 1 : hAllocator->GetBufferImageGranularity(),

         createInfo.frameInUseCount,

-        true) // isCustomPool

+        true, // isCustomPool

+        createInfo.blockSize != 0, // explicitBlockSize

+        (createInfo.flags & VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) != 0), // linearAlgorithm

+    m_Id(0)

 {

 }

 

@@ -6460,7 +9359,9 @@
     size_t maxBlockCount,

     VkDeviceSize bufferImageGranularity,

     uint32_t frameInUseCount,

-    bool isCustomPool) :

+    bool isCustomPool,

+    bool explicitBlockSize,

+    bool linearAlgorithm) :

     m_hAllocator(hAllocator),

     m_MemoryTypeIndex(memoryTypeIndex),

     m_PreferredBlockSize(preferredBlockSize),

@@ -6469,9 +9370,12 @@
     m_BufferImageGranularity(bufferImageGranularity),

     m_FrameInUseCount(frameInUseCount),

     m_IsCustomPool(isCustomPool),

+    m_ExplicitBlockSize(explicitBlockSize),

+    m_LinearAlgorithm(linearAlgorithm),

     m_Blocks(VmaStlAllocator<VmaDeviceMemoryBlock*>(hAllocator->GetAllocationCallbacks())),

     m_HasEmptyBlock(false),

-    m_pDefragmentator(VMA_NULL)

+    m_pDefragmentator(VMA_NULL),

+    m_NextBlockId(0)

 {

 }

 

@@ -6501,181 +9405,211 @@
 

 void VmaBlockVector::GetPoolStats(VmaPoolStats* pStats)

 {

+    VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex);

+

+    const size_t blockCount = m_Blocks.size();

+

     pStats->size = 0;

     pStats->unusedSize = 0;

     pStats->allocationCount = 0;

     pStats->unusedRangeCount = 0;

     pStats->unusedRangeSizeMax = 0;

+    pStats->blockCount = blockCount;

 

-    VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex);

-

-    for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex)

+    for(uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)

     {

         const VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex];

         VMA_ASSERT(pBlock);

         VMA_HEAVY_ASSERT(pBlock->Validate());

-        pBlock->m_Metadata.AddPoolStats(*pStats);

+        pBlock->m_pMetadata->AddPoolStats(*pStats);

     }

 }

 

+bool VmaBlockVector::IsCorruptionDetectionEnabled() const

+{

+    const uint32_t requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;

+    return (VMA_DEBUG_DETECT_CORRUPTION != 0) &&

+        (VMA_DEBUG_MARGIN > 0) &&

+        (m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags & requiredMemFlags) == requiredMemFlags;

+}

+

 static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32;

 

 VkResult VmaBlockVector::Allocate(

     VmaPool hCurrentPool,

     uint32_t currentFrameIndex,

-    const VkMemoryRequirements& vkMemReq,

+    VkDeviceSize size,

+    VkDeviceSize alignment,

     const VmaAllocationCreateInfo& createInfo,

     VmaSuballocationType suballocType,

     VmaAllocation* pAllocation)

 {

+    const bool isUpperAddress = (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0;

+    bool canMakeOtherLost = (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) != 0;

     const bool mapped = (createInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0;

     const bool isUserDataString = (createInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0;

-

-    VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex);

-

-    // 1. Search existing allocations. Try to allocate without making other allocations lost.

-    // Forward order in m_Blocks - prefer blocks with smallest amount of free space.

-    for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex )

-    {

-        VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex];

-        VMA_ASSERT(pCurrBlock);

-        VmaAllocationRequest currRequest = {};

-        if(pCurrBlock->m_Metadata.CreateAllocationRequest(

-            currentFrameIndex,

-            m_FrameInUseCount,

-            m_BufferImageGranularity,

-            vkMemReq.size,

-            vkMemReq.alignment,

-            suballocType,

-            false, // canMakeOtherLost

-            &currRequest))

-        {

-            // Allocate from pCurrBlock.

-            VMA_ASSERT(currRequest.itemsToMakeLostCount == 0);

-

-            if(mapped)

-            {

-                VkResult res = pCurrBlock->Map(m_hAllocator, 1, VMA_NULL);

-                if(res != VK_SUCCESS)

-                {

-                    return res;

-                }

-            }

-            

-            // We no longer have an empty Allocation.

-            if(pCurrBlock->m_Metadata.IsEmpty())

-            {

-                m_HasEmptyBlock = false;

-            }

-            

-            *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);

-            pCurrBlock->m_Metadata.Alloc(currRequest, suballocType, vkMemReq.size, *pAllocation);

-            (*pAllocation)->InitBlockAllocation(

-                hCurrentPool,

-                pCurrBlock,

-                currRequest.offset,

-                vkMemReq.alignment,

-                vkMemReq.size,

-                suballocType,

-                mapped,

-                (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0);

-            VMA_HEAVY_ASSERT(pCurrBlock->Validate());

-            VMA_DEBUG_LOG("    Returned from existing allocation #%u", (uint32_t)blockIndex);

-            (*pAllocation)->SetUserData(m_hAllocator, createInfo.pUserData);

-            return VK_SUCCESS;

-        }

-    }

-

     const bool canCreateNewBlock =

         ((createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0) &&

         (m_Blocks.size() < m_MaxBlockCount);

 

-    // 2. Try to create new block.

-    if(canCreateNewBlock)

+    // If linearAlgorithm is used, canMakeOtherLost is available only when used as ring buffer.

+    // Which in turn is available only when maxBlockCount = 1.

+    if(m_LinearAlgorithm && m_MaxBlockCount > 1)

     {

-        // Calculate optimal size for new block.

-        VkDeviceSize newBlockSize = m_PreferredBlockSize;

-        uint32_t newBlockSizeShift = 0;

-        const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3;

-

-        // Allocating blocks of other sizes is allowed only in default pools.

-        // In custom pools block size is fixed.

-        if(m_IsCustomPool == false)

-        {

-            // Allocate 1/8, 1/4, 1/2 as first blocks.

-            const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize();

-            for(uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i)

-            {

-                const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;

-                if(smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= vkMemReq.size * 2)

-                {

-                    newBlockSize = smallerNewBlockSize;

-                    ++newBlockSizeShift;

-                }

-                else

-                {

-                    break;

-                }

-            }

-        }

-

-        size_t newBlockIndex = 0;

-        VkResult res = CreateBlock(newBlockSize, &newBlockIndex);

-        // Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.

-        if(m_IsCustomPool == false)

-        {

-            while(res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX)

-            {

-                const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;

-                if(smallerNewBlockSize >= vkMemReq.size)

-                {

-                    newBlockSize = smallerNewBlockSize;

-                    ++newBlockSizeShift;

-                    res = CreateBlock(newBlockSize, &newBlockIndex);

-                }

-                else

-                {

-                    break;

-                }

-            }

-        }

-

-        if(res == VK_SUCCESS)

-        {

-            VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex];

-            VMA_ASSERT(pBlock->m_Metadata.GetSize() >= vkMemReq.size);

-

-            if(mapped)

-            {

-                res = pBlock->Map(m_hAllocator, 1, VMA_NULL);

-                if(res != VK_SUCCESS)

-                {

-                    return res;

-                }

-            }

-

-            // Allocate from pBlock. Because it is empty, dstAllocRequest can be trivially filled.

-            VmaAllocationRequest allocRequest;

-            pBlock->m_Metadata.CreateFirstAllocationRequest(&allocRequest);

-            *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);

-            pBlock->m_Metadata.Alloc(allocRequest, suballocType, vkMemReq.size, *pAllocation);

-            (*pAllocation)->InitBlockAllocation(

-                hCurrentPool,

-                pBlock,

-                allocRequest.offset,

-                vkMemReq.alignment,

-                vkMemReq.size,

-                suballocType,

-                mapped,

-                (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0);

-            VMA_HEAVY_ASSERT(pBlock->Validate());

-            VMA_DEBUG_LOG("    Created new allocation Size=%llu", allocInfo.allocationSize);

-            (*pAllocation)->SetUserData(m_hAllocator, createInfo.pUserData);

-            return VK_SUCCESS;

-        }

+        canMakeOtherLost = false;

     }

 

-    const bool canMakeOtherLost = (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) != 0;

+    // Upper address can only be used with linear allocator and within single memory block.

+    if(isUpperAddress &&

+        (!m_LinearAlgorithm || m_MaxBlockCount > 1))

+    {

+        return VK_ERROR_FEATURE_NOT_PRESENT;

+    }

+

+    // Early reject: requested allocation size is larger that maximum block size for this block vector.

+    if(size + 2 * VMA_DEBUG_MARGIN > m_PreferredBlockSize)

+    {

+        return VK_ERROR_OUT_OF_DEVICE_MEMORY;

+    }

+

+    VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex);

+

+    /*

+    Under certain condition, this whole section can be skipped for optimization, so

+    we move on directly to trying to allocate with canMakeOtherLost. That's the case

+    e.g. for custom pools with linear algorithm.

+    */

+    if(!canMakeOtherLost || canCreateNewBlock)

+    {

+        // 1. Search existing allocations. Try to allocate without making other allocations lost.

+        VmaAllocationCreateFlags allocFlagsCopy = createInfo.flags;

+        allocFlagsCopy &= ~VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT;

+

+        if(m_LinearAlgorithm)

+        {

+            // Use only last block.

+            if(!m_Blocks.empty())

+            {

+                VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks.back();

+                VMA_ASSERT(pCurrBlock);

+                VkResult res = AllocateFromBlock(

+                    pCurrBlock,

+                    hCurrentPool,

+                    currentFrameIndex,

+                    size,

+                    alignment,

+                    allocFlagsCopy,

+                    createInfo.pUserData,

+                    suballocType,

+                    pAllocation);

+                if(res == VK_SUCCESS)

+                {

+                    VMA_DEBUG_LOG("    Returned from last block #%u", (uint32_t)(m_Blocks.size() - 1));

+                    return VK_SUCCESS;

+                }

+            }

+        }

+        else

+        {

+            // Forward order in m_Blocks - prefer blocks with smallest amount of free space.

+            for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex )

+            {

+                VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex];

+                VMA_ASSERT(pCurrBlock);

+                VkResult res = AllocateFromBlock(

+                    pCurrBlock,

+                    hCurrentPool,

+                    currentFrameIndex,

+                    size,

+                    alignment,

+                    allocFlagsCopy,

+                    createInfo.pUserData,

+                    suballocType,

+                    pAllocation);

+                if(res == VK_SUCCESS)

+                {

+                    VMA_DEBUG_LOG("    Returned from existing block #%u", (uint32_t)blockIndex);

+                    return VK_SUCCESS;

+                }

+            }

+        }

+

+        // 2. Try to create new block.

+        if(canCreateNewBlock)

+        {

+            // Calculate optimal size for new block.

+            VkDeviceSize newBlockSize = m_PreferredBlockSize;

+            uint32_t newBlockSizeShift = 0;

+            const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3;

+

+            if(!m_ExplicitBlockSize)

+            {

+                // Allocate 1/8, 1/4, 1/2 as first blocks.

+                const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize();

+                for(uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i)

+                {

+                    const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;

+                    if(smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= size * 2)

+                    {

+                        newBlockSize = smallerNewBlockSize;

+                        ++newBlockSizeShift;

+                    }

+                    else

+                    {

+                        break;

+                    }

+                }

+            }

+

+            size_t newBlockIndex = 0;

+            VkResult res = CreateBlock(newBlockSize, &newBlockIndex);

+            // Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.

+            if(!m_ExplicitBlockSize)

+            {

+                while(res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX)

+                {

+                    const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;

+                    if(smallerNewBlockSize >= size)

+                    {

+                        newBlockSize = smallerNewBlockSize;

+                        ++newBlockSizeShift;

+                        res = CreateBlock(newBlockSize, &newBlockIndex);

+                    }

+                    else

+                    {

+                        break;

+                    }

+                }

+            }

+

+            if(res == VK_SUCCESS)

+            {

+                VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex];

+                VMA_ASSERT(pBlock->m_pMetadata->GetSize() >= size);

+

+                res = AllocateFromBlock(

+                    pBlock,

+                    hCurrentPool,

+                    currentFrameIndex,

+                    size,

+                    alignment,

+                    allocFlagsCopy,

+                    createInfo.pUserData,

+                    suballocType,

+                    pAllocation);

+                if(res == VK_SUCCESS)

+                {

+                    VMA_DEBUG_LOG("    Created new block Size=%llu", newBlockSize);

+                    return VK_SUCCESS;

+                }

+                else

+                {

+                    // Allocation from new block failed, possibly due to VMA_DEBUG_MARGIN or alignment.

+                    return VK_ERROR_OUT_OF_DEVICE_MEMORY;

+                }

+            }

+        }

+    }

 

     // 3. Try to allocate from existing blocks with making other allocations lost.

     if(canMakeOtherLost)

@@ -6694,12 +9628,13 @@
                 VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex];

                 VMA_ASSERT(pCurrBlock);

                 VmaAllocationRequest currRequest = {};

-                if(pCurrBlock->m_Metadata.CreateAllocationRequest(

+                if(pCurrBlock->m_pMetadata->CreateAllocationRequest(

                     currentFrameIndex,

                     m_FrameInUseCount,

                     m_BufferImageGranularity,

-                    vkMemReq.size,

-                    vkMemReq.alignment,

+                    size,

+                    alignment,

+                    (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0,

                     suballocType,

                     canMakeOtherLost,

                     &currRequest))

@@ -6731,31 +9666,40 @@
                     }

                 }

 

-                if(pBestRequestBlock->m_Metadata.MakeRequestedAllocationsLost(

+                if(pBestRequestBlock->m_pMetadata->MakeRequestedAllocationsLost(

                     currentFrameIndex,

                     m_FrameInUseCount,

                     &bestRequest))

                 {

                     // We no longer have an empty Allocation.

-                    if(pBestRequestBlock->m_Metadata.IsEmpty())

+                    if(pBestRequestBlock->m_pMetadata->IsEmpty())

                     {

                         m_HasEmptyBlock = false;

                     }

                     // Allocate from this pBlock.

                     *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);

-                    pBestRequestBlock->m_Metadata.Alloc(bestRequest, suballocType, vkMemReq.size, *pAllocation);

+                    pBestRequestBlock->m_pMetadata->Alloc(bestRequest, suballocType, size, isUpperAddress, *pAllocation);

                     (*pAllocation)->InitBlockAllocation(

                         hCurrentPool,

                         pBestRequestBlock,

                         bestRequest.offset,

-                        vkMemReq.alignment,

-                        vkMemReq.size,

+                        alignment,

+                        size,

                         suballocType,

                         mapped,

                         (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0);

                     VMA_HEAVY_ASSERT(pBestRequestBlock->Validate());

                     VMA_DEBUG_LOG("    Returned from existing allocation #%u", (uint32_t)blockIndex);

                     (*pAllocation)->SetUserData(m_hAllocator, createInfo.pUserData);

+                    if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)

+                    {

+                        m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);

+                    }

+                    if(IsCorruptionDetectionEnabled())

+                    {

+                        VkResult res = pBestRequestBlock->WriteMagicValueAroundAllocation(m_hAllocator, bestRequest.offset, size);

+                        VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value.");

+                    }

                     return VK_SUCCESS;

                 }

                 // else: Some allocations must have been touched while we are here. Next try.

@@ -6789,18 +9733,24 @@
 

         VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock();

 

+        if(IsCorruptionDetectionEnabled())

+        {

+            VkResult res = pBlock->ValidateMagicValueAroundAllocation(m_hAllocator, hAllocation->GetOffset(), hAllocation->GetSize());

+            VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to validate magic value.");

+        }

+

         if(hAllocation->IsPersistentMap())

         {

             pBlock->Unmap(m_hAllocator, 1);

         }

 

-        pBlock->m_Metadata.Free(hAllocation);

+        pBlock->m_pMetadata->Free(hAllocation);

         VMA_HEAVY_ASSERT(pBlock->Validate());

 

         VMA_DEBUG_LOG("  Freed from MemoryTypeIndex=%u", memTypeIndex);

 

         // pBlock became empty after this deallocation.

-        if(pBlock->m_Metadata.IsEmpty())

+        if(pBlock->m_pMetadata->IsEmpty())

         {

             // Already has empty Allocation. We don't want to have two, so delete this one.

             if(m_HasEmptyBlock && m_Blocks.size() > m_MinBlockCount)

@@ -6808,7 +9758,7 @@
                 pBlockToDelete = pBlock;

                 Remove(pBlock);

             }

-            // We now have first empty Allocation.

+            // We now have first empty block.

             else

             {

                 m_HasEmptyBlock = true;

@@ -6819,7 +9769,7 @@
         else if(m_HasEmptyBlock)

         {

             VmaDeviceMemoryBlock* pLastBlock = m_Blocks.back();

-            if(pLastBlock->m_Metadata.IsEmpty() && m_Blocks.size() > m_MinBlockCount)

+            if(pLastBlock->m_pMetadata->IsEmpty() && m_Blocks.size() > m_MinBlockCount)

             {

                 pBlockToDelete = pLastBlock;

                 m_Blocks.pop_back();

@@ -6840,12 +9790,12 @@
     }

 }

 

-size_t VmaBlockVector::CalcMaxBlockSize() const

+VkDeviceSize VmaBlockVector::CalcMaxBlockSize() const

 {

-    size_t result = 0;

+    VkDeviceSize result = 0;

     for(size_t i = m_Blocks.size(); i--; )

     {

-        result = VMA_MAX((uint64_t)result, (uint64_t)m_Blocks[i]->m_Metadata.GetSize());

+        result = VMA_MAX(result, m_Blocks[i]->m_pMetadata->GetSize());

         if(result >= m_PreferredBlockSize)

         {

             break;

@@ -6869,17 +9819,93 @@
 

 void VmaBlockVector::IncrementallySortBlocks()

 {

-    // Bubble sort only until first swap.

-    for(size_t i = 1; i < m_Blocks.size(); ++i)

+    if(!m_LinearAlgorithm)

     {

-        if(m_Blocks[i - 1]->m_Metadata.GetSumFreeSize() > m_Blocks[i]->m_Metadata.GetSumFreeSize())

+        // Bubble sort only until first swap.

+        for(size_t i = 1; i < m_Blocks.size(); ++i)

         {

-            VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]);

-            return;

+            if(m_Blocks[i - 1]->m_pMetadata->GetSumFreeSize() > m_Blocks[i]->m_pMetadata->GetSumFreeSize())

+            {

+                VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]);

+                return;

+            }

         }

     }

 }

 

+VkResult VmaBlockVector::AllocateFromBlock(

+    VmaDeviceMemoryBlock* pBlock,

+    VmaPool hCurrentPool,

+    uint32_t currentFrameIndex,

+    VkDeviceSize size,

+    VkDeviceSize alignment,

+    VmaAllocationCreateFlags allocFlags,

+    void* pUserData,

+    VmaSuballocationType suballocType,

+    VmaAllocation* pAllocation)

+{

+    VMA_ASSERT((allocFlags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) == 0);

+    const bool isUpperAddress = (allocFlags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0;

+    const bool mapped = (allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0;

+    const bool isUserDataString = (allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0;

+

+    VmaAllocationRequest currRequest = {};

+    if(pBlock->m_pMetadata->CreateAllocationRequest(

+        currentFrameIndex,

+        m_FrameInUseCount,

+        m_BufferImageGranularity,

+        size,

+        alignment,

+        isUpperAddress,

+        suballocType,

+        false, // canMakeOtherLost

+        &currRequest))

+    {

+        // Allocate from pCurrBlock.

+        VMA_ASSERT(currRequest.itemsToMakeLostCount == 0);

+

+        if(mapped)

+        {

+            VkResult res = pBlock->Map(m_hAllocator, 1, VMA_NULL);

+            if(res != VK_SUCCESS)

+            {

+                return res;

+            }

+        }

+            

+        // We no longer have an empty Allocation.

+        if(pBlock->m_pMetadata->IsEmpty())

+        {

+            m_HasEmptyBlock = false;

+        }

+            

+        *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString);

+        pBlock->m_pMetadata->Alloc(currRequest, suballocType, size, isUpperAddress, *pAllocation);

+        (*pAllocation)->InitBlockAllocation(

+            hCurrentPool,

+            pBlock,

+            currRequest.offset,

+            alignment,

+            size,

+            suballocType,

+            mapped,

+            (allocFlags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0);

+        VMA_HEAVY_ASSERT(pBlock->Validate());

+        (*pAllocation)->SetUserData(m_hAllocator, pUserData);

+        if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)

+        {

+            m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);

+        }

+        if(IsCorruptionDetectionEnabled())

+        {

+            VkResult res = pBlock->WriteMagicValueAroundAllocation(m_hAllocator, currRequest.offset, size);

+            VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value.");

+        }

+        return VK_SUCCESS;

+    }

+    return VK_ERROR_OUT_OF_DEVICE_MEMORY;

+}

+

 VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex)

 {

     VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };

@@ -6897,9 +9923,12 @@
     // Create new Allocation for it.

     VmaDeviceMemoryBlock* const pBlock = vma_new(m_hAllocator, VmaDeviceMemoryBlock)(m_hAllocator);

     pBlock->Init(

+        m_hAllocator,

         m_MemoryTypeIndex,

         mem,

-        allocInfo.allocationSize);

+        allocInfo.allocationSize,

+        m_NextBlockId++,

+        m_LinearAlgorithm);

 

     m_Blocks.push_back(pBlock);

     if(pNewBlockIndex != VMA_NULL)

@@ -6947,6 +9976,12 @@
             json.WriteString("FrameInUseCount");

             json.WriteNumber(m_FrameInUseCount);

         }

+

+        if(m_LinearAlgorithm)

+        {

+            json.WriteString("LinearAlgorithm");

+            json.WriteBool(true);

+        }

     }

     else

     {

@@ -6955,12 +9990,16 @@
     }

 

     json.WriteString("Blocks");

-    json.BeginArray();

+    json.BeginObject();

     for(size_t i = 0; i < m_Blocks.size(); ++i)

     {

-        m_Blocks[i]->m_Metadata.PrintDetailedMap(json);

+        json.BeginString();

+        json.ContinueString(m_Blocks[i]->GetId());

+        json.EndString();

+

+        m_Blocks[i]->m_pMetadata->PrintDetailedMap(json);

     }

-    json.EndArray();

+    json.EndObject();

 

     json.EndObject();

 }

@@ -7015,14 +10054,14 @@
     for(size_t blockIndex = m_Blocks.size(); blockIndex--; )

     {

         VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex];

-        if(pBlock->m_Metadata.IsEmpty())

+        if(pBlock->m_pMetadata->IsEmpty())

         {

             if(m_Blocks.size() > m_MinBlockCount)

             {

                 if(pDefragmentationStats != VMA_NULL)

                 {

                     ++pDefragmentationStats->deviceMemoryBlocksFreed;

-                    pDefragmentationStats->bytesFreed += pBlock->m_Metadata.GetSize();

+                    pDefragmentationStats->bytesFreed += pBlock->m_pMetadata->GetSize();

                 }

 

                 VmaVectorRemove(m_Blocks, blockIndex);

@@ -7058,7 +10097,7 @@
     {

         VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex];

         VMA_ASSERT(pBlock);

-        lostAllocationCount += pBlock->m_Metadata.MakeAllocationsLost(currentFrameIndex, m_FrameInUseCount);

+        lostAllocationCount += pBlock->m_pMetadata->MakeAllocationsLost(currentFrameIndex, m_FrameInUseCount);

     }

     if(pLostAllocationCount != VMA_NULL)

     {

@@ -7066,6 +10105,27 @@
     }

 }

 

+VkResult VmaBlockVector::CheckCorruption()

+{

+    if(!IsCorruptionDetectionEnabled())

+    {

+        return VK_ERROR_FEATURE_NOT_PRESENT;

+    }

+

+    VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex);

+    for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex)

+    {

+        VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex];

+        VMA_ASSERT(pBlock);

+        VkResult res = pBlock->CheckCorruption(m_hAllocator);

+        if(res != VK_SUCCESS)

+        {

+            return res;

+        }

+    }

+    return VK_SUCCESS;

+}

+

 void VmaBlockVector::AddStats(VmaStats* pStats)

 {

     const uint32_t memTypeIndex = m_MemoryTypeIndex;

@@ -7079,7 +10139,7 @@
         VMA_ASSERT(pBlock);

         VMA_HEAVY_ASSERT(pBlock->Validate());

         VmaStatInfo allocationStatInfo;

-        pBlock->m_Metadata.CalcAllocationStatInfo(allocationStatInfo);

+        pBlock->m_pMetadata->CalcAllocationStatInfo(allocationStatInfo);

         VmaAddStatInfo(pStats->total, allocationStatInfo);

         VmaAddStatInfo(pStats->memoryType[memTypeIndex], allocationStatInfo);

         VmaAddStatInfo(pStats->memoryHeap[memHeapIndex], allocationStatInfo);

@@ -7101,6 +10161,7 @@
     m_Allocations(VmaStlAllocator<AllocationInfo>(hAllocator->GetAllocationCallbacks())),

     m_Blocks(VmaStlAllocator<BlockInfo*>(hAllocator->GetAllocationCallbacks()))

 {

+    VMA_ASSERT(!pBlockVector->UsesLinearAlgorithm());

 }

 

 VmaDefragmentator::~VmaDefragmentator()

@@ -7199,12 +10260,13 @@
         {

             BlockInfo* pDstBlockInfo = m_Blocks[dstBlockIndex];

             VmaAllocationRequest dstAllocRequest;

-            if(pDstBlockInfo->m_pBlock->m_Metadata.CreateAllocationRequest(

+            if(pDstBlockInfo->m_pBlock->m_pMetadata->CreateAllocationRequest(

                 m_CurrentFrameIndex,

                 m_pBlockVector->GetFrameInUseCount(),

                 m_pBlockVector->GetBufferImageGranularity(),

                 size,

                 alignment,

+                false, // upperAddress

                 suballocType,

                 false, // canMakeOtherLost

                 &dstAllocRequest) &&

@@ -7239,9 +10301,20 @@
                     reinterpret_cast<char*>(pDstMappedData) + dstAllocRequest.offset,

                     reinterpret_cast<char*>(pSrcMappedData) + srcOffset,

                     static_cast<size_t>(size));

+

+                if(VMA_DEBUG_MARGIN > 0)

+                {

+                    VmaWriteMagicValue(pDstMappedData, dstAllocRequest.offset - VMA_DEBUG_MARGIN);

+                    VmaWriteMagicValue(pDstMappedData, dstAllocRequest.offset + size);

+                }

                 

-                pDstBlockInfo->m_pBlock->m_Metadata.Alloc(dstAllocRequest, suballocType, size, allocInfo.m_hAllocation);

-                pSrcBlockInfo->m_pBlock->m_Metadata.FreeAtOffset(srcOffset);

+                pDstBlockInfo->m_pBlock->m_pMetadata->Alloc(

+                    dstAllocRequest,

+                    suballocType,

+                    size,

+                    false, // upperAddress

+                    allocInfo.m_hAllocation);

+                pSrcBlockInfo->m_pBlock->m_pMetadata->FreeAtOffset(srcOffset);

                 

                 allocInfo.m_hAllocation->ChangeBlockAllocation(m_hAllocator, pDstBlockInfo->m_pBlock, dstAllocRequest.offset);

 

@@ -7368,6 +10441,480 @@
 }

 

 ////////////////////////////////////////////////////////////////////////////////

+// VmaRecorder

+

+#if VMA_RECORDING_ENABLED

+

+VmaRecorder::VmaRecorder() :

+    m_UseMutex(true),

+    m_Flags(0),

+    m_File(VMA_NULL),

+    m_Freq(INT64_MAX),

+    m_StartCounter(INT64_MAX)

+{

+}

+

+VkResult VmaRecorder::Init(const VmaRecordSettings& settings, bool useMutex)

+{

+    m_UseMutex = useMutex;

+    m_Flags = settings.flags;

+

+    QueryPerformanceFrequency((LARGE_INTEGER*)&m_Freq);

+    QueryPerformanceCounter((LARGE_INTEGER*)&m_StartCounter);

+

+    // Open file for writing.

+    errno_t err = fopen_s(&m_File, settings.pFilePath, "wb");

+    if(err != 0)

+    {

+        return VK_ERROR_INITIALIZATION_FAILED;

+    }

+

+    // Write header.

+    fprintf(m_File, "%s\n", "Vulkan Memory Allocator,Calls recording");

+    fprintf(m_File, "%s\n", "1,3");

+

+    return VK_SUCCESS;

+}

+

+VmaRecorder::~VmaRecorder()

+{

+    if(m_File != VMA_NULL)

+    {

+        fclose(m_File);

+    }

+}

+

+void VmaRecorder::RecordCreateAllocator(uint32_t frameIndex)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaCreateAllocator\n", callParams.threadId, callParams.time, frameIndex);

+    Flush();

+}

+

+void VmaRecorder::RecordDestroyAllocator(uint32_t frameIndex)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaDestroyAllocator\n", callParams.threadId, callParams.time, frameIndex);

+    Flush();

+}

+

+void VmaRecorder::RecordCreatePool(uint32_t frameIndex, const VmaPoolCreateInfo& createInfo, VmaPool pool)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaCreatePool,%u,%u,%llu,%llu,%llu,%u,%p\n", callParams.threadId, callParams.time, frameIndex,

+        createInfo.memoryTypeIndex,

+        createInfo.flags,

+        createInfo.blockSize,

+        createInfo.minBlockCount,

+        createInfo.maxBlockCount,

+        createInfo.frameInUseCount,

+        pool);

+    Flush();

+}

+

+void VmaRecorder::RecordDestroyPool(uint32_t frameIndex, VmaPool pool)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaDestroyPool,%p\n", callParams.threadId, callParams.time, frameIndex,

+        pool);

+    Flush();

+}

+

+void VmaRecorder::RecordAllocateMemory(uint32_t frameIndex,

+        const VkMemoryRequirements& vkMemReq,

+        const VmaAllocationCreateInfo& createInfo,

+        VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    UserDataString userDataStr(createInfo.flags, createInfo.pUserData);

+    fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemory,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex,

+        vkMemReq.size,

+        vkMemReq.alignment,

+        vkMemReq.memoryTypeBits,

+        createInfo.flags,

+        createInfo.usage,

+        createInfo.requiredFlags,

+        createInfo.preferredFlags,

+        createInfo.memoryTypeBits,

+        createInfo.pool,

+        allocation,

+        userDataStr.GetString());

+    Flush();

+}

+

+void VmaRecorder::RecordAllocateMemoryForBuffer(uint32_t frameIndex,

+    const VkMemoryRequirements& vkMemReq,

+    bool requiresDedicatedAllocation,

+    bool prefersDedicatedAllocation,

+    const VmaAllocationCreateInfo& createInfo,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    UserDataString userDataStr(createInfo.flags, createInfo.pUserData);

+    fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryForBuffer,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex,

+        vkMemReq.size,

+        vkMemReq.alignment,

+        vkMemReq.memoryTypeBits,

+        requiresDedicatedAllocation ? 1 : 0,

+        prefersDedicatedAllocation ? 1 : 0,

+        createInfo.flags,

+        createInfo.usage,

+        createInfo.requiredFlags,

+        createInfo.preferredFlags,

+        createInfo.memoryTypeBits,

+        createInfo.pool,

+        allocation,

+        userDataStr.GetString());

+    Flush();

+}

+

+void VmaRecorder::RecordAllocateMemoryForImage(uint32_t frameIndex,

+    const VkMemoryRequirements& vkMemReq,

+    bool requiresDedicatedAllocation,

+    bool prefersDedicatedAllocation,

+    const VmaAllocationCreateInfo& createInfo,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    UserDataString userDataStr(createInfo.flags, createInfo.pUserData);

+    fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryForImage,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex,

+        vkMemReq.size,

+        vkMemReq.alignment,

+        vkMemReq.memoryTypeBits,

+        requiresDedicatedAllocation ? 1 : 0,

+        prefersDedicatedAllocation ? 1 : 0,

+        createInfo.flags,

+        createInfo.usage,

+        createInfo.requiredFlags,

+        createInfo.preferredFlags,

+        createInfo.memoryTypeBits,

+        createInfo.pool,

+        allocation,

+        userDataStr.GetString());

+    Flush();

+}

+

+void VmaRecorder::RecordFreeMemory(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaFreeMemory,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordSetAllocationUserData(uint32_t frameIndex,

+    VmaAllocation allocation,

+    const void* pUserData)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    UserDataString userDataStr(

+        allocation->IsUserDataString() ? VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT : 0,

+        pUserData);

+    fprintf(m_File, "%u,%.3f,%u,vmaSetAllocationUserData,%p,%s\n", callParams.threadId, callParams.time, frameIndex,

+        allocation,

+        userDataStr.GetString());

+    Flush();

+}

+

+void VmaRecorder::RecordCreateLostAllocation(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaCreateLostAllocation,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordMapMemory(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaMapMemory,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordUnmapMemory(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaUnmapMemory,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordFlushAllocation(uint32_t frameIndex,

+    VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaFlushAllocation,%p,%llu,%llu\n", callParams.threadId, callParams.time, frameIndex,

+        allocation,

+        offset,

+        size);

+    Flush();

+}

+

+void VmaRecorder::RecordInvalidateAllocation(uint32_t frameIndex,

+    VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaInvalidateAllocation,%p,%llu,%llu\n", callParams.threadId, callParams.time, frameIndex,

+        allocation,

+        offset,

+        size);

+    Flush();

+}

+

+void VmaRecorder::RecordCreateBuffer(uint32_t frameIndex,

+    const VkBufferCreateInfo& bufCreateInfo,

+    const VmaAllocationCreateInfo& allocCreateInfo,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    UserDataString userDataStr(allocCreateInfo.flags, allocCreateInfo.pUserData);

+    fprintf(m_File, "%u,%.3f,%u,vmaCreateBuffer,%u,%llu,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex,

+        bufCreateInfo.flags,

+        bufCreateInfo.size,

+        bufCreateInfo.usage,

+        bufCreateInfo.sharingMode,

+        allocCreateInfo.flags,

+        allocCreateInfo.usage,

+        allocCreateInfo.requiredFlags,

+        allocCreateInfo.preferredFlags,

+        allocCreateInfo.memoryTypeBits,

+        allocCreateInfo.pool,

+        allocation,

+        userDataStr.GetString());

+    Flush();

+}

+

+void VmaRecorder::RecordCreateImage(uint32_t frameIndex,

+    const VkImageCreateInfo& imageCreateInfo,

+    const VmaAllocationCreateInfo& allocCreateInfo,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    UserDataString userDataStr(allocCreateInfo.flags, allocCreateInfo.pUserData);

+    fprintf(m_File, "%u,%.3f,%u,vmaCreateImage,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex,

+        imageCreateInfo.flags,

+        imageCreateInfo.imageType,

+        imageCreateInfo.format,

+        imageCreateInfo.extent.width,

+        imageCreateInfo.extent.height,

+        imageCreateInfo.extent.depth,

+        imageCreateInfo.mipLevels,

+        imageCreateInfo.arrayLayers,

+        imageCreateInfo.samples,

+        imageCreateInfo.tiling,

+        imageCreateInfo.usage,

+        imageCreateInfo.sharingMode,

+        imageCreateInfo.initialLayout,

+        allocCreateInfo.flags,

+        allocCreateInfo.usage,

+        allocCreateInfo.requiredFlags,

+        allocCreateInfo.preferredFlags,

+        allocCreateInfo.memoryTypeBits,

+        allocCreateInfo.pool,

+        allocation,

+        userDataStr.GetString());

+    Flush();

+}

+

+void VmaRecorder::RecordDestroyBuffer(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaDestroyBuffer,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordDestroyImage(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaDestroyImage,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordTouchAllocation(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaTouchAllocation,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordGetAllocationInfo(uint32_t frameIndex,

+    VmaAllocation allocation)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaGetAllocationInfo,%p\n", callParams.threadId, callParams.time, frameIndex,

+        allocation);

+    Flush();

+}

+

+void VmaRecorder::RecordMakePoolAllocationsLost(uint32_t frameIndex,

+    VmaPool pool)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaMakePoolAllocationsLost,%p\n", callParams.threadId, callParams.time, frameIndex,

+        pool);

+    Flush();

+}

+

+VmaRecorder::UserDataString::UserDataString(VmaAllocationCreateFlags allocFlags, const void* pUserData)

+{

+    if(pUserData != VMA_NULL)

+    {

+        if((allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0)

+        {

+            m_Str = (const char*)pUserData;

+        }

+        else

+        {

+            sprintf_s(m_PtrStr, "%p", pUserData);

+            m_Str = m_PtrStr;

+        }

+    }

+    else

+    {

+        m_Str = "";

+    }

+}

+

+void VmaRecorder::WriteConfiguration(

+    const VkPhysicalDeviceProperties& devProps,

+    const VkPhysicalDeviceMemoryProperties& memProps,

+    bool dedicatedAllocationExtensionEnabled)

+{

+    fprintf(m_File, "Config,Begin\n");

+

+    fprintf(m_File, "PhysicalDevice,apiVersion,%u\n", devProps.apiVersion);

+    fprintf(m_File, "PhysicalDevice,driverVersion,%u\n", devProps.driverVersion);

+    fprintf(m_File, "PhysicalDevice,vendorID,%u\n", devProps.vendorID);

+    fprintf(m_File, "PhysicalDevice,deviceID,%u\n", devProps.deviceID);

+    fprintf(m_File, "PhysicalDevice,deviceType,%u\n", devProps.deviceType);

+    fprintf(m_File, "PhysicalDevice,deviceName,%s\n", devProps.deviceName);

+

+    fprintf(m_File, "PhysicalDeviceLimits,maxMemoryAllocationCount,%u\n", devProps.limits.maxMemoryAllocationCount);

+    fprintf(m_File, "PhysicalDeviceLimits,bufferImageGranularity,%llu\n", devProps.limits.bufferImageGranularity);

+    fprintf(m_File, "PhysicalDeviceLimits,nonCoherentAtomSize,%llu\n", devProps.limits.nonCoherentAtomSize);

+

+    fprintf(m_File, "PhysicalDeviceMemory,HeapCount,%u\n", memProps.memoryHeapCount);

+    for(uint32_t i = 0; i < memProps.memoryHeapCount; ++i)

+    {

+        fprintf(m_File, "PhysicalDeviceMemory,Heap,%u,size,%llu\n", i, memProps.memoryHeaps[i].size);

+        fprintf(m_File, "PhysicalDeviceMemory,Heap,%u,flags,%u\n", i, memProps.memoryHeaps[i].flags);

+    }

+    fprintf(m_File, "PhysicalDeviceMemory,TypeCount,%u\n", memProps.memoryTypeCount);

+    for(uint32_t i = 0; i < memProps.memoryTypeCount; ++i)

+    {

+        fprintf(m_File, "PhysicalDeviceMemory,Type,%u,heapIndex,%u\n", i, memProps.memoryTypes[i].heapIndex);

+        fprintf(m_File, "PhysicalDeviceMemory,Type,%u,propertyFlags,%u\n", i, memProps.memoryTypes[i].propertyFlags);

+    }

+

+    fprintf(m_File, "Extension,VK_KHR_dedicated_allocation,%u\n", dedicatedAllocationExtensionEnabled ? 1 : 0);

+

+    fprintf(m_File, "Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,%u\n", VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ? 1 : 0);

+    fprintf(m_File, "Macro,VMA_DEBUG_ALIGNMENT,%llu\n", (VkDeviceSize)VMA_DEBUG_ALIGNMENT);

+    fprintf(m_File, "Macro,VMA_DEBUG_MARGIN,%llu\n", (VkDeviceSize)VMA_DEBUG_MARGIN);

+    fprintf(m_File, "Macro,VMA_DEBUG_INITIALIZE_ALLOCATIONS,%u\n", VMA_DEBUG_INITIALIZE_ALLOCATIONS ? 1 : 0);

+    fprintf(m_File, "Macro,VMA_DEBUG_DETECT_CORRUPTION,%u\n", VMA_DEBUG_DETECT_CORRUPTION ? 1 : 0);

+    fprintf(m_File, "Macro,VMA_DEBUG_GLOBAL_MUTEX,%u\n", VMA_DEBUG_GLOBAL_MUTEX ? 1 : 0);

+    fprintf(m_File, "Macro,VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,%llu\n", (VkDeviceSize)VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY);

+    fprintf(m_File, "Macro,VMA_SMALL_HEAP_MAX_SIZE,%llu\n", (VkDeviceSize)VMA_SMALL_HEAP_MAX_SIZE);

+    fprintf(m_File, "Macro,VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,%llu\n", (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE);

+

+    fprintf(m_File, "Config,End\n");

+}

+

+void VmaRecorder::GetBasicParams(CallParams& outParams)

+{

+    outParams.threadId = GetCurrentThreadId();

+

+    LARGE_INTEGER counter;

+    QueryPerformanceCounter(&counter);

+    outParams.time = (double)(counter.QuadPart - m_StartCounter) / (double)m_Freq;

+}

+

+void VmaRecorder::Flush()

+{

+    if((m_Flags & VMA_RECORD_FLUSH_AFTER_CALL_BIT) != 0)

+    {

+        fflush(m_File);

+    }

+}

+

+#endif // #if VMA_RECORDING_ENABLED

+

+////////////////////////////////////////////////////////////////////////////////

 // VmaAllocator_T

 

 VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :

@@ -7380,13 +10927,30 @@
     m_PreferredLargeHeapBlockSize(0),

     m_PhysicalDevice(pCreateInfo->physicalDevice),

     m_CurrentFrameIndex(0),

-    m_Pools(VmaStlAllocator<VmaPool>(GetAllocationCallbacks()))

+    m_Pools(VmaStlAllocator<VmaPool>(GetAllocationCallbacks())),

+    m_NextPoolId(0)

+#if VMA_RECORDING_ENABLED

+    ,m_pRecorder(VMA_NULL)

+#endif

 {

-    VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device);    

+    if(VMA_DEBUG_DETECT_CORRUPTION)

+    {

+        // Needs to be multiply of uint32_t size because we are going to write VMA_CORRUPTION_DETECTION_MAGIC_VALUE to it.

+        VMA_ASSERT(VMA_DEBUG_MARGIN % sizeof(uint32_t) == 0);

+    }

+

+    VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device);

+

+#if !(VMA_DEDICATED_ALLOCATION)

+    if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT) != 0)

+    {

+        VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT set but required extensions are disabled by preprocessor macros.");

+    }

+#endif

 

     memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks));

-    memset(&m_MemProps, 0, sizeof(m_MemProps));

     memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));

+    memset(&m_MemProps, 0, sizeof(m_MemProps));

         

     memset(&m_pBlockVectors, 0, sizeof(m_pBlockVectors));

     memset(&m_pDedicatedAllocations, 0, sizeof(m_pDedicatedAllocations));

@@ -7438,15 +11002,54 @@
             SIZE_MAX,

             GetBufferImageGranularity(),

             pCreateInfo->frameInUseCount,

-            false); // isCustomPool

+            false, // isCustomPool

+            false, // explicitBlockSize

+            false); // linearAlgorithm

         // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here,

         // becase minBlockCount is 0.

         m_pDedicatedAllocations[memTypeIndex] = vma_new(this, AllocationVectorType)(VmaStlAllocator<VmaAllocation>(GetAllocationCallbacks()));

+

     }

 }

 

+VkResult VmaAllocator_T::Init(const VmaAllocatorCreateInfo* pCreateInfo)

+{

+    VkResult res = VK_SUCCESS;

+

+    if(pCreateInfo->pRecordSettings != VMA_NULL &&

+        !VmaStrIsEmpty(pCreateInfo->pRecordSettings->pFilePath))

+    {

+#if VMA_RECORDING_ENABLED

+        m_pRecorder = vma_new(this, VmaRecorder)();

+        res = m_pRecorder->Init(*pCreateInfo->pRecordSettings, m_UseMutex);

+        if(res != VK_SUCCESS)

+        {

+            return res;

+        }

+        m_pRecorder->WriteConfiguration(

+            m_PhysicalDeviceProperties,

+            m_MemProps,

+            m_UseKhrDedicatedAllocation);

+        m_pRecorder->RecordCreateAllocator(GetCurrentFrameIndex());

+#else

+        VMA_ASSERT(0 && "VmaAllocatorCreateInfo::pRecordSettings used, but not supported due to VMA_RECORDING_ENABLED not defined to 1.");

+        return VK_ERROR_FEATURE_NOT_PRESENT;

+#endif

+    }

+

+    return res;

+}

+

 VmaAllocator_T::~VmaAllocator_T()

 {

+#if VMA_RECORDING_ENABLED

+    if(m_pRecorder != VMA_NULL)

+    {

+        m_pRecorder->RecordDestroyAllocator(GetCurrentFrameIndex());

+        vma_delete(this, m_pRecorder);

+    }

+#endif

+    

     VMA_ASSERT(m_Pools.empty());

 

     for(size_t i = GetMemoryTypeCount(); i--; )

@@ -7465,6 +11068,8 @@
     m_VulkanFunctions.vkFreeMemory = &vkFreeMemory;

     m_VulkanFunctions.vkMapMemory = &vkMapMemory;

     m_VulkanFunctions.vkUnmapMemory = &vkUnmapMemory;

+    m_VulkanFunctions.vkFlushMappedMemoryRanges = &vkFlushMappedMemoryRanges;

+    m_VulkanFunctions.vkInvalidateMappedMemoryRanges = &vkInvalidateMappedMemoryRanges;

     m_VulkanFunctions.vkBindBufferMemory = &vkBindBufferMemory;

     m_VulkanFunctions.vkBindImageMemory = &vkBindImageMemory;

     m_VulkanFunctions.vkGetBufferMemoryRequirements = &vkGetBufferMemoryRequirements;

@@ -7473,6 +11078,7 @@
     m_VulkanFunctions.vkDestroyBuffer = &vkDestroyBuffer;

     m_VulkanFunctions.vkCreateImage = &vkCreateImage;

     m_VulkanFunctions.vkDestroyImage = &vkDestroyImage;

+#if VMA_DEDICATED_ALLOCATION

     if(m_UseKhrDedicatedAllocation)

     {

         m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR =

@@ -7480,6 +11086,7 @@
         m_VulkanFunctions.vkGetImageMemoryRequirements2KHR =

             (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(m_hDevice, "vkGetImageMemoryRequirements2KHR");

     }

+#endif // #if VMA_DEDICATED_ALLOCATION

 #endif // #if VMA_STATIC_VULKAN_FUNCTIONS == 1

 

 #define VMA_COPY_IF_NOT_NULL(funcName) \

@@ -7493,6 +11100,8 @@
         VMA_COPY_IF_NOT_NULL(vkFreeMemory);

         VMA_COPY_IF_NOT_NULL(vkMapMemory);

         VMA_COPY_IF_NOT_NULL(vkUnmapMemory);

+        VMA_COPY_IF_NOT_NULL(vkFlushMappedMemoryRanges);

+        VMA_COPY_IF_NOT_NULL(vkInvalidateMappedMemoryRanges);

         VMA_COPY_IF_NOT_NULL(vkBindBufferMemory);

         VMA_COPY_IF_NOT_NULL(vkBindImageMemory);

         VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements);

@@ -7501,8 +11110,10 @@
         VMA_COPY_IF_NOT_NULL(vkDestroyBuffer);

         VMA_COPY_IF_NOT_NULL(vkCreateImage);

         VMA_COPY_IF_NOT_NULL(vkDestroyImage);

+#if VMA_DEDICATED_ALLOCATION

         VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements2KHR);

         VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements2KHR);

+#endif

     }

 

 #undef VMA_COPY_IF_NOT_NULL

@@ -7515,6 +11126,8 @@
     VMA_ASSERT(m_VulkanFunctions.vkFreeMemory != VMA_NULL);

     VMA_ASSERT(m_VulkanFunctions.vkMapMemory != VMA_NULL);

     VMA_ASSERT(m_VulkanFunctions.vkUnmapMemory != VMA_NULL);

+    VMA_ASSERT(m_VulkanFunctions.vkFlushMappedMemoryRanges != VMA_NULL);

+    VMA_ASSERT(m_VulkanFunctions.vkInvalidateMappedMemoryRanges != VMA_NULL);

     VMA_ASSERT(m_VulkanFunctions.vkBindBufferMemory != VMA_NULL);

     VMA_ASSERT(m_VulkanFunctions.vkBindImageMemory != VMA_NULL);

     VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements != VMA_NULL);

@@ -7523,11 +11136,13 @@
     VMA_ASSERT(m_VulkanFunctions.vkDestroyBuffer != VMA_NULL);

     VMA_ASSERT(m_VulkanFunctions.vkCreateImage != VMA_NULL);

     VMA_ASSERT(m_VulkanFunctions.vkDestroyImage != VMA_NULL);

+#if VMA_DEDICATED_ALLOCATION

     if(m_UseKhrDedicatedAllocation)

     {

         VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR != VMA_NULL);

         VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements2KHR != VMA_NULL);

     }

+#endif

 }

 

 VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)

@@ -7539,7 +11154,8 @@
 }

 

 VkResult VmaAllocator_T::AllocateMemoryOfType(

-    const VkMemoryRequirements& vkMemReq,

+    VkDeviceSize size,

+    VkDeviceSize alignment,

     bool dedicatedAllocation,

     VkBuffer dedicatedBuffer,

     VkImage dedicatedImage,

@@ -7568,7 +11184,7 @@
         VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ||

         dedicatedAllocation ||

         // Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size.

-        vkMemReq.size > preferredBlockSize / 2;

+        size > preferredBlockSize / 2;

 

     if(preferDedicatedMemory &&

         (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0 &&

@@ -7586,7 +11202,7 @@
         else

         {

             return AllocateDedicatedMemory(

-                vkMemReq.size,

+                size,

                 suballocType,

                 memTypeIndex,

                 (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0,

@@ -7602,7 +11218,8 @@
         VkResult res = blockVector->Allocate(

             VK_NULL_HANDLE, // hCurrentPool

             m_CurrentFrameIndex.load(),

-            vkMemReq,

+            size,

+            alignment,

             finalCreateInfo,

             suballocType,

             pAllocation);

@@ -7619,7 +11236,7 @@
         else

         {

             res = AllocateDedicatedMemory(

-                vkMemReq.size,

+                size,

                 suballocType,

                 memTypeIndex,

                 (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0,

@@ -7661,6 +11278,7 @@
     allocInfo.memoryTypeIndex = memTypeIndex;

     allocInfo.allocationSize = size;

 

+#if VMA_DEDICATED_ALLOCATION

     VkMemoryDedicatedAllocateInfoKHR dedicatedAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR };

     if(m_UseKhrDedicatedAllocation)

     {

@@ -7676,6 +11294,7 @@
             allocInfo.pNext = &dedicatedAllocInfo;

         }

     }

+#endif // #if VMA_DEDICATED_ALLOCATION

 

     // Allocate VkDeviceMemory.

     VkDeviceMemory hMemory = VK_NULL_HANDLE;

@@ -7707,6 +11326,10 @@
     *pAllocation = vma_new(this, VmaAllocation_T)(m_CurrentFrameIndex.load(), isUserDataString);

     (*pAllocation)->InitDedicatedAllocation(memTypeIndex, hMemory, suballocType, pMappedData, size);

     (*pAllocation)->SetUserData(this, pUserData);

+    if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)

+    {

+        FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);

+    }

 

     // Register it in m_pDedicatedAllocations.

     {

@@ -7727,6 +11350,7 @@
     bool& requiresDedicatedAllocation,

     bool& prefersDedicatedAllocation) const

 {

+#if VMA_DEDICATED_ALLOCATION

     if(m_UseKhrDedicatedAllocation)

     {

         VkBufferMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR };

@@ -7744,6 +11368,7 @@
         prefersDedicatedAllocation  = (memDedicatedReq.prefersDedicatedAllocation  != VK_FALSE);

     }

     else

+#endif // #if VMA_DEDICATED_ALLOCATION

     {

         (*m_VulkanFunctions.vkGetBufferMemoryRequirements)(m_hDevice, hBuffer, &memReq);

         requiresDedicatedAllocation = false;

@@ -7757,6 +11382,7 @@
     bool& requiresDedicatedAllocation,

     bool& prefersDedicatedAllocation) const

 {

+#if VMA_DEDICATED_ALLOCATION

     if(m_UseKhrDedicatedAllocation)

     {

         VkImageMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR };

@@ -7774,6 +11400,7 @@
         prefersDedicatedAllocation  = (memDedicatedReq.prefersDedicatedAllocation  != VK_FALSE);

     }

     else

+#endif // #if VMA_DEDICATED_ALLOCATION

     {

         (*m_VulkanFunctions.vkGetImageMemoryRequirements)(m_hDevice, hImage, &memReq);

         requiresDedicatedAllocation = false;

@@ -7825,10 +11452,14 @@
 

     if(createInfo.pool != VK_NULL_HANDLE)

     {

+        const VkDeviceSize alignmentForPool = VMA_MAX(

+            vkMemReq.alignment,

+            GetMemoryTypeMinAlignment(createInfo.pool->m_BlockVector.GetMemoryTypeIndex()));

         return createInfo.pool->m_BlockVector.Allocate(

             createInfo.pool,

             m_CurrentFrameIndex.load(),

-            vkMemReq,

+            vkMemReq.size,

+            alignmentForPool,

             createInfo,

             suballocType,

             pAllocation);

@@ -7841,8 +11472,13 @@
         VkResult res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &createInfo, &memTypeIndex);

         if(res == VK_SUCCESS)

         {

+            VkDeviceSize alignmentForMemType = VMA_MAX(

+                vkMemReq.alignment,

+                GetMemoryTypeMinAlignment(memTypeIndex));

+

             res = AllocateMemoryOfType(

-                vkMemReq,

+                vkMemReq.size,

+                alignmentForMemType,

                 requiresDedicatedAllocation || prefersDedicatedAllocation,

                 dedicatedBuffer,

                 dedicatedImage,

@@ -7866,8 +11502,13 @@
                     res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &createInfo, &memTypeIndex);

                     if(res == VK_SUCCESS)

                     {

+                        alignmentForMemType = VMA_MAX(

+                            vkMemReq.alignment,

+                            GetMemoryTypeMinAlignment(memTypeIndex));

+                        

                         res = AllocateMemoryOfType(

-                            vkMemReq,

+                            vkMemReq.size,

+                            alignmentForMemType,

                             requiresDedicatedAllocation || prefersDedicatedAllocation,

                             dedicatedBuffer,

                             dedicatedImage,

@@ -7901,9 +11542,13 @@
 {

     VMA_ASSERT(allocation);

 

-    if(allocation->CanBecomeLost() == false ||

-        allocation->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)

+    if(TouchAllocation(allocation))

     {

+        if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)

+        {

+            FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);

+        }

+

         switch(allocation->GetType())

         {

         case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:

@@ -7956,7 +11601,7 @@
         VmaMutexLock lock(m_PoolsMutex, m_UseMutex);

         for(size_t poolIndex = 0, poolCount = m_Pools.size(); poolIndex < poolCount; ++poolIndex)

         {

-            m_Pools[poolIndex]->GetBlockVector().AddStats(pStats);

+            m_Pools[poolIndex]->m_BlockVector.AddStats(pStats);

         }

     }

 

@@ -8016,9 +11661,10 @@
         VMA_ASSERT(hAlloc);

         const uint32_t memTypeIndex = hAlloc->GetMemoryTypeIndex();

         // DedicatedAlloc cannot be defragmented.

+        const VkMemoryPropertyFlags requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;

         if((hAlloc->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK) &&

-            // Only HOST_VISIBLE memory types can be defragmented.

-            ((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) &&

+            // Only HOST_VISIBLE and HOST_COHERENT memory types can be defragmented.

+            ((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & requiredMemFlags) == requiredMemFlags) &&

             // Lost allocation cannot be defragmented.

             (hAlloc->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST))

         {

@@ -8028,7 +11674,11 @@
             // This allocation belongs to custom pool.

             if(hAllocPool != VK_NULL_HANDLE)

             {

-                pAllocBlockVector = &hAllocPool->GetBlockVector();

+                // Pools with linear algorithm are not defragmented.

+                if(!hAllocPool->m_BlockVector.UsesLinearAlgorithm())

+                {

+                    pAllocBlockVector = &hAllocPool->m_BlockVector;

+                }

             }

             // This allocation belongs to general pool.

             else

@@ -8036,11 +11686,14 @@
                 pAllocBlockVector = m_pBlockVectors[memTypeIndex];

             }

 

-            VmaDefragmentator* const pDefragmentator = pAllocBlockVector->EnsureDefragmentator(this, currentFrameIndex);

-

-            VkBool32* const pChanged = (pAllocationsChanged != VMA_NULL) ?

-                &pAllocationsChanged[allocIndex] : VMA_NULL;

-            pDefragmentator->AddAllocation(hAlloc, pChanged);

+            if(pAllocBlockVector != VMA_NULL)

+            {

+                VmaDefragmentator* const pDefragmentator =

+                    pAllocBlockVector->EnsureDefragmentator(this, currentFrameIndex);

+                VkBool32* const pChanged = (pAllocationsChanged != VMA_NULL) ?

+                    &pAllocationsChanged[allocIndex] : VMA_NULL;

+                pDefragmentator->AddAllocation(hAlloc, pChanged);

+            }

         }

     }

 

@@ -8074,7 +11727,7 @@
     // Process custom pools.

     for(size_t poolIndex = 0; (poolIndex < poolCount) && (result == VK_SUCCESS); ++poolIndex)

     {

-        result = m_Pools[poolIndex]->GetBlockVector().Defragment(

+        result = m_Pools[poolIndex]->m_BlockVector.Defragment(

             pDefragmentationStats,

             maxBytesToMove,

             maxAllocationsToMove);

@@ -8085,7 +11738,7 @@
     // Process custom pools.

     for(size_t poolIndex = poolCount; poolIndex--; )

     {

-        m_Pools[poolIndex]->GetBlockVector().DestroyDefragmentator();

+        m_Pools[poolIndex]->m_BlockVector.DestroyDefragmentator();

     }

 

     // Process standard memory.

@@ -8108,7 +11761,7 @@
         Warning: This is a carefully designed algorithm.

         Do not modify unless you really know what you're doing :)

         */

-        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();

+        const uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();

         uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex();

         for(;;)

         {

@@ -8143,6 +11796,26 @@
     }

     else

     {

+#if VMA_STATS_STRING_ENABLED

+        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();

+        uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex();

+        for(;;)

+        {

+            VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST);

+            if(localLastUseFrameIndex == localCurrFrameIndex)

+            {

+                break;

+            }

+            else // Last use time earlier than current time.

+            {

+                if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))

+                {

+                    localLastUseFrameIndex = localCurrFrameIndex;

+                }

+            }

+        }

+#endif

+

         pAllocationInfo->memoryType = hAllocation->GetMemoryTypeIndex();

         pAllocationInfo->deviceMemory = hAllocation->GetMemory();

         pAllocationInfo->offset = hAllocation->GetOffset();

@@ -8180,13 +11853,35 @@
     }

     else

     {

+#if VMA_STATS_STRING_ENABLED

+        uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load();

+        uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex();

+        for(;;)

+        {

+            VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST);

+            if(localLastUseFrameIndex == localCurrFrameIndex)

+            {

+                break;

+            }

+            else // Last use time earlier than current time.

+            {

+                if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex))

+                {

+                    localLastUseFrameIndex = localCurrFrameIndex;

+                }

+            }

+        }

+#endif

+

         return true;

     }

 }

 

 VkResult VmaAllocator_T::CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool)

 {

-    VMA_DEBUG_LOG("  CreatePool: MemoryTypeIndex=%u", pCreateInfo->memoryTypeIndex);

+    VMA_DEBUG_LOG("  CreatePool: MemoryTypeIndex=%u, flags=%u", pCreateInfo->memoryTypeIndex, pCreateInfo->flags);

+

+    const bool isLinearAlgorithm = (pCreateInfo->flags & VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) != 0;

 

     VmaPoolCreateInfo newCreateInfo = *pCreateInfo;

 

@@ -8194,12 +11889,14 @@
     {

         newCreateInfo.maxBlockCount = SIZE_MAX;

     }

-    if(newCreateInfo.blockSize == 0)

+    if(newCreateInfo.minBlockCount > newCreateInfo.maxBlockCount)

     {

-        newCreateInfo.blockSize = CalcPreferredBlockSize(newCreateInfo.memoryTypeIndex);

+        return VK_ERROR_INITIALIZATION_FAILED;

     }

 

-    *pPool = vma_new(this, VmaPool_T)(this, newCreateInfo);

+    const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(newCreateInfo.memoryTypeIndex);

+

+    *pPool = vma_new(this, VmaPool_T)(this, newCreateInfo, preferredBlockSize);

 

     VkResult res = (*pPool)->m_BlockVector.CreateMinBlocks();

     if(res != VK_SUCCESS)

@@ -8212,6 +11909,7 @@
     // Add to m_Pools.

     {

         VmaMutexLock lock(m_PoolsMutex, m_UseMutex);

+        (*pPool)->SetId(m_NextPoolId++);

         VmaVectorInsertSorted<VmaPointerLess>(m_Pools, *pPool);

     }

 

@@ -8249,6 +11947,61 @@
         pLostAllocationCount);

 }

 

+VkResult VmaAllocator_T::CheckPoolCorruption(VmaPool hPool)

+{

+    return hPool->m_BlockVector.CheckCorruption();

+}

+

+VkResult VmaAllocator_T::CheckCorruption(uint32_t memoryTypeBits)

+{

+    VkResult finalRes = VK_ERROR_FEATURE_NOT_PRESENT;

+

+    // Process default pools.

+    for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)

+    {

+        if(((1u << memTypeIndex) & memoryTypeBits) != 0)

+        {

+            VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex];

+            VMA_ASSERT(pBlockVector);

+            VkResult localRes = pBlockVector->CheckCorruption();

+            switch(localRes)

+            {

+            case VK_ERROR_FEATURE_NOT_PRESENT:

+                break;

+            case VK_SUCCESS:

+                finalRes = VK_SUCCESS;

+                break;

+            default:

+                return localRes;

+            }

+        }

+    }

+

+    // Process custom pools.

+    {

+        VmaMutexLock lock(m_PoolsMutex, m_UseMutex);

+        for(size_t poolIndex = 0, poolCount = m_Pools.size(); poolIndex < poolCount; ++poolIndex)

+        {

+            if(((1u << m_Pools[poolIndex]->m_BlockVector.GetMemoryTypeIndex()) & memoryTypeBits) != 0)

+            {

+                VkResult localRes = m_Pools[poolIndex]->m_BlockVector.CheckCorruption();

+                switch(localRes)

+                {

+                case VK_ERROR_FEATURE_NOT_PRESENT:

+                    break;

+                case VK_SUCCESS:

+                    finalRes = VK_SUCCESS;

+                    break;

+                default:

+                    return localRes;

+                }

+            }

+        }

+    }

+

+    return finalRes;

+}

+

 void VmaAllocator_T::CreateLostAllocation(VmaAllocation* pAllocation)

 {

     *pAllocation = vma_new(this, VmaAllocation_T)(VMA_FRAME_INDEX_LOST, false);

@@ -8404,6 +12157,82 @@
     return res;

 }

 

+void VmaAllocator_T::FlushOrInvalidateAllocation(

+    VmaAllocation hAllocation,

+    VkDeviceSize offset, VkDeviceSize size,

+    VMA_CACHE_OPERATION op)

+{

+    const uint32_t memTypeIndex = hAllocation->GetMemoryTypeIndex();

+    if(size > 0 && IsMemoryTypeNonCoherent(memTypeIndex))

+    {

+        const VkDeviceSize allocationSize = hAllocation->GetSize();

+        VMA_ASSERT(offset <= allocationSize);

+

+        const VkDeviceSize nonCoherentAtomSize = m_PhysicalDeviceProperties.limits.nonCoherentAtomSize;

+

+        VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };

+        memRange.memory = hAllocation->GetMemory();

+        

+        switch(hAllocation->GetType())

+        {

+        case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:

+            memRange.offset = VmaAlignDown(offset, nonCoherentAtomSize);

+            if(size == VK_WHOLE_SIZE)

+            {

+                memRange.size = allocationSize - memRange.offset;

+            }

+            else

+            {

+                VMA_ASSERT(offset + size <= allocationSize);

+                memRange.size = VMA_MIN(

+                    VmaAlignUp(size + (offset - memRange.offset), nonCoherentAtomSize),

+                    allocationSize - memRange.offset);

+            }

+            break;

+

+        case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:

+        {

+            // 1. Still within this allocation.

+            memRange.offset = VmaAlignDown(offset, nonCoherentAtomSize);

+            if(size == VK_WHOLE_SIZE)

+            {

+                size = allocationSize - offset;

+            }

+            else

+            {

+                VMA_ASSERT(offset + size <= allocationSize);

+            }

+            memRange.size = VmaAlignUp(size + (offset - memRange.offset), nonCoherentAtomSize);

+

+            // 2. Adjust to whole block.

+            const VkDeviceSize allocationOffset = hAllocation->GetOffset();

+            VMA_ASSERT(allocationOffset % nonCoherentAtomSize == 0);

+            const VkDeviceSize blockSize = hAllocation->GetBlock()->m_pMetadata->GetSize();

+            memRange.offset += allocationOffset;

+            memRange.size = VMA_MIN(memRange.size, blockSize - memRange.offset);

+            

+            break;

+        }

+        

+        default:

+            VMA_ASSERT(0);

+        }

+

+        switch(op)

+        {

+        case VMA_CACHE_FLUSH:

+            (*GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hDevice, 1, &memRange);

+            break;

+        case VMA_CACHE_INVALIDATE:

+            (*GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hDevice, 1, &memRange);

+            break;

+        default:

+            VMA_ASSERT(0);

+        }

+    }

+    // else: Just ignore this call.

+}

+

 void VmaAllocator_T::FreeDedicatedMemory(VmaAllocation allocation)

 {

     VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);

@@ -8429,6 +12258,27 @@
     VMA_DEBUG_LOG("    Freed DedicatedMemory MemoryTypeIndex=%u", memTypeIndex);

 }

 

+void VmaAllocator_T::FillAllocation(const VmaAllocation hAllocation, uint8_t pattern)

+{

+    if(VMA_DEBUG_INITIALIZE_ALLOCATIONS &&

+        !hAllocation->CanBecomeLost() &&

+        (m_MemProps.memoryTypes[hAllocation->GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)

+    {

+        void* pData = VMA_NULL;

+        VkResult res = Map(hAllocation, &pData);

+        if(res == VK_SUCCESS)

+        {

+            memset(pData, (int)pattern, (size_t)hAllocation->GetSize());

+            FlushOrInvalidateAllocation(hAllocation, 0, VK_WHOLE_SIZE, VMA_CACHE_FLUSH);

+            Unmap(hAllocation);

+        }

+        else

+        {

+            VMA_ASSERT(0 && "VMA_DEBUG_INITIALIZE_ALLOCATIONS is enabled, but couldn't map memory to fill allocation.");

+        }

+    }

+}

+

 #if VMA_STATS_STRING_ENABLED

 

 void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)

@@ -8456,31 +12306,9 @@
 

             for(size_t i = 0; i < pDedicatedAllocVector->size(); ++i)

             {

-                const VmaAllocation hAlloc = (*pDedicatedAllocVector)[i];

                 json.BeginObject(true);

-                    

-                json.WriteString("Type");

-                json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[hAlloc->GetSuballocationType()]);

-

-                json.WriteString("Size");

-                json.WriteNumber(hAlloc->GetSize());

-

-                const void* pUserData = hAlloc->GetUserData();

-                if(pUserData != VMA_NULL)

-                {

-                    json.WriteString("UserData");

-                    if(hAlloc->IsUserDataString())

-                    {

-                        json.WriteString((const char*)pUserData);

-                    }

-                    else

-                    {

-                        json.BeginString();

-                        json.ContinueString_Pointer(pUserData);

-                        json.EndString();

-                    }

-                }

-

+                const VmaAllocation hAlloc = (*pDedicatedAllocVector)[i];

+                hAlloc->PrintParameters(json);

                 json.EndObject();

             }

 

@@ -8518,50 +12346,29 @@
         }

     }

 

+    // Custom pools

     {

         VmaMutexLock lock(m_PoolsMutex, m_UseMutex);

         const size_t poolCount = m_Pools.size();

         if(poolCount > 0)

         {

             json.WriteString("Pools");

-            json.BeginArray();

+            json.BeginObject();

             for(size_t poolIndex = 0; poolIndex < poolCount; ++poolIndex)

             {

+                json.BeginString();

+                json.ContinueString(m_Pools[poolIndex]->GetId());

+                json.EndString();

+

                 m_Pools[poolIndex]->m_BlockVector.PrintDetailedMap(json);

             }

-            json.EndArray();

+            json.EndObject();

         }

     }

 }

 

 #endif // #if VMA_STATS_STRING_ENABLED

 

-static VkResult AllocateMemoryForImage(

-    VmaAllocator allocator,

-    VkImage image,

-    const VmaAllocationCreateInfo* pAllocationCreateInfo,

-    VmaSuballocationType suballocType,

-    VmaAllocation* pAllocation)

-{

-    VMA_ASSERT(allocator && (image != VK_NULL_HANDLE) && pAllocationCreateInfo && pAllocation);

-    

-    VkMemoryRequirements vkMemReq = {};

-    bool requiresDedicatedAllocation = false;

-    bool prefersDedicatedAllocation  = false;

-    allocator->GetImageMemoryRequirements(image, vkMemReq,

-        requiresDedicatedAllocation, prefersDedicatedAllocation);

-

-    return allocator->AllocateMemory(

-        vkMemReq,

-        requiresDedicatedAllocation,

-        prefersDedicatedAllocation,

-        VK_NULL_HANDLE, // dedicatedBuffer

-        image, // dedicatedImage

-        *pAllocationCreateInfo,

-        suballocType,

-        pAllocation);

-}

-

 ////////////////////////////////////////////////////////////////////////////////

 // Public interface

 

@@ -8572,7 +12379,7 @@
     VMA_ASSERT(pCreateInfo && pAllocator);

     VMA_DEBUG_LOG("vmaCreateAllocator");

     *pAllocator = vma_new(pCreateInfo->pAllocationCallbacks, VmaAllocator_T)(pCreateInfo);

-    return VK_SUCCESS;

+    return (*pAllocator)->Init(pCreateInfo);

 }

 

 void vmaDestroyAllocator(

@@ -8778,20 +12585,32 @@
     uint32_t requiredFlags = pAllocationCreateInfo->requiredFlags;

     uint32_t preferredFlags = pAllocationCreateInfo->preferredFlags;

 

+    const bool mapped = (pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0;

+    if(mapped)

+    {

+        preferredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

+    }

+

     // Convert usage to requiredFlags and preferredFlags.

     switch(pAllocationCreateInfo->usage)

     {

     case VMA_MEMORY_USAGE_UNKNOWN:

         break;

     case VMA_MEMORY_USAGE_GPU_ONLY:

-        preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;

+        if(!allocator->IsIntegratedGpu() || (preferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)

+        {

+            preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;

+        }

         break;

     case VMA_MEMORY_USAGE_CPU_ONLY:

         requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;

         break;

     case VMA_MEMORY_USAGE_CPU_TO_GPU:

         requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

-        preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;

+        if(!allocator->IsIntegratedGpu() || (preferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)

+        {

+            preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;

+        }

         break;

     case VMA_MEMORY_USAGE_GPU_TO_CPU:

         requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

@@ -8905,12 +12724,21 @@
 	VmaPool* pPool)

 {

     VMA_ASSERT(allocator && pCreateInfo && pPool);

-

+    

     VMA_DEBUG_LOG("vmaCreatePool");

-

+    

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

-

-    return allocator->CreatePool(pCreateInfo, pPool);

+    

+    VkResult res = allocator->CreatePool(pCreateInfo, pPool);

+    

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordCreatePool(allocator->GetCurrentFrameIndex(), *pCreateInfo, *pPool);

+    }

+#endif

+    

+    return res;

 }

 

 void vmaDestroyPool(

@@ -8918,15 +12746,22 @@
     VmaPool pool)

 {

     VMA_ASSERT(allocator);

-

+    

     if(pool == VK_NULL_HANDLE)

     {

         return;

     }

-

+    

     VMA_DEBUG_LOG("vmaDestroyPool");

-

+    

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

+    

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordDestroyPool(allocator->GetCurrentFrameIndex(), pool);

+    }

+#endif

 

     allocator->DestroyPool(pool);

 }

@@ -8952,9 +12787,27 @@
 

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordMakePoolAllocationsLost(allocator->GetCurrentFrameIndex(), pool);

+    }

+#endif

+

     allocator->MakePoolAllocationsLost(pool, pLostAllocationCount);

 }

 

+VkResult vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool)

+{

+    VMA_ASSERT(allocator && pool);

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    VMA_DEBUG_LOG("vmaCheckPoolCorruption");

+

+    return allocator->CheckPoolCorruption(pool);

+}

+

 VkResult vmaAllocateMemory(

     VmaAllocator allocator,

     const VkMemoryRequirements* pVkMemoryRequirements,

@@ -8978,7 +12831,18 @@
         VMA_SUBALLOCATION_TYPE_UNKNOWN,

         pAllocation);

 

-    if(pAllocationInfo && result == VK_SUCCESS)

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordAllocateMemory(

+            allocator->GetCurrentFrameIndex(),

+            *pVkMemoryRequirements,

+            *pCreateInfo,

+            *pAllocation);

+    }

+#endif

+        

+    if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS)

     {

         allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);

     }

@@ -9016,6 +12880,19 @@
         VMA_SUBALLOCATION_TYPE_BUFFER,

         pAllocation);

 

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordAllocateMemoryForBuffer(

+            allocator->GetCurrentFrameIndex(),

+            vkMemReq,

+            requiresDedicatedAllocation,

+            prefersDedicatedAllocation,

+            *pCreateInfo,

+            *pAllocation);

+    }

+#endif

+

     if(pAllocationInfo && result == VK_SUCCESS)

     {

         allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);

@@ -9037,13 +12914,35 @@
 

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

-    VkResult result = AllocateMemoryForImage(

-        allocator,

-        image,

-        pCreateInfo,

+    VkMemoryRequirements vkMemReq = {};

+    bool requiresDedicatedAllocation = false;

+    bool prefersDedicatedAllocation  = false;

+    allocator->GetImageMemoryRequirements(image, vkMemReq,

+        requiresDedicatedAllocation, prefersDedicatedAllocation);

+

+    VkResult result = allocator->AllocateMemory(

+        vkMemReq,

+        requiresDedicatedAllocation,

+        prefersDedicatedAllocation,

+        VK_NULL_HANDLE, // dedicatedBuffer

+        image, // dedicatedImage

+        *pCreateInfo,

         VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,

         pAllocation);

 

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordAllocateMemoryForImage(

+            allocator->GetCurrentFrameIndex(),

+            vkMemReq,

+            requiresDedicatedAllocation,

+            prefersDedicatedAllocation,

+            *pCreateInfo,

+            *pAllocation);

+    }

+#endif

+

     if(pAllocationInfo && result == VK_SUCCESS)

     {

         allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);

@@ -9056,12 +12955,26 @@
     VmaAllocator allocator,

     VmaAllocation allocation)

 {

-    VMA_ASSERT(allocator && allocation);

-

+    VMA_ASSERT(allocator);

+    

+    if(allocation == VK_NULL_HANDLE)

+    {

+        return;

+    }

+    

     VMA_DEBUG_LOG("vmaFreeMemory");

-

+    

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordFreeMemory(

+            allocator->GetCurrentFrameIndex(),

+            allocation);

+    }

+#endif

+    

     allocator->FreeMemory(allocation);

 }

 

@@ -9074,6 +12987,15 @@
 

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordGetAllocationInfo(

+            allocator->GetCurrentFrameIndex(),

+            allocation);

+    }

+#endif

+

     allocator->GetAllocationInfo(allocation, pAllocationInfo);

 }

 

@@ -9085,6 +13007,15 @@
 

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordTouchAllocation(

+            allocator->GetCurrentFrameIndex(),

+            allocation);

+    }

+#endif

+

     return allocator->TouchAllocation(allocation);

 }

 

@@ -9098,6 +13029,16 @@
     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

     allocation->SetUserData(allocator, pUserData);

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordSetAllocationUserData(

+            allocator->GetCurrentFrameIndex(),

+            allocation,

+            pUserData);

+    }

+#endif

 }

 

 void vmaCreateLostAllocation(

@@ -9109,6 +13050,15 @@
     VMA_DEBUG_GLOBAL_MUTEX_LOCK;

 

     allocator->CreateLostAllocation(pAllocation);

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordCreateLostAllocation(

+            allocator->GetCurrentFrameIndex(),

+            *pAllocation);

+    }

+#endif

 }

 

 VkResult vmaMapMemory(

@@ -9120,7 +13070,18 @@
 

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

-    return allocator->Map(allocation, ppData);

+    VkResult res = allocator->Map(allocation, ppData);

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordMapMemory(

+            allocator->GetCurrentFrameIndex(),

+            allocation);

+    }

+#endif

+

+    return res;

 }

 

 void vmaUnmapMemory(

@@ -9131,9 +13092,69 @@
 

     VMA_DEBUG_GLOBAL_MUTEX_LOCK

 

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordUnmapMemory(

+            allocator->GetCurrentFrameIndex(),

+            allocation);

+    }

+#endif

+

     allocator->Unmap(allocation);

 }

 

+void vmaFlushAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size)

+{

+    VMA_ASSERT(allocator && allocation);

+

+    VMA_DEBUG_LOG("vmaFlushAllocation");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_FLUSH);

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordFlushAllocation(

+            allocator->GetCurrentFrameIndex(),

+            allocation, offset, size);

+    }

+#endif

+}

+

+void vmaInvalidateAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size)

+{

+    VMA_ASSERT(allocator && allocation);

+

+    VMA_DEBUG_LOG("vmaInvalidateAllocation");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_INVALIDATE);

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordInvalidateAllocation(

+            allocator->GetCurrentFrameIndex(),

+            allocation, offset, size);

+    }

+#endif

+}

+

+VkResult vmaCheckCorruption(VmaAllocator allocator, uint32_t memoryTypeBits)

+{

+    VMA_ASSERT(allocator);

+

+    VMA_DEBUG_LOG("vmaCheckCorruption");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    return allocator->CheckCorruption(memoryTypeBits);

+}

+

 VkResult vmaDefragment(

     VmaAllocator allocator,

     VmaAllocation* pAllocations,

@@ -9211,8 +13232,8 @@
         allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq,

             requiresDedicatedAllocation, prefersDedicatedAllocation);

 

-         // Make sure alignment requirements for specific buffer usages reported

-         // in Physical Device Properties are included in alignment reported by memory requirements.

+        // Make sure alignment requirements for specific buffer usages reported

+        // in Physical Device Properties are included in alignment reported by memory requirements.

         if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) != 0)

         {

            VMA_ASSERT(vkMemReq.alignment %

@@ -9239,6 +13260,18 @@
             *pAllocationCreateInfo,

             VMA_SUBALLOCATION_TYPE_BUFFER,

             pAllocation);

+

+#if VMA_RECORDING_ENABLED

+        if(allocator->GetRecorder() != VMA_NULL)

+        {

+            allocator->GetRecorder()->RecordCreateBuffer(

+                allocator->GetCurrentFrameIndex(),

+                *pBufferCreateInfo,

+                *pAllocationCreateInfo,

+                *pAllocation);

+        }

+#endif

+

         if(res >= 0)

         {

             // 3. Bind buffer with memory.

@@ -9246,10 +13279,14 @@
             if(res >= 0)

             {

                 // All steps succeeded.

+                #if VMA_STATS_STRING_ENABLED

+                    (*pAllocation)->InitBufferImageUsage(pBufferCreateInfo->usage);

+                #endif

                 if(pAllocationInfo != VMA_NULL)

                 {

                     allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);

                 }

+

                 return VK_SUCCESS;

             }

             allocator->FreeMemory(*pAllocation);

@@ -9270,16 +13307,33 @@
     VkBuffer buffer,

     VmaAllocation allocation)

 {

+    VMA_ASSERT(allocator);

+

+    if(buffer == VK_NULL_HANDLE && allocation == VK_NULL_HANDLE)

+    {

+        return;

+    }

+

+    VMA_DEBUG_LOG("vmaDestroyBuffer");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordDestroyBuffer(

+            allocator->GetCurrentFrameIndex(),

+            allocation);

+    }

+#endif

+

     if(buffer != VK_NULL_HANDLE)

     {

-        VMA_ASSERT(allocator);

-

-        VMA_DEBUG_LOG("vmaDestroyBuffer");

-

-        VMA_DEBUG_GLOBAL_MUTEX_LOCK

-

         (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, buffer, allocator->GetAllocationCallbacks());

-        

+    }

+

+    if(allocation != VK_NULL_HANDLE)

+    {

         allocator->FreeMemory(allocation);

     }

 }

@@ -9314,7 +13368,33 @@
             VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR;

         

         // 2. Allocate memory using allocator.

-        res = AllocateMemoryForImage(allocator, *pImage, pAllocationCreateInfo, suballocType, pAllocation);

+        VkMemoryRequirements vkMemReq = {};

+        bool requiresDedicatedAllocation = false;

+        bool prefersDedicatedAllocation  = false;

+        allocator->GetImageMemoryRequirements(*pImage, vkMemReq,

+            requiresDedicatedAllocation, prefersDedicatedAllocation);

+

+        res = allocator->AllocateMemory(

+            vkMemReq,

+            requiresDedicatedAllocation,

+            prefersDedicatedAllocation,

+            VK_NULL_HANDLE, // dedicatedBuffer

+            *pImage, // dedicatedImage

+            *pAllocationCreateInfo,

+            suballocType,

+            pAllocation);

+

+#if VMA_RECORDING_ENABLED

+        if(allocator->GetRecorder() != VMA_NULL)

+        {

+            allocator->GetRecorder()->RecordCreateImage(

+                allocator->GetCurrentFrameIndex(),

+                *pImageCreateInfo,

+                *pAllocationCreateInfo,

+                *pAllocation);

+        }

+#endif

+

         if(res >= 0)

         {

             // 3. Bind image with memory.

@@ -9322,10 +13402,14 @@
             if(res >= 0)

             {

                 // All steps succeeded.

+                #if VMA_STATS_STRING_ENABLED

+                    (*pAllocation)->InitBufferImageUsage(pImageCreateInfo->usage);

+                #endif

                 if(pAllocationInfo != VMA_NULL)

                 {

                     allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);

                 }

+

                 return VK_SUCCESS;

             }

             allocator->FreeMemory(*pAllocation);

@@ -9346,16 +13430,32 @@
     VkImage image,

     VmaAllocation allocation)

 {

+    VMA_ASSERT(allocator);

+

+    if(image == VK_NULL_HANDLE && allocation == VK_NULL_HANDLE)

+    {

+        return;

+    }

+

+    VMA_DEBUG_LOG("vmaDestroyImage");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordDestroyImage(

+            allocator->GetCurrentFrameIndex(),

+            allocation);

+    }

+#endif

+

     if(image != VK_NULL_HANDLE)

     {

-        VMA_ASSERT(allocator);

-

-        VMA_DEBUG_LOG("vmaDestroyImage");

-

-        VMA_DEBUG_GLOBAL_MUTEX_LOCK

-

         (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, image, allocator->GetAllocationCallbacks());

-

+    }

+    if(allocation != VK_NULL_HANDLE)

+    {

         allocator->FreeMemory(allocation);

     }

 }

diff --git a/third_party/mathfu-1.1.0/.gitignore b/third_party/mathfu-1.1.0/.gitignore
deleted file mode 100644
index 0b01b9c..0000000
--- a/third_party/mathfu-1.1.0/.gitignore
+++ /dev/null
@@ -1,37 +0,0 @@
-**/bin/**
-**/libs/**
-**/obj/**
-*.pyc
-apks/**
-docs/html/
-docs/linklint_results/
-CMakeCache.txt
-CMakeFiles
-CMakeScripts/
-Makefile
-MathFu.build/
-MathFu.xcodeproj/
-benchmarks/CMakeFiles
-benchmarks/Debug/
-benchmarks/Makefile
-benchmarks/MathFu.build/
-benchmarks/Release/
-benchmarks/cmake_install.cmake
-benchmarks/matrix_*benchmarks
-benchmarks/vector_*benchmarks
-unit_tests/CMakeFiles/
-unit_tests/Debug/
-unit_tests/Makefile
-unit_tests/MathFu.build/
-unit_tests/Release/
-unit_tests/cmake_install.cmake
-unit_tests/matrix_*tests
-unit_tests/quaternion_*tests
-unit_tests/vector_*tests
-build.xml
-cmake_install.cmake
-googletest/
-local.properties
-proguard-project.txt
-project.properties
-.DS_Store
diff --git a/third_party/mathfu-1.1.0/.gitmodules b/third_party/mathfu-1.1.0/.gitmodules
deleted file mode 100644
index 986d17b..0000000
--- a/third_party/mathfu-1.1.0/.gitmodules
+++ /dev/null
@@ -1,9 +0,0 @@
-[submodule "dependencies/fplutil"]
-	path = dependencies/fplutil
-	url = http://github.com/google/fplutil.git
-[submodule "dependencies/vectorial"]
-	path = dependencies/vectorial
-	url = http://github.com/scoopr/vectorial.git
-[submodule "dependencies/googletest"]
-	path = dependencies/googletest
-	url = http://github.com/google/googletest.git
diff --git a/third_party/mathfu-1.1.0/AndroidManifest.xml b/third_party/mathfu-1.1.0/AndroidManifest.xml
deleted file mode 100644
index 54c5340..0000000
--- a/third_party/mathfu-1.1.0/AndroidManifest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- Empty Manifest so the NDK build process can find the project
-     directory. -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu"
-          android:versionCode="1"
-          android:versionName="1.0">
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- Empty application since this project just builds the mathfu
-         libraries -->
-    <application android:label="mathfu" android:enabled="false"
-                 android:hasCode="false">
-        <activity android:name="android.app.NativeActivity">
-            <meta-data android:name="android.app.lib_name"
-                       android:value="mathfu" />
-        </activity>
-    </application>
-</manifest>
diff --git a/third_party/mathfu-1.1.0/CMakeLists.txt b/third_party/mathfu-1.1.0/CMakeLists.txt
deleted file mode 100644
index 04a29f1..0000000
--- a/third_party/mathfu-1.1.0/CMakeLists.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-cmake_minimum_required(VERSION 2.8.12)
-
-set(PROJECT_NAME MathFu)
-project(MathFu)
-
-# Call fplutil to get locations of dependencies and set common build settings.
-include("cmake/find_fplutil.cmake")
-include("${fplutil_dir}/buildutil/cmake_common.txt")
-set_common_build_variables()
-
-# Options that control the build configuration.
-# To configure MathFu flags per build target, see the
-# mathfu_configure_flags() function.
-option(mathfu_enable_simd "Use SIMD implementations when available." ON)
-option(mathfu_build_benchmarks "Build MathFu benchmarks." ON)
-option(mathfu_build_tests "Build MathFu unit tests." ON)
-
-# Save the mathfu directory, store this in the cache so that it's globally
-# accessible from mathfu_configure_flags().
-set(mathfu_dir ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "mathfu directory")
-
-# Set build options for ${target} that are required to build with MathFu.
-# This takes the optional arguments "enable_simd force_padding".
-#
-# If enable_simd is specified it configures whether the project should be
-# built with SIMD optimized functions.  If force_padding is specified and
-# SIMD is enabled, some data structures are padded to work more efficiently
-# with SIMD instructions.
-#
-# If enable_simd is not specified, the mathfu_enable_simd option is used.
-# If force_padding isn't specified padding is enabled based upon the
-# best general configuration for the target architecture.
-function(mathfu_configure_flags target)
-  if(fpl_ios)
-    set(enable_simd NO)
-  else()
-    set(enable_simd ${mathfu_enable_simd})
-  endif()
-
-  # Add required includes to the target.
-  target_include_directories(${target}
-    PRIVATE ${mathfu_dir}/include ${dependencies_vectorial_dir}/include)
-
-  # Parse optional arguments.
-  set(additional_args ${ARGN})
-  list(LENGTH additional_args num_additional_args)
-  if(${num_additional_args} GREATER 0)
-    list(GET additional_args 0 enable_simd)
-  endif()
-  if(${num_additional_args} GREATER 1)
-    list(GET additional_args 1 force_padding)
-  endif()
-
-  # If the SIMD build option is enabled.
-  if(enable_simd)
-    # Enable SSE4.1 when building with GCC / Clang.
-    # NOTE: It's also possible to build the library using using SSE2 with GCC /
-    # Clang, change -msse4.1 to -msse2.
-    if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR
-        CMAKE_COMPILER_IS_CLANGXX)
-      target_compile_options(${target} PRIVATE -msse4.1)
-    endif()
-    # Enable SSE2 by default when building with MSVC for 32-bit targets.
-    # Note that SSE2 is enabled by default for 64-bit targets, and the
-    # compile option will generate an "unknown option" warning.
-    if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 4)
-      target_compile_options(${target} PRIVATE /arch:SSE2)
-    endif()
-    # Conditionally enable padding.
-    if(DEFINED force_padding)
-      if(force_padding)
-        target_compile_definitions(${target} PRIVATE
-          -DMATHFU_COMPILE_FORCE_PADDING=1)
-      else()
-        target_compile_definitions(${target} PRIVATE
-          -DMATHFU_COMPILE_FORCE_PADDING=0)
-      endif()
-    endif()
-  else()
-    target_compile_definitions(${target} PRIVATE
-      -DMATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
-  endif()
-endfunction()
-
-# Modify CMAKE_C_FLAGS and CMAKE_CXX_FLAGS to enable a maximum reasonable
-# warning level.
-function(mathfu_enable_warnings target)
-  get_target_property(target_compile_flags ${target} COMPILE_FLAGS)
-  if(MSVC)
-    # C4127: conditional expression is constant
-    # C4577: 'noexcept' used with no exception handling mode specified.
-    target_compile_options(${target} PRIVATE /W4 /WX /wd4127 /wd4577)
-  elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR
-      CMAKE_COMPILER_IS_CLANGXX)
-    # Set the maximum warning level for gcc.
-    target_compile_options(${target} PRIVATE -Wall -Wextra -Werror
-      -Wno-long-long -Wno-variadic-macros)
-  endif()
-endfunction()
-
-# Macro defined here so that it can be used by all projects included
-macro(mathfu_set_ios_attributes project)
-  if(fpl_ios)
-    set_target_properties(${project} PROPERTIES
-      XCODE_ATTRIBUTE_SDKROOT "iphoneos")
-    set_target_properties(${project} PROPERTIES
-      XCODE_ATTRIBUTE_ARCHS "$(ARCHS_STANDARD)")
-    set_target_properties(${project} PROPERTIES
-      XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO")
-    set_target_properties(${project} PROPERTIES
-      XCODE_ATTRIBUTE_VALID_ARCHS "$(ARCHS_STANDARD)")
-    set_target_properties(${project} PROPERTIES
-      XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "8.0")
-  endif()
-endmacro(mathfu_set_ios_attributes)
-
-file(GLOB_RECURSE MATHFU_HEADERS ${CMAKE_CURRENT_LIST_DIR}/include/mathfu *.h)
-
-if(mathfu_build_benchmarks)
-  add_subdirectory(benchmarks)
-endif()
-if(mathfu_build_tests)
-  add_subdirectory(unit_tests)
-endif()
diff --git a/third_party/mathfu-1.1.0/CONTRIBUTING b/third_party/mathfu-1.1.0/CONTRIBUTING
deleted file mode 100644
index aebd885..0000000
--- a/third_party/mathfu-1.1.0/CONTRIBUTING
+++ /dev/null
@@ -1,28 +0,0 @@
-Contributing    {#contributing}
-============
-
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-# Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-# Code reviews
-All submissions, including submissions by project members, require review. We
-use Github pull requests for this purpose.
-
-# The small print
-Contributions made by corporations are covered by a different agreement than
-the one above, the Software Grant and Corporate Contributor License Agreement.
diff --git a/third_party/mathfu-1.1.0/LICENSE b/third_party/mathfu-1.1.0/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/third_party/mathfu-1.1.0/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/third_party/mathfu-1.1.0/android_config.mk b/third_party/mathfu-1.1.0/android_config.mk
deleted file mode 100644
index d4a25df..0000000
--- a/third_party/mathfu-1.1.0/android_config.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-FIND_FPLUTIL_OK_IF_NOT_FOUND:=1
-include $(call my-dir)/jni/find_fplutil.mk
-
-ifneq ($(FPLUTIL_DIR),)
-  # If fplutil is found, grab the project locations from it.
-  include $(FPLUTIL_DIR)/buildutil/android_common.mk
-
-else
-  # If fplutil is not found, assume project locations are in 'dependencies'
-  # or are set externally with the DEPENDENCIES_ROOT value.
-  #
-  # If the dependencies directory exists either as a subdirectory or as the
-  # container of this project directory, assume the dependencies directory is
-  # the root directory for all libraries required by this project.
-  $(foreach dep_dir,$(wildcard $(MATHFU_DIR)/dependencies) \
-                    $(wildcard $(MATHFU_DIR)/../../dependencies),\
-    $(eval DEPENDENCIES_ROOT?=$(dep_dir)))
-
-  ifeq ($(DEPENDENCIES_ROOT),)
-    $(error "Cannot find directory with dependent projects.")
-  endif
-
-  # Location of the vectorial library.
-  DEPENDENCIES_VECTORIAL_DIR?=$(DEPENDENCIES_ROOT)/vectorial
-  # Location of the googletest library.
-  DEPENDENCIES_GTEST_DIR?=$(DEPENDENCIES_ROOT)/fplutil/libfplutil/jni/libs/googletest
-  # Location of the fplutil library.
-  DEPENDENCIES_FPLUTIL_DIR?=$(DEPENDENCIES_ROOT)/fplutil
-endif
-
-# Whether to disable SIMD.
-MATHFU_DISABLE_SIMD?=0
-# Whether to force padding of data structures with SIMD enabled.
-# -1 = default, 0 = no padding, 1 = padding
-MATHFU_FORCE_PADDING?=-1
diff --git a/third_party/mathfu-1.1.0/benchmarks/CMakeLists.txt b/third_party/mathfu-1.1.0/benchmarks/CMakeLists.txt
deleted file mode 100644
index 859e35d..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/CMakeLists.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-cmake_minimum_required(VERSION 2.8)
-
-# Generate a rule to build a performance test executable
-# ${benchmark_executable_name} from ${benchmark_source}.  For details of
-# additional arguments, see mathfu_configure_flags().
-function(benchmark_executable benchmark_executable_name benchmark_source)
-  add_executable(${benchmark_executable_name} ${benchmark_source})
-  mathfu_configure_flags(${benchmark_executable_name} ${ARGN})
-  mathfu_enable_warnings(${benchmark_executable_name})
-  target_include_directories(${benchmark_executable_name}
-    PRIVATE ${CMAKE_CURRENT_LIST_DIR})
-  if(UNIX AND NOT APPLE)
-    target_link_libraries(${benchmark_executable_name} rt)
-  endif(UNIX AND NOT APPLE)
-endfunction()
-
-# Generates a rule to build performance test executables.  This only builds
-# ${benchmark_name}_benchmarks if SIMD is disabled (see ${mathfu_enable_simd})
-# or ${benchmark_name}_benchmarks and ${benchmark_name}_no_simd_benchmarks if
-# SIMD is enabled where the no_simd_benchmarks binary has SIMD disabled.
-function(benchmark_executables benchmark_name benchmark_source)
-  # Default build options.
-  benchmark_executable(${benchmark_name}_benchmarks ${benchmark_source})
-  if(mathfu_enable_simd)
-    # NOTE: A build configuration below will deliberately duplicate the
-    # default build configuration, since these configs could result in
-    # different compile time preprocessor code paths.
-    # SIMD enabled, padding enabled.
-    benchmark_executable(${benchmark_name}_simd_padding_benchmarks
-      ${benchmark_source} TRUE TRUE)
-    # SIMD enabled, padding disabled.
-    benchmark_executable(${benchmark_name}_simd_no_padding_benchmarks
-      ${benchmark_source} TRUE FALSE)
-    # SIMD disabled, padding disabled.
-    benchmark_executable(${benchmark_name}_no_simd_benchmarks
-      ${benchmark_source} FALSE FALSE)
-  endif()
-endfunction()
-
-benchmark_executables(matrix matrix_benchmark/main.cpp)
-benchmark_executables(vector vector_benchmark/main.cpp)
diff --git a/third_party/mathfu-1.1.0/benchmarks/android_common.mk b/third_party/mathfu-1.1.0/benchmarks/android_common.mk
deleted file mode 100644
index 60983a8..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/android_common.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(CLEAR_VARS)
-
-# Configure the locations of MathFu's dependencies.
-MATHFU_DIR:=$(LOCAL_PATH)/../..
-MATHFU_DIR_BASENAME:=$(notdir $(abspath $(MATHFU_DIR)))
-include $(MATHFU_DIR)/android_config.mk
-
-namespace:=$(if $(NDK_PROJECT_PATH),,_mathfu)
-LOCAL_MODULE:=$(LOCAL_BENCHMARK_NAME)${namespace}
-LOCAL_MODULE_TAGS:=optional
-LOCAL_SRC_FILES:= main.cpp
-LOCAL_C_INCLUDES:=$(MATHFU_DIR)/benchmarks
-LOCAL_LDLIBS:=-llog -landroid
-LOCAL_WHOLE_STATIC_LIBRARIES:=\
-	libfplutil_main \
-	libfplutil_print
-# MATHFU_LIB (by default libmathfu) is used to select the build configuration
-# for the target using mathfu.
-LOCAL_STATIC_LIBRARIES:=\
-	android_native_app_glue \
-	libgtest \
-	$(MATHFU_LIB)
-LOCAL_CFLAGS:=-Wall -Werror
-LOCAL_ARM_MODE:=arm
-include $(BUILD_SHARED_LIBRARY)
-
-$(call import-add-path,$(abspath $(MATHFU_DIR)/..))
-$(call import-add-path,$(abspath $(DEPENDENCIES_FPLUTIL_DIR)))
-
-$(call import-module,$(MATHFU_DIR_BASENAME)/jni)
-$(call import-module,libfplutil/jni)
-$(call import-module,android/native_app_glue)
-
-LOCAL_BENCHMARK_NAME:=
-MATHFU_DIR:=
diff --git a/third_party/mathfu-1.1.0/benchmarks/application_common.mk b/third_party/mathfu-1.1.0/benchmarks/application_common.mk
deleted file mode 100644
index e0be21e..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/application_common.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-APP_PLATFORM:=android-10
-APP_ABI:=armeabi-v7a
-APP_STL:=c++_static
-
diff --git a/third_party/mathfu-1.1.0/benchmarks/benchmark_common.h b/third_party/mathfu-1.1.0/benchmarks/benchmark_common.h
deleted file mode 100644
index bb6dd80..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/benchmark_common.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_BENCHMARKS_BENCHMARKCOMMON_H_
-#define MATHFU_BENCHMARKS_BENCHMARKCOMMON_H_
-
-#if defined(_WIN32)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#else
-#include <sys/time.h>
-#include <time.h>
-#endif  // defined(_WIN32)
-
-// This macro stands in for a double loop over a vector with size elements.
-// This double loop is repeated iterations times to create more accurate
-// performance test.
-#define PERFTEST_2D_VECTOR_LOOP(iterations, size) \
-  for (unsigned int k = 0; k < iterations; k++) \
-  for (unsigned int i = 0; i < size; i++) \
-  for (unsigned int j = 0; j < size; j++)
-
-// High resolution timer.
-class Timer {
- public:
-  Timer() {
-    InitializeTickPeriod();
-    Reset();
-  }
-
-  // Save the current number of counter ticks.
-  void Reset() {
-    start_ = GetTicks();
-  }
-
-  // Get the time elapsed in counter ticks since Reset() was called.
-  unsigned long long GetElapsedTicks() {
-    return GetTicks() - start_;
-  }
-
-  // Get the time elapsed in seconds since Reset() was called.
-  double GetElapsedSeconds() {
-    return static_cast<double>(GetElapsedTicks()) * tick_period();
-  }
-
- public:
-  // Initialize the tick period value.
-  static void InitializeTickPeriod() {
-    if (tick_period_ != 0) {
-      return;
-    }
-#if defined(_WIN32)
-    LARGE_INTEGER frequency;
-    QueryPerformanceFrequency(&frequency);
-    tick_period_ = 1.0 / static_cast<double>(frequency.QuadPart);
-#elif defined(__linux__)
-    // Use a fixed frequency of 1ns to match timespec.
-    tick_period_ = 1e-9;
-#else
-    // Use a fixed frequency of 1us to match timeval.
-    tick_period_ = 1e-6;
-#endif // defined(_WIN32)
-  }
-
-  // Get the period of one counter tick.
-  static double tick_period() {
-    return tick_period_;
-  }
-
-  // Get the number of counter ticks elapsed.
-  static unsigned long long GetTicks() {
-#if defined(_WIN32)
-    LARGE_INTEGER ticks;
-    QueryPerformanceCounter(&ticks);
-    return ticks.QuadPart;
-#elif defined(__linux__)
-    struct timespec time;
-    clock_gettime(CLOCK_MONOTONIC, &time);
-    return (static_cast<unsigned long long>(time.tv_sec) * 1000000000ULL) +
-        time.tv_nsec;
-#else
-    struct timeval time;
-    gettimeofday(&time, NULL);
-    return (static_cast<unsigned long long>(time.tv_sec) * 1000000ULL) +
-        time.tv_usec;
-#endif
-  }
-
- private:
-  unsigned long long start_;
-  static double tick_period_;
-};
-double Timer::tick_period_ = 0;
-
-#endif  // MATHFU_BENCHMARKS_BENCHMARKCOMMON_H_
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/AndroidManifest.xml
deleted file mode 100644
index 64602c5..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/jni/Android.mk
deleted file mode 100644
index 538820c..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=matrix_benchmark
-MATHFU_LIB:=libmathfu
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/jni/Application.mk
deleted file mode 100644
index 5dfc700..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/res/values/strings.xml
deleted file mode 100644
index efd0618..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/default/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/main.cpp b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/main.cpp
deleted file mode 100644
index 5f8e834..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/main.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "mathfu/matrix_4x4.h"
-#include "mathfu/utilities.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "benchmark_common.h"
-
-// Number of elements to iterate over
-static const size_t kMatrixSize = 1000;
-// Number of iterations of each operation.
-static const size_t kIterations = 50;
-
-using mathfu::Matrix;
-using mathfu::Random;
-
-#define MATRIX_DIMENSIONS 4
-
-typedef float T;
-
-typedef Matrix<T, MATRIX_DIMENSIONS> TestMatrix;
-
-// This test creates a number of matrices and performs some mathematical
-// operations on them in order to measure expected performance of matrix
-// operations.
-int main(int argc, char** argv) {
-  (void)argc;
-  (void)argv;
-  // Create an array of matrices containing random values.
-  TestMatrix * const matrices = new TestMatrix[kMatrixSize];
-  TestMatrix mul = TestMatrix::Identity();
-  for (size_t i = 0; i < kMatrixSize; ++i) {
-    TestMatrix mat;
-    for (size_t j = 0; j < MATRIX_DIMENSIONS; ++j) {
-      mat[static_cast<int>(j)] = Random<T>();
-    }
-    matrices[i] = mat;
-  }
-  // Start matrix benchmark, running a number of loops for more accurate
-  // numbers.
-  printf("Running matrix benchmark (%s)...\n", MATHFU_BUILD_OPTIONS_STRING);
-  Timer timer;
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) mul += matrices[j];
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) mul *= matrices[j];
-
-#if MATRIX_DIMENSIONS == 4
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) {
-    mathfu::Vector<T, MATRIX_DIMENSIONS> tmp =
-      matrices[j] * mathfu::Vector<T, MATRIX_DIMENSIONS>(
-          matrices[i](0, 0), matrices[i](1, 0),
-          matrices[i](2, 0), matrices[i](3, 0));
-    mul -= TestMatrix::OuterProduct(tmp, tmp);
-  }
-#endif  // MATRIX_DIMENSIONS == 4
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) {
-    mul += matrices[j] * Random<T>();
-  }
-  // End matrix performance code
-  double elapsed = timer.GetElapsedSeconds();
-  printf("Took %f seconds\n", elapsed);
-  delete [] matrices;
-  return 0;
-}
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/AndroidManifest.xml
deleted file mode 100644
index 9cf426c..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_no_simd_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_no_simd_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/jni/Android.mk
deleted file mode 100644
index 05e9251..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=matrix_no_simd_benchmark
-MATHFU_LIB:=libmathfu_no_simd
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/jni/Application.mk
deleted file mode 100644
index f8057f5..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_no_simd_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/res/values/strings.xml
deleted file mode 100644
index acf9caf..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/no_simd/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_no_simd_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/AndroidManifest.xml
deleted file mode 100644
index 6447fd2..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_simd_no_padding_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_simd_no_padding_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/jni/Android.mk
deleted file mode 100644
index 0faba83..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=matrix_simd_no_padding_benchmark
-MATHFU_LIB:=libmathfu_simd_no_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/jni/Application.mk
deleted file mode 100644
index 3b4fcc1..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_simd_no_padding_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/res/values/strings.xml
deleted file mode 100644
index 91e06cf..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_no_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_simd_no_padding_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/AndroidManifest.xml
deleted file mode 100644
index 0c15634..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_simd_padding_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_simd_padding_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/jni/Android.mk
deleted file mode 100644
index fe47935..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=matrix_simd_padding_benchmark
-MATHFU_LIB:=libmathfu_simd_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/jni/Application.mk
deleted file mode 100644
index 3f0fb8d..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_simd_padding_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/res/values/strings.xml
deleted file mode 100644
index 0ff300a..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/matrix_benchmark/simd_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_simd_padding_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/AndroidManifest.xml
deleted file mode 100644
index b1fddc4..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/jni/Android.mk
deleted file mode 100644
index 4a7bdf2..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=vector_benchmark
-MATHFU_LIB:=libmathfu
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/jni/Application.mk
deleted file mode 100644
index 4645783..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/res/values/strings.xml
deleted file mode 100644
index a256817..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/default/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/main.cpp b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/main.cpp
deleted file mode 100644
index d76dfe1..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "mathfu/vector.h"
-#include "mathfu/utilities.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "benchmark_common.h"
-
-// Number of elements to iterate over.
-static const size_t kVectorSize = 1000;
-// Number of iterations of each operation.
-static const size_t kIterations = 100;
-
-using mathfu::Random;
-using mathfu::Vector;
-
-// This test creates a number of vectors and performs some mathematical
-// operations on them in order to measure expected performance of vector
-// operations.
-int main(int argc, char** argv) {
-  typedef float T;
-  (void)argc;
-  (void)argv;
-  // Create a array of vectors
-  Vector<T, 3> *vectors = new Vector<T, 3>[kVectorSize];
-  T final_sum = 0;
-  Vector<T, 3> sum(0.0f);
-  for (size_t i = 0; i < kVectorSize; i++) {
-    Vector<T, 3> vec(Random<T>(), Random<T>(), Random<T>());
-    if (vec.LengthSquared() == static_cast<T>(0.0)) {
-      vec.x = static_cast<T>(1.0);
-    }
-    vectors[i] = vec;
-  }
-  printf("Running vector benchmark (%s)...\n", MATHFU_BUILD_OPTIONS_STRING);
-  // Start vector performance code. Run a number of loops for more accurate
-  // numbers.
-  Timer timer;
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) sum += vectors[j];
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) sum -= vectors[j];
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) sum *= 0.1f;
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
-    sum += Vector<T, 3>::CrossProduct(vectors[i], vectors[j]);
-  }
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
-    final_sum += Vector<T, 3>::DotProduct(vectors[j], vectors[i]);
-  }
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
-      final_sum -= vectors[i].Length();
-  }
-  PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
-    final_sum += vectors[i].Normalize();
-  }
-  final_sum += sum[0] + sum[1] + sum[2];
-  // End vector performance code
-  double elapsed = timer.GetElapsedSeconds();
-  printf("Took %f seconds\n", elapsed);
-  delete [] vectors;
-  return 0;
-}
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/AndroidManifest.xml
deleted file mode 100644
index e964522..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_no_simd_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_no_simd_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/jni/Android.mk
deleted file mode 100644
index 4594bad..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=vector_no_simd_benchmark
-MATHFU_LIB:=libmathfu_no_simd
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/jni/Application.mk
deleted file mode 100644
index ce2854b..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_no_simd_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/res/values/strings.xml
deleted file mode 100644
index c69945b..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/no_simd/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_no_simd_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/AndroidManifest.xml
deleted file mode 100644
index 53d34ad..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_simd_no_padding_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_simd_no_padding_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/jni/Android.mk
deleted file mode 100644
index 919eefe..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=vector_simd_no_padding_benchmark
-MATHFU_LIB:=libmathfu_simd_no_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/jni/Application.mk
deleted file mode 100644
index 1d12b74..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_simd_no_padding_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/res/values/strings.xml
deleted file mode 100644
index 4e6f706..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_no_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_simd_no_padding_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/AndroidManifest.xml
deleted file mode 100644
index a05211a..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_simd_padding_benchmark"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_simd_padding_benchmark" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/jni/Android.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/jni/Android.mk
deleted file mode 100644
index da50be3..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_BENCHMARK_NAME:=vector_simd_padding_benchmark
-MATHFU_LIB:=libmathfu_simd_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/jni/Application.mk b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/jni/Application.mk
deleted file mode 100644
index f48bb01..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_simd_padding_benchmark
diff --git a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/res/values/strings.xml
deleted file mode 100644
index aa93f49..0000000
--- a/third_party/mathfu-1.1.0/benchmarks/vector_benchmark/simd_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_simd_padding_benchmark</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/cmake/find_fplutil.cmake b/third_party/mathfu-1.1.0/cmake/find_fplutil.cmake
deleted file mode 100644
index 0653c41..0000000
--- a/third_party/mathfu-1.1.0/cmake/find_fplutil.cmake
+++ /dev/null
@@ -1,41 +0,0 @@
-# Find the fplutil directory and set it in `fplutil_dir`.
-#
-# We search some standard locations, such as
-# (1) the cached variable ${dependencies_fplutil_dir}, which can be specified
-#     on the command line,
-#         cmake -Ddependencies_fplutil_dir=your_fplutil_directory
-# (2) under ${fpl_root}, which is another cached variable that can be
-#     specified on the command line,
-#         cmake -Dfpl_root=your_fpl_root_directory
-# (3) the "dependencies" directory that gets created when cloning from GitHub,
-# (4) several levels up in the directory tree.
-#
-# Notes
-# -----
-# - fplutil is the project where we keep all our shared code, so the code in
-#   this file (which locates fplutil) can unfortunately not be shared.
-# - Since this file is duplicated in all FPL projects (except fplutil itself),
-#   please copy new versions to all FPL projects whenever you make a change.
-
-set(fplutil_dir_possibilities
-    "${dependencies_fplutil_dir}"
-    "${fpl_root}/fplutil"
-    "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/fplutil"
-    "${CMAKE_CURRENT_LIST_DIR}/../../fplutil"
-    "${CMAKE_CURRENT_LIST_DIR}/../../../fplutil"
-    "${CMAKE_CURRENT_LIST_DIR}/../../../../fplutil"
-    "${CMAKE_CURRENT_LIST_DIR}/../../../../../fplutil")
-
-foreach(dir ${fplutil_dir_possibilities})
-  if(EXISTS ${dir})
-    set(fplutil_dir ${dir})
-    return()
-  endif()
-endforeach(dir)
-
-# Define this cached variable so that cmake GUIs can expose it to the user.
-set(dependencies_fplutil_dir ""
-    CACHE PATH "Directory containing the fplutil library.")
-
-MESSAGE(ERROR
-    "Can't find fplutil directory. Try cmake -Ddependencies_fplutil_dir=your_location.")
diff --git a/third_party/mathfu-1.1.0/disttools/config.json b/third_party/mathfu-1.1.0/disttools/config.json
deleted file mode 100644
index d36d7c7..0000000
--- a/third_party/mathfu-1.1.0/disttools/config.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  "package": {
-    "name": "mathfu",
-    "url": "http://github.com/google/mathfu.git",
-    "branch": "develop",
-    "is_library": 1,
-    "third_party": 0,
-    "push": 1
-  },
-  "dependencies": [
-    {
-      "name": "googletest",
-      "url": "http://github.com/google/googletest.git",
-      "branch": "master",
-      "revision": "13206d6f53aaff844f2d3595a01ac83a29e383db",
-      "is_library": 1,
-      "third_party": 1,
-      "push": 0
-    },
-    {
-      "name": "fplutil",
-      "url": "http://github.com/google/fplutil.git",
-      "branch": "develop",
-      "is_library": 1,
-      "third_party": 0,
-      "push": 1
-    },
-    {
-      "name": "vectorial",
-      "url": "http://github.com/scoopr/vectorial.git",
-      "branch": "master",
-      "is_library": 1,
-      "third_party": 1,
-      "push": 0
-    }
-  ]
-}
diff --git a/third_party/mathfu-1.1.0/disttools/push_package.py b/third_party/mathfu-1.1.0/disttools/push_package.py
deleted file mode 100644
index c253f12..0000000
--- a/third_party/mathfu-1.1.0/disttools/push_package.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/python
-# Copyright 2014 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Push this project and its dependencies to another git repo.
-
-Uses fplutil/disttools/push_package.py to push the remote of
-this git repository and its dependencies (defined by config.json)
-to another git repository.
-"""
-
-import os
-import sys
-sys.path.extend((
-    os.path.realpath(os.path.join(
-        os.path.dirname(__file__), os.path.pardir, 'dependencies', 'fplutil')),
-    os.path.realpath(os.path.join(
-        os.path.dirname(__file__), os.path.pardir, os.path.pardir,
-        'fplutil'))))
-import disttools.push_package  # pylint: disable=g-import-not-at-top
-
-## The directory containing this file.
-THIS_DIR = os.path.realpath(os.path.dirname(__file__))
-
-## Default root directory of the project.
-PROJECT_DIR = os.path.realpath(os.path.join(THIS_DIR, os.path.pardir))
-
-## Default package configuration file.
-CONFIG_JSON = os.path.realpath(os.path.join(THIS_DIR, 'config.json'))
-
-
-def main():
-  """See fplutil/disttools/push_package.py.
-
-  Returns:
-    0 if successful, non-zero otherwise.
-  """
-  return disttools.push_package.main(disttools.push_package.parse_arguments(
-      project_dir=PROJECT_DIR, config_json=CONFIG_JSON))
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/third_party/mathfu-1.1.0/docs/generate_docs.py b/third_party/mathfu-1.1.0/docs/generate_docs.py
deleted file mode 100644
index 3340eeb..0000000
--- a/third_party/mathfu-1.1.0/docs/generate_docs.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/python
-# Copyright 2014 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Generate html documentation from markdown and doxygen comments."""
-
-import os
-import sys
-
-THIS_DIR = os.path.realpath(os.path.dirname(__file__))
-PROJECT_DIR = os.path.realpath(os.path.join(THIS_DIR, os.pardir))
-sys.path.extend(
-    [os.path.realpath(os.path.join(PROJECT_DIR, os.pardir, 'fplutil')),
-     os.path.realpath(os.path.join(PROJECT_DIR, 'dependencies', 'fplutil'))])
-import docs  # pylint: disable=C6204
-
-
-def main():
-  """Generate html documentation from markdown and doxygen comments.
-
-  Returns:
-    0 if successful, 1 otherwise.
-  """
-  sys.argv.extend(('--linklint-dir', THIS_DIR,
-                   '--source-dir', os.path.join(THIS_DIR, 'src'),
-                   '--project-dir', PROJECT_DIR))
-  return docs.generate_docs.main()
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/third_party/mathfu-1.1.0/docs/src/api_reference.md b/third_party/mathfu-1.1.0/docs/src/api_reference.md
deleted file mode 100644
index 967a9cf..0000000
--- a/third_party/mathfu-1.1.0/docs/src/api_reference.md
+++ /dev/null
@@ -1,37 +0,0 @@
-API Reference    {#mathfu_api_reference}
-=============
-
-This document describes all classes, functions, macros and files that make
-up the [MathFu][] library.  This is intended to be used as a reference for
-C++ programmers who are familiar with [geometry][], [vectors][], [matrices][],
-[quaternions][] and [linear algebra][].
-
-The API reference is broken into the following sections:
-   * [Build Configuration](@ref mathfu_build_config)
-      - Describes configuration options for [MathFu][] code generation.
-   * [Allocators](@ref mathfu_allocator)
-      - Allocators to simplify the process of memory allocation for [MathFu][]
-        data structures.
-   * [Constants](@ref mathfu_constants)
-      - Constants to use in conjunction with [MathFu][] classes.
-   * [Vectors](@ref mathfu_vector)
-      - Class and functions to manipulate [vectors][].
-   * [Matrices](@ref mathfu_matrix)
-      - Class and functions to manipulate [matrices][].
-   * [Quaternions](@ref mathfu_quaternion)
-      - Class and functions to manipulate [quaternions][].
-   * [GLSL Mappings](@ref mathfu_glsl)
-      - Mappings to GLSL data types and functions.
-   * [Utility Functions](@ref mathfu_utilities)
-      - Variety of useful functions that can be used with
-        [Vector](@ref mathfu::Vector) and [Matrix](@ref mathfu::Matrix)
-        classes.
-   * [Version Constants](@ref mathfu_version)
-      - Constants which identify the library version.
-
-   [MathFu]: @ref mathfu_overview
-   [geometry]: http://en.wikipedia.org/wiki/Geometry
-   [vectors]: http://en.wikipedia.org/wiki/Euclidean_vector
-   [matrices]: http://en.wikipedia.org/wiki/Matrix_(mathematics)
-   [quaternions]: http://en.wikipedia.org/wiki/Quaternion
-   [linear algebra]: http://en.wikipedia.org/wiki/Linear_algebra
diff --git a/third_party/mathfu-1.1.0/docs/src/contributing.md b/third_party/mathfu-1.1.0/docs/src/contributing.md
deleted file mode 100644
index 433b7d3..0000000
--- a/third_party/mathfu-1.1.0/docs/src/contributing.md
+++ /dev/null
@@ -1 +0,0 @@
-../../CONTRIBUTING
\ No newline at end of file
diff --git a/third_party/mathfu-1.1.0/docs/src/doxyfile b/third_party/mathfu-1.1.0/docs/src/doxyfile
deleted file mode 100644
index a5bd0d6..0000000
--- a/third_party/mathfu-1.1.0/docs/src/doxyfile
+++ /dev/null
@@ -1,2371 +0,0 @@
-
-# Doxyfile 1.8.5
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-# 
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-# 
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
-# for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME           = "MathFu"
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER         = 
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF          = 
-
-# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
-# the documentation. The maximum height of the logo should not exceed 55 pixels
-# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
-# to the output directory.
-
-PROJECT_LOGO           = 
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = "../"
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-
-# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi,
-# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en,
-# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish,
-# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
-# Turkish, Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
-# description of a member or function before the detailed description
-# 
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF       = "The $name class" \
-                         "The $name widget" \
-                         "The $name file" \
-                         is \
-                         provides \
-                         specifies \
-                         contains \
-                         represents \
-                         a \
-                         an \
-                         the
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES        = NO
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-# 
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH        =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH    = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF      = NO
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF           = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-# 
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
-# new page for each member. If set to NO, the documentation of a member will be
-# part of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE               = 2
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
-
-ALIASES                = 
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST              = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C  = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C.
-# 
-# Note For files without extension you can use no_extension as a placeholder.
-# 
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING      = 
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT       = YES
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by by putting a % sign in front of the word
-# or globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT       = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT    = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT        = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT            = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT   = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING            = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-# 
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS  = NO
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT   = NO
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE      = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL            = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC         = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES  = NO
-
-# This flag is only useful for Objective-C code. When set to YES local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES   = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO these classes will be included in the various overviews. This option has
-# no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES       = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES   = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO the members will appear in declaration order.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING  = NO
-
-# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
-# todo list. This list is created by putting \todo commands in the
-# documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST      = NO
-
-# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
-# test list. This list is created by putting \test commands in the
-# documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST      = NO
-
-# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST       = NO
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES the list
-# will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES        = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES             = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES        = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER    = 
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-# 
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE            = doxygen_layout.xml
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. Do not use file names with spaces, bibtex cannot handle them. See
-# also \cite for info how to create references.
-
-CITE_BIB_FILES         = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-# 
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS               = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO doxygen will only warn about wrong or incomplete parameter
-# documentation, but not about the absence of documentation.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC       = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces.
-# Note: If this tag is empty the current directory is searched.
-
-INPUT                  = "index.md" \
-                         "programmers_guide/introduction.md" \
-                         "programmers_guide/building.md" \
-                         "programmers_guide/building_android.md" \
-                         "programmers_guide/building_linux.md" \
-                         "programmers_guide/building_osx.md" \
-                         "programmers_guide/building_windows.md" \
-                         "programmers_guide/vectors.md" \
-                         "programmers_guide/quaternions.md" \
-                         "programmers_guide/matrices.md" \
-                         "programmers_guide/utilities.md" \
-                         "api_reference.md" \
-                         "readme.md" \
-                         "contributing.md" \
-                         "groups" \
-                         "../../include"
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank the
-# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
-# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
-# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
-# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
-# *.qsf, *.as and *.js.
-
-FILE_PATTERNS          = *.c \
-                         *.cc \
-                         *.cxx \
-                         *.cpp \
-                         *.c++ \
-                         *.java \
-                         *.ii \
-                         *.ixx \
-                         *.ipp \
-                         *.i++ \
-                         *.inl \
-                         *.idl \
-                         *.ddl \
-                         *.odl \
-                         *.h \
-                         *.hh \
-                         *.hxx \
-                         *.hpp \
-                         *.h++ \
-                         *.cs \
-                         *.d \
-                         *.php \
-                         *.php4 \
-                         *.php5 \
-                         *.phtml \
-                         *.inc \
-                         *.m \
-                         *.markdown \
-                         *.md \
-                         *.mm \
-                         *.dox \
-                         *.py \
-                         *.f90 \
-                         *.f \
-                         *.for \
-                         *.tcl \
-                         *.vhd \
-                         *.vhdl \
-                         *.ucf \
-                         *.qsf \
-                         *.as \
-                         *.js
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE              = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-# 
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE                =
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-# 
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       = *_test.py \
-                         __init__.py
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-# 
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS        =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH           = ../../unit_tests/
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS       = *.cpp
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-# 
-# <filter> <input-file>
-# 
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-# 
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-
-INPUT_FILTER           =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-
-FILTER_PATTERNS        = *.py=py_filter
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER ) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES    = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE = index.md
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-# 
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS    = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION    = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS        = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-# 
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-# 
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-# 
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS       = YES
-
-# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# compiled with the --with-libclang option.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = NO
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS          = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX     = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-# 
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER            = $(SHARED_DOCS_PATH)/header.html
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER            = $(SHARED_DOCS_PATH)/footer.html
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET        = 
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
-# defined cascading style sheet that is included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefor more robust against future updates.
-# Doxygen will copy the style sheet file to the output directory. For an example
-# see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET  = $(SHARED_DOCS_PATH)/style.css
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES       = 
-
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the stylesheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE    = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT    = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA  = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP         = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS  = NO
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET        = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME  = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-# 
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP      = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE               = 
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler ( hhc.exe). If non-empty
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION           = 
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated (
-# YES) or that it should be included in the master .chm file ( NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI           = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING     = 
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated (
-# YES) or a normal table of contents ( NO) in the .chm file.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND             = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP           = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE               = 
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE          = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER     = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME   = 
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS  = 
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS  = 
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION           = 
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP   = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID         = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX          = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW      = YES
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-# 
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH         = 250
-
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW    = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE       = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-# 
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT    = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using prerendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX            = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT         = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS     = 
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE       = 
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE           = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavours of web server based searching depending on the
-# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
-# searching and an index file used by the script. When EXTERNAL_SEARCH is
-# enabled the indexing and searching needs to be provided by external tools. See
-# the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH    = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-# 
-# Doxygen ships with an example indexer ( doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
-# 
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH        = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-# 
-# Doxygen ships with an example indexer ( doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL       = 
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE        = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID     = 
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS  = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-# 
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE             = a4
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. To get the times font for
-# instance you can specify
-# EXTRA_PACKAGES=times
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-# 
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
-# replace them by respectively the title of the page, the current date and time,
-# only the current date, the version number of doxygen, the project name (see
-# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER           = 
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer.
-# 
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER           = 
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES      = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS         = YES
-
-# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE        = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES     = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-# 
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE      = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE        = plain
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-# 
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
-# 
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
-# validating XML parser to check the syntax of the XML files.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
-# validating XML parser to check the syntax of the XML files.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK       = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT         = docbook
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
-# Definitions (see http://autogen.sf.net) file that captures the structure of
-# the code including all documentation. Note that this feature is still
-# experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-# 
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
-# in the source code. If set to NO only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION        = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF     = YES
-
-# If the SEARCH_INCLUDES tag is set to YES the includes files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH           = "../../include/mathfu/"
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED             = DOXYGEN \
-                         __ANDROID__ \
-                         __attribute__(x)= \
-                         MATHFU_COMPILE_WITH_SIMD
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all refrences to function-like macros that are alone on a line, have an
-# all uppercase name, and do not end with a semicolon. Such function macros are
-# typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have an unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
-# class index. If set to NO only the inherited external classes will be listed.
-# The default value is: NO.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
-# the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS        = NO
-
-# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES         = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS         = NO
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH            =
-
-# If set to YES, the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: NO.
-
-HAVE_DOT               = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS        = 0
-
-# When you want a differently looking font n the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME           = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE           = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH           = 
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK               = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS   = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH          = YES
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-# 
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH             = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-# 
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH           = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot.
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, jpg, gif and svg.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT       = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-# 
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG        = NO
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS           = 
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS           = 
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES    = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-# 
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP            = YES
diff --git a/third_party/mathfu-1.1.0/docs/src/doxygen_layout.xml b/third_party/mathfu-1.1.0/docs/src/doxygen_layout.xml
deleted file mode 100644
index bca1c7b..0000000
--- a/third_party/mathfu-1.1.0/docs/src/doxygen_layout.xml
+++ /dev/null
@@ -1,370 +0,0 @@
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<doxygenlayout version="1.0">
-  <navindex>
-    <tab type="mainpage" visible="no" title=""/>
-    <tab type="usergroup" url="" title="Programmer's Guide">
-      <tab type="usergroup" url="@ref mathfu_guide_introduction"
-           title="Introduction">
-        <tab type="user" url="@ref mathfu_guide_about_mathfu"
-             title="About MathFu"/>
-        <tab type="user" url="@ref mathfu_guide_prerequisites"
-             title="Prerequisites"/>
-        <tab type="user" url="@ref mathfu_guide_about_guide"
-             title="About This Guide"/>
-        <tab type="user" url="@ref mathfu_guide_concepts"
-             title="Concepts"/>
-        <tab type="user" url="@ref mathfu_guide_optimization"
-             title="Optimization"/>
-      </tab>
-      <tab type="usergroup" url="@ref mathfu_guide_building"
-           title="Building">
-        <tab type="user" url="@ref mathfu_guide_building_options"
-             title="Integration Options"/>
-        <tab type="user" url="@ref mathfu_guide_building_compiler_config"
-             title="Manual Compiler Configuration"/>
-        <tab type="user" url="@ref mathfu_guide_building_cmake"
-             title="CMake"/>
-        <tab type="user" url="@ref mathfu_guide_building_android_makefiles"
-             title="Android NDK Makefiles"/>
-        <tab type="usergroup" url="" title="Building Unit Tests">
-          <tab type="usergroup" url="@ref mathfu_guide_building_android"
-               title="Building for Android">
-            <tab type="user" url="@ref mathfu_guide_building_android_version"
-                 title="Version Requirements"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_prerequisites"
-                 title="Prerequisites"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_building"
-                 title="Building"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_building_ndk_build"
-                 title="Building with ndk-build"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_building_fplutil"
-                 title="Building with fplutil"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_running"
-                 title="Installing and Running Applications"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_eclipse"
-                 title="Using Eclipse"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_fplutil"
-                 title="Using fplutil"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_android_code_generation"
-                 title="Code Generation"/>
-          </tab>
-          <tab type="usergroup" url="@ref mathfu_guide_building_linux"
-               title="Building for Linux">
-            <tab type="user" url="@ref mathfu_guide_building_linux_version"
-                 title="Version Requirements"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_linux_prerequisites"
-                 title="Prerequisites"/>
-            <tab type="user" url="@ref mathfu_guide_building_linux_building"
-                 title="Building"/>
-            <tab type="user" url="@ref mathfu_guide_building_linux_running"
-                 title="Running Applications"/>
-          </tab>
-          <tab type="usergroup" url="@ref mathfu_guide_building_osx"
-               title="Building for OS X">
-            <tab type="user" url="@ref mathfu_guide_building_osx_version"
-                 title="Version Requirements"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_osx_prerequisites"
-                 title="Prerequisites"/>
-            <tab type="user" url="@ref mathfu_guide_building_osx_building"
-                 title="Building with Xcode"/>
-            <tab type="user" url="@ref mathfu_guide_building_osx_running"
-                 title="Running Applications"/>
-          </tab>
-          <tab type="usergroup" url="@ref mathfu_guide_building_windows"
-               title="Building for Windows">
-            <tab type="user" url="@ref mathfu_guide_building_windows_version"
-                 title="Version Requirements"/>
-            <tab type="user"
-                 url="@ref mathfu_guide_building_windows_prerequisites"
-                 title="Prerequisites"/>
-            <tab type="user" url="@ref mathfu_guide_building_windows_building"
-                 title="Building with Visual Studio"/>
-            <tab type="user" url="@ref mathfu_guide_building_windows_running"
-                 title="Running Applications"/>
-          </tab>
-        </tab>
-      </tab>
-      <tab type="usergroup" url="@ref mathfu_guide_vectors"
-           title="Vectors">
-        <tab type="usergroup" url="@ref mathfu_guide_vectors_declaration"
-             title="Declaration">
-          <tab type="user" url="@ref mathfu_guide_vectors_initialization"
-               title="Initialization"/>
-        </tab>
-        <tab type="usergroup" url="@ref mathfu_guide_vectors_accessors"
-             title="Accessors">
-          <tab type="user" url="@ref mathfu_guide_vectors_assignment"
-               title="Assignment"/>
-        </tab>
-        <tab type="user" url="@ref mathfu_guide_vectors_arithmetic"
-             title="Arithmetic"/>
-        <tab type="user" url="@ref mathfu_guide_vectors_constants"
-             title="Constants"/>
-        <tab type="user" url="@ref mathfu_guide_vectors_geometric"
-             title="Geometric Operations"/>
-        <tab type="user" url="@ref mathfu_guide_vectors_other"
-             title="Other Operations"/>
-        <tab type="user" url="@ref mathfu_guide_vectors_packing"
-             title="Packing"/>
-      </tab>
-      <tab type="usergroup" url="@ref mathfu_guide_quaternions"
-           title="Quaternions">
-        <tab type="usergroup" url="@ref mathfu_guide_quaternions_declaration"
-             title="Declaration">
-          <tab type="user" url="@ref mathfu_guide_quaternions_initialization"
-               title="Initialization"/>
-        </tab>
-        <tab type="usergroup" url="@ref mathfu_guide_quaternions_accessors"
-             title="Accessors">
-          <tab type="user" url="@ref mathfu_guide_quaternions_assignment"
-               title="Assignment"/>
-        </tab>
-        <tab type="user" url="@ref mathfu_guide_quaternions_repr"
-             title="Converting Between Representations"/>
-        <tab type="user" url="@ref mathfu_guide_quaternions_manipulation"
-             title="Manipulation"/>
-        <tab type="user" url="@ref mathfu_guide_quaternions_application"
-             title="Application"/>
-      </tab>
-      <tab type="usergroup" url="@ref mathfu_guide_matrices"
-           title="Matrices">
-        <tab type="usergroup" url="@ref mathfu_guide_matrices_declaration"
-             title="Declaration">
-          <tab type="user" url="@ref mathfu_guide_matrices_initialization"
-               title="Initialization"/>
-        </tab>
-        <tab type="usergroup" url="@ref mathfu_guide_matrices_accessors"
-             title="Accessors">
-          <tab type="user" url="@ref mathfu_guide_matrices_assignment"
-               title="Assignment"/>
-        </tab>
-        <tab type="user" url="@ref mathfu_guide_matrices_arithmetic"
-             title="Arithmetic"/>
-        <tab type="user" url="@ref mathfu_guide_matrices_matrix_ops"
-             title="Matrix Operations"/>
-        <tab type="user" url="@ref mathfu_guide_matrices_packing"
-             title="Packing"/>
-      </tab>
-      <tab type="usergroup" url="@ref mathfu_guide_utilities"
-           title="Utilities">
-        <tab type="user" url="@ref mathfu_guide_utilities_allocation"
-             title="Memory Allocation"/>
-        <tab type="usergroup" url="@ref mathfu_guide_utilities_misc"
-             title="Miscellaneous Functions">
-          <tab type="user" url="@ref mathfu_guide_utilities_random"
-               title="Random Number Generation"/>
-        </tab>
-      </tab>
-    </tab>
-    <tab type="usergroup" url="@ref mathfu_api_reference"
-         title="API reference">
-      <tab type="modules" visible="yes" title="" intro=""/>
-      <tab type="classes" visible="yes" title="">
-        <tab type="classlist" visible="yes" title="" intro=""/>
-        <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
-        <tab type="hierarchy" visible="yes" title="" intro=""/>
-        <tab type="classmembers" visible="yes" title="" intro=""/>
-      </tab>
-      <tab type="files" visible="yes" title="">
-        <tab type="filelist" visible="yes" title="" intro=""/>
-        <tab type="globals" visible="yes" title="" intro=""/>
-      </tab>
-      <!--tab type="examples" visible="yes" title="" intro=""/-->
-    </tab>
-    <tab type="user" url="@ref mathfu_readme" title="readme"/>
-    <tab type="user" url="@ref contributing" title="contributing"/>
-  </navindex>
-
-  <!-- Layout definition for a class page -->
-  <class>
-    <briefdescription visible="yes"/>
-    <includes visible="$SHOW_INCLUDE_FILES"/>
-    <inheritancegraph visible="$CLASS_GRAPH"/>
-    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
-    <detaileddescription title=""/>
-    <memberdecl>
-      <nestedclasses visible="yes" title=""/>
-      <publictypes title=""/>
-      <services title=""/>
-      <interfaces title=""/>
-      <publicslots title=""/>
-      <signals title=""/>
-      <publicmethods title=""/>
-      <publicstaticmethods title=""/>
-      <publicattributes title=""/>
-      <publicstaticattributes title=""/>
-      <protectedtypes title=""/>
-      <protectedslots title=""/>
-      <protectedmethods title=""/>
-      <protectedstaticmethods title=""/>
-      <protectedattributes title=""/>
-      <protectedstaticattributes title=""/>
-      <packagetypes title=""/>
-      <packagemethods title=""/>
-      <packagestaticmethods title=""/>
-      <packageattributes title=""/>
-      <packagestaticattributes title=""/>
-      <properties title=""/>
-      <events title=""/>
-      <privatetypes title=""/>
-      <privateslots title=""/>
-      <privatemethods title=""/>
-      <privatestaticmethods title=""/>
-      <privateattributes title=""/>
-      <privatestaticattributes title=""/>
-      <friends title=""/>
-      <related title="" subtitle=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <memberdef>
-      <inlineclasses title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <services title=""/>
-      <interfaces title=""/>
-      <constructors title=""/>
-      <functions title=""/>
-      <related title=""/>
-      <variables title=""/>
-      <properties title=""/>
-      <events title=""/>
-    </memberdef>
-    <allmemberslink visible="yes"/>
-    <usedfiles visible="$SHOW_USED_FILES"/>
-    <authorsection visible="yes"/>
-  </class>
-
-  <!-- Layout definition for a namespace page -->
-  <namespace>
-    <briefdescription visible="yes"/>
-    <memberdecl>
-      <nestednamespaces visible="yes" title=""/>
-      <constantgroups visible="yes" title=""/>
-      <classes visible="yes" title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-    <memberdef>
-      <inlineclasses title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdef>
-    <authorsection visible="yes"/>
-  </namespace>
-
-  <!-- Layout definition for a file page -->
-  <file>
-    <briefdescription visible="yes"/>
-    <includes visible="$SHOW_INCLUDE_FILES"/>
-    <includegraph visible="$INCLUDE_GRAPH"/>
-    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
-    <sourcelink visible="yes"/>
-    <detaileddescription title=""/>
-    <memberdecl>
-      <classes visible="yes" title=""/>
-      <namespaces visible="yes" title=""/>
-      <constantgroups visible="yes" title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <memberdef>
-      <inlineclasses title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdef>
-    <authorsection/>
-  </file>
-
-  <!-- Layout definition for a group page -->
-  <group>
-    <briefdescription visible="yes"/>
-    <groupgraph visible="$GROUP_GRAPHS"/>
-    <detaileddescription title=""/>
-    <memberdecl>
-      <nestedgroups visible="yes" title=""/>
-      <dirs visible="yes" title=""/>
-      <files visible="yes" title=""/>
-      <namespaces visible="yes" title=""/>
-      <classes visible="yes" title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <enumvalues title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <signals title=""/>
-      <publicslots title=""/>
-      <protectedslots title=""/>
-      <privateslots title=""/>
-      <events title=""/>
-      <properties title=""/>
-      <friends title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <memberdef>
-      <pagedocs/>
-      <inlineclasses title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <enumvalues title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <signals title=""/>
-      <publicslots title=""/>
-      <protectedslots title=""/>
-      <privateslots title=""/>
-      <events title=""/>
-      <properties title=""/>
-      <friends title=""/>
-    </memberdef>
-    <authorsection visible="yes"/>
-  </group>
-
-  <!-- Layout definition for a directory page -->
-  <directory>
-    <briefdescription visible="yes"/>
-    <directorygraph visible="yes"/>
-    <memberdecl>
-      <dirs visible="yes"/>
-      <files visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-  </directory>
-</doxygenlayout>
diff --git a/third_party/mathfu-1.1.0/docs/src/groups b/third_party/mathfu-1.1.0/docs/src/groups
deleted file mode 100644
index 1348fac..0000000
--- a/third_party/mathfu-1.1.0/docs/src/groups
+++ /dev/null
@@ -1,28 +0,0 @@
-
-/// @defgroup mathfu_build_config Build Configuration
-/// @brief Macros that control build configuration.
-
-/// @defgroup mathfu_allocator Allocators
-/// @brief SIMD-safe memory allocators.
-
-/// @defgroup mathfu_constants Constants
-/// @brief Vector constants for specific dimensions.
-
-/// @defgroup mathfu_vector Vectors
-/// @brief Vector class and functions.
-
-/// @defgroup mathfu_matrix Matrices
-/// @brief Matrix class and functions.
-
-/// @defgroup mathfu_quaternion Quaternions
-/// @brief Quaternion class and functions.
-
-/// @defgroup mathfu_glsl GLSL Mappings
-/// @brief <a href="https://www.opengl.org/documentation/glsl/">GLSL</a>
-/// compatible data types.
-
-/// @defgroup mathfu_utilities Utility Functions
-/// @brief Utility functions.
-
-/// @defgroup mathfu_version Version Constants
-/// @brief Macros and variables that describe the library version.
diff --git a/third_party/mathfu-1.1.0/docs/src/index.md b/third_party/mathfu-1.1.0/docs/src/index.md
deleted file mode 100644
index 546a833..0000000
--- a/third_party/mathfu-1.1.0/docs/src/index.md
+++ /dev/null
@@ -1,79 +0,0 @@
-MathFu    {#mathfu_index}
-======
-
-# Overview    {#mathfu_overview}
-
-[MathFu][] is a C++ math library developed primarily for games focused on
-simplicity and efficiency.
-
-It provides a suite of [vector][], [matrix][] and [quaternion][] classes
-to perform basic [geometry][] suitable for game developers.  This functionality
-can be used to construct geometry for graphics libraries like [OpenGL][] or
-perform calculations for animation or physics systems.
-
-[MathFu] can be downloaded from [GitHub](http://github.com/google/mathfu) or
-the [releases page](http://github.com/google/mathfu/releases).
-
-**Important**: MathFu uses submodules to reference other components it depends
-upon so download the source using:
-
-~~~{.sh}
-    git clone --recursive https://github.com/google/mathfu.git
-~~~
-
-# Functionality
-
-Each [vector][], [matrix][] and [quaternion][] class implements basic
-arithmetic operators (addition, subtraction, multiplication, division) in
-addition to simple [linear algebra][] operators (e.g dot product,
-cross product, inverse, slerp).
-
-# Optimization
-
-[MathFu][] is optimized using [SIMD][] instructions (including [NEON][] for
-[ARM][] and [SSE][] for [x86][] architectures).  [SIMD][] optimization is
-enabled by default based upon the target platform and compiler options used
-to build a project.  In addition, [MathFu][] provides compile time options to
-modify code generation, see [Build Configurations][] for more details.
-
-# Supported Platforms
-
-[MathFu][] has been tested on the following platforms:
-
-   * [Android][]
-   * [Linux][] (x86_64)
-   * [OS X][]
-   * [Windows][]
-
-This library is entirely written in C++ with the exception of some
-conditionally enabled compiler intrinsics and some workarounds for different
-compiler quirks, which means that it *should* work with either no or little
-modification on any platform that has a C++ compiler.
-
-# Feedback and Reporting Bugs
-
-   * Discuss MathFu with other developers and users on the
-     [MathFu Google Group][].
-   * File issues on the [MathFu Issues Tracker][].
-   * Post your questions to [stackoverflow.com][] with a mention of **mathfu**.
-
-  [Android]: http://www.android.com
-  [ARM]: http://en.wikipedia.org/wiki/ARM_architecture
-  [Build Configurations]: @ref mathfu_build_config
-  [Linux]: http://en.m.wikipedia.org/wiki/Linux
-  [MathFu Google Group]: http://groups.google.com/group/mathfulib
-  [MathFu Issues Tracker]: http://github.com/google/mathfu/issues
-  [MathFu]: @ref mathfu_overview
-  [NEON]: http://www.arm.com/products/processors/technologies/neon.php
-  [OS X]: http://www.apple.com/osx/
-  [OpenGL]: http://www.opengl.org/
-  [SIMD]: http://en.wikipedia.org/wiki/SIMD
-  [SSE]: http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions
-  [Windows]: http://windows.microsoft.com/
-  [geometry]: http://en.wikipedia.org/wiki/Geometry
-  [linear algebra]: http://en.wikipedia.org/wiki/Linear_algebra
-  [matrix]: http://en.wikipedia.org/wiki/Matrix_(mathematics)
-  [quaternion]: http://en.wikipedia.org/wiki/Quaternion
-  [stackoverflow.com]: http://stackoverflow.com/search?q=mathfu
-  [vector]: http://en.wikipedia.org/wiki/Euclidean_vector
-  [x86]: http://en.wikipedia.org/wiki/X86
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/building.md
deleted file mode 100644
index b9b5dc8..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building.md
+++ /dev/null
@@ -1,177 +0,0 @@
-Building    {#mathfu_guide_building}
-========
-
-# Integration Options    {#mathfu_guide_building_options}
-
-[MathFu][] is designed as a C++ header only library to simplify the process
-of including the library in projects.  [MathFu] provides the following options
-for using it in a project:
-
-   * [Manually configure the compiler][] by simply include the appropriate
-     headers into a project's source code.
-   * Use the [CMake project][].
-   * Include the [Android NDK project][] when developing for [Android][]
-
-Before diving into using [MathFu][] in your project, we recommend you spend
-some time building and running the unit tests for each platform you wish to
-target by working through the following sections:
-
-   * [Building for Android][]
-   * [Building for Linux][]
-   * [Building for OS X][]
-   * [Building for Windows][]
-
-# Manual Compiler Configuration   {#mathfu_guide_building_compiler_config}
-
-The following directories need to be added to the include paths of a project
-to build the default configuration:
-   * `mathfu/include`
-   * `vectorial/include`
-      - If [vectorial][] was downloaded with the [MathFu][] project, this
-        will be located under the `dependencies/` directory.
-
-In addition, to compile with [SIMD][] enabled an architecture specific flag
-must be specified:
-
-Architecture    | Compiler            | Flag
-----------------|---------------------|------------
-[x86][]         | Android GCC / Clang | -msse
-[x86_64][]      | Android GCC / Clang | -msse4.1
-[x86][]         | GCC / Clang         | -msse4.1
-[ARM][]         | GCC / Clang         | -mfpu=neon
-[x86][]         | Visual Studio       | /arch:SSE2
-
-For example, to compile the following file `test.cpp` against [MathFu][] with
-gcc for x86:
-
-~~~{.cpp}
-#include <stdio.h>
-#include "mathfu/vector.h"
-
-int main(int argc, char *argv[]) {
-  mathfu::Vector<float, 3> v1(1.0f, 2.0f, 3.0f), v2(3.0f, 2.5f, 0.5f), v3;
-  v3 = v1 + v2;
-  printf("%.1f %.1f %.1f\n", v3.x(), v3.y(), v3.z());
-  return 0;
-}
-~~~
-
-requires the following command line (assuming vectorial is in the
-`mathfu/dependencies` directory):
-
-~~~{.sh}
-g++ -Imathfu/include -Imathfu/dependencies/vectorial/include test.cpp -msse4.1
-~~~
-
-In addition, [MathFu][] provides a set of build configuration options that
-are controlled using preprocessor symbols described by [Build Configuration][].
-
-# CMake    {#mathfu_guide_building_cmake}
-
-[MathFu][] uses a [CMake][] project to build unit tests and benchmarks
-for [Linux][], [OS X][] and [Windows][].
-
-[CMake][] is used to generate a platform projects for each target platform:
-  * [Makefiles][] ([Linux][] / [OS X][])
-  * [Xcode][] projects ([OS X][])
-  * [Visual Studio][] projects ([Windows][])
-
-If you're not familiar with [CMake][], see the following sections to learn how
-to build on each platform:
-
-   * [Building for Linux][]
-   * [Building for OS X][]
-   * [Building for Windows][]
-
-In addition to building the [MathFu][] unit tests and benchmarks,
-the [MathFu][] [CMake][] project can be used in developers own projects by:
-
-   * Disabling the build of unit tests and benchmarks using the options:
-      - `mathfu_build_benchmarks`
-      - `mathfu_build_tests`
-   * Including the [CMake][] project.
-   * Using the `mathfu_configure_flags` function to add the appropriate
-     include directories and compiler flags for the project.
-
-For example, in a CMakeLists.txt project file which contains the executable
-`mygame`:
-
-~~~
-# Include MathFu in this project with test and benchmark builds disabled
-# then add MathFu compiler flags to the mygame build target.
-set(mathfu_build_benchmarks OFF CACHE BOOL "")
-set(mathfu_build_tests OFF CACHE BOOL "")
-add_subdirectory(path/to/mathfu mathfu)
-
-mathfu_configure_flags(mygame)
-~~~
-
-[MathFu][] build options (see [Build Configuration][]) can be configured
-with the `mathfu_configure_flags` function using the optional arguments
-`enable_simd` and `force_padding`.  For example:
-
-Function Call                               | Build Configuration
---------------------------------------------|----------------------------------
-`mathfu_configure_flags(mygame)`            | Default, SIMD & padding enabled.
-`mathfu_configure_flags(mygame TRUE FALSE)` | SIMD enabled & padding disabled.
-`mathfu_configure_flags(mygame FALSE)`      | SIMD disabled.
-
-See the function comment in the CMakeLists.txt file for more information.
-
-# Android NDK Makefiles    {#mathfu_guide_building_android_makefiles}
-
-If you're not familiar developing applications with the [Android NDK][],
-see [Building for Android][] first.
-
-To use [MathFu][] with an [Android NDK][] makefile project, add the following
-lines to your project's `Android.mk` file.
-
-~~~{.mk}
-# Add the empty MathFu static library target to configure the project.
-LOCAL_STATIC_LIBRARIES += libmathfu
-
-# This is used to build your project's shared library, this should already
-# be in your Android.mk makefile.
-include $(BUILD_SHARED_LIBRARY)
-
-# Add the directory containing MathFu to the module search path.
-$(call import-add-path,$(abspath path/to/mathfu/..))
-# Import the MathFu project.
-$(call import-module,mathfu/jni)
-~~~
-
-[MathFu][] build options (see [Build Configuration][]) can be configured
-by linking against the different static libraries the [MathFu][] project
-builds:
-
-Library                | Build Configuration
------------------------|--------------------------------------------------
-`libmathfu`            | Default configuration, SIMD and padding enabled.
-`libmathfu_no_padding` | SIMD enabled (if supported), padding disabled.
-`libmathfu_no_simd`    | SIMD disabled, padding disabled.
-
-<br>
-
-  [Android NDK project]: @ref mathfu_guide_building_android_makefiles
-  [Android NDK]: http://developer.android.com/tools/sdk/ndk/index.html
-  [Android]: http://www.android.com
-  [ARM]: http://en.wikipedia.org/wiki/ARM_architecture
-  [Build Configuration]: @ref mathfu_build_config
-  [Building for Android]: @ref mathfu_guide_building_android
-  [Building for Linux]: @ref mathfu_guide_building_linux
-  [Building for OS X]: @ref mathfu_guide_building_osx
-  [Building for Windows]: @ref mathfu_guide_building_windows
-  [CMake project]: @ref mathfu_guide_building_cmake
-  [CMake]: http://www.cmake.org/
-  [Linux]: http://en.m.wikipedia.org/wiki/Linux
-  [Makefiles]: http://www.gnu.org/software/make/
-  [Manually configure the compiler]: @ref mathfu_guide_building_compiler_config
-  [MathFu]: @ref mathfu_overview
-  [OS X]: http://www.apple.com/osx/
-  [SIMD]: http://en.wikipedia.org/wiki/SIMD
-  [Visual Studio]: http://www.visualstudio.com/
-  [Windows]: http://windows.microsoft.com/
-  [Xcode]: http://developer.apple.com/xcode/
-  [vectorial]: http://github.com/scoopr/vectorial
-  [x86]: http://en.wikipedia.org/wiki/X86
-  [x86_64]: http://en.wikipedia.org/wiki/X86
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_android.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_android.md
deleted file mode 100644
index 6f1a40f..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_android.md
+++ /dev/null
@@ -1,159 +0,0 @@
-Building for Android    {#mathfu_guide_building_android}
-====================
-
-# Version Requirements    {#mathfu_guide_building_android_version}
-
-Following are the minimum tested versions of the tools and libraries you
-need to build [MathFu][] for Android:
-
-   * [Android SDK][]:  Android 2.3.3 (API Level 10) or above.
-   * [Android Developer Tools][] ([ADT][]): 20140702
-      - NDK plugn for Eclipse (bundled with [ADT][]) if using Eclipse to build.
-   * [Android NDK][]: android-ndk-r10e
-   * [fplutil][]: 1.0 or above, if using [fplutil][] to build, install and run.
-
-# Prerequisites    {#mathfu_guide_building_android_prerequisites}
-
-Prior to building:
-
-   * Install the [Android SDK][].
-   * Install the [Android NDK][].
-   * Install [fplutil prerequisites][] if using [fplutil][] to build, install
-     and run.
-
-# Building    {#mathfu_guide_building_android_building}
-
-Each [MathFu][] project for Android has an associated `AndroidManifest.xml`
-file and `jni` subdirectory.  Unit tests and benchmarks directories contain
-projects that each build an Android package ([apk][]) which can be installed
-and executed on Android devices.
-
-The following directories in the [MathFu] project contain [Android NDK][]
-projects:
-
-   * `mathfu/`
-      - Rules used to build the [MathFu][] library.
-   * `mathfu/benchmarks`
-      - Each subdirectory under this directory contains a simple benchmark
-        used to measure the performance of different build configurations.
-   * `mathfu/unit_tests`
-      - Each subdirectory under this directory contains a unit test application
-        used to test different components of the library in different build
-        configurations.
-
-## Building with ndk-build  {#mathfu_guide_building_android_building_ndk_build}
-
-To build a single [Android NDK][] project (without packaging the native
-component in an [apk][]):
-
-   * Open a command line window.
-   * Go to the directory containing the project to build.
-   * `ndk-build`
-
-For example, to build the matrix test for the default build configuration
-without generating an [apk][]:
-
-~~~{.sh}
-    cd mathfu/unit_tests/matrix_test/default
-    ndk-build
-~~~
-
-## Building with fplutil    {#mathfu_guide_building_android_building_fplutil}
-
-To build all [Android NDK][] projects, install and run them on a device:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Execute `dependencies/fplutil/bin/build_all_android.py`
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    ./dependencies/fplutil/bin/build_all_android.py
-~~~
-
-# Installing and Running Applications {#mathfu_guide_building_android_running}
-
-## Using Eclipse {#mathfu_guide_building_android_eclipse}
-
-Running a sample requires the [Android Developer Tools][] ([ADT][]) plugin and
-the [NDK Eclipse plugin][].
-
-   * Build a project using `ndk-build`
-     ([see above](@ref mathfu_guide_building_android_building_ndk_build)).
-   * Open [ADT][] Eclipse.
-   * Select "File->Import..." from the menu.
-   * Select "Android > Existing Android Code Into Workspace", and click "Next".
-   * Click the "Browse..." button next to `Root Directory:` and select the
-     project folder (e.g. `mathfu/unit_tests/matrix_test/default`).
-   * Click "Finish". Eclipse imports the project, and displays it in the
-     Package Explorer pane.
-   * Right-click the project, and select "Run->Run As->Android Application"
-      from the menu.
-   * If you do not have a physical device, you must define a virtual one.
-     For details about how to define a virtual device, see [managing avds][].
-     We don’t recommend a virtual device for development.
-   * None of the applications have a visual component so their output is
-     visible via the log ([adb][] logcat).
-
-## Using fplutil {#mathfu_guide_building_android_fplutil}
-
-To install and run a single application:
-
-   * Open a command line window.
-   * Go to the directory containing the project to install and run.
-   * Execute `dependencies/fplutil/bin/build_all_android.py` with the `-i`
-     and `-r` options.
-
-For example:
-
-~~~{.sh}
-    cd mathfu/unit_tests/matrix_test/default
-    ./dependencies/fplutil/bin/build_all_android.py -i -r
-~~~
-
-To install and run all applications:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Execute `dependencies/fplutil/bin/build_all_android.py` with the `-i`
-     and `-r` options.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    ./dependencies/fplutil/bin/build_all_android.py -i -r
-~~~
-
-# Code Generation    {#mathfu_guide_building_android_code_generation}
-
-By default, code is generated for devices that support the `armeabi-v7a`
-ABI.  Alternatively, you can generate a fat `.apk` that includes code for all
-ABIs.  To do so, override APP\_ABI on ndk-build's command line.
-
-Using `ndk-build`:
-
-~~~{.sh}
-    ndk-build APP_ABI=all
-~~~
-
-Using `fplutil`:
-~~~{.sh}
-    ./dependencies/fplutil/bin/build_all_android.py -f APP_ABI=all
-~~~
-
-<br>
-
-  [MathFu]: @ref mathfu_overview
-  [adb]: http://developer.android.com/tools/help/adb.html
-  [ADT]: http://developer.android.com/tools/sdk/eclipse-adt.html
-  [Android Developer Tools]: http://developer.android.com/sdk/index.html
-  [Android NDK]: http://developer.android.com/tools/sdk/ndk/index.html
-  [Android SDK]: http://developer.android.com/sdk/index.html
-  [NDK Eclipse plugin]: http://developer.android.com/sdk/index.html
-  [apk]: http://en.wikipedia.org/wiki/Android_application_package
-  [fplutil]: http://google.github.io/fplutil
-  [fplutil prerequisites]: http://google.github.io/fplutil/fplutil_prerequisites.html
-  [managing avds]: http://developer.android.com/tools/devices/managing-avds.html
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_linux.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_linux.md
deleted file mode 100644
index 7c3d294..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_linux.md
+++ /dev/null
@@ -1,106 +0,0 @@
-Building for Linux    {#mathfu_guide_building_linux}
-==================
-
-# Version Requirements    {#mathfu_guide_building_linux_version}
-
-Following are the minimum required versions of tools and libraries you
-need to build [MathFu][] for Android:
-
-   * [CMake][]: 2.8.12.1
-
-# Prerequisites    {#mathfu_guide_building_linux_prerequisites}
-
-Prior to building, install the following components using the [Linux][]
-distribution's package manager:
-
-   * [CMake][].  You can also manually install packages from
-     [cmake.org](http://cmake.org).
-
-For example, on [Ubuntu][]:
-
-~~~{.sh}
-    sudo apt-get install cmake
-~~~
-
-# Building    {#mathfu_guide_building_linux_building}
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Generate [Makefiles][] from the [CMake][] project.
-   * Execute `make` to build the unit tests and benchmarks.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    cmake -G'Unix Makefiles' .
-    make
-~~~
-
-To perform a debug build:
-
-~~~{.sh}
-    cd mathfu
-    cmake -G'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug .
-    make
-~~~
-
-Build targets can be configured using options exposed in
-`mathfu/CMakeLists.txt` by using [CMake]'s `-D` option.
-Build configuration set using the `-D` option is sticky across subsequent
-builds.
-
-For example, if a build is performed using:
-
-~~~{.sh}
-    cd mathfu
-    cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug .
-    make
-~~~
-
-to switch to a release build CMAKE_BUILD_TYPE must be explicitly specified:
-
-~~~{.sh}
-    cd mathfu
-    cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .
-    make
-~~~
-
-# Running Applications    {#mathfu_guide_building_linux_running}
-
-Each benchmark binaries are located in the `benchmarks/` directory and
-unit test binaries are located in the `unit_tests/` directory.
-
-To run all benchmarks:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Run each benchmark binary in the `benchmarks/` directory.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    for binary in ./benchmarks/*_benchmarks; do ${binary}; done
-~~~
-
-To run all unit tests:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Run each unit test binary in the `unit_tests/` directory.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    for binary in ./unit_tests/*_tests; do ${binary}; done
-~~~
-
-<br>
-
-  [CMake]: http://www.cmake.org/
-  [Linux]: http://en.wikipedia.org/wiki/Linux
-  [Makefiles]: http://www.gnu.org/software/make/
-  [MathFu]: @ref mathfu_overview
-  [Ubuntu]: http://www.ubuntu.com
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_osx.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_osx.md
deleted file mode 100644
index b34512b..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_osx.md
+++ /dev/null
@@ -1,98 +0,0 @@
-Building for OS X    {#mathfu_guide_building_osx}
-=================
-
-# Version Requirements    {#mathfu_guide_building_osx_version}
-
-Following are the minimum required versions of tools and libraries you
-need to build [MathFu][] for [OS X][]:
-
-   * [OS X][]: Mavericks 10.9.1.
-   * [Xcode][]: 5.0.1
-   * [CMake][]: 2.8.12.1
-
-# Prerequisites    {#mathfu_guide_building_osx_prerequisites}
-
-   * Install [Xcode][].
-   * Install [CMake][].
-
-# Building with Xcode    {#mathfu_guide_building_osx_building}
-
-Firstly, the [Xcode][] project needs to be generated using [CMake][]:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Use [CMake][] to generate the [Xcode][] project.
-
-~~~{.sh}
-    cd mathfu
-    cmake -G Xcode .
-~~~
-
-Then the project can be opened in [Xcode][] and built:
-
-   * Double-click on `mathfu/MathFu.xcodeproj` to open the project in
-     [Xcode][].
-   * Select "Product-->Build" from the menu.
-
-# Running Applications    {#mathfu_guide_building_osx_running}
-
-## Running in Xcode    {#mathfu_guide_building_osx_run_xcode}
-
-Open [Xcode][] select a build target and run it:
-
-   * Double-click on `mathfu/MathFu.xcodeproj` to open the project in
-     [Xcode][].
-   * Select an application `Scheme`, for example
-     "matrix_tests-->My Mac 64-bit", from the combo box to the right of the
-     "Run" button.
-   * Click the "Run" button.
-
-## Running from the Command Line {#mathfu_guide_building_osx_cmdline}
-
-To build:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Generate the [Xcode][] project.
-   * Run xcodebuild.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    cmake -G Xcode .
-    xcodebuild
-~~~
-
-To run all benchmarks:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Run each benchmark binary in the `benchmarks/` directory.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    for binary in ./benchmarks/Debug/*_benchmarks; do ${binary}; done
-~~~
-
-To run all unit tests:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Run each unit test binary in the `unit_tests/` directory.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    for binary in ./unit_tests/Debug/*_tests; do ${binary}; done
-~~~
-
-<br>
-
-  [CMake]: http://www.cmake.org
-  [MathFu]: @ref mathfu_overview
-  [OS X]: http://www.apple.com/osx/
-  [Xcode]: http://developer.apple.com/xcode/
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_windows.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_windows.md
deleted file mode 100644
index a99170b..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/building_windows.md
+++ /dev/null
@@ -1,84 +0,0 @@
-Building for Windows    {#mathfu_guide_building_windows}
-====================
-
-# Version Requirements    {#mathfu_guide_building_windows_version}
-
-Following are the minimum required versions of tools and libraries you
-need to build [MathFu][] for Android:
-
-   * [Windows][]: 7
-   * [Visual Studio][]: 2012
-   * [CMake][]: 2.8.12.1
-
-# Prerequisites    {#mathfu_guide_building_windows_prerequisites}
-
-Prior to building, install the following:
-
-   * [Visual Studio][]
-   * [CMake][] from [cmake.org](http://cmake.org).
-
-# Building with Visual Studio    {#mathfu_guide_building_windows_building}
-
-Generate the [Visual Studio][] project using [CMake][]:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Use [CMake][] to generate the [Visual Studio][] project.
-
-~~~{.sh}
-    cd mathfu
-    cmake -G "Visual Studio 11 2012" .
-~~~
-
-Open the [MathFu][] solution in [Visual Studio][].
-
-   * Double-click on `mathfu/MathFu.sln` to open the solution.
-   * Select "Build-->Build Solution" from the menu.
-
-# Running Applications    {#mathfu_guide_building_windows_running}
-
-## Running in Visual Studio    {#mathfu_guide_building_osx_run_vs}
-
-Open [Visual Studio][] select a build target and run it:
-
-   * Double-click on `mathfu/MathFu.sln` to open the solution in
-     [Visual Studio][].
-   * Right click on a project, for example `matrix_tests`, select
-     "Set as StartUp Project" from the menu.
-   * Select "Debug-->Start Debugging" from the menu.
-
-## Running from the Command Line {#mathfu_guide_building_windows_cmdline}
-
-To run all benchmarks:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Run each benchmark binary in the `benchmarks/` directory.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    for %a in (benchmarks\Debug\*.exe) do %a
-~~~
-
-To run all unit tests:
-
-   * Open a command line window.
-   * Go to the [MathFu][] project directory.
-   * Run each unit test binary in the `unit_tests/` directory.
-
-For example:
-
-~~~{.sh}
-    cd mathfu
-    for %a in (unit_tests\Debug\*.exe) do %a
-~~~
-
-<br>
-
-  [CMake]: http://www.cmake.org
-  [MathFu]: @ref mathfu_overview
-  [Visual Studio]: http://www.visualstudio.com/
-  [Windows]: http://windows.microsoft.com/
-
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/introduction.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/introduction.md
deleted file mode 100644
index 325416f..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/introduction.md
+++ /dev/null
@@ -1,80 +0,0 @@
-Introduction    {#mathfu_guide_introduction}
-============
-
-# About MathFu    {#mathfu_guide_about_mathfu}
-
-[MathFu][] is a C++ math library developed primarily for games focused on
-simplicity and efficiency.
-
-It provides a suite of [vector][], [matrix][] and [quaternion][] classes
-to perform basic [geometry][] suitable for game developers.  This functionality
-can be used to construct geometry for graphics libraries like [OpenGL][] or
-perform calculations for animation or physics systems.
-
-# Prerequisites    {#mathfu_guide_prerequisites}
-
-[MathFu][] is written in C++, you are expected to be experienced in C++
-programming. [MathFu][] should not be your first C++ programming project! You
-should be comfortable with compiling, linking, and debugging.
-
-# About This Guide    {#mathfu_guide_about_guide}
-
-This guide provides an overview of the [MathFu] API, it does *not* cover
-every aspect of functionality provided by the library.  The entire API
-is documented by the [API reference][].  In addition, the unit tests
-(under `mathfu/unit_tests`) provide example usage of each class and function
-in the library.
-
-# Concepts    {#mathfu_guide_concepts}
-
-The core functionality of [MathFu][] is provided by the following classes:
-   * [Vector](@ref mathfu::Vector)
-   * [Matrix](@ref mathfu::Matrix)
-   * [Quaternion](@ref mathfu::Quaternion)
-
-Each class is described in the following sections of the guide:
-   * [Vector](@ref mathfu_guide_vectors)
-      - A geometric concept with a magnitude and direction, defined in any
-        dimensional space.
-   * [Matrix](@ref mathfu_guide_matrices)
-      - A set of data organized in rows and columns.
-        [MathFu][] matricies may have any number of rows and columns.
-   * [Quaternion](@ref mathfu_guide_quaternions)
-      - A specific type of four dimensional vector and defines a rotation in
-        three dimensional space.
-
-In addition, [MathFu][] provides a suite of general math functions and method
-that make it easier to handle the special requirements of [SIMD][] data types
-described in the [Utilities](@ref mathfu_guide_utilities) section.
-
-# Optimization    {#mathfu_guide_optimization}
-
-[MathFu][] is optimized using [SIMD][] instructions (including [NEON][] for
-[ARM][] and [SSE][] for [x86][] architectures).  [SIMD][] optimization is
-enabled by default based upon the target platform and compiler options used
-to build a project.  In addition, [MathFu][] provides compile time options to
-modify code generation, see [Build Configurations][] for more details.
-
-## Supporting Additional Architectures
-
-[MathFu][]'s [SIMD][] implementation uses [vectorial][] as an abstraction
-layer for common [SIMD][] instructions and data types.  To support additional
-architectures, contributors can add support for new [SIMD][] instructions and
-data types to the [vectorial][] project and then modify the code in
-mathfu/utilities.h to define the macro <code>MATHFU_COMPILE_WITH_SIMD</code>
-for the new architecture.
-
-  [ARM]: http://en.wikipedia.org/wiki/ARM_architecture
-  [API reference]: @ref mathfu_api_reference
-  [matrix]: http://en.wikipedia.org/wiki/Matrix_(mathematics)
-  [geometry]: http://en.wikipedia.org/wiki/Geometry
-  [vector]: http://en.wikipedia.org/wiki/Euclidean_vector
-  [quaternion]: http://en.wikipedia.org/wiki/Quaternion
-  [OpenGL]: http://www.opengl.org/
-  [MathFu]: @ref mathfu_overview
-  [vectorial]: http://github.com/scoopr/vectorial
-  [SIMD]: http://en.wikipedia.org/wiki/SIMD
-  [SSE]: http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions
-  [x86]: http://en.wikipedia.org/wiki/X86
-  [NEON]: http://www.arm.com/products/processors/technologies/neon.php
-  [Build Configurations]: @ref mathfu_build_config
\ No newline at end of file
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/matrices.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/matrices.md
deleted file mode 100644
index 57ce28e..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/matrices.md
+++ /dev/null
@@ -1,358 +0,0 @@
-Matrices    {#mathfu_guide_matrices}
-========
-
-Matrices consist of a set of elements (usually floating point or integer
-scalars) arranged in rows and columns.  For more information see
-[this description](http://en.wikipedia.org/wiki/Matrix_(mathematics))
-of matrices.
-
-The [MathFu][] [Matrix][] class is a template declared in
-[mathfu/matrix.h](@ref mathfu/matrix.h) which has been specialized and
-optimized for the most regularly used case (floating point elements with
-4 rows and 4 columns).
-Implementing [Matrix][] as a template reduces code duplication, provides
-compile time optimization opportunities through specialization and allows
-users to use the class with any scalar type.
-
-# Declaration  {#mathfu_guide_matrices_declaration}
-
-The [Matrix][] class template takes either 2 or 3 arguments in the form:
-
-    * Matrix<type, number_of_rows_and_columns>
-    * Matrix<type, number_of_rows, number_of_columns>
-
-For example, a floating point 4 row, 4 column (4x4) matrix can be declared
-using either:
-
-~~~{.cpp}
-    mathfu::Matrix<float, 4, 4> matrix;
-~~~
-
-or:
-
-~~~{.cpp}
-    mathfu::Matrix<float, 4> matrix;
-~~~
-
-To eliminate the need for explicit template instantiation for common matrices,
-[GLSL][] style `typedef`s are provided in
-[mathfu/glsl_mappings.h](@ref mathfu/glsl_mappings.h).  Using a [GLSL][]
-style `typedef` a 4x4 floating point matrix variable is declared
-using the following:
-
-~~~{.cpp}
-    mathfu::mat4 matrix;
-~~~
-
-## Initialization  {#mathfu_guide_matrices_initialization}
-
-For efficiency, [Matrix][] is uninitialized when constructed.  Constructors
-are provided for common matrix sizes that allow initialization on construction.
-For example, to initialize a 2x2 floating point matrix:
-
-~~~{.cpp}
-    mathfu::mat2 matrix(1.0f, 2.0f,  // column 0
-                        3.0f, 4.0f); // column 1
-~~~
-
-It's also possible to initialize a [Matrix][] with another instance:
-
-~~~{.cpp}
-    const mathfu::mat2 matrix1(1.0f, 2.0f,  // column 0
-                               3.0f, 4.0f); // column 1
-    mathfu::mat2 matrix2(matrix1);
-~~~
-
-This can also be achieved with:
-
-~~~{.cpp}
-    const mathfu::mat2 matrix1(1.0f, 2.0f,  // column 0
-                               3.0f, 4.0f); // column 1
-    mathfu::mat2 matrix2 = matrix1;
-~~~
-
-# Accessors    {#mathfu_guide_matrices_accessors}
-
-[Matrix][] provides an array operator to retrieve individual elements in a
-flattened array and a parenthesis operator to access an element by row and
-column index.
-
-When using the array operator, the [Matrix][] is indexed by rows then columns.
-For example, a 3x3 matrix will access the following locations:
-
-Array Index | Column | Row
-------------|--------|--------
-0           | 0      | 0
-1           | 0      | 1
-2           | 0      | 2
-3           | 1      | 0
-4           | 1      | 1
-5           | 1      | 2
-6           | 2      | 0
-7           | 2      | 1
-8           | 2      | 2
-
-For example, to access column 1, row 2 of a 3x3 matrix using the array
-operator, use index "5":
-
-~~~{.cpp}
-    const mathfu::mat3 matrix(1.0f, 2.0f, 3.0f,   // column 0
-                              4.0f, 5.0f, 6.0f,   // column 1
-                              7.0f, 8.0f, 9.0f);  // column 2
-    float column1_row2 = matrix[5]; // 6.0f
-~~~
-
-The parenthesis operator allows access to an element by specifying the row
-and column indices directly.  For example, to access column 1, row 2 of a
-3x3 matrix:
-
-~~~{.cpp}
-    const mathfu::mat3 matrix(1.0f, 2.0f, 3.0f,   // column 0
-                              4.0f, 5.0f, 6.0f,   // column 1
-                              7.0f, 8.0f, 9.0f);  // column 2
-    float column1_row2 = matrix(2, 1);
-~~~
-
-
-## Assignment    {#mathfu_guide_matrices_assignment}
-
-[Matrix][] array and parenthesis operators return a reference to an element
-which can be modified by the caller.
-
-For example, to update column 1, row 2 of a 3x3 matrix using the array
-operator:
-
-~~~{.cpp}
-    mathfu::mat3 matrix(1.0f, 2.0f, 3.0f,   // column 0
-                        4.0f, 5.0f, 0.0f,   // column 1
-                        7.0f, 8.0f, 9.0f);  // column 2
-    matrix[5] = 6.0f;
-~~~
-
-To update column 1, row 2 of a 3x3 matrix using the parenthesis operator:
-
-~~~{.cpp}
-    mathfu::mat3 matrix(1.0f, 2.0f, 3.0f,   // column 0
-                        4.0f, 5.0f, 6.0f,   // column 1
-                        7.0f, 0.0f, 9.0f);  // column 2
-    matrix(2, 1) = 8.0f;
-~~~
-
-# Arithmetic    {#mathfu_guide_matrices_arithmetic}
-
-[Matrix][] supports in-place and out-of-place addition and subtraction
-with other matrices and scalars.  Multiplication and division of matrix
-elements is supported with scalars.
-
-For example, two matrices can be added together using the following:
-
-~~~{.cpp}
-    const mathfu::mat2 matrix1(1.0f, 2.0f,
-                               3.0f, 4.0f);
-    const mathfu::mat2 matrix2(5.0f, 6.0f,
-                               7.0f, 8.0f);
-    mathfu::mat2 matrix3 = matrix1 + matrix2;
-~~~
-
-The above preserves the contents of `matrix1` and `matrix2` with the following
-in `matrix3`:
-
-    6.0f,  8.0f
-    10.0f, 12.0f
-
-The same can be achieved with an in-place addition which mutates `matrix1`:
-
-~~~{.cpp}
-    mathfu::mat2 matrix1(1.0f, 2.0f,
-                         3.0f, 4.0f);
-    const mathfu::mat2 matrix2(5.0f, 6.0f,
-                               7.0f, 8.0f);
-    matrix1 += matrix2;
-~~~
-
-Addition with a scalar results in the value being added to all elements.
-For example:
-
-~~~{.cpp}
-    mathfu::mat2 matrix1(1.0f, 2.0f,
-                         3.0f, 4.0f);
-    matrix1 += 1.0f;
-~~~
-
-where `matrix1` contains the following:
-
-    2.0f, 3.0f,
-    4.0f, 5.0f
-
-Subtraction is similar to addition:
-
-~~~{.cpp}
-    const mathfu::mat2 matrix1(1.0f, 2.0f,
-                               3.0f, 4.0f);
-    const mathfu::mat2 matrix2(5.0f, 6.0f,
-                               7.0f, 8.0f);
-    mathfu::mat2 matrix3 = matrix2 - matrix1;
-~~~
-
-where `matrix3` contains the following:
-
-    4.0f, 4.0f,
-    4.0f, 4.0f
-
-Subtraction with a scalar:
-
-~~~{.cpp}
-    mathfu::mat2 matrix1(1.0f, 2.0f,
-                         3.0f, 4.0f);
-    matrix1 -= 1.0f;
-~~~
-
-where `matrix1` contains the following:
-
-    0.0f, 1.0f
-    2.0f, 3.0f
-
-Multiplication with a scalar:
-
-~~~{.cpp}
-    mathfu::mat2 matrix1(1.0f, 2.0f,
-                         3.0f, 4.0f);
-    matrix1 *= 2.0f;
-~~~
-
-where `matrix1` contains the following:
-
-    2.0f, 4.0f
-    6.0f, 8.0f
-
-Division with a scalar:
-
-~~~{.cpp}
-    mathfu::mat2 matrix1(1.0f, 2.0f,
-                         3.0f, 4.0f);
-    matrix1 /= 2.0f;
-~~~
-
-where `matrix1` contains the following:
-
-    0.5f, 1.0f
-    1.5f, 2.0f
-
-# Matrix Operations    {#mathfu_guide_matrices_matrix_ops}
-
-Identity matrices are constructed using
-[Matrix::Identity](@ref mathfu::Matrix::Identity):
-
-~~~{.cpp}
-    mathfu::mat2 identity = mathfu::mat2::Identity();
-~~~
-
-[Matrix][] supports matrix multiplication using the `* operator`.
-
-Matrix multiplication is performed using the `* operator`:
-
-~~~{.cpp}
-    const mathfu::mat2 matrix1(1.0f, 2.0f,
-                               3.0f, 4.0f);
-    const mathfu::mat2 matrix2(5.0f, 6.0f,
-                               7.0f, 8.0f);
-    mathfu::mat2 matrix3 = matrix1 * matrix2;
-~~~
-
-which preserves `matrix1` and `matrix2` while storing the result in
-`matrix3`:
-
-    23.0f, 31.0f
-    34.0f, 46.0f
-
-The [inverse](http://en.wikipedia.org/wiki/Invertible_matrix) of a [Matrix][]
-can be calculated using [Matrix::Inverse](@ref mathfu::Matrix::Inverse):
-
-~~~{.cpp}
-    const mathfu::mat2 matrix(1.0f, 2.0f,
-                              3.0f, 4.0f);
-    const mathfu::mat2 inverse = matrix.Inverse();
-~~~
-
-A [Matrix][] multiplied with its' inverse yields the identity matrix:
-
-~~~{.cpp}
-    const mathfu::mat2 matrix(1.0f, 2.0f,
-                              3.0f, 4.0f);
-    const mathfu::mat2 inverse = matrix.Inverse();
-    const mathfu::mat2 identity = matrix * inverse;
-~~~
-
-[Matrix][] provides a set of static methods that construct
-[transformation matrices][]:
-
-   * [Matrix::FromTranslationVector()](@ref mathfu::Matrix::FromTranslationVector)
-   * [Matrix::FromScaleVector()](@ref mathfu::Matrix::FromScaleVector)
-   * [Matrix::RotationX()](@ref mathfu::Matrix::RotationX)
-   * [Matrix::RotationY()](@ref mathfu::Matrix::RotationY)
-   * [Matrix::RotationZ()](@ref mathfu::Matrix::RotationZ)
-
-Transformation matrices yielded by these operations can be multiplied with
-vector to translate, scale and rotate.  For example, to rotate a 3-dimensional
-vector around the X axis by PI/2 radians (90 degrees):
-
-~~~{.cpp}
-    const mathfu::vec3 vector(1.0f, 2.0f, 3.0f);
-    const mathfu::mat3 rotation_around_x(mathfu::mat3::RotationX(M_PI / 2.0f));
-    const mathfu::vec3 rotated_vector = vector * rotation_around_x;
-~~~
-
-To scale a vector:
-
-~~~{.cpp}
-    const mathfu::vec3 vector(1.0f, 2.0f, 3.0f);
-    const mathfu::mat4 scale_by_2(
-      mathfu::mat4::FromScaleVector(mathfu::vec3(2.0f)));
-    const mathfu::vec3 scaled_vector = scale_by_2 * vector;
-~~~
-
-In addition, a set of static methods are provided to construct
-[camera matrices][]:
-
-   * [Matrix::Perspective()](@ref mathfu::Matrix::Perspective)
-   * [Matrix::Ortho()](@ref mathfu::Matrix::Ortho)
-   * [Matrix::LookAt()](@ref mathfu::Matrix::LookAt)
-
-For example, to construct a perspective matrix:
-
-~~~{.cpp}
-  const mathfu::mat4 perspective_matrix_ = mathfu::mat4::Perspective(
-      1.0f, 16.0f / 9.0f, 1.0f, 100.0f, -1.0f);
-~~~
-
-# Packing    {#mathfu_guide_matrices_packing}
-
-The size of the class can change based upon the [Build Configuration][] so it
-should *not* be treated like a C style array.  To serialize the class to a
-flat array see [VectorPacked][].
-
-For example, to pack (store) a [Matrix] to an array of packed vectors:
-
-~~~{.cpp}
-    mathfu::mat4 matrix(1.0f);
-    mathfu::vec4_packed packed[4];
-    matrix.Pack(packed);
-~~~
-
-To unpack an array of packed vectors:
-
-~~~{.cpp}
-    mathfu::vec4_packed packed[4];
-    mathfu::mat4 matrix(packed);
-~~~
-
-<br>
-
-  [Build Configuration]: @ref mathfu_build_config
-  [GLSL]: http://www.opengl.org/documentation/glsl/
-  [MathFu]: @ref mathfu_overview
-  [Matrix]: @ref mathfu::Matrix
-  [camera matrices]: http://en.wikipedia.org/wiki/3D_projection
-  [transformation matrices]: http://en.wikipedia.org/wiki/Transformation_matrix
-  [transformation matrix]: http://en.wikipedia.org/wiki/Transformation_matrix
-  [VectorPacked]: @ref mathfu::VectorPacked
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/quaternions.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/quaternions.md
deleted file mode 100644
index 370fac4..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/quaternions.md
+++ /dev/null
@@ -1,220 +0,0 @@
-Quaternions    {#mathfu_guide_quaternions}
-===========
-
-[Quaternions] provide a representation of a 3-dimensional orientation or
-rotation.  [Quaternions] are especially useful when interpolating between
-angles to avoid [Gimbal lock][].  For more information, see [this description].
-
-[MathFu] implements a quaternion as the [Quaternion][] class template which is
-constructed from one 3-dimensional [Vector][] and scalar component.  The
-[Quaternion][] template is intended to be instanced with `float` or `double`
-floating point scalar types.
-
-# Declaration  {#mathfu_guide_quaternions_declaration}
-
-The [Quaternions][] template takes a single argument which specifies the
-floating point type of each element in the class:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion;
-~~~
-
-## Initialization  {#mathfu_guide_quaternions_initialization}
-
-For efficiency, [Quaternion][] is uninitialized when constructed.  Constructors
-are provided to initialize the class from a set of scalars, a 3-dimensional
-[Vector][] and a scalar or another [Quaternion][].
-
-For example, to initialize a [Quaternion][] using a set of scalars:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion(0.71f, 0.0f, 0.71f, 0.0f);
-~~~
-
-To initialize a [Quaternion][] from a scalar and 3-dimensional vector
-component:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion(
-        0.50f, mathfu::vec3(0.76f, 0.38f, 0.19f));
-~~~
-
-# Accessors    {#mathfu_guide_quaternions_accessors}
-
-[Quaternion][] provides an array operator to retrieve elements of the object.
-The first index is the scalar component with the remaining 3 indices referring
-to elements in the vector component.
-
-~~~{.cpp}
-    const mathfu::Quaternion<float> quaternion(
-        0.50f, mathfu::vec3(0.76f, 0.38f, 0.19f));
-    float s = quaternion[0];
-    float x = quaternion[1];
-    float y = quaternion[2];
-    float z = quaternion[3];
-~~~
-
-## Assignment    {#mathfu_guide_quaternions_assignment}
-
-The array operator returns a reference to an element in the [Quaternion][]
-which can be updated:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion;
-    quaternion[0] = 0.5f;
-    quaternion[1] = 0.76f;
-    quaternion[2] = 0.38f;
-    quaternion[3] = 0.19f;
-~~~
-
-# Converting Between Representations {#mathfu_guide_quaternions_repr}
-
-[Quaternion][] provides a number of ways to create a rotation or orientation:
-
-   * [Quaternion::FromAngleAxis()](@ref mathfu::Quaternion::FromAngleAxis)
-   * [Quaternion::FromEulerAngles()](@ref mathfu::Quaternion::FromEulerAngles)
-   * [Quaternion::FromMatrix()](@ref mathfu::Quaternion::FromMatrix)
-
-For example, to create a [Quaternion][] which rotates PI / 2 radians around
-the X-axis:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion =
-        mathfu::Quaternion<float>::FromAngleAxis(
-            M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
-~~~
-
-The rotation of PI / 2 radians around the X-axis can also be achieved with:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion =
-        mathfu::Quaternion<float>::FromEulerAngles(
-            mathfu::vec3(M_PI / 2.0f, 0.0f, 0.0f));
-~~~
-
-Similarly, a quaternion can be constructed from an existing rotation matrix
-using:
-
-~~~{.cpp}
-    // Assuming rotation_matrix is an existing matrix.
-    mathfu::Quaternion<float> quaternion =
-        mathfu::Quaternion<float>::FromMatrix(rotation_matrix);
-~~~
-
-In addition, methods are provided to calculate an angle / axis pair,
-Euler angles, or rotation matrix from a [Quaternion][]:
-
-   * [Quaternion::ToAngleAxis()](@ref mathfu::Quaternion::ToAngleAxis)
-   * [Quaternion::ToEulerAngles()](@ref mathfu::Quaternion::ToEulerAngles)
-   * [Quaternion::ToMatrix()](@ref mathfu::Quaternion::ToMatrix)
-
-For example, to calculate the angle and axis from a [Quaternion][]:
-
-~~~{.cpp}
-    // Assuming "quaternion" is an existing float quaternion.
-    float angle;
-    mathfu::vec3 axis;
-    quaternion.ToAngleAxis(&angle, &axis);
-~~~
-
-To calculate a vector of Euler angles from a [Quaternion][]
-
-~~~{.cpp}
-    // Assuming "quaternion" is an existing float quaternion.
-    mathfu::vec3 euler_angles = quaternion.ToEulerAngles();
-~~~
-
-Finally, to convert a [Quaternion][] to a rotation matrix:
-
-~~~{.cpp}
-    // Assuming "quaternion" is an existing float quaternion.
-    mathfu::Matrix<float, 3> rotation_matrix = quaternion.ToMatrix();
-~~~
-
-# Manipulation    {#mathfu_guide_quaternions_manipulation}
-
-[Quaternion][] objects can be multiplied with each other to combine their
-rotations.
-
-For example, if a quaternion that rotates by PI / 2 radians around
-the X axis is multiplied by itself it will result in a quaternion that rotates
-by PI radians around the X axis:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion_pi_by_2_around_x =
-        mathfu::Quaternion<float>::FromAngleAxis(
-            M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
-    mathfu::Quaternion<float> quaternion_pi_around_x =
-        quaternion_pi_by_2_around_x * quaternion_pi_by_2_around_x;
-~~~
-
-It's also possible to multiply a [Quaternion][] with a scalar to scale the
-existing rotation expressed by the object.
-
-For example, if a quaternion that rotates by PI / 2 radians around
-the X axis is multiplied by 2 it will result in a quaternion that rotates
-by PI radians around the X axis:
-
-~~~{.cpp}
-    mathfu::Quaternion<float> quaternion_pi_by_2_around_x =
-        mathfu::Quaternion<float>::FromAngleAxis(
-            M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
-    mathfu::Quaternion<float> quaternion_pi_around_x =
-        quaternion_pi_by_2_around_x * 2.0f;
-~~~
-
-In addition, [Quaternion][] provides the ability to perform
-[spherical linear interpolation][] between two [Quaternion][] objects enabling
-smooth transitions between rotations while avoiding [Gimbal lock][].
-
-For example, the rotation half way between two quaternions can be calculated
-by the following:
-
-~~~{.cpp}
-    // Assuming "quaternion1" and "quaternion2" represent arbitrary rotations.
-    mathfu::Quaternion<float> quaternion3 =
-        mathfu::Quaternion<float>(quaternion1, quaternion2, 0.5f);
-~~~
-
-Finally, the inverse (opposite rotation) of a [Quaternion][] is calculated
-using [Quaternion::Inverse()](@ref mathfu::Quaternion::Inverse).  For example,
-if a [Quaternion][] represents a rotation PI / 2 radians around the X axis
-the rotation -PI / 2 degrees around the X axis can be calculated by:
-
-~~~{.cpp}
-    const mathfu::Quaternion<float> quaternion =
-        mathfu::Quaternion<float>::FromAngleAxis(
-            M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
-    mathfu::Quaternion<float> inverse_rotation = quaternion.Inverse();
-~~~
-
-# Application    {#mathfu_guide_quaternions_application}
-
-A rotation expressed by a [Quaternion][] is applied to a [Vector][] by
-multiplying the [Quaternion][] with the [Vector][].
-
-For example, to rotate a [Vector][] by PI / 2 radians around the X axis:
-
-~~~{.cpp}
-    const mathfu::vec3 vector(0.0f, 1.0f, 0.0f);
-    const mathfu::Quaternion<float> quaternion =
-        mathfu::Quaternion<float>::FromAngleAxis(
-            M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
-    mathfu::vec3 rotated_vector = quaternion * vector;
-~~~
-
-When  applying rotations to a large number of vectors or points
-(e.g transforming a set of vertices) it is easier to use
-[Quaternion::ToMatrix()](@ref mathfu::Quaternion::ToMatrix) to calculate
-the rotation matrix and apply the same transform to the set of vectors.
-
-<br>
-
-  [Quaternions]: http://en.wikipedia.org/wiki/Quaternion
-  [this description]: http://en.wikipedia.org/wiki/Quaternion
-  [Gimbal lock]: http://en.wikipedia.org/wiki/Gimbal_lock
-  [spherical linear interpolation]: http://en.wikipedia.org/wiki/Slerp
-  [Quaternion]: @ref mathfu::Quaternion
-  [MathFu]: @ref mathfu_overview
-  [Matrix]: @ref mathfu::Matrix
-  [Vector]: @ref mathfu::Vector
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/utilities.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/utilities.md
deleted file mode 100644
index 3816204..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/utilities.md
+++ /dev/null
@@ -1,113 +0,0 @@
-Utilities    {#mathfu_guide_utilities}
-=========
-
-# Memory Allocation    {#mathfu_guide_utilities_allocation}
-
-[MathFu][]'s use of [SIMD][] instructions provides significant performance
-gains in many use cases.  However, some architectures have memory
-alignment requirements for data used by [SIMD][] operations (e.g [SIMD][]
-data structures must be 16-byte aligned on x86).  Some STL implementations do
-not respect data type alignment which makes it more difficult to respect the
-[SIMD][] memory alignment requirements.
-
-In order to adhere to [SIMD][] alignment requirements, [MathFu][] provides a
-dynamic memory allocator [AllocateAligned()][] which ensures data is correctly
-aligned.  Memory allocated by [AllocateAligned()][] **must** be deallocated
-using [FreeAligned()][], for example:
-
-~~~{.cpp}
-   void *memory = mathfu::AllocateAligned(32);
-   mathfu::FreeAligned(memory);
-~~~
-
-The [simd_allocator](@ref mathfu::simd_allocator) class is provided to perform
-aligned memory allocation with STL classes like std::vector.  For example, the
-following constructs a vector of `vec4` which uses the aligned memory
-allocator:
-
-~~~{.cpp}
-    std::vector<vec4, mathfu::simd_allocator<mathfu::vec4>> myvector;
-~~~
-
-The aligned memory allocator uses [MATHFU_ALIGNMENT](@ref MATHFU_ALIGNMENT)
-bytes of additional memory per allocation.  If the additional memory usage
-per allocation is acceptable for an application, the most simple solution
-is to override the global `new` and `delete` operators by adding
-[MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE](@ref MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE)
-to the source file containing an application's entry point (e.g `main.cpp`):
-
-~~~{.cpp}
-#include "mathfu/utilities.h"
-
-MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
-
-int main(int argc, char *argv[]) {
-  // The application.
-  return 0;
-}
-~~~
-
-# Miscellaneous Functions    {#mathfu_guide_utilities_misc}
-
-[Clamp](@ref mathfu_Clamp) is used to clamp a value within a specified
-range.  For example:
-
-~~~{.cpp}
-    float x = 1.0f;
-    z = mathfu::Clamp(x, 1.0f, 2.0f);  // z = 1.0
-    z = mathfu::Clamp(x, 1.5f, 2.0f);  // z = 1.5
-    z = mathfu::Clamp(x, 0.0f, 0.5f);  // z = 0.5
-~~~
-
-[Lerp](@ref mathfu_Lerp) linearly interpolates between two values of an
-arbitrary type in a specified range.  For example, an object whose position is
-specified by a [Vector][] could be moved over a range as time elapses:
-
-~~~{.cpp}
-    const mathfu::vec2 start(2.0f, 3.0f);
-    const mathfu::vec2 end(10.0f, 0.0f);
-    // Update the position of an object every 100ms.
-    for (float time = 0.0f; time < 1.1f; time += 0.1f) {
-      mathfu::vec2 position = mathfu::Lerp(start, end, time);
-      // Draw object.
-      // Wait 100ms.
-    }
-~~~
-
-## Random Number Generation    {#mathfu_guide_utilities_random}
-
-[Random()][] generates pseudo random floating point numbers using `rand()`
-from the C standard library.  For example, the following generates 3 random
-numbers:
-
-~~~{.cpp}
-    float value1, value2, value2;
-    value1 = mathfu::Random<float>();
-    value2 = mathfu::Random<float>();
-    value3 = mathfu::Random<float>();
-~~~
-
-[Random()][] is used by [RandomRange()](@ref mathfu_RandomRange) to generate
-a random number within a symmetric range.  For example, to generate a random
-value between -10.0f..10.0f:
-
-~~~{.cpp}
-    float random_value = mathfu::RandomRange(10.0f);
-~~~
-
-Finally, [RandomInRange](@ref mathfu_RandomInRange) can be used to generate
-a random number within an arbitrary range.  For example, to generate a random
-value between 5.0f..7.0f:
-
-~~~{.cpp}
-    float random_value = mathfu::RandomInRange(5.0f, 7.0f);
-~~~
-
-<br>
-
-  [AllocateAligned()]: @ref mathfu_AllocateAligned
-  [FreeAligned()]: @ref mathfu_FreeAligned
-  [MathFu]: @ref mathfu_overview
-  [Random()]: @ref mathfu_Random
-  [SIMD]: http://en.wikipedia.org/wiki/SIMD
-  [Vector]: @ref mathfu::Vector
diff --git a/third_party/mathfu-1.1.0/docs/src/programmers_guide/vectors.md b/third_party/mathfu-1.1.0/docs/src/programmers_guide/vectors.md
deleted file mode 100644
index b291662..0000000
--- a/third_party/mathfu-1.1.0/docs/src/programmers_guide/vectors.md
+++ /dev/null
@@ -1,272 +0,0 @@
-Vectors    {#mathfu_guide_vectors}
-=======
-
-Vectors consist of a set of elements (usually floating point or integer
-scalars) that are regularly used to describe a point in space or a direction.
-For more information see this description of
-[Euclidiean Vectors](http://en.wikipedia.org/wiki/Euclidean_vector).
-
-The [MathFu][] [Vector][] class is a template declared in
-[mathfu/vector.h](@ref mathfu/vector.h) which has been specialized and
-optimized for regularly used cases.  Implementing [Vector][] as a template
-reduces code duplication, provides compile time optimization opportunities
-through specialization and allows users to use the class with any scalar
-type.
-
-# Declaration  {#mathfu_guide_vectors_declaration}
-
-[Vector][] template takes two arguments: the type and number of elements in
-the [Vector][].
-
-For example, a 2-dimensional floating point vector variable is declared using
-the following:
-
-~~~{.cpp}
-    mathfu::Vector<float, 2> vector;
-~~~
-
-To eliminate the need for explicit template instantiation, [GLSL][] style
-`typedef`s are provided in
-[mathfu/glsl_mappings.h](@ref mathfu/glsl_mappings.h).  Using a [GLSL][]
-style `typedef` a 2-dimensional floating point vector variable is declared
-using the following:
-
-~~~{.cpp}
-    math::vec2 vector;
-~~~
-
-## Initialization  {#mathfu_guide_vectors_initialization}
-
-For efficiency, [Vector][] is uninitialized when constructed.  Constructors
-are provided for common vector sizes that allow initialization on construction:
-
-~~~{.cpp}
-    mathfu::vec2 vector(1.0f, 2.0f);
-~~~
-
-It's also possible to initialize a [Vector][] with another instance:
-
-~~~{.cpp}
-    mathfu::vec2 vector1(1.0f, 2.0f);
-    mathfu::vec2 vector2(vector1);
-~~~
-
-This can also be achieved with:
-
-~~~{.cpp}
-    mathfu::vec2 vector1(1.0f, 2.0f);
-    mathfu::vec2 vector2 = vector1;
-~~~
-
-# Accessors    {#mathfu_guide_vectors_accessors}
-
-[Vector][] provides array and [GLSL][] style accessors.  For example, to
-read two elements from a 2-dimensional vector using array accessors:
-
-~~~{.cpp}
-    const mathfu::vec2 vector(1.0f, 2.0f);
-    float x = vector[0];
-    float y = vector[1];
-~~~
-
-It's also possible to read elements from 2, 3 and 4-dimensional vectors using
-[GLSL][] style accessors:
-
-~~~{.cpp}
-    const mathfu::vec4 vector(1.0f, 2.0f, 3.0f, 4.0f);
-    float x = vector.x();
-    float y = vector.y();
-    float z = vector.z();
-    float w = vector.w();
-~~~
-
-Similar to [GLSL][], [Vector][] provides accessors which allow a subset of
-elements to be accessed:
-
-~~~{.cpp}
-    const mathfu::vec3 vector1(1.0f, 2.0f, 3.0f);
-    mathfu::vec3 xy = vector1.xy();
-~~~
-
-## Assignment    {#mathfu_guide_vectors_assignment}
-
-Individual elements returned by [Vector][]'s array accessors are references
-that can be assigned values to update the contents of the class:
-
-~~~{.cpp}
-    mathfu::vec2 vector(1.0f, 2.0f);
-    vector[0] = 3.0f;
-    vector[1] = 4.0f;
-~~~
-
-# Arithmetic    {#mathfu_guide_vectors_arithmetic}
-
-[Vector][] supports in-place and out-of-place arithmetic operators
-(addition, subtraction, multiplication, division) that perform
-component-wise operations.
-
-For example, two vectors can be added together using the following:
-
-~~~{.cpp}
-    const mathfu::vec2 vector1(1.0f, 2.0f), vector2(3.0f, 4.0f);
-    mathfu::vec2 vector3 = vector1 + vector2;
-~~~
-
-The above results in the values `(4.0f, 6.0f)` stored in `vector3` while
-preserving the values of `vector1` and `vector2`.
-
-The same can be achieved with an in-place addition which mutates `vector1`:
-
-~~~{.cpp}
-    mathfu::vec2 vector1(1.0f, 2.0f);
-    const mathfu::vec2 vector2(3.0f, 4.0f);
-    vector1 += vector2;
-~~~
-
-Subtraction is similar to addition:
-
-~~~{.cpp}
-    const mathfu::vec2 vector1(4.0f, 6.0f), vector2(3.0f, 4.0f);
-    mathfu::vec2 vector3 = vector2 - vector1;
-~~~
-
-Multiplication is performed component-wise, which means that each component
-is multiplied with the same index component in the other [Vector][] involved
-in the operation:
-
-~~~{.cpp}
-    const mathfu::vec2 vector1(2.0f, 0.5f), vector2(3.0f, 10.0f);
-    vector3 = vector1 * vector2;
-~~~
-
-The above results in the values `(6.0f, 5.0f)` stored in `vector3` while
-preserving the values of `vector1` and `vector2`.
-
-Similar to the other operators, multiplication can be performed in place:
-
-~~~{.cpp}
-    mathfu::vec2 vector1(2.0f, 0.5f);
-    const mathfu::vec2 vector2(3.0f, 10.0f);
-    vector1 *= vector2;
-~~~
-
-Division is also a component-wise operation:
-
-~~~{.cpp}
-    const mathfu::vec2 vector1(4.0f, 4.0f), vector2(2.0f, 4.0f);
-    vector3 = vector1 / vector2;
-~~~
-
-The above results in the values `(2.0f, 1.0f)` stored in `vector3` while
-preserving the values of `vector1` and `vector2`.
-
-# Constants    {#mathfu_guide_vectors_constants}
-
-Commonly used constants are provided by
-[mathfu/constants.h](@ref mathfu/constants.h).  These values eliminate the need
-to construct [Vector][] objects for common values like cardinal axes.
-
-For example, the following initializes a 2-dimensional vector with the X-axis:
-
-~~~{.cpp}
-    const mathfu::vec2 vector = mathfu::kAxisX2f;
-~~~
-
-# Geometric Operations    {#mathfu_guide_vectors_geometric}
-
-[Vector][] also provides functions for commonly used geometric operations
-that are utilized by graphics and games developers.
-
-For example, the length of a [Vector][] is calculated using
-[Length()](@ref mathfu::Vector::Length):
-
-~~~{.cpp}
-    const mathfu::vec2 vector(3.0f, 4.0f);
-    float length = vector.Length();
-~~~
-
-The projection of one [Vector][] onto another (dot product) can be calculated
-using [DotProduct()](@ref mathfu::Vector::DotProduct).  For example, the
-following calculates the projection of a vector onto the X-axis:
-
-~~~{.cpp}
-  float projection = mathfu::vec2::DotProduct(mathfu::vec2(5.0f, 2.0f),
-                                              mathfu::kAxisX2f);
-~~~
-
-It's possible to normalize (scale to a length of 1) a vector in-place using
-[Normalize()](@ref mathfu::Vector::Normalize) or out-of-place using
-[Normalized()](@ref mathfu::Vector::Normalized).  For example, the following
-normalizes the vector in-place:
-
-~~~{.cpp}
-    mathfu::vec2 vector(3.0f, 4.0f);
-    vector.Normalize();
-~~~
-
-The cross product of two 3-dimensional [Vectors][] (the vector perpendicular
-to two vectors) can be calculated using
-[CrossProduct()](@ref mathfu::Vector::CrossProduct), for example:
-
-~~~{.cpp}
-    mathfu::vec3 zaxis = mathfu::vec3::CrossProduct(mathfu::kAxisX3f,
-                                                    mathfu::kAxisY3f);
-~~~
-
-Alternatively, to create three points and compute the normal of the plane
-defined by the points use:
-
-~~~{.cpp}
-    mathfu::vec3 point1(0.5f, 0.4f, 0.1f);
-    mathfu::vec3 point2(0.4f, 0.9f, 0.1f);
-    mathfu::vec3 point3(0.1f, 0.8f, 0.6f);
-
-    mathfu::vec3 vector1 = point2 - point1;
-    mathfu::vec3 vector2 = point3 - point1;
-
-    mathfu::vec3 normal = Vector<float, 3>::CrossProduct(vector2, vector1);
-~~~
-
-# Other Operations    {#mathfu_guide_vectors_other}
-
-In addition, to basic arithmetic and geometric operations, [Vector][] also
-implements functions to perform the following:
-
-   * [Lerp](@ref mathfu::Vector::Lerp) to linearly interpolate between two
-     vectors.
-   * [RandomInRange](@ref mathfu::Vector::RandomInRange) to generate a vector
-     with random value for elements.
-
-# Packing    {#mathfu_guide_vectors_packing}
-
-The size of the class can change based upon the [Build Configuration][] so it
-should *not* be treated like a C style array.  To serialize the class to a
-flat array see [VectorPacked](@ref mathfu::VectorPacked).
-
-For example, to pack (store) an unpacked to packed vector:
-
-~~~{.cpp}
-    mathfu::vec3 vector(3.0f, 2.0f, 1.0f);
-    mathfu::vec3_packed packed = vector;
-~~~
-
-Since [VectorPacked][] is plain-old-data (POD) it can be cast to an array
-of elements of the same type used by the [Vector][] so it's possible to use
-an array of [VectorPacked][] data structures to contiguous arrays of data like
-vertex buffers.
-
-Similarly, [VectorPacked][] can be used to deserialize (load) data into
-[Vector][]:
-
-~~~{.cpp}
-    VectorPacked<float, 3> packed = { 3, 2, 1 };
-    Vector<float, 3> vector(packed);
-~~~
-
-<br>
-
-  [Build Configuration]: @ref mathfu_build_config
-  [MathFu]: @ref mathfu_overview
-  [GLSL]: http://www.opengl.org/documentation/glsl/
-  [Vector]: @ref mathfu::Vector
-  [VectorPacked]: @ref mathfu::VectorPacked
diff --git a/third_party/mathfu-1.1.0/docs/src/readme.md b/third_party/mathfu-1.1.0/docs/src/readme.md
deleted file mode 100644
index 2e75a7b..0000000
--- a/third_party/mathfu-1.1.0/docs/src/readme.md
+++ /dev/null
@@ -1 +0,0 @@
-../../readme.md
\ No newline at end of file
diff --git a/third_party/mathfu-1.1.0/include/mathfu/constants.h b/third_party/mathfu-1.1.0/include/mathfu/constants.h
deleted file mode 100644
index e4f58f8..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/constants.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_CONSTANTS_H
-#define MATHFU_CONSTANTS_H
-
-#include "mathfu/matrix.h"
-#include "mathfu/quaternion.h"
-#include "mathfu/vector.h"
-
-namespace mathfu {
-
-/// @file mathfu/constants.h
-/// @brief Vector constants for specific dimensions.
-/// @addtogroup mathfu_constants
-///
-/// It is preferable to use these constants rather than constructing them
-/// when they're required. Construction most-likely slower than loading them
-/// from memory.
-/// <p>
-/// For example, the following:<br>
-/// <code>
-/// lookat = mat4::LookAt(target, position, mathfu::kAxisY3f);
-/// </code>
-/// <br>is preferable to:<br>
-/// <code>
-/// lookat = mat4::LookAt(target, position,
-///                       mathfu::Vector<float, 3>(0.0f, 1.0f, 0.0f));
-/// </code>
-/// <br> in terms of efficiency and in addition to resulting in more concise
-/// code.
-/// </p>
-///
-/// Depending on your linker's sophistication and settings, these constants may
-/// be duplicated in every compilation unit in which they're used. However,
-/// most linkers should be able to detect and eliminate this duplication.
-
-/// @addtogroup mathfu_constants
-/// @{
-
-/// 2-dimensional <code>float</code> Vector of zeros.
-static const Vector<float, 2> kZeros2f(0.0f, 0.0f);
-/// 2-dimensional <code>float</code> Vector of ones.
-static const Vector<float, 2> kOnes2f(1.0f, 1.0f);
-/// 2-dimensional <code>float</code> unit Vector pointing along the X axis.
-static const Vector<float, 2> kAxisX2f(1.0f, 0.0f);
-/// 2-dimensional <code>float</code> unit Vector pointing along the Y axis.
-static const Vector<float, 2> kAxisY2f(0.0f, 1.0f);
-
-/// 3-dimensional <code>float</code> Vector of zeros.
-static const Vector<float, 3> kZeros3f(0.0f, 0.0f, 0.0f);
-/// 3-dimensional <code>float</code> Vector of ones.
-static const Vector<float, 3> kOnes3f(1.0f, 1.0f, 1.0f);
-/// 3-dimensional <code>float</code> unit Vector pointing along the X axis.
-static const Vector<float, 3> kAxisX3f(1.0f, 0.0f, 0.0f);
-/// 3-dimensional <code>float</code> unit Vector pointing along the Y axis.
-static const Vector<float, 3> kAxisY3f(0.0f, 1.0f, 0.0f);
-/// 3-dimensional <code>float</code> unit Vector pointing along the Z axis.
-static const Vector<float, 3> kAxisZ3f(0.0f, 0.0f, 1.0f);
-
-/// 4-dimensional <code>float</code> Vector of zeros.
-static const Vector<float, 4> kZeros4f(0.0f, 0.0f, 0.0f, 0.0f);
-/// 4-dimensional <code>float</code> Vector of ones.
-static const Vector<float, 4> kOnes4f(1.0f, 1.0f, 1.0f, 1.0f);
-/// 4-dimensional <code>float</code> unit Vector pointing along the X axis.
-static const Vector<float, 4> kAxisX4f(1.0f, 0.0f, 0.0f, 0.0f);
-/// 4-dimensional <code>float</code> unit Vector pointing along the Y axis.
-static const Vector<float, 4> kAxisY4f(0.0f, 1.0f, 0.0f, 0.0f);
-/// 4-dimensional <code>float</code> unit Vector pointing along the Z axis.
-static const Vector<float, 4> kAxisZ4f(0.0f, 0.0f, 1.0f, 0.0f);
-/// 4-dimensional <code>float</code> unit Vector pointing along the W axis.
-static const Vector<float, 4> kAxisW4f(0.0f, 0.0f, 0.0f, 1.0f);
-
-/// 2-dimensional <code>double</code> Vector of zeros.
-static const Vector<double, 2> kZeros2d(0.0, 0.0);
-/// 2-dimensional <code>double</code> Vector of ones.
-static const Vector<double, 2> kOnes2d(1.0, 1.0);
-/// 2-dimensional <code>double</code> unit Vector pointing along the X axis.
-static const Vector<double, 2> kAxisX2d(1.0, 0.0);
-/// 2-dimensional <code>double</code> unit Vector pointing along the Y axis.
-static const Vector<double, 2> kAxisY2d(0.0, 1.0);
-
-/// 3-dimensional <code>double</code> Vector of zeros.
-static const Vector<double, 3> kZeros3d(0.0, 0.0, 0.0);
-/// 3-dimensional <code>double</code> Vector of ones.
-static const Vector<double, 3> kOnes3d(1.0, 1.0, 1.0);
-/// 3-dimensional <code>double</code> unit Vector pointing along the X axis.
-static const Vector<double, 3> kAxisX3d(1.0, 0.0, 0.0);
-/// 3-dimensional <code>double</code> unit Vector pointing along the Y axis.
-static const Vector<double, 3> kAxisY3d(0.0, 1.0, 0.0);
-/// 3-dimensional <code>double</code> unit Vector pointing along the Z axis.
-static const Vector<double, 3> kAxisZ3d(0.0, 0.0, 1.0);
-
-/// 4-dimensional <code>double</code> Vector of zeros.
-static const Vector<double, 4> kZeros4d(0.0, 0.0, 0.0, 0.0);
-/// 4-dimensional <code>double</code> Vector of ones.
-static const Vector<double, 4> kOnes4d(1.0, 1.0, 1.0, 1.0);
-/// 4-dimensional <code>double</code> unit Vector pointing along the X axis.
-static const Vector<double, 4> kAxisX4d(1.0, 0.0, 0.0, 0.0);
-/// 4-dimensional <code>double</code> unit Vector pointing along the Y axis.
-static const Vector<double, 4> kAxisY4d(0.0, 1.0, 0.0, 0.0);
-/// 4-dimensional <code>double</code> unit Vector pointing along the Z axis.
-static const Vector<double, 4> kAxisZ4d(0.0, 0.0, 1.0, 0.0);
-/// 4-dimensional <code>double</code> unit Vector pointing along the W axis.
-static const Vector<double, 4> kAxisW4d(0.0, 0.0, 0.0, 1.0);
-
-/// 2-dimensional <code>int</code> Vector of zeros.
-static const Vector<int, 2> kOnes2i(1, 1);
-/// 2-dimensional <code>int</code> Vector of ones.
-static const Vector<int, 2> kZeros2i(0, 0);
-/// 2-dimensional <code>int</code> unit Vector pointing along the X axis.
-static const Vector<int, 2> kAxisX2i(1, 0);
-/// 2-dimensional <code>int</code> unit Vector pointing along the Y axis.
-static const Vector<int, 2> kAxisY2i(0, 1);
-
-/// 3-dimensional <code>int</code> Vector of zeros.
-static const Vector<int, 3> kZeros3i(0, 0, 0);
-/// 3-dimensional <code>int</code> Vector of ones.
-static const Vector<int, 3> kOnes3i(1, 1, 1);
-/// 3-dimensional <code>int</code> unit Vector pointing along the X axis.
-static const Vector<int, 3> kAxisX3i(1, 0, 0);
-/// 3-dimensional <code>int</code> unit Vector pointing along the Y axis.
-static const Vector<int, 3> kAxisY3i(0, 1, 0);
-/// 3-dimensional <code>int</code> unit Vector pointing along the Z axis.
-static const Vector<int, 3> kAxisZ3i(0, 0, 1);
-
-/// 4-dimensional <code>int</code> Vector of zeros.
-static const Vector<int, 4> kZeros4i(0, 0, 0, 0);
-/// 4-dimensional <code>int</code> Vector of ones.
-static const Vector<int, 4> kOnes4i(1, 1, 1 ,1);
-/// 4-dimensional <code>int</code> unit Vector pointing along the X axis.
-static const Vector<int, 4> kAxisX4i(1, 0, 0, 0);
-/// 4-dimensional <code>int</code> unit Vector pointing along the Z axis.
-static const Vector<int, 4> kAxisY4i(0, 1, 0, 0);
-/// 4-dimensional <code>int</code> unit Vector pointing along the Y axis.
-static const Vector<int, 4> kAxisZ4i(0, 0, 1, 0);
-/// 4-dimensional <code>int</code> unit Vector pointing along the W axis.
-static const Vector<int, 4> kAxisW4i(0, 0, 0, 1);
-
-/// Quaternion Identity
-static const Quaternion<float> kQuatIdentityf(1.0f, 0.0f, 0.0f, 0.0f);
-/// Quaternion Identity
-static const Quaternion<double> kQuatIdentityd(1.0, 0.0, 0.0, 0.0);
-
-// An AffineTransform versoin of the mat4 Identity matrix.
-static const AffineTransform kAffineIdentity(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-                                             0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-                                             0.0f);
-/// @}
-
-}  // namespace mathfu
-
-#endif  // MATHFU_CONSTANTS_H
diff --git a/third_party/mathfu-1.1.0/include/mathfu/glsl_mappings.h b/third_party/mathfu-1.1.0/include/mathfu/glsl_mappings.h
deleted file mode 100644
index d00d828..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/glsl_mappings.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_GLSL_MAPPINGS_H_
-#define MATHFU_GLSL_MAPPINGS_H_
-
-#include "mathfu/matrix.h"
-#include "mathfu/quaternion.h"
-#include "mathfu/rect.h"
-#include "mathfu/vector.h"
-
-/// @file mathfu/glsl_mappings.h
-/// @brief GLSL compatible data types.
-/// @addtogroup mathfu_glsl
-///
-/// To simplify the use of MathFu template classes and make it possible to
-/// write code that looks similar to
-/// <a href="http://www.opengl.org/documentation/glsl/">GLSL</a> in C++,
-/// MathFu provides a set of data types that are similar in style to
-/// GLSL Vector and Matrix data types.
-
-/// @brief Namespace for MathFu library.
-namespace mathfu {
-
-/// @addtogroup mathfu_glsl
-/// @{
-
-/// 2-dimensional <code>float</code> Vector.
-typedef Vector<float, 2> vec2;
-/// 3-dimensional <code>float</code> Vector.
-typedef Vector<float, 3> vec3;
-/// 4-dimensional <code>float</code> Vector.
-typedef Vector<float, 4> vec4;
-
-/// 2-dimensional <code>int</code> Vector.
-typedef Vector<int, 2> vec2i;
-/// 3-dimensional <code>int</code> Vector.
-typedef Vector<int, 3> vec3i;
-/// 4-dimensional <code>int</code> Vector.
-typedef Vector<int, 4> vec4i;
-
-/// 2x2 <code>float</code> Matrix.
-typedef Matrix<float, 2, 2> mat2;
-/// 3x3 <code>float</code> Matrix.
-typedef Matrix<float, 3, 3> mat3;
-/// 3x3 <code>float</code> Matrix.
-typedef Matrix<float, 4, 4> mat4;
-
-/// 2-dimensional <code>float</code> packed Vector (VectorPacked).
-typedef VectorPacked<float, 2> vec2_packed;
-/// 3-dimensional <code>float</code> packed Vector (VectorPacked).
-typedef VectorPacked<float, 3> vec3_packed;
-/// 4-dimensional <code>float</code> packed Vector (VectorPacked).
-typedef VectorPacked<float, 4> vec4_packed;
-
-/// 2-dimensional <code>int</code> packed Vector (VectorPacked).
-typedef VectorPacked<int, 2> vec2i_packed;
-/// 3-dimensional <code>int</code> packed Vector (VectorPacked).
-typedef VectorPacked<int, 3> vec3i_packed;
-/// 4-dimensional <code>int</code> packed Vector (VectorPacked).
-typedef VectorPacked<int, 4> vec4i_packed;
-
-/// Float-based quaternion.  Note that this is not technically
-/// a GLES type, but is included for convenience.
-typedef mathfu::Quaternion<float> quat;
-
-/// Rect composed of type <code>float</code>.
-typedef Rect<float> rectf;
-/// Rect composed of type <code>double</code>.
-typedef Rect<double> rectd;
-/// Rect composed of type <code>int</code>.
-typedef Rect<int> recti;
-
-/// @brief Calculate the cross product of two 3-dimensional Vectors.
-///
-/// @param v1 Vector to multiply
-/// @param v2 Vector to multiply
-/// @return 3-dimensional vector that contains the result.
-template<class T>
-inline Vector<T, 3> cross(const Vector<T, 3>& v1, const Vector<T, 3>& v2) {
-  return Vector<T, 3>::CrossProduct(v1,v2);
-}
-
-/// @brief Calculate the dot product of two N-dimensional Vectors of any type.
-///
-/// @param v1 Vector to multiply
-/// @param v2 Vector to multiply
-/// @return Scalar dot product result.
-template<class TV>
-inline typename TV::Scalar dot(const TV& v1, const TV& v2) {
-  return TV::DotProduct(v1,v2);
-}
-
-/// @brief Normalize an N-dimensional Vector of an arbitrary type.
-///
-/// @param v1 Vector to normalize.
-/// @return Normalized vector.
-template<class TV>
-inline TV normalize(const TV& v1) {
-  return v1.Normalized();
-}
-
-/// @}
-
-}  // namespace mathfu
-
-#endif  // MATHFU_GLSL_MAPPINGS_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/hlsl_mappings.h b/third_party/mathfu-1.1.0/include/mathfu/hlsl_mappings.h
deleted file mode 100644
index 6db5213..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/hlsl_mappings.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*

-* Copyright 2017 Google Inc. All rights reserved.

-*

-* Licensed under the Apache License, Version 2.0 (the "License");

-* you may not use this file except in compliance with the License.

-* You may obtain a copy of the License at

-*

-*     http://www.apache.org/licenses/LICENSE-2.0

-*

-* Unless required by applicable law or agreed to in writing, software

-* distributed under the License is distributed on an "AS IS" BASIS,

-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-* See the License for the specific language governing permissions and

-* limitations under the License.

-*/

-#ifndef MATHFU_HLSL_MAPPINGS_H_

-#define MATHFU_HLSL_MAPPINGS_H_

-

-#include "mathfu/matrix.h"

-#include "mathfu/quaternion.h"

-#include "mathfu/vector.h"

-

-/// @file mathfu/hlsl_mappings.h

-/// @brief HLSL compatible data types.

-/// @addtogroup mathfu_hlsl

-///

-/// To simplify the use of MathFu template classes and make it possible to

-/// write code that looks similar to

-/// <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb509587(v=vs.85).aspx">HLSL</a> data types in C++,

-/// MathFu provides a set of data types that are similar in style to

-/// HLSL Vector and Matrix data types.

-

-/// @brief Namespace for MathFu library.

-namespace mathfu {

-

-/// @addtogroup mathfu_hlsl

-/// @{

-

-/// Scalar unsigned integer

-typedef unsigned int   uint;

-typedef unsigned int   dword;

-typedef unsigned short half;

-

-/// 2-dimensional <code>float</code> Vector.

-typedef Vector<float, 2> float2;

-/// 3-dimensional <code>float</code> Vector.

-typedef Vector<float, 3> float3;

-/// 4-dimensional <code>float</code> Vector.

-typedef Vector<float, 4> float4;

-

-/// 2-dimensional <code>int</code> Vector.

-typedef Vector<int, 2> int2;

-/// 3-dimensional <code>int</code> Vector.

-typedef Vector<int, 3> int3;

-/// 4-dimensional <code>int</code> Vector.

-typedef Vector<int, 4> int4;

-

-/// 2-dimensional <code>uint</code> Vector.

-typedef Vector<uint, 2> uint2;

-/// 3-dimensional <code>uint</code> Vector.

-typedef Vector<uint, 3> uint3;

-/// 4-dimensional <code>uint</code> Vector.

-typedef Vector<uint, 4> uint4;

-

-/// 1x1 <code>float</code> Matrix.

-typedef Matrix<float, 2, 2> float1x1;

-/// 2x2 <code>float</code> Matrix.

-typedef Matrix<float, 2, 2> float2x2;

-/// 3x3 <code>float</code> Matrix.

-typedef Matrix<float, 3, 3> float3x3;

-/// 3x3 <code>float</code> Matrix.

-typedef Matrix<float, 4, 4> float4x4;

-

-/// 1x1 <code>double</code> Matrix.

-typedef Matrix<double, 2, 2> double1x1;

-/// 2x2 <code>double</code> Matrix.

-typedef Matrix<double, 2, 2> double2x2;

-/// 3x3 <code>double</code> Matrix.

-typedef Matrix<double, 3, 3> double3x3;

-/// 3x3 <code>double</code> Matrix.

-typedef Matrix<double, 4, 4> double4x4;

-

-/// 1x1 <code>int</code> Matrix.

-typedef Matrix<int, 2, 2> int1x1;

-/// 2x2 <code>int</code> Matrix.

-typedef Matrix<int, 2, 2> int2x2;

-/// 3x3 <code>int</code> Matrix.

-typedef Matrix<int, 3, 3> int3x3;

-/// 3x3 <code>int</code> Matrix.

-typedef Matrix<int, 4, 4> int4x4;

-

-/// 1x1 <code>int</code> Matrix.

-typedef Matrix<int, 2, 2> uint1x1;

-/// 2x2 <code>int</code> Matrix.

-typedef Matrix<int, 2, 2> uint2x2;

-/// 3x3 <code>int</code> Matrix.

-typedef Matrix<int, 3, 3> uint3x3;

-/// 3x3 <code>int</code> Matrix.

-typedef Matrix<int, 4, 4> uint4x4;

-

-/// @brief Calculate the cross product of two 3-dimensional Vectors.

-///

-/// @param v1 Vector to multiply

-/// @param v2 Vector to multiply

-/// @return 3-dimensional vector that contains the result.

-template<class T>

-inline Vector<T, 3> cross(const Vector<T, 3>& v1, const Vector<T, 3>& v2) {

-  return Vector<T, 3>::CrossProduct(v1,v2);

-}

-

-/// @brief Calculate the dot product of two N-dimensional Vectors of any type.

-///

-/// @param v1 Vector to multiply

-/// @param v2 Vector to multiply

-/// @return Scalar dot product result.

-template<class TV>

-inline typename TV::Scalar dot(const TV& v1, const TV& v2) {

-  return TV::DotProduct(v1,v2);

-}

-

-/// @brief Normalize an N-dimensional Vector of an arbitrary type.

-///

-/// @param v1 Vector to normalize.

-/// @return Normalized vector.

-template<class TV>

-inline TV normalize(const TV& v1) {

-  return v1.Normalized();

-}

-

-/// @}

-

-}  // namespace mathfu

-

-#endif  // MATHFU_HLSL_MAPPINGS_H_

diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/disable_warnings_begin.h b/third_party/mathfu-1.1.0/include/mathfu/internal/disable_warnings_begin.h
deleted file mode 100644
index 9f7bee1..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/disable_warnings_begin.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-* Copyright 2016 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-// Suppress pedantic warnings.
-// To re-enable, include "mathfu/internal/disable_warnings_end.h".
-//
-// We need this to use anonymous unions and structs, which generate the
-// the following warning in GCC and Clang,
-//     error: ISO C++ prohibits anonymous structs [-Werror=pedantic]
-// The only way to suppress this warning is to turn off all pedantic warnings.
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpedantic"
-#pragma GCC diagnostic ignored "-Wignored-qualifiers"
-#endif  // defined(__GNUC__)
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpedantic"
-#pragma clang diagnostic ignored "-Wignored-qualifiers"
-#endif  // defined(__clang__)
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/disable_warnings_end.h b/third_party/mathfu-1.1.0/include/mathfu/internal/disable_warnings_end.h
deleted file mode 100644
index 8639ff7..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/disable_warnings_end.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-* Copyright 2016 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif  // defined(__clang__)
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif  // defined(__GNUC__)
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/matrix_4x4_simd.h b/third_party/mathfu-1.1.0/include/mathfu/internal/matrix_4x4_simd.h
deleted file mode 100644
index 73dc447..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/matrix_4x4_simd.h
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_MATRIX_4X4_SIMD_H_
-#define MATHFU_MATRIX_4X4_SIMD_H_
-
-#include "mathfu/matrix.h"
-
-#ifdef MATHFU_COMPILE_WITH_SIMD
-#include "vectorial/simd4x4f.h"
-#endif
-
-/// @file mathfu/internal/matrix_4x4_simd.h MathFu Matrix<T, 4, 4>
-///       Specialization
-/// @brief 4x4 specialization of mathfu::Matrix for SIMD optimized builds.
-/// @see mathfu::Matrix
-
-namespace mathfu {
-
-#ifdef MATHFU_COMPILE_WITH_SIMD
-
-static const Vector<float, 4> kAffineWColumn(0.0f, 0.0f, 0.0f, 1.0f);
-
-/// @cond MATHFU_INTERNAL
-template <>
-class Matrix<float, 4> {
- public:
-  Matrix<float, 4>() {}
-
-  inline Matrix<float, 4>(const Matrix<float, 4>& m) {
-    data_.simd_matrix.x = m.data_.simd_matrix.x;
-    data_.simd_matrix.y = m.data_.simd_matrix.y;
-    data_.simd_matrix.z = m.data_.simd_matrix.z;
-    data_.simd_matrix.w = m.data_.simd_matrix.w;
-  }
-
-  explicit inline Matrix<float, 4>(const float& s) {
-    simd4f v = simd4f_create(s, s, s, s);
-    data_.simd_matrix = simd4x4f_create(v, v, v, v);
-  }
-
-  inline Matrix<float, 4>(const float& s00, const float& s10, const float& s20,
-                          const float& s30, const float& s01, const float& s11,
-                          const float& s21, const float& s31, const float& s02,
-                          const float& s12, const float& s22, const float& s32,
-                          const float& s03, const float& s13, const float& s23,
-                          const float& s33) {
-    data_.simd_matrix = simd4x4f_create(
-        simd4f_create(s00, s10, s20, s30), simd4f_create(s01, s11, s21, s31),
-        simd4f_create(s02, s12, s22, s32), simd4f_create(s03, s13, s23, s33));
-  }
-
-  explicit inline Matrix<float, 4>(const float* m) {
-    data_.simd_matrix =
-        simd4x4f_create(simd4f_create(m[0], m[1], m[2], m[3]),
-                        simd4f_create(m[4], m[5], m[6], m[7]),
-                        simd4f_create(m[8], m[9], m[10], m[11]),
-                        simd4f_create(m[12], m[13], m[14], m[15]));
-  }
-
-  inline Matrix<float, 4>(const Vector<float, 4>& column0,
-                          const Vector<float, 4>& column1,
-                          const Vector<float, 4>& column2,
-                          const Vector<float, 4>& column3) {
-#if defined(MATHFU_COMPILE_WITH_PADDING)
-    data_.simd_matrix = simd4x4f_create(column0.data_.simd, column1.data_.simd,
-                                        column2.data_.simd, column3.data_.simd);
-#else
-    data_.simd_matrix = simd4x4f_create(
-        simd4f_create(column0[0], column0[1], column0[2], column0[3]),
-        simd4f_create(column1[0], column1[1], column1[2], column1[3]),
-        simd4f_create(column2[0], column2[1], column2[2], column2[3]),
-        simd4f_create(column3[0], column3[1], column3[2], column3[3]));
-#endif  // defined(MATHFU_COMPILE_WITH_PADDING)
-  }
-
-  explicit inline Matrix(const VectorPacked<float, 4>* const vectors) {
-    data_.simd_matrix.x = simd4f_uload4(vectors[0].data);
-    data_.simd_matrix.y = simd4f_uload4(vectors[1].data);
-    data_.simd_matrix.z = simd4f_uload4(vectors[2].data);
-    data_.simd_matrix.w = simd4f_uload4(vectors[3].data);
-  }
-
-  inline const float& operator()(const int i, const int j) const {
-    return FindElem(i, FindColumn(j));
-  }
-
-  inline float& operator()(const int i, const int j) {
-    return FindElem(i, FindColumn(j));
-  }
-
-  inline const float& operator()(const int i) const {
-    return this->operator[](i);
-  }
-
-  inline float& operator()(const int i) { return this->operator[](i); }
-
-  inline const float& operator[](const int i) const {
-    const int col = i / 4;
-    const int row = i % 4;
-    return FindElem(row, FindColumn(col));
-  }
-
-  inline float& operator[](const int i) {
-    const int col = i / 4;
-    const int row = i % 4;
-    return FindElem(row, FindColumn(col));
-  }
-
-  inline void Pack(VectorPacked<float, 4>* const vector) const {
-    simd4f_ustore4(data_.simd_matrix.x, vector[0].data);
-    simd4f_ustore4(data_.simd_matrix.y, vector[1].data);
-    simd4f_ustore4(data_.simd_matrix.z, vector[2].data);
-    simd4f_ustore4(data_.simd_matrix.w, vector[3].data);
-  }
-
-  inline Matrix<float, 4> operator-() const {
-    Matrix<float, 4> m(0.f);
-    simd4x4f_sub(&m.data_.simd_matrix, &data_.simd_matrix,
-                 &m.data_.simd_matrix);
-    return m;
-  }
-
-  inline Matrix<float, 4> operator+(const Matrix<float, 4>& m) const {
-    Matrix<float, 4> return_m;
-    simd4x4f_add(&data_.simd_matrix, &m.data_.simd_matrix,
-                 &return_m.data_.simd_matrix);
-    return return_m;
-  }
-
-  inline Matrix<float, 4> operator-(const Matrix<float, 4>& m) const {
-    Matrix<float, 4> return_m;
-    simd4x4f_sub(&data_.simd_matrix, &m.data_.simd_matrix,
-                 &return_m.data_.simd_matrix);
-    return return_m;
-  }
-
-  inline Matrix<float, 4> operator*(const float& s) const {
-    Matrix<float, 4> m(s);
-    simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix,
-                 &m.data_.simd_matrix);
-    return m;
-  }
-
-  inline Matrix<float, 4> operator/(const float& s) const {
-    Matrix<float, 4> m(1 / s);
-    simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix,
-                 &m.data_.simd_matrix);
-    return m;
-  }
-
-  inline Vector<float, 3> operator*(const Vector<float, 3>& v) const {
-    Vector<float, 3> return_v;
-    Simd4fUnion temp_v;
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    temp_v.simd = v.data_.simd;
-    temp_v.float_array[3] = 1;
-    simd4x4f_matrix_vector_mul(&data_.simd_matrix, &temp_v.simd,
-                               &return_v.data_.simd);
-    return_v *= (1 / return_v.data_.float_array[3]);
-#else
-    temp_v.simd = simd4f_create(v[0], v[1], v[2], 1.0f);
-    simd4x4f_matrix_vector_mul(&data_.simd_matrix, &temp_v.simd, &temp_v.simd);
-    simd4f_mul(temp_v.simd, simd4f_splat(temp_v.float_array[3]));
-    MATHFU_VECTOR3_STORE3(temp_v.simd, return_v.data_);
-#endif  // MATHFU_COMPILE_WITH_PADDING
-    return return_v;
-  }
-
-  inline Vector<float, 4> operator*(const Vector<float, 4>& v) const {
-    Vector<float, 4> return_v;
-    simd4x4f_matrix_vector_mul(&data_.simd_matrix, &v.data_.simd,
-                               &return_v.data_.simd);
-    return return_v;
-  }
-
-  inline Vector<float, 4> VecMatTimes(const Vector<float, 4>& v) const {
-    return Vector<float, 4>(
-        simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.x),
-        simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.y),
-        simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.z),
-        simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.w));
-  }
-
-  inline Matrix<float, 4> operator*(const Matrix<float, 4>& m) const {
-    Matrix<float, 4> return_m;
-    simd4x4f_matrix_mul(&data_.simd_matrix, &m.data_.simd_matrix,
-                        &return_m.data_.simd_matrix);
-    return return_m;
-  }
-
-  inline Matrix<float, 4> Inverse() const {
-    Matrix<float, 4> return_m;
-    simd4x4f_inverse(&data_.simd_matrix, &return_m.data_.simd_matrix);
-    return return_m;
-  }
-
-  inline bool InverseWithDeterminantCheck(
-      Matrix<float, 4, 4>* const inverse) const {
-    return fabs(simd4f_get_x(simd4x4f_inverse(&data_.simd_matrix,
-                                              &inverse->data_.simd_matrix))) >=
-           Constants<float>::GetDeterminantThreshold();
-  }
-
-  /// Calculate the transpose of matrix.
-  /// @return The transpose of the specified matrix.
-  inline Matrix<float, 4, 4> Transpose() const {
-    Matrix<float, 4, 4> transpose;
-    simd4x4f_transpose(&data_.simd_matrix, &transpose.data_.simd_matrix);
-    return transpose;
-  }
-
-  inline Vector<float, 3> TranslationVector3D() const {
-    Vector<float, 3> return_v;
-    MATHFU_VECTOR3_STORE3(FindColumn(3).simd, return_v.data_);
-    return return_v;
-  }
-
-  inline Matrix<float, 4>& operator+=(const Matrix<float, 4>& m) {
-    simd4x4f_add(&data_.simd_matrix, &m.data_.simd_matrix, &data_.simd_matrix);
-    return *this;
-  }
-
-  inline Matrix<float, 4>& operator-=(const Matrix<float, 4>& m) {
-    simd4x4f_sub(&data_.simd_matrix, &m.data_.simd_matrix, &data_.simd_matrix);
-    return *this;
-  }
-
-  inline Matrix<float, 4>& operator*=(const float& s) {
-    Matrix<float, 4> m(s);
-    simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix, &data_.simd_matrix);
-    return *this;
-  }
-
-  inline Matrix<float, 4>& operator/=(const float& s) {
-    Matrix<float, 4> m(1 / s);
-    simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix, &data_.simd_matrix);
-    return *this;
-  }
-
-  inline Matrix<float, 4> operator*=(const Matrix<float, 4>& m) {
-    Matrix<float, 4> copy_of_this(*this);
-    simd4x4f_matrix_mul(&copy_of_this.data_.simd_matrix, &m.data_.simd_matrix,
-                        &data_.simd_matrix);
-    return *this;
-  }
-
-  template <typename CompatibleT>
-  static inline Matrix<float, 4> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<float, 4, 4, CompatibleT>(compatible);
-  }
-
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Matrix<float, 4>& m) {
-    return ToTypeHelper<float, 4, 4, CompatibleT>(m);
-  }
-
-  static inline Matrix<float, 4> OuterProduct(const Vector<float, 4>& v1,
-                                              const Vector<float, 4>& v2) {
-    Matrix<float, 4> m;
-    m.data_.simd_matrix =
-        simd4x4f_create(simd4f_mul(v1.data_.simd, simd4f_splat(v2[0])),
-                        simd4f_mul(v1.data_.simd, simd4f_splat(v2[1])),
-                        simd4f_mul(v1.data_.simd, simd4f_splat(v2[2])),
-                        simd4f_mul(v1.data_.simd, simd4f_splat(v2[3])));
-    return m;
-  }
-
-  static inline Matrix<float, 4> HadamardProduct(const Matrix<float, 4>& m1,
-                                                 const Matrix<float, 4>& m2) {
-    Matrix<float, 4> return_m;
-    simd4x4f_mul(&m1.data_.simd_matrix, &m2.data_.simd_matrix,
-                 &return_m.data_.simd_matrix);
-    return return_m;
-  }
-
-  static inline Matrix<float, 4> Identity() {
-    Matrix<float, 4> return_m;
-    simd4x4f_identity(&return_m.data_.simd_matrix);
-    return return_m;
-  }
-
-  static inline Matrix<float, 4> FromTranslationVector(
-      const Vector<float, 3>& v) {
-    return Matrix<float, 4>(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, v[0], v[1],
-                            v[2], 1);
-  }
-
-  static inline Matrix<float, 4> FromScaleVector(const Vector<float, 3>& v) {
-    return Matrix<float, 4>(v[0], 0, 0, 0, 0, v[1], 0, 0, 0, 0, v[2], 0, 0, 0,
-                            0, 1);
-  }
-
-  static inline Matrix<float, 4> FromRotationMatrix(const Matrix<float, 3>& m) {
-    return Matrix<float, 4>(m[0], m[1], m[2], 0, m[3], m[4], m[5], 0, m[6],
-                            m[7], m[8], 0, 0, 0, 0, 1);
-  }
-
-  /// @brief Constructs a Matrix<float, 4> from an AffineTransform.
-  ///
-  /// @param affine An AffineTransform reference to be used to construct
-  /// a Matrix<float, 4> by adding in the 'w' row of [0, 0, 0, 1].
-  static inline Matrix<float, 4> FromAffineTransform(
-      const AffineTransform& affine) {
-    Matrix<float, 4> m;
-    m.data_.simd_matrix.x = simd4f_uload4(&affine[0]);
-    m.data_.simd_matrix.y = simd4f_uload4(&affine[4]);
-    m.data_.simd_matrix.z = simd4f_uload4(&affine[8]);
-    m.data_.simd_matrix.w = simd4f_uload4(&kAffineWColumn[0]);
-    return m.Transpose();
-  }
-
-  /// @brief Converts a Matrix<float, 4> into an AffineTransform.
-  ///
-  /// @param m A Matrix<float, 4> reference to be converted into an
-  /// AffineTransform by dropping the fixed 'w' row.
-  ///
-  /// @return Returns an AffineTransform that contains the essential
-  /// transformation data from the Matrix<float, 4>.
-  static inline AffineTransform ToAffineTransform(const Matrix<float, 4>& m) {
-    AffineTransform affine;
-    const Matrix<float, 4> mt = m.Transpose();
-    simd4f_ustore4(mt.data_.simd_matrix.x, &affine[0]);
-    simd4f_ustore4(mt.data_.simd_matrix.y, &affine[4]);
-    simd4f_ustore4(mt.data_.simd_matrix.z, &affine[8]);
-    return affine;
-  }
-
-  /// Create a 4x4 perpective matrix.
-  /// @handedness: 1.0f for RH, -1.0f for LH
-  static inline Matrix<float, 4, 4> Perspective(float fovy, float aspect,
-                                                float znear, float zfar,
-                                                float handedness = 1.0f) {
-    return PerspectiveHelper(fovy, aspect, znear, zfar, handedness);
-  }
-
-  /// Create a 4x4 orthographic matrix.
-  /// @param handedness 1.0f for RH, -1.0f for LH
-  static inline Matrix<float, 4, 4> Ortho(float left, float right, float bottom,
-                                          float top, float znear, float zfar,
-                                          float handedness = 1.0f) {
-    return OrthoHelper(left, right, bottom, top, znear, zfar, handedness);
-  }
-
-  /// Create a 3-dimensional camera matrix.
-  /// @param at The look-at target of the camera.
-  /// @param eye The position of the camera.
-  /// @param up The up vector in the world, for example (0, 1, 0) if the
-  /// @handedness: 1.0f for RH, -1.0f for LH
-  /// TODO: Change default handedness to 1.0f, to match Perspective().
-  /// y-axis is up.
-  static inline Matrix<float, 4, 4> LookAt(const Vector<float, 3>& at,
-                                           const Vector<float, 3>& eye,
-                                           const Vector<float, 3>& up,
-                                           float handedness = -1.0f) {
-    return LookAtHelper(at, eye, up, handedness);
-  }
-
-  /// @brief Get the 3D position in object space from a window coordinate.
-  ///
-  /// @param window_coord The window coordinate. The z value is for depth.
-  /// A window coordinate on the near plane will have 0 as the z value.
-  /// And a window coordinate on the far plane will have 1 as the z value.
-  /// z value should be with in [0, 1] here.
-  /// @param model_view The Model View matrix.
-  /// @param projection The projection matrix.
-  /// @param window_width Width of the window.
-  /// @param window_height Height of the window.
-  /// @return the mapped 3D position in object space.
-  static inline Vector<float, 3> UnProject(
-      const Vector<float, 3>& window_coord,
-      const Matrix<float, 4, 4>& model_view,
-      const Matrix<float, 4, 4>& projection, const float window_width,
-      const float window_height) {
-    Vector<float, 3> result;
-    UnProjectHelper(window_coord, model_view, projection, window_width,
-                    window_height, result);
-    return result;
-  }
-
-  // Dimensions of the matrix.
-  /// Number of rows in the matrix.
-  static const int kRows = 4;
-  /// Number of columns in the matrix.
-  static const int kColumns = 4;
-  /// Total number of elements in the matrix.
-  static const int kElements = 4 * 4;
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
- private:
-  inline const Simd4fUnion& FindColumn(const int i) const {
-    return data_.simd4f_union_array[i];
-  }
-
-  inline Simd4fUnion& FindColumn(const int i) {
-    return data_.simd4f_union_array[i];
-  }
-
-  static inline const float& FindElem(const int i, const Simd4fUnion& column) {
-    return column.float_array[i];
-  }
-
-  static inline float& FindElem(const int i, Simd4fUnion& column) {
-    return column.float_array[i];
-  }
-
-  // Contents of the Matrix in different representations to work around
-  // strict aliasing rules.
-  union {
-    simd4x4f simd_matrix;
-    Simd4fUnion simd4f_union_array[4];
-    float float_array[16];
-  } data_;
-};
-
-inline Matrix<float, 4> operator*(const float& s, const Matrix<float, 4>& m) {
-  return m * s;
-}
-
-inline Vector<float, 4> operator*(const Vector<float, 4>& v,
-                                  const Matrix<float, 4>& m) {
-  return m.VecMatTimes(v);
-}
-/// @endcond
-#endif  // MATHFU_COMPILE_WITH_SIMD
-}  // namespace mathfu
-
-#endif  // MATHFU_MATRIX_4X4_SIMD_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_2.h b/third_party/mathfu-1.1.0/include/mathfu/internal/vector_2.h
deleted file mode 100644
index 01c5b50..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_2.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-* Copyright 2016 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_INTERNAL_VECTOR_2_H_
-#define MATHFU_INTERNAL_VECTOR_2_H_
-
-#include "mathfu/vector.h"
-
-namespace mathfu {
-
-template <class T>
-class Vector<T, 2> {
- public:
-  typedef T Scalar;
-  static const int d = 2;
-
-  inline Vector() {}
-
-  inline Vector(const Vector<T, 2>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
-  }
-
-  template <typename U>
-  explicit inline Vector(const Vector<U, 2>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
-  }
-
-  explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
-
-  explicit inline Vector(const T* a) {
-    MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
-  }
-
-  inline Vector(const T& s1, const T& s2) {
-    x = s1;
-    y = s2;
-  }
-
-  explicit inline Vector(const VectorPacked<T, 2>& vector) {
-    MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
-  }
-
-  inline T& operator()(const int i) { return data_[i]; }
-
-  inline const T& operator()(const int i) const { return data_[i]; }
-
-  inline T& operator[](const int i) { return data_[i]; }
-
-  inline const T& operator[](const int i) const { return data_[i]; }
-
-  inline Vector<T, 2> xy() { return Vector<T, 2>(x, y); }
-
-  inline const Vector<T, 2> xy() const { return Vector<T, 2>(x, y); }
-
-  inline void Pack(VectorPacked<T, 2>* const vector) const {
-    MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
-  }
-
-  inline T LengthSquared() const { return LengthSquaredHelper(*this); }
-
-  inline T Length() const { return LengthHelper(*this); }
-
-  inline T Normalize() { return NormalizeHelper(*this); }
-
-  inline Vector<T, 2> Normalized() const { return NormalizedHelper(*this); }
-
-  template <typename CompatibleT>
-  static inline Vector<T, 2> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<T, d, CompatibleT>(compatible);
-  }
-
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Vector<T, 2>& v) {
-    return ToTypeHelper<T, d, CompatibleT>(v);
-  }
-
-  static inline T DotProduct(const Vector<T, 2>& v1, const Vector<T, 2>& v2) {
-    return DotProductHelper(v1, v2);
-  }
-
-  static inline Vector<T, 2> HadamardProduct(const Vector<T, 2>& v1,
-                                             const Vector<T, 2>& v2) {
-    return HadamardProductHelper(v1, v2);
-  }
-
-  static inline Vector<T, 2> Lerp(const Vector<T, 2>& v1,
-                                  const Vector<T, 2>& v2, const T percent) {
-    return LerpHelper(v1, v2, percent);
-  }
-
-  static inline Vector<T, 2> RandomInRange(const Vector<T, 2>& min,
-                                           const Vector<T, 2>& max) {
-    return RandomInRangeHelper(min, max);
-  }
-
-  static inline Vector<T, 2> Max(const Vector<T, 2>& v1,
-                                 const Vector<T, 2>& v2) {
-    return MaxHelper(v1, v2);
-  }
-
-  static inline Vector<T, 2> Min(const Vector<T, 2>& v1,
-                                 const Vector<T, 2>& v2) {
-    return MinHelper(v1, v2);
-  }
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  union {
-    T data_[2];
-    struct {
-      T x;
-      T y;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-
-template <class T>
-struct VectorPacked<T, 2> {
-  /// Create an uninitialized VectorPacked.
-  VectorPacked() {}
-
-  /// Create a VectorPacked from a Vector.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to create the VectorPacked from.
-  explicit VectorPacked(const Vector<T, 2>& vector) { vector.Pack(this); }
-
-  /// Copy a Vector to a VectorPacked.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to copy to the VectorPacked.
-  /// @returns A reference to this VectorPacked.
-  VectorPacked& operator=(const Vector<T, 2>& vector) {
-    vector.Pack(this);
-    return *this;
-  }
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  /// Elements of the packed vector one per dimension.
-  union {
-    T data[2];
-    struct {
-      T x;
-      T y;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-
-}  //  namespace mathfu
-
-#endif  // MATHFU_INTERNAL_VECTOR_2_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_2_simd.h b/third_party/mathfu-1.1.0/include/mathfu/internal/vector_2_simd.h
deleted file mode 100644
index 21ea74e..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_2_simd.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_VECTOR_2_SIMD_H_
-#define MATHFU_VECTOR_2_SIMD_H_
-
-#include "mathfu/internal/vector_2.h"
-#include "mathfu/utilities.h"
-
-#include <math.h>
-
-/// @file mathfu/internal/vector_2_simd.h MathFu Vector<T, 2> Specialization
-/// @brief 2-dimensional specialization of mathfu::Vector for SIMD optimized
-/// builds.
-/// @see mathfu::Vector
-
-#if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) && defined(__ARM_NEON__)
-#include <vectorial/simd2f.h>
-#endif
-
-namespace mathfu {
-
-#if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) && defined(__ARM_NEON__)
-/// @cond MATHFU_INTERNAL
-template <>
-class Vector<float, 2> {
- public:
-  typedef float Scalar;
-
-  inline Vector() {}
-
-  inline Vector(const Vector<float, 2>& v) { simd = v.simd; }
-
-  explicit inline Vector(const Vector<int, 2>& v) {
-    data_[0] = static_cast<float>(v[0]);
-    data_[1] = static_cast<float>(v[1]);
-  }
-
-  explicit inline Vector(const simd2f& v) { simd = v; }
-
-  explicit inline Vector(const float& s) { simd = simd2f_create(s, s); }
-
-  inline Vector(const float& s1, const float& s2) {
-    simd = simd2f_create(s1, s2);
-  }
-
-  explicit inline Vector(const float* v) { simd = simd2f_uload2(v); }
-
-  explicit inline Vector(const VectorPacked<float, 2>& vector) {
-    simd = simd2f_uload2(vector.data);
-  }
-
-  inline float& operator()(const int i) { return data_[i]; }
-
-  inline const float& operator()(const int i) const { return data_[i]; }
-
-  inline float& operator[](const int i) { return data_[i]; }
-
-  inline const float& operator[](const int i) const { return data_[i]; }
-
-  inline void Pack(VectorPacked<float, 2>* const vector) const {
-    simd2f_ustore2(simd, vector->data);
-  }
-
-  inline Vector<float, 2> operator-() const {
-    return Vector<float, 2>(simd2f_sub(simd2f_zero(), simd));
-  }
-
-  inline Vector<float, 2> operator*(const Vector<float, 2>& v) const {
-    return Vector<float, 2>(simd2f_mul(simd, v.simd));
-  }
-
-  inline Vector<float, 2> operator/(const Vector<float, 2>& v) const {
-    return Vector<float, 2>(simd2f_div(simd, v.simd));
-  }
-
-  inline Vector<float, 2> operator+(const Vector<float, 2>& v) const {
-    return Vector<float, 2>(simd2f_add(simd, v.simd));
-  }
-
-  inline Vector<float, 2> operator-(const Vector<float, 2>& v) const {
-    return Vector<float, 2>(simd2f_sub(simd, v.simd));
-  }
-
-  inline Vector<float, 2> operator*(const float& s) const {
-    return Vector<float, 2>(simd2f_mul(simd, simd2f_splat(s)));
-  }
-
-  inline Vector<float, 2> operator/(const float& s) const {
-    return Vector<float, 2>(simd2f_div(simd, simd2f_splat(s)));
-  }
-
-  inline Vector<float, 2> operator+(const float& s) const {
-    return Vector<float, 2>(simd2f_add(simd, simd2f_splat(s)));
-  }
-
-  inline Vector<float, 2> operator-(const float& s) const {
-    return Vector<float, 2>(simd2f_sub(simd, simd2f_splat(s)));
-  }
-
-  inline Vector<float, 2>& operator*=(const Vector<float, 2>& v) {
-    simd = simd2f_mul(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 2>& operator/=(const Vector<float, 2>& v) {
-    simd = simd2f_div(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 2>& operator+=(const Vector<float, 2>& v) {
-    simd = simd2f_add(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 2>& operator-=(const Vector<float, 2>& v) {
-    simd = simd2f_sub(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 2>& operator*=(const float& s) {
-    simd = simd2f_mul(simd, simd2f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 2>& operator/=(const float& s) {
-    simd = simd2f_div(simd, simd2f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 2>& operator+=(const float& s) {
-    simd = simd2f_add(simd, simd2f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 2>& operator-=(const float& s) {
-    simd = simd2f_sub(simd, simd2f_splat(s));
-    return *this;
-  }
-
-  inline bool operator==(const Vector<float, 2>& v) const {
-    for (int i = 0; i < 2; ++i) {
-      if ((*this)[i] != v[i]) return false;
-    }
-    return true;
-  }
-
-  inline bool operator!=(const Vector<float, 2>& v) const {
-    return !operator==(v);
-  }
-
-  inline float LengthSquared() const {
-    return simd2f_get_x(simd2f_dot2(simd, simd));
-  }
-
-  inline float Length() const { return simd2f_get_x(simd2f_length2(simd)); }
-
-  inline float Normalize() {
-    const float length = Length();
-    simd = simd2f_mul(simd, simd2f_splat(1 / length));
-    return length;
-  }
-
-  inline Vector<float, 2> Normalized() const {
-    return Vector<float, 2>(simd2f_normalize2(simd));
-  }
-
-  template <typename CompatibleT>
-  static inline Vector<float, 2> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<float, 2, CompatibleT>(compatible);
-  }
-
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Vector<float, 2>& v) {
-    return ToTypeHelper<float, 2, CompatibleT>(v);
-  }
-
-  static inline float DotProduct(const Vector<float, 2>& v1,
-                                 const Vector<float, 2>& v2) {
-    return simd2f_get_x(simd2f_dot2(v1.simd, v2.simd));
-  }
-
-  static inline Vector<float, 2> HadamardProduct(const Vector<float, 2>& v1,
-                                                 const Vector<float, 2>& v2) {
-    return Vector<float, 2>(simd2f_mul(v1.simd, v2.simd));
-  }
-
-  static inline Vector<float, 2> Lerp(const Vector<float, 2>& v1,
-                                      const Vector<float, 2>& v2,
-                                      float percent) {
-    const Vector<float, 2> percentv(percent);
-    const Vector<float, 2> one_minus_percent(
-        simd2f_sub(simd2f_splat(1.0f), percentv.simd));
-    return Vector<float, 2>(
-        simd2f_add(simd2f_mul(one_minus_percent.simd, v1.simd),
-                   simd2f_mul(percentv.simd, v2.simd)));
-  }
-
-  /// Generates a random vector, where the range for each component is
-  /// bounded by min and max.
-  static inline Vector<float, 2> RandomInRange(const Vector<float, 2>& min,
-                                               const Vector<float, 2>& max) {
-    return Vector<float, 2>(mathfu::RandomInRange<float>(min[0], max[0]),
-                            mathfu::RandomInRange<float>(min[1], max[1]));
-  }
-
-  static inline Vector<float, 2> Max(const Vector<float, 2>& v1,
-                                     const Vector<float, 2>& v2) {
-    return Vector<float, 2>(std::max(v1[0], v2[0]), std::max(v1[1], v2[1]));
-  }
-
-  static inline Vector<float, 2> Min(const Vector<float, 2>& v1,
-                                     const Vector<float, 2>& v2) {
-    return Vector<float, 2>(std::min(v1[0], v2[0]), std::min(v1[1], v2[1]));
-  }
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpedantic"
-#endif  // defined(__clang__)
-  union {
-    simd2f simd;
-    float data_[2];
-    struct {
-      float x;
-      float y;
-    };
-  };
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif  // defined(__clang__)
-};
-/// @endcond
-#endif  // !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) &&
-        // defined(__ARM_NEON__)
-
-}  // namespace mathfu
-
-#endif  // MATHFU_VECTOR_2_SIMD_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_3.h b/third_party/mathfu-1.1.0/include/mathfu/internal/vector_3.h
deleted file mode 100644
index 3e38335..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_3.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-* Copyright 2016 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_INTERNAL_VECTOR_3_H_
-#define MATHFU_INTERNAL_VECTOR_3_H_
-
-#include "mathfu/vector.h"
-
-namespace mathfu {
-
-template <class T>
-class Vector<T, 3> {
- public:
-  typedef T Scalar;
-  static const int d = 3;
-
-  inline Vector() {}
-
-  inline Vector(const Vector<T, 3>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
-  }
-
-  template <typename U>
-  explicit inline Vector(const Vector<U, 3>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
-  }
-
-  explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
-
-  explicit inline Vector(const T* a) {
-    MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
-  }
-
-  inline Vector(const T& s1, const T& s2, const T& s3) {
-    x = s1;
-    y = s2;
-    z = s3;
-  }
-
-  inline Vector(const Vector<T, 2>& v12, const T& s3) {
-    x = v12[0];
-    y = v12[1];
-    z = s3;
-  }
-
-  explicit inline Vector(const VectorPacked<T, 3>& vector) {
-    MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
-  }
-
-  inline T& operator()(const int i) { return data_[i]; }
-
-  inline const T& operator()(const int i) const { return data_[i]; }
-
-  inline T& operator[](const int i) { return data_[i]; }
-
-  inline const T& operator[](const int i) const { return data_[i]; }
-
-  inline Vector<T, 3> xyz() { return Vector<T, 3>(x, y, z); }
-
-  inline const Vector<T, 3> xyz() const { return Vector<T, 3>(x, y, z); }
-
-  inline Vector<T, 2> xy() { return Vector<T, 2>(x, y); }
-
-  inline const Vector<T, 2> xy() const { return Vector<T, 2>(x, y); }
-
-  inline void Pack(VectorPacked<T, 3>* const vector) const {
-    MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
-  }
-
-  inline T LengthSquared() const { return LengthSquaredHelper(*this); }
-
-  inline T Length() const { return LengthHelper(*this); }
-
-  inline T Normalize() { return NormalizeHelper(*this); }
-
-  inline Vector<T, 3> Normalized() const { return NormalizedHelper(*this); }
-
-  template <typename CompatibleT>
-  static inline Vector<T, 3> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<T, d, CompatibleT>(compatible);
-  }
-
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Vector<T, 3>& v) {
-    return ToTypeHelper<T, d, CompatibleT>(v);
-  }
-
-  static inline T DotProduct(const Vector<T, 3>& v1, const Vector<T, 3>& v2) {
-    return DotProductHelper(v1, v2);
-  }
-
-  static inline Vector<T, 3> HadamardProduct(const Vector<T, 3>& v1,
-                                             const Vector<T, 3>& v2) {
-    return HadamardProductHelper(v1, v2);
-  }
-
-  static inline Vector<T, 3> CrossProduct(const Vector<T, 3>& v1,
-                                          const Vector<T, 3>& v2) {
-    return CrossProductHelper(v1, v2);
-  }
-
-  static inline Vector<T, 3> Lerp(const Vector<T, 3>& v1,
-                                  const Vector<T, 3>& v2, const T percent) {
-    return LerpHelper(v1, v2, percent);
-  }
-
-  static inline Vector<T, 3> RandomInRange(const Vector<T, 3>& min,
-                                           const Vector<T, 3>& max) {
-    return RandomInRangeHelper(min, max);
-  }
-
-  static inline Vector<T, 3> Max(const Vector<T, 3>& v1,
-                                 const Vector<T, 3>& v2) {
-    return MaxHelper(v1, v2);
-  }
-
-  static inline Vector<T, 3> Min(const Vector<T, 3>& v1,
-                                 const Vector<T, 3>& v2) {
-    return MinHelper(v1, v2);
-  }
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  union {
-    T data_[3];
-    struct {
-      T x;
-      T y;
-      T z;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-
-template <class T>
-struct VectorPacked<T, 3> {
-  /// Create an uninitialized VectorPacked.
-  VectorPacked() {}
-
-  /// Create a VectorPacked from a Vector.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to create the VectorPacked from.
-  explicit VectorPacked(const Vector<T, 3>& vector) { vector.Pack(this); }
-
-  /// Copy a Vector to a VectorPacked.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to copy to the VectorPacked.
-  /// @returns A reference to this VectorPacked.
-  VectorPacked& operator=(const Vector<T, 3>& vector) {
-    vector.Pack(this);
-    return *this;
-  }
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  /// Elements of the packed vector one per dimension.
-  union {
-    T data[3];
-    struct {
-      T x;
-      T y;
-      T z;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-
-}  //  namespace mathfu
-
-#endif  // MATHFU_INTERNAL_VECTOR_3_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_3_simd.h b/third_party/mathfu-1.1.0/include/mathfu/internal/vector_3_simd.h
deleted file mode 100644
index a0af830..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_3_simd.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_VECTOR_3_SIMD_H_
-#define MATHFU_VECTOR_3_SIMD_H_
-
-#include "mathfu/internal/vector_3.h"
-#include "mathfu/utilities.h"
-
-#include <math.h>
-
-#ifdef MATHFU_COMPILE_WITH_SIMD
-#include "vectorial/simd4f.h"
-#endif
-
-/// @file mathfu/internal/vector_3_simd.h MathFu Vector<T, 3> Specialization
-/// @brief 3-dimensional specialization of mathfu::Vector for SIMD optimized
-/// builds.
-/// @see mathfu::Vector
-
-/// @cond MATHFU_INTERNAL
-/// Add macros to account for both the case where the vector is stored as a
-/// simd intrinsic using 4 elements or as 3 values of type T.
-/// MATHFU_VECTOR3_STORE3/MATHFU_VECTOR3_LOAD3 are additional operations used
-/// to load/store the non simd values from and to simd datatypes. If intrinsics
-/// are used these amount to essentially noops. MATHFU_VECTOR3_INIT3 either
-/// creates a simd datatype if the intrinsic is used or sets the T values if
-/// not.
-#ifdef MATHFU_COMPILE_WITH_PADDING
-#define MATHFU_VECTOR3_STORE3(simd_to_store, data) \
-  { (data).simd = simd_to_store; }
-#define MATHFU_VECTOR3_LOAD3(data) (data).simd
-#define MATHFU_VECTOR3_INIT3(data, v1, v2, v3) \
-  { (data).simd = simd4f_create(v1, v2, v3, 0); }
-#else
-#define MATHFU_VECTOR3_STORE3(simd_to_store, data) \
-  { simd4f_ustore3(simd_to_store, (data).data_); }
-#define MATHFU_VECTOR3_LOAD3(data) simd4f_uload3((data).data_)
-#define MATHFU_VECTOR3_INIT3(data, v1, v2, v3) \
-  {                                            \
-    (data).data_[0] = v1;                      \
-    (data).data_[1] = v2;                      \
-    (data).data_[2] = v3;                      \
-  }
-#endif  // MATHFU_COMPILE_WITH_PADDING
-/// @endcond
-
-namespace mathfu {
-
-#ifdef MATHFU_COMPILE_WITH_SIMD
-/// @cond MATHFU_INTERNAL
-// This class should remain plain old data.
-template <>
-class Vector<float, 3> {
- public:
-  typedef float Scalar;
-
-  inline Vector() {}
-
-  inline Vector(const Vector<float, 3>& v) {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    simd = v.simd;
-#else
-    MATHFU_VECTOR3_INIT3(*this, v[0], v[1], v[2]);
-#endif  // MATHFU_COMPILE_WITH_PADDING
-  }
-
-  explicit inline Vector(const Vector<int, 3>& v) {
-    MATHFU_VECTOR3_INIT3(*this, static_cast<float>(v[0]),
-                         static_cast<float>(v[1]), static_cast<float>(v[2]));
-  }
-
-  inline Vector(const simd4f& v) { MATHFU_VECTOR3_STORE3(v, *this); }
-
-  explicit inline Vector(const float& s) {
-    MATHFU_VECTOR3_INIT3(*this, s, s, s);
-  }
-
-  inline Vector(const float& v1, const float& v2, const float& v3) {
-    MATHFU_VECTOR3_INIT3(*this, v1, v2, v3);
-  }
-
-  inline Vector(const Vector<float, 2>& v12, const float& v3) {
-    MATHFU_VECTOR3_INIT3(*this, v12[0], v12[1], v3);
-  }
-
-  explicit inline Vector(const float* v) {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    simd = simd4f_uload3(v);
-#else
-    MATHFU_VECTOR3_INIT3(*this, v[0], v[1], v[2]);
-#endif  // MATHFU_COMPILE_WITH_PADDING
-  }
-
-  explicit inline Vector(const VectorPacked<float, 3>& vector) {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    simd = simd4f_uload3(vector.data);
-#else
-    MATHFU_VECTOR3_INIT3(*this, vector.data[0], vector.data[1], vector.data[2]);
-#endif  // MATHFU_COMPILE_WITH_PADDING
-  }
-
-  inline float& operator()(const int i) { return data_[i]; }
-
-  inline const float& operator()(const int i) const { return data_[i]; }
-
-  inline float& operator[](const int i) { return data_[i]; }
-
-  inline const float& operator[](const int i) const { return data_[i]; }
-
-  /// GLSL style multi-component accessors.
-  inline Vector<float, 2> xy() { return Vector<float, 2>(x, y); }
-  inline const Vector<float, 2> xy() const { return Vector<float, 2>(x, y); }
-
-  inline void Pack(VectorPacked<float, 3>* const vector) const {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    simd4f_ustore3(simd, vector->data);
-#else
-    vector->data[0] = data_[0];
-    vector->data[1] = data_[1];
-    vector->data[2] = data_[2];
-#endif  // MATHFU_COMPILE_WITH_PADDING
-  }
-
-  inline Vector<float, 3> operator-() const {
-    return Vector<float, 3>(
-        simd4f_sub(simd4f_zero(), MATHFU_VECTOR3_LOAD3(*this)));
-  }
-
-  inline Vector<float, 3> operator*(const Vector<float, 3>& v) const {
-    return Vector<float, 3>(
-        simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
-  }
-
-  inline Vector<float, 3> operator/(const Vector<float, 3>& v) const {
-    return Vector<float, 3>(
-        simd4f_div(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
-  }
-
-  inline Vector<float, 3> operator+(const Vector<float, 3>& v) const {
-    return Vector<float, 3>(
-        simd4f_add(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
-  }
-
-  inline Vector<float, 3> operator-(const Vector<float, 3>& v) const {
-    return Vector<float, 3>(
-        simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
-  }
-
-  inline Vector<float, 3> operator*(const float& s) const {
-    return Vector<float, 3>(
-        simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
-  }
-
-  inline Vector<float, 3> operator/(const float& s) const {
-    return Vector<float, 3>(
-        simd4f_div(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
-  }
-
-  inline Vector<float, 3> operator+(const float& s) const {
-    return Vector<float, 3>(
-        simd4f_add(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
-  }
-
-  inline Vector<float, 3> operator-(const float& s) const {
-    return Vector<float, 3>(
-        simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
-  }
-
-  inline Vector<float, 3>& operator*=(const Vector<float, 3>& v) {
-    *this = simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
-    return *this;
-  }
-
-  inline Vector<float, 3>& operator/=(const Vector<float, 3>& v) {
-    *this = simd4f_div(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
-    return *this;
-  }
-
-  inline Vector<float, 3>& operator+=(const Vector<float, 3>& v) {
-    *this = simd4f_add(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
-    return *this;
-  }
-
-  inline Vector<float, 3>& operator-=(const Vector<float, 3>& v) {
-    *this = simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
-    return *this;
-  }
-
-  inline Vector<float, 3>& operator*=(const float& s) {
-    *this = simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 3>& operator/=(const float& s) {
-    *this = simd4f_div(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 3>& operator+=(const float& s) {
-    *this = simd4f_add(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 3>& operator-=(const float& s) {
-    *this = simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
-    return *this;
-  }
-
-  inline bool operator==(const Vector<float, 3>& v) const {
-    for (int i = 0; i < 3; ++i) {
-      if ((*this)[i] != v[i]) return false;
-    }
-    return true;
-  }
-
-  inline bool operator!=(const Vector<float, 3>& v) const {
-    return !operator==(v);
-  }
-
-  inline float LengthSquared() const {
-    return simd4f_dot3_scalar(MATHFU_VECTOR3_LOAD3(*this),
-                              MATHFU_VECTOR3_LOAD3(*this));
-  }
-
-  inline float Length() const {
-    return simd4f_get_x(simd4f_length3(MATHFU_VECTOR3_LOAD3(*this)));
-  }
-
-  inline float Normalize() {
-    const float length = Length();
-    *this = simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(1 / length));
-    return length;
-  }
-
-  inline Vector<float, 3> Normalized() const {
-    return Vector<float, 3>(simd4f_normalize3(MATHFU_VECTOR3_LOAD3(*this)));
-  }
-
-  template <typename CompatibleT>
-  static inline Vector<float, 3> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<float, 3, CompatibleT>(compatible);
-  }
-
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Vector<float, 3>& v) {
-    return ToTypeHelper<float, 3, CompatibleT>(v);
-  }
-
-  static inline float DotProduct(const Vector<float, 3>& v1,
-                                 const Vector<float, 3>& v2) {
-    return simd4f_dot3_scalar(MATHFU_VECTOR3_LOAD3(v1),
-                              MATHFU_VECTOR3_LOAD3(v2));
-  }
-
-  static inline Vector<float, 3> CrossProduct(const Vector<float, 3>& v1,
-                                              const Vector<float, 3>& v2) {
-    return Vector<float, 3>(
-        simd4f_cross3(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
-  }
-
-  static inline Vector<float, 3> HadamardProduct(const Vector<float, 3>& v1,
-                                                 const Vector<float, 3>& v2) {
-    return Vector<float, 3>(
-        simd4f_mul(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
-  }
-
-  static inline Vector<float, 3> Lerp(const Vector<float, 3>& v1,
-                                      const Vector<float, 3>& v2,
-                                      float percent) {
-    const Vector<float, 3> percentv(percent);
-    const Vector<float, 3> one(1.0f);
-    const Vector<float, 3> one_minus_percent = one - percentv;
-    return Vector<float, 3>(simd4f_add(
-        simd4f_mul(MATHFU_VECTOR3_LOAD3(one_minus_percent),
-                   MATHFU_VECTOR3_LOAD3(v1)),
-        simd4f_mul(MATHFU_VECTOR3_LOAD3(percentv), MATHFU_VECTOR3_LOAD3(v2))));
-  }
-
-  /// Generates a random vector, where the range for each component is
-  /// bounded by min and max.
-  static inline Vector<float, 3> RandomInRange(const Vector<float, 3>& min,
-                                               const Vector<float, 3>& max) {
-    return Vector<float, 3>(mathfu::RandomInRange<float>(min[0], max[0]),
-                            mathfu::RandomInRange<float>(min[1], max[1]),
-                            mathfu::RandomInRange<float>(min[2], max[2]));
-  }
-
-  static inline Vector<float, 3> Max(const Vector<float, 3>& v1,
-                                     const Vector<float, 3>& v2) {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    return Vector<float, 3>(
-        simd4f_max(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
-#else
-    return Vector<float, 3>(std::max(v1[0], v2[0]), std::max(v1[1], v2[1]),
-                            std::max(v1[2], v2[2]));
-#endif  // MATHFU_COMPILE_WITH_PADDING
-  }
-
-  static inline Vector<float, 3> Min(const Vector<float, 3>& v1,
-                                     const Vector<float, 3>& v2) {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    return Vector<float, 3>(
-        simd4f_min(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
-#else
-    return Vector<float, 3>(std::min(v1[0], v2[0]), std::min(v1[1], v2[1]),
-                            std::min(v1[2], v2[2]));
-#endif  // MATHFU_COMPILE_WITH_PADDING
-  }
-
-  template <class T, int rows, int cols>
-  friend class Matrix;
-  template <class T, int d>
-  friend class Vector;
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  union {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    simd4f simd;
-    float data_[4];
-#else
-    float data_[3];
-#endif  // MATHFU_COMPILE_WITH_PADDING
-
-    struct {
-      float x;
-      float y;
-      float z;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-/// @endcond
-#endif  // MATHFU_COMPILE_WITH_SIMD
-
-}  // namespace mathfu
-
-#endif  // MATHFU_VECTOR_3_SIMD_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_4.h b/third_party/mathfu-1.1.0/include/mathfu/internal/vector_4.h
deleted file mode 100644
index 269ecac..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_4.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
-* Copyright 2016 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_INTERNAL_VECTOR_4_H_
-#define MATHFU_INTERNAL_VECTOR_4_H_
-
-// Prefer including vector.h directly, since it includes specializations.
-#include "mathfu/vector.h"
-
-namespace mathfu {
-
-template <class T>
-class Vector<T, 4> {
- public:
-  typedef T Scalar;
-  static const int d = 4;
-
-  inline Vector() {}
-
-  inline Vector(const Vector<T, 4>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
-  }
-
-  template <typename U>
-  explicit inline Vector(const Vector<U, 4>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
-  }
-
-  explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
-
-  explicit inline Vector(const T* a) {
-    MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
-  }
-
-  inline Vector(const T& s1, const T& s2, const T& s3, const T& s4) {
-    x = s1;
-    y = s2;
-    z = s3;
-    w = s4;
-  }
-
-  inline Vector(const Vector<T, 3>& vector3, const T& value) {
-    x = vector3[0];
-    y = vector3[1];
-    z = vector3[2];
-    w = value;
-  }
-
-  inline Vector(const Vector<T, 2>& v12, const Vector<T, 2>& v34) {
-    x = v12[0];
-    y = v12[1];
-    z = v34[0];
-    w = v34[1];
-  }
-
-  explicit inline Vector(const VectorPacked<T, 4>& vector) {
-    MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
-  }
-
-  inline T& operator()(const int i) { return data_[i]; }
-
-  inline const T& operator()(const int i) const { return data_[i]; }
-
-  inline T& operator[](const int i) { return data_[i]; }
-
-  inline const T& operator[](const int i) const { return data_[i]; }
-
-  inline Vector<T, 3> xyz() { return Vector<T, 3>(x, y, z); }
-
-  inline const Vector<T, 3> xyz() const { return Vector<T, 3>(x, y, z); }
-
-  inline Vector<T, 2> xy() { return Vector<T, 2>(x, y); }
-
-  inline const Vector<T, 2> xy() const { return Vector<T, 2>(x, y); }
-
-  inline Vector<T, 2> zw() { return Vector<T, 2>(z, w); }
-
-  inline const Vector<T, 2> zw() const { return Vector<T, 2>(z, w); }
-
-  inline void Pack(VectorPacked<T, 4>* const vector) const {
-    MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
-  }
-
-  inline T LengthSquared() const { return LengthSquaredHelper(*this); }
-
-  inline T Length() const { return LengthHelper(*this); }
-
-  inline T Normalize() { return NormalizeHelper(*this); }
-
-  inline Vector<T, 4> Normalized() const { return NormalizedHelper(*this); }
-
-  template <typename CompatibleT>
-  static inline Vector<T, 4> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<T, d, CompatibleT>(compatible);
-  }
-
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Vector<T, 4>& v) {
-    return ToTypeHelper<T, d, CompatibleT>(v);
-  }
-
-  static inline T DotProduct(const Vector<T, 4>& v1, const Vector<T, 4>& v2) {
-    return DotProductHelper(v1, v2);
-  }
-
-  static inline Vector<T, 4> HadamardProduct(const Vector<T, 4>& v1,
-                                             const Vector<T, 4>& v2) {
-    return HadamardProductHelper(v1, v2);
-  }
-
-  static inline Vector<T, 4> Lerp(const Vector<T, 4>& v1,
-                                  const Vector<T, 4>& v2, const T percent) {
-    return LerpHelper(v1, v2, percent);
-  }
-
-  static inline Vector<T, 4> RandomInRange(const Vector<T, 4>& min,
-                                           const Vector<T, 4>& max) {
-    return RandomInRangeHelper(min, max);
-  }
-
-  static inline Vector<T, 4> Max(const Vector<T, 4>& v1,
-                                 const Vector<T, 4>& v2) {
-    return MaxHelper(v1, v2);
-  }
-
-  static inline Vector<T, 4> Min(const Vector<T, 4>& v1,
-                                 const Vector<T, 4>& v2) {
-    return MinHelper(v1, v2);
-  }
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  union {
-    T data_[4];
-    struct {
-      T x;
-      T y;
-      T z;
-      T w;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-
-template <class T>
-struct VectorPacked<T, 4> {
-  /// Create an uninitialized VectorPacked.
-  VectorPacked() {}
-
-  /// Create a VectorPacked from a Vector.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to create the VectorPacked from.
-  explicit VectorPacked(const Vector<T, 4>& vector) { vector.Pack(this); }
-
-  /// Copy a Vector to a VectorPacked.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to copy to the VectorPacked.
-  /// @returns A reference to this VectorPacked.
-  VectorPacked& operator=(const Vector<T, 4>& vector) {
-    vector.Pack(this);
-    return *this;
-  }
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  /// Elements of the packed vector one per dimension.
-  union {
-    T data[4];
-    struct {
-      T x;
-      T y;
-      T z;
-      T w;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-
-}  // namespace mathfu
-
-#endif  // MATHFU_INTERNAL_VECTOR_4_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_4_simd.h b/third_party/mathfu-1.1.0/include/mathfu/internal/vector_4_simd.h
deleted file mode 100644
index c741feb..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/internal/vector_4_simd.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_VECTOR_4_SIMD_H_
-#define MATHFU_VECTOR_4_SIMD_H_
-
-#include "mathfu/internal/vector_4.h"
-#include "mathfu/utilities.h"
-
-#include <math.h>
-
-#ifdef MATHFU_COMPILE_WITH_SIMD
-#include "vectorial/simd4f.h"
-#endif
-
-/// @file mathfu/internal/vector_4_simd.h MathFu Vector<T, 4> Specialization
-/// @brief 4-dimensional specialization of mathfu::Vector for SIMD optimized
-/// builds.
-/// @see mathfu::Vector
-
-namespace mathfu {
-
-#ifdef MATHFU_COMPILE_WITH_SIMD
-
-template <>
-class Vector<float, 4> {
- public:
-  typedef float Scalar;
-
-  inline Vector() {}
-
-  inline Vector(const Vector<float, 4>& v) { simd = v.simd; }
-
-  explicit inline Vector(const Vector<int, 4>& v) {
-    data_[0] = static_cast<float>(v[0]);
-    data_[1] = static_cast<float>(v[1]);
-    data_[2] = static_cast<float>(v[2]);
-    data_[3] = static_cast<float>(v[3]);
-  }
-
-  explicit inline Vector(const simd4f& v) { simd = v; }
-
-  explicit inline Vector(const float& s) { simd = simd4f_splat(s); }
-
-  inline Vector(const float& s1, const float& s2, const float& s3,
-                const float& s4) {
-    simd = simd4f_create(s1, s2, s3, s4);
-  }
-
-  explicit inline Vector(const float* v) { simd = simd4f_uload4(v); }
-
-  inline Vector(const Vector<float, 3>& vector3, const float& value) {
-#ifdef MATHFU_COMPILE_WITH_PADDING
-    simd = vector3.simd;
-    (*this)[3] = value;
-#else
-    simd = simd4f_create(vector3[0], vector3[1], vector3[2], value);
-#endif  // MATHFU_COMPILE_WITH_PADDING
-  }
-
-  inline Vector(const Vector<float, 2>& vector12,
-                const Vector<float, 2>& vector34) {
-    simd = simd4f_create(vector12[0], vector12[1], vector34[0], vector34[1]);
-  }
-
-  explicit inline Vector(const VectorPacked<float, 4>& vector) {
-    simd = simd4f_uload4(vector.data);
-  }
-
-  inline float& operator()(const int i) { return data_[i]; }
-
-  inline const float& operator()(const int i) const { return data_[i]; }
-
-  inline float& operator[](const int i) { return data_[i]; }
-
-  inline const float& operator[](const int i) const { return data_[i]; }
-
-  /// GLSL style multi-component accessors.
-  inline Vector<float, 3> xyz() { return Vector<float, 3>(x, y, z); }
-  inline const Vector<float, 3> xyz() const {
-    return Vector<float, 3>(x, y, z);
-  }
-
-  inline Vector<float, 2> xy() { return Vector<float, 2>(x, y); }
-  inline const Vector<float, 2> xy() const { return Vector<float, 2>(x, y); }
-
-  inline Vector<float, 2> zw() { return Vector<float, 2>(z, w); }
-  inline const Vector<float, 2> zw() const { return Vector<float, 2>(z, w); }
-
-  inline void Pack(VectorPacked<float, 4>* const vector) const {
-    simd4f_ustore4(simd, vector->data);
-  }
-
-  inline Vector<float, 4> operator-() const {
-    return Vector<float, 4>(simd4f_sub(simd4f_zero(), simd));
-  }
-
-  inline Vector<float, 4> operator*(const Vector<float, 4>& v) const {
-    return Vector<float, 4>(simd4f_mul(simd, v.simd));
-  }
-
-  inline Vector<float, 4> operator/(const Vector<float, 4>& v) const {
-    return Vector<float, 4>(simd4f_div(simd, v.simd));
-  }
-
-  inline Vector<float, 4> operator+(const Vector<float, 4>& v) const {
-    return Vector<float, 4>(simd4f_add(simd, v.simd));
-  }
-
-  inline Vector<float, 4> operator-(const Vector<float, 4>& v) const {
-    return Vector<float, 4>(simd4f_sub(simd, v.simd));
-  }
-
-  inline Vector<float, 4> operator*(const float& s) const {
-    return Vector<float, 4>(simd4f_mul(simd, simd4f_splat(s)));
-  }
-
-  inline Vector<float, 4> operator/(const float& s) const {
-    return Vector<float, 4>(simd4f_div(simd, simd4f_splat(s)));
-  }
-
-  inline Vector<float, 4> operator+(const float& s) const {
-    return Vector<float, 4>(simd4f_add(simd, simd4f_splat(s)));
-  }
-
-  inline Vector<float, 4> operator-(const float& s) const {
-    return Vector<float, 4>(simd4f_sub(simd, simd4f_splat(s)));
-  }
-
-  inline Vector<float, 4>& operator*=(const Vector<float, 4>& v) {
-    simd = simd4f_mul(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 4>& operator/=(const Vector<float, 4>& v) {
-    simd = simd4f_div(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 4>& operator+=(const Vector<float, 4>& v) {
-    simd = simd4f_add(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 4>& operator-=(const Vector<float, 4>& v) {
-    simd = simd4f_sub(simd, v.simd);
-    return *this;
-  }
-
-  inline Vector<float, 4>& operator*=(const float& s) {
-    simd = simd4f_mul(simd, simd4f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 4>& operator/=(const float& s) {
-    simd = simd4f_div(simd, simd4f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 4>& operator+=(const float& s) {
-    simd = simd4f_add(simd, simd4f_splat(s));
-    return *this;
-  }
-
-  inline Vector<float, 4>& operator-=(const float& s) {
-    simd = simd4f_sub(simd, simd4f_splat(s));
-    return *this;
-  }
-
-  inline bool operator==(const Vector<float, 4>& v) const {
-    for (int i = 0; i < 4; ++i) {
-      if ((*this)[i] != v[i]) return false;
-    }
-    return true;
-  }
-
-  inline bool operator!=(const Vector<float, 4>& v) const {
-    return !operator==(v);
-  }
-
-  inline float LengthSquared() const {
-    return simd4f_get_x(simd4f_dot4(simd, simd));
-  }
-
-  inline float Length() const { return simd4f_get_x(simd4f_length4(simd)); }
-
-  inline float Normalize() {
-    const float length = Length();
-    simd = simd4f_mul(simd, simd4f_splat(1 / length));
-    return length;
-  }
-
-  inline Vector<float, 4> Normalized() const {
-    return Vector<float, 4>(simd4f_normalize4(simd));
-  }
-
-  template <typename CompatibleT>
-  static inline Vector<float, 4> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<float, 4, CompatibleT>(compatible);
-  }
-
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Vector<float, 4>& v) {
-    return ToTypeHelper<float, 4, CompatibleT>(v);
-  }
-
-  static inline float DotProduct(const Vector<float, 4>& v1,
-                                 const Vector<float, 4>& v2) {
-    return simd4f_get_x(simd4f_dot4(v1.simd, v2.simd));
-  }
-
-  static inline Vector<float, 4> HadamardProduct(const Vector<float, 4>& v1,
-                                                 const Vector<float, 4>& v2) {
-    return Vector<float, 4>(simd4f_mul(v1.simd, v2.simd));
-  }
-
-  static inline Vector<float, 4> Lerp(const Vector<float, 4>& v1,
-                                      const Vector<float, 4>& v2,
-                                      float percent) {
-    const Vector<float, 4> percentv(percent);
-    const Vector<float, 4> one(1.0f);
-    const Vector<float, 4> one_minus_percent = one - percentv;
-    return Vector<float, 4>(
-        simd4f_add(simd4f_mul(one_minus_percent.simd, v1.simd),
-                   simd4f_mul(percentv.simd, v2.simd)));
-  }
-
-  /// Generates a random vector, where the range for each component is
-  /// bounded by min and max.
-  static inline Vector<float, 4> RandomInRange(const Vector<float, 4>& min,
-                                               const Vector<float, 4>& max) {
-    return Vector<float, 4>(mathfu::RandomInRange<float>(min[0], max[0]),
-                            mathfu::RandomInRange<float>(min[1], max[1]),
-                            mathfu::RandomInRange<float>(min[2], max[2]),
-                            mathfu::RandomInRange<float>(min[3], max[3]));
-  }
-
-  static inline Vector<float, 4> Max(const Vector<float, 4>& v1,
-                                     const Vector<float, 4>& v2) {
-    return Vector<float, 4>(simd4f_max(v1.simd, v2.simd));
-  }
-
-  static inline Vector<float, 4> Min(const Vector<float, 4>& v1,
-                                     const Vector<float, 4>& v2) {
-    return Vector<float, 4>(simd4f_min(v1.simd, v2.simd));
-  }
-
-  template <class T, int rows, int cols>
-  friend class Matrix;
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
-#include "mathfu/internal/disable_warnings_begin.h"
-  union {
-    simd4f simd;
-    float data_[4];
-    struct {
-      float x;
-      float y;
-      float z;
-      float w;
-    };
-  };
-#include "mathfu/internal/disable_warnings_end.h"
-};
-/// @endcond
-#endif  // MATHFU_COMPILE_WITH_SIMD
-
-}  // namespace mathfu
-
-#endif  // MATHFU_VECTOR_4_SIMD_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/matrix.h b/third_party/mathfu-1.1.0/include/mathfu/matrix.h
deleted file mode 100644
index 8dda3e9..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/matrix.h
+++ /dev/null
@@ -1,1542 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_MATRIX_H_
-#define MATHFU_MATRIX_H_
-
-#include "mathfu/utilities.h"
-#include "mathfu/vector.h"
-
-#include <cmath>
-
-#include <assert.h>
-
-/// @file mathfu/matrix.h
-/// @brief Matrix class and functions.
-/// @addtogroup mathfu_matrix
-///
-/// MathFu provides a generic Matrix implementation which is specialized
-/// for 4x4 matrices to take advantage of optimization opportunities using
-/// SIMD instructions.
-
-#ifdef _MSC_VER
-#pragma warning(push)
-// The following disables warnings for MATHFU_MAT_OPERATION.
-// The buffer overrun warning must be disabled as MSVC doesn't treat
-// "columns" as constant and therefore assumes that it's possible
-// to overrun arrays indexed by "i".
-// The conditional expression is constant warning is disabled since
-// MSVC decides that "columns" *is* constant when unrolling the operation
-// loop.
-#pragma warning(disable : 4127)  // conditional expression is constant
-#pragma warning(disable : 4789)  // buffer overrun
-#if _MSC_VER >= 1900             // MSVC 2015
-#pragma warning(disable : 4456)  // allow shadowing in unrolled loops
-#pragma warning(disable : 4723)  // suppress "potential divide by 0" warning
-#endif                           // _MSC_VER >= 1900
-#endif                           // _MSC_VER
-
-/// @cond MATHFU_INTERNAL
-/// The stride of a vector (e.g Vector<T, 3>) when cast as an array of floats.
-#define MATHFU_VECTOR_STRIDE_FLOATS(vector) (sizeof(vector) / sizeof(float))
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// This will unroll loops for matrices with <= 4 columns
-#define MATHFU_MAT_OPERATION(OP) MATHFU_UNROLLED_LOOP(i, columns, OP)
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// This will perform a given OP on each matrix column and return the result
-#define MATHFU_MAT_OPERATOR(OP)                   \
-  {                                               \
-    Matrix<T, rows, columns> result;              \
-    MATHFU_MAT_OPERATION(result.data_[i] = (OP)); \
-    return result;                                \
-  }
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// This will perform a given OP on each matrix column
-#define MATHFU_MAT_SELF_OPERATOR(OP) \
-  {                                  \
-    MATHFU_MAT_OPERATION(OP);        \
-    return *this;                    \
-  }
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// This macro will take the dot product for a row from data1 and a column from
-/// data2.
-#define MATHFU_MATRIX_4X4_DOT(data1, data2, r)               \
-  ((data1)[r] * (data2)[0] + (data1)[(r) + 4] * (data2)[1] + \
-   (data1)[(r) + 8] * (data2)[2] + (data1)[(r) + 12] * (data2)[3])
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-#define MATHFU_MATRIX_3X3_DOT(data1, data2, r, size)              \
-  ((data1)[r] * (data2)[0] + (data1)[(r) + (size)] * (data2)[1] + \
-   (data1)[(r) + 2 * (size)] * (data2)[2])
-/// @endcond
-
-namespace mathfu {
-
-/// @cond MATHFU_INTERNAL
-template <class T, int rows, int columns = rows>
-class Matrix;
-template <class T, int rows, int columns>
-inline Matrix<T, rows, columns> IdentityHelper();
-template <bool check_invertible, class T, int rows, int columns>
-inline bool InverseHelper(const Matrix<T, rows, columns>& m,
-                          Matrix<T, rows, columns>* const inverse);
-template <class T, int rows, int columns>
-inline void TimesHelper(const Matrix<T, rows, columns>& m1,
-                        const Matrix<T, rows, columns>& m2,
-                        Matrix<T, rows, columns>* out_m);
-template <class T, int rows, int columns>
-static inline Matrix<T, rows, columns> OuterProductHelper(
-    const Vector<T, rows>& v1, const Vector<T, columns>& v2);
-template <class T>
-inline Matrix<T, 4, 4> PerspectiveHelper(T fovy, T aspect, T znear, T zfar,
-                                         T handedness);
-template <class T>
-static inline Matrix<T, 4, 4> OrthoHelper(T left, T right, T bottom, T top,
-                                          T znear, T zfar, T handedness);
-template <class T>
-static inline Matrix<T, 4, 4> LookAtHelper(const Vector<T, 3>& at,
-                                           const Vector<T, 3>& eye,
-                                           const Vector<T, 3>& up,
-                                           T handedness);
-template <class T>
-static inline bool UnProjectHelper(const Vector<T, 3>& window_coord,
-                                   const Matrix<T, 4, 4>& model_view,
-                                   const Matrix<T, 4, 4>& projection,
-                                   const float window_width,
-                                   const float window_height,
-                                   Vector<T, 3>& result);
-
-template <typename T, int rows, int columns, typename CompatibleT>
-static inline Matrix<T, rows, columns> FromTypeHelper(const CompatibleT& compatible);
-
-template <typename T, int rows, int columns, typename CompatibleT>
-static inline CompatibleT ToTypeHelper(const Matrix<T, rows, columns>& m);
-/// @endcond
-
-/// @addtogroup mathfu_matrix
-/// @{
-/// @class Matrix
-/// @brief Matrix stores a set of "rows" by "columns" elements of type T
-/// and provides functions that operate on the set of elements.
-///
-/// @tparam T type of each element in the matrix.
-/// @tparam rows Number of rows in the matrix.
-/// @tparam columns Number of columns in the matrix.
-template <class T, int rows, int columns>
-class Matrix {
- public:
-  /// @brief Construct a Matrix of uninitialized values.
-  inline Matrix() {}
-
-  /// @brief Construct a Matrix from another Matrix copying each element.
-  ////
-  /// @param m Matrix that the data will be copied from.
-  inline Matrix(const Matrix<T, rows, columns>& m) {
-    MATHFU_MAT_OPERATION(data_[i] = m.data_[i]);
-  }
-
-  /// @brief Construct a Matrix from a single float.
-  ///
-  /// @param s Scalar value used to initialize each element of the matrix.
-  explicit inline Matrix(const T& s) {
-    MATHFU_MAT_OPERATION((data_[i] = Vector<T, rows>(s)));
-  }
-
-  /// @brief Construct a Matrix from four floats.
-  ///
-  /// @note This method only works with a 2x2 Matrix.
-  ///
-  /// @param s00 Value of the first row and column.
-  /// @param s10 Value of the second row, first column.
-  /// @param s01 Value of the first row, second column.
-  /// @param s11 Value of the second row and column.
-  inline Matrix(const T& s00, const T& s10, const T& s01, const T& s11) {
-    MATHFU_STATIC_ASSERT(rows == 2 && columns == 2);
-    data_[0] = Vector<T, rows>(s00, s10);
-    data_[1] = Vector<T, rows>(s01, s11);
-  }
-
-  /// @brief Create a Matrix from nine floats.
-  ///
-  /// @note This method only works with a 3x3 Matrix.
-  ///
-  /// @param s00 Value of the first row and column.
-  /// @param s10 Value of the second row, first column.
-  /// @param s20 Value of the third row, first column.
-  /// @param s01 Value of the first row, second column.
-  /// @param s11 Value of the second row and column.
-  /// @param s21 Value of the third row, second column.
-  /// @param s02 Value of the first row, third column.
-  /// @param s12 Value of the second row, third column.
-  /// @param s22 Value of the third row and column.
-  inline Matrix(const T& s00, const T& s10, const T& s20, const T& s01,
-                const T& s11, const T& s21, const T& s02, const T& s12,
-                const T& s22) {
-    MATHFU_STATIC_ASSERT(rows == 3 && columns == 3);
-    data_[0] = Vector<T, rows>(s00, s10, s20);
-    data_[1] = Vector<T, rows>(s01, s11, s21);
-    data_[2] = Vector<T, rows>(s02, s12, s22);
-  }
-
-  /// @brief Creates a Matrix from twelve floats.
-  ///
-  /// @note This method only works with Matrix<float, 4, 3>.
-  ///
-  ///
-  /// @param s00 Value of the first row and column.
-  /// @param s10 Value of the second row, first column.
-  /// @param s20 Value of the third row, first column.
-  /// @param s30 Value of the fourth row, first column.
-  /// @param s01 Value of the first row, second column.
-  /// @param s11 Value of the second row and column.
-  /// @param s21 Value of the third row, second column.
-  /// @param s31 Value of the fourth row, second column.
-  /// @param s02 Value of the first row, third column.
-  /// @param s12 Value of the second row, third column.
-  /// @param s22 Value of the third row and column.
-  /// @param s32 Value of the fourth row, third column.
-  inline Matrix(const T& s00, const T& s10, const T& s20, const T& s30,
-                const T& s01, const T& s11, const T& s21, const T& s31,
-                const T& s02, const T& s12, const T& s22, const T& s32) {
-    MATHFU_STATIC_ASSERT(rows == 4 && columns == 3);
-    data_[0] = Vector<T, rows>(s00, s10, s20, s30);
-    data_[1] = Vector<T, rows>(s01, s11, s21, s31);
-    data_[2] = Vector<T, rows>(s02, s12, s22, s32);
-  }
-
-  /// @brief Create a Matrix from sixteen floats.
-  ///
-  /// @note This method only works with a 4x4 Matrix.
-  ///
-  /// @param s00 Value of the first row and column.
-  /// @param s10 Value of the second row, first column.
-  /// @param s20 Value of the third row, first column.
-  /// @param s30 Value of the fourth row, first column.
-  /// @param s01 Value of the first row, second column.
-  /// @param s11 Value of the second row and column.
-  /// @param s21 Value of the third row, second column.
-  /// @param s31 Value of the fourth row, second column.
-  /// @param s02 Value of the first row, third column.
-  /// @param s12 Value of the second row, third column.
-  /// @param s22 Value of the third row and column.
-  /// @param s32 Value of the fourth row, third column.
-  /// @param s03 Value of the first row, fourth column.
-  /// @param s13 Value of the second row, fourth column.
-  /// @param s23 Value of the third row, fourth column.
-  /// @param s33 Value of the fourth row and column.
-  inline Matrix(const T& s00, const T& s10, const T& s20, const T& s30,
-                const T& s01, const T& s11, const T& s21, const T& s31,
-                const T& s02, const T& s12, const T& s22, const T& s32,
-                const T& s03, const T& s13, const T& s23, const T& s33) {
-    MATHFU_STATIC_ASSERT(rows == 4 && columns == 4);
-    data_[0] = Vector<T, rows>(s00, s10, s20, s30);
-    data_[1] = Vector<T, rows>(s01, s11, s21, s31);
-    data_[2] = Vector<T, rows>(s02, s12, s22, s32);
-    data_[3] = Vector<T, rows>(s03, s13, s23, s33);
-  }
-
-  /// @brief Create 4x4 Matrix from 4, 4 element vectors.
-  ///
-  /// @note This method only works with a 4x4 Matrix.
-  ///
-  /// @param column0 Vector used for the first column.
-  /// @param column1 Vector used for the second column.
-  /// @param column2 Vector used for the third column.
-  /// @param column3 Vector used for the fourth column.
-  inline Matrix(const Vector<T, 4>& column0, const Vector<T, 4>& column1,
-                const Vector<T, 4>& column2, const Vector<T, 4>& column3) {
-    MATHFU_STATIC_ASSERT(rows == 4 && columns == 4);
-    data_[0] = column0;
-    data_[1] = column1;
-    data_[2] = column2;
-    data_[3] = column3;
-  }
-
-  /// @brief Create a Matrix from the first row * column elements of an array.
-  ///
-  /// @param a Array of values that the matrix will be iniitlized to.
-  explicit inline Matrix(const T* const a) {
-    MATHFU_MAT_OPERATION((data_[i] = Vector<T, rows>(&a[i * columns])));
-  }
-
-  /// @brief Create a Matrix from an array of "columns", "rows" element packed
-  /// vectors.
-  ///
-  /// @param vectors Array of "columns", "rows" element packed vectors.
-  explicit inline Matrix(const VectorPacked<T, rows>* const vectors) {
-    MATHFU_MAT_OPERATION((data_[i] = Vector<T, rows>(vectors[i])));
-  }
-
-  /// @brief Access an element of the matrix.
-  ///
-  /// @param row Index of the row to access.
-  /// @param column Index of the column to access.
-  /// @return Const reference to the element.
-  inline const T& operator()(const int row, const int column) const {
-    return data_[column][row];
-  }
-
-  /// @brief Access an element of the Matrix.
-  ///
-  /// @param row Index of the row to access.
-  /// @param column Index of the column to access.
-  /// @return Reference to the data that can be modified by the caller.
-  inline T& operator()(const int row, const int column) {
-    return data_[column][row];
-  }
-
-  /// @brief Access an element of the Matrix.
-  ///
-  /// @param i Index of the element to access in flattened memory.  Where
-  /// the column accessed is i / rows and the row is i % rows.
-  /// @return Reference to the data that can be modified by the caller.
-  inline const T& operator()(const int i) const { return operator[](i); }
-
-  /// @brief Access an element of the Matrix.
-  ///
-  /// @param i Index of the element to access in flattened memory.  Where
-  /// the column accessed is i / rows and the row is i % rows.
-  /// @return Reference to the data that can be modified by the caller.
-  inline T& operator()(const int i) { return operator[](i); }
-
-  /// @brief Access an element of the Matrix.
-  ///
-  /// @param i Index of the element to access in flattened memory.  Where
-  /// the column accessed is i / rows and the row is i % rows.
-  /// @return Const reference to the data.
-  inline const T& operator[](const int i) const {
-    return const_cast<Matrix<T, rows, columns>*>(this)->operator[](i);
-  }
-
-  /// @brief Access an element of the Matrix.
-  ///
-  /// @param i Index of the element to access in flattened memory.  Where
-  /// the column accessed is i / rows and the row is i % rows.
-  /// @return Reference to the data that can be modified by the caller.
-  inline T& operator[](const int i) {
-#if defined(MATHFU_COMPILE_WITH_PADDING)
-    // In this case Vector<T, 3> is padded, so the element offset must be
-    // accessed using the array operator.
-    if (rows == 3) {
-      const int row = i % rows;
-      const int col = i / rows;
-      return data_[col][row];
-    } else {
-      return reinterpret_cast<T*>(data_)[i];
-    }
-#else
-    return reinterpret_cast<T*>(data_)[i];
-#endif  // defined(MATHFU_COMPILE_WITH_PADDING)
-  }
-
-  /// @brief Pack the matrix to an array of "rows" element vectors,
-  /// one vector per matrix column.
-  ///
-  /// @param vector Array of "columns" entries to write to.
-  inline void Pack(VectorPacked<T, rows>* const vector) const {
-    MATHFU_MAT_OPERATION(GetColumn(i).Pack(&vector[i]));
-  }
-
-  /// @cond MATHFU_INTERNAL
-  /// @brief Access a column vector of the Matrix.
-  ///
-  /// @param i Index of the column to access.
-  /// @return Reference to the data that can be modified by the caller.
-  inline Vector<T, rows>& GetColumn(const int i) { return data_[i]; }
-
-  /// @brief Access a column vector of the Matrix.
-  ///
-  /// @param i Index of the column to access.
-  /// @return Const reference to the data.
-  inline const Vector<T, rows>& GetColumn(const int i) const {
-    return data_[i];
-  }
-  /// @endcond
-
-  /// @brief Negate this Matrix.
-  ///
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator-() const {
-    MATHFU_MAT_OPERATOR(-data_[i]);
-  }
-
-  /// @brief Add a Matrix to this Matrix.
-  ///
-  /// @param m Matrix to add to this Matrix.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator+(
-      const Matrix<T, rows, columns>& m) const {
-    MATHFU_MAT_OPERATOR(data_[i] + m.data_[i]);
-  }
-
-  /// @brief Subtract a Matrix from this Matrix.
-  ///
-  /// @param m Matrix to subtract from this Matrix.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator-(
-      const Matrix<T, rows, columns>& m) const {
-    MATHFU_MAT_OPERATOR(data_[i] - m.data_[i]);
-  }
-
-  /// @brief Add a scalar to each element of this Matrix.
-  ///
-  /// @param s Scalar to add to this Matrix.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator+(const T& s) const {
-    MATHFU_MAT_OPERATOR(data_[i] + s);
-  }
-
-  /// @brief Subtract a scalar from each element of this Matrix.
-  ///
-  /// @param s Scalar to subtract from this matrix.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator-(const T& s) const {
-    MATHFU_MAT_OPERATOR(data_[i] - s);
-  }
-
-  /// @brief Multiply each element of this Matrix with a scalar.
-  ///
-  /// @param s Scalar to multiply with this Matrix.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator*(const T& s) const {
-    MATHFU_MAT_OPERATOR(data_[i] * s);
-  }
-
-  /// @brief Divide each element of this Matrix with a scalar.
-  ///
-  /// @param s Scalar to divide this Matrix with.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator/(const T& s) const {
-    return (*this) * (1 / s);
-  }
-
-  /// @brief Multiply this Matrix with another Matrix.
-  ///
-  /// @param m Matrix to multiply with this Matrix.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> operator*(
-      const Matrix<T, rows, columns>& m) const {
-    Matrix<T, rows, columns> result;
-    TimesHelper(*this, m, &result);
-    return result;
-  }
-
-  /// @brief Add a Matrix to this Matrix (in-place).
-  ///
-  /// @param m Matrix to add to this Matrix.
-  /// @return Reference to this class.
-  inline Matrix<T, rows, columns>& operator+=(
-      const Matrix<T, rows, columns>& m) {
-    MATHFU_MAT_SELF_OPERATOR(data_[i] += m.data_[i]);
-  }
-
-  /// @brief Subtract a Matrix from this Matrix (in-place).
-  ///
-  /// @param m Matrix to subtract from this Matrix.
-  /// @return Reference to this class.
-  inline Matrix<T, rows, columns>& operator-=(
-      const Matrix<T, rows, columns>& m) {
-    MATHFU_MAT_SELF_OPERATOR(data_[i] -= m.data_[i]);
-  }
-
-  /// @brief Add a scalar to each element of this Matrix (in-place).
-  ///
-  /// @param s Scalar to add to each element of this Matrix.
-  /// @return Reference to this class.
-  inline Matrix<T, rows, columns>& operator+=(const T& s) {
-    MATHFU_MAT_SELF_OPERATOR(data_[i] += s);
-  }
-
-  /// @brief Subtract a scalar from each element of this Matrix (in-place).
-  ///
-  /// @param s Scalar to subtract from each element of this Matrix.
-  /// @return Reference to this class.
-  inline Matrix<T, rows, columns>& operator-=(const T& s) {
-    MATHFU_MAT_SELF_OPERATOR(data_[i] -= s);
-  }
-
-  /// @brief Multiply each element of this Matrix with a scalar (in-place).
-  ///
-  /// @param s Scalar to multiply with each element of this Matrix.
-  /// @return Reference to this class.
-  inline Matrix<T, rows, columns>& operator*=(const T& s) {
-    MATHFU_MAT_SELF_OPERATOR(data_[i] *= s);
-  }
-
-  /// @brief Divide each element of this Matrix by a scalar (in-place).
-  ///
-  /// @param s Scalar to divide this Matrix by.
-  /// @return Reference to this class.
-  inline Matrix<T, rows, columns>& operator/=(const T& s) {
-    return (*this) *= (1 / s);
-  }
-
-  /// @brief Multiply this Matrix with another Matrix (in-place).
-  ///
-  /// @param m Matrix to multiply with this Matrix.
-  /// @return Reference to this class.
-  inline Matrix<T, rows, columns>& operator*=(
-      const Matrix<T, rows, columns>& m) {
-    const Matrix<T, rows, columns> copy_of_this(*this);
-    TimesHelper(copy_of_this, m, this);
-    return *this;
-  }
-
-  /// @brief Calculate the inverse of this Matrix.
-  ///
-  /// This calculates the inverse Matrix such that
-  /// <code>(m * m).Inverse()</code> is the identity.
-  /// @return Matrix containing the result.
-  inline Matrix<T, rows, columns> Inverse() const {
-    Matrix<T, rows, columns> inverse;
-    InverseHelper<false>(*this, &inverse);
-    return inverse;
-  }
-
-  /// @brief Calculate the inverse of this Matrix.
-  ///
-  /// This calculates the inverse Matrix such that
-  /// <code>(m * m).Inverse()</code> is the identity.
-  /// By contrast to Inverse() this returns whether the matrix is invertible.
-  ///
-  /// The invertible check simply compares the calculated determinant with
-  /// Constants<T>::GetDeterminantThreshold() to roughly determine whether the
-  /// matrix is invertible.  This simple check works in common cases but will
-  /// fail for corner cases where the matrix is a combination of huge and tiny
-  /// values that can't be accurately represented by the floating point
-  /// datatype T.  More extensive checks (relative to the input values) are
-  /// possible but <b>far</b> more expensive, complicated and difficult to
-  /// test.
-  /// @return Whether the matrix is invertible.
-  inline bool InverseWithDeterminantCheck(
-      Matrix<T, rows, columns>* const inverse) const {
-    return InverseHelper<true>(*this, inverse);
-  }
-
-  /// @brief Calculate the transpose of this Matrix.
-  ///
-  /// @return The transpose of the specified Matrix.
-  inline Matrix<T, columns, rows> Transpose() const {
-    Matrix<T, columns, rows> transpose;
-    MATHFU_UNROLLED_LOOP(
-        i, columns, MATHFU_UNROLLED_LOOP(
-                        j, rows, transpose.GetColumn(j)[i] = GetColumn(i)[j]))
-    return transpose;
-  }
-
-  /// @brief Get the 2-dimensional translation of a 2-dimensional affine
-  /// transform.
-  ///
-  /// @note 2-dimensional affine transforms are represented by 3x3 matrices.
-  /// @return Vector with the first two components of column 2 of this Matrix.
-  inline Vector<T, 2> TranslationVector2D() const {
-    MATHFU_STATIC_ASSERT(rows == 3 && columns == 3);
-    return Vector<T, 2>(data_[2][0], data_[2][1]);
-  }
-
-  /// @brief Get the 3-dimensional translation of a 3-dimensional affine
-  /// transform.
-  ///
-  /// @note 3-dimensional affine transforms are represented by 4x4 matrices.
-  /// @return Vector with the first three components of column 3.
-  inline Vector<T, 3> TranslationVector3D() const {
-    MATHFU_STATIC_ASSERT(rows == 4 && columns == 4);
-    return Vector<T, 3>(data_[3][0], data_[3][1], data_[3][2]);
-  }
-
-  /// @brief Load from any byte-wise compatible external matrix.
-  ///
-  /// Format should be `columns` vectors, each holding `rows` values of type T.
-  ///
-  /// Use this for safe conversion from external matrix classes.
-  /// Often, external libraries will have their own matrix types that are,
-  /// byte-for-byte, exactly the same as mathfu::Matrix. This function allows
-  /// you to load a mathfu::Matrix from those external types, without potential
-  /// aliasing bugs that are caused by casting.
-  ///
-  /// @note If your external type gives you access to a T*, then you can
-  ///       equivalently use the Matrix(const T*) constructor.
-  ///
-  /// @param compatible reference to a byte-wise compatible matrix structure;
-  ///                   array of columns x rows Ts.
-  /// @returns `compatible` loaded as a mathfu::Matrix.
-  template <typename CompatibleT>
-  static inline Matrix<T, rows, columns> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<T, rows, columns, CompatibleT>(compatible);
-  }
-
-  /// @brief Load into any byte-wise compatible external matrix.
-  ///
-  /// Format should be `columns` vectors, each holding `rows` values of type T.
-  ///
-  /// Use this for safe conversion to external matrix classes.
-  /// Often, external libraries will have their own matrix types that are,
-  /// byte-for-byte, exactly the same as mathfu::Matrix. This function allows
-  /// you to load an external type from a mathfu::Matrix, without potential
-  /// aliasing bugs that are caused by casting.
-  ///
-  /// @param m reference to mathfu::Matrix to convert.
-  /// @returns CompatibleT loaded from m.
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Matrix<T, rows, columns>& m) {
-    return ToTypeHelper<T, rows, columns, CompatibleT>(m);
-  }
-
-  /// @brief Calculate the outer product of two Vectors.
-  ///
-  /// @return Matrix containing the result.
-  static inline Matrix<T, rows, columns> OuterProduct(
-      const Vector<T, rows>& v1, const Vector<T, columns>& v2) {
-    return OuterProductHelper(v1, v2);
-  }
-
-  /// @brief Calculate the hadamard / component-wise product of two matrices.
-  ///
-  /// @param m1 First Matrix.
-  /// @param m2 Second Matrix.
-  /// @return Matrix containing the result.
-  static inline Matrix<T, rows, columns> HadamardProduct(
-      const Matrix<T, rows, columns>& m1, const Matrix<T, rows, columns>& m2) {
-    MATHFU_MAT_OPERATOR(m1[i] * m2[i]);
-  }
-
-  /// @brief Calculate the identity Matrix.
-  ///
-  /// @return Matrix containing the result.
-  static inline Matrix<T, rows, columns> Identity() {
-    return IdentityHelper<T, rows, columns>();
-  }
-
-  /// @brief Create a 3x3 translation Matrix from a 2-dimensional Vector.
-  ///
-  /// This matrix will have an empty or zero rotation component.
-  ///
-  /// @param v Vector of size 2.
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 3> FromTranslationVector(const Vector<T, 2>& v) {
-    return Matrix<T, 3>(1, 0, 0, 0, 1, 0, v[0], v[1], 1);
-  }
-
-  /// @brief Create a 4x4 translation Matrix from a 3-dimensional Vector.
-  ///
-  /// This matrix will have an empty or zero rotation component.
-  ///
-  /// @param v The vector of size 3.
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 4> FromTranslationVector(const Vector<T, 3>& v) {
-    return Matrix<T, 4>(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, v[0], v[1], v[2],
-                        1);
-  }
-
-  /// @brief Create a square Matrix with the diagonal component set to v.
-  ///
-  /// This is an affine transform matrix, so the dimension of the vector is
-  /// one less than the dimension of the matrix.
-  ///
-  /// @param v Vector containing components for scaling.
-  /// @return Matrix with v along the diagonal, and 1 in the bottom right.
-  static inline Matrix<T, rows> FromScaleVector(const Vector<T, rows - 1>& v) {
-    // TODO OPT: Use a helper function in a similar way to Identity to
-    // construct the matrix for the specialized cases 2, 3, 4, and only run
-    // this method in the general case. This will also allow you to use the
-    // helper methods from specialized classes like Matrix<T, 4, 4>.
-    Matrix<T, rows> return_matrix(Identity());
-    for (int i = 0; i < rows - 1; ++i) return_matrix(i, i) = v[i];
-    return return_matrix;
-  }
-
-  /// @brief Create a 4x4 Matrix from a 3x3 rotation Matrix.
-  ///
-  /// This Matrix will have an empty or zero translation component.
-  ///
-  /// @param m 3x3 rotation Matrix.
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 4> FromRotationMatrix(const Matrix<T, 3>& m) {
-    return Matrix<T, 4>(m[0], m[1], m[2], 0, m[3], m[4], m[5], 0, m[6], m[7],
-                        m[8], 0, 0, 0, 0, 1);
-  }
-
-  /// @brief Constructs a Matrix<float, 4> from an AffineTransform.
-  ///
-  /// @param affine An AffineTransform reference to be used to construct
-  /// a Matrix<float, 4> by adding in the 'w' row of [0, 0, 0, 1].
-  static inline Matrix<T, 4> FromAffineTransform(
-      const Matrix<T, 4, 3>& affine) {
-    return Matrix<T, 4>(affine[0], affine[4], affine[8], static_cast<T>(0),
-                        affine[1], affine[5], affine[9], static_cast<T>(0),
-                        affine[2], affine[6], affine[10], static_cast<T>(0),
-                        affine[3], affine[7], affine[11], static_cast<T>(1));
-  }
-
-  /// @brief Converts a Matrix<float, 4> into an AffineTransform.
-  ///
-  /// @param m A Matrix<float, 4> reference to be converted into an
-  /// AffineTransform by dropping the fixed 'w' row.
-  ///
-  /// @return Returns an AffineTransform that contains the essential
-  /// transformation data from the Matrix<float, 4>.
-  static inline Matrix<T, 4, 3> ToAffineTransform(const Matrix<T, 4>& m) {
-    return Matrix<T, 4, 3>(m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13],
-                           m[2], m[6], m[10], m[14]);
-  }
-
-  /// @brief Create a 3x3 rotation Matrix from a 2D normalized directional
-  /// Vector around the X axis.
-  ///
-  /// @param v 2D normalized directional Vector.
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 3> RotationX(const Vector<T, 2>& v) {
-    return Matrix<T, 3>(1, 0, 0, 0, v.x, v.y, 0, -v.y, v.x);
-  }
-
-  /// @brief Create a 3x3 rotation Matrix from a 2D normalized directional
-  /// Vector around the Y axis.
-  ///
-  /// @param v 2D normalized directional Vector.
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 3> RotationY(const Vector<T, 2>& v) {
-    return Matrix<T, 3>(v.x, 0, -v.y, 0, 1, 0, v.y, 0, v.x);
-  }
-
-  /// @brief Create a 3x3 rotation Matrix from a 2D normalized directional
-  /// Vector around the Z axis.
-  ///
-  /// @param v 2D normalized directional Vector.
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 3> RotationZ(const Vector<T, 2>& v) {
-    return Matrix<T, 3>(v.x, v.y, 0, -v.y, v.x, 0, 0, 0, 1);
-  }
-
-  /// @brief Create a 3x3 rotation Matrix from an angle (in radians) around
-  /// the X axis.
-  ///
-  /// @param angle Angle (in radians).
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 3> RotationX(T angle) {
-    return RotationX(Vector<T, 2>(cosf(angle), sinf(angle)));
-  }
-
-  /// @brief Create a 3x3 rotation Matrix from an angle (in radians) around
-  /// the Y axis.
-  ///
-  /// @param angle Angle (in radians).
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 3> RotationY(T angle) {
-    return RotationY(Vector<T, 2>(cosf(angle), sinf(angle)));
-  }
-
-  /// @brief Create a 3x3 rotation Matrix from an angle (in radians)
-  /// around the Z axis.
-  ///
-  /// @param angle Angle (in radians).
-  /// @return Matrix containing the result.
-  static inline Matrix<T, 3> RotationZ(T angle) {
-    return RotationZ(Vector<T, 2>(cosf(angle), sinf(angle)));
-  }
-
-  /// @brief Create a 4x4 perspective Matrix.
-  ///
-  /// @param fovy Field of view.
-  /// @param aspect Aspect ratio.
-  /// @param znear Near plane location.
-  /// @param zfar Far plane location.
-  /// @param handedness 1.0f for RH, -1.0f for LH
-  /// @return 4x4 perspective Matrix.
-  static inline Matrix<T, 4, 4> Perspective(T fovy, T aspect, T znear, T zfar,
-                                            T handedness = 1) {
-    return PerspectiveHelper(fovy, aspect, znear, zfar, handedness);
-  }
-
-  /// @brief Create a 4x4 orthographic Matrix.
-  ///
-  /// @param left Left extent.
-  /// @param right Right extent.
-  /// @param bottom Bottom extent.
-  /// @param top Top extent.
-  /// @param znear Near plane location.
-  /// @param zfar Far plane location.
-  /// @param handedness 1.0f for RH, -1.0f for LH
-  /// @return 4x4 orthographic Matrix.
-  static inline Matrix<T, 4, 4> Ortho(T left, T right, T bottom, T top, T znear,
-                                      T zfar, T handedness = 1) {
-    return OrthoHelper(left, right, bottom, top, znear, zfar, handedness);
-  }
-
-  /// @brief Create a 3-dimensional camera Matrix.
-  ///
-  /// @param at The look-at target of the camera.
-  /// @param eye The position of the camera.
-  /// @param up The up vector in the world, for example (0, 1, 0) if the
-  /// y-axis is up.
-  /// @param handedness 1.0f for RH, -1.0f for LH.
-  /// @return 3-dimensional camera Matrix.
-  /// TODO: Change default handedness to +1 so that it matches Perspective().
-  static inline Matrix<T, 4, 4> LookAt(const Vector<T, 3>& at,
-                                       const Vector<T, 3>& eye,
-                                       const Vector<T, 3>& up,
-                                       T handedness = -1) {
-    return LookAtHelper(at, eye, up, handedness);
-  }
-
-  /// @brief Get the 3D position in object space from a window coordinate.
-  ///
-  /// @param window_coord The window coordinate. The z value is for depth.
-  /// A window coordinate on the near plane will have 0 as the z value.
-  /// And a window coordinate on the far plane will have 1 as the z value.
-  /// z value should be with in [0, 1] here.
-  /// @param model_view The Model View matrix.
-  /// @param projection The projection matrix.
-  /// @param window_width Width of the window.
-  /// @param window_height Height of the window.
-  /// @return the mapped 3D position in object space.
-  static inline Vector<T, 3> UnProject(const Vector<T, 3>& window_coord,
-                                       const Matrix<T, 4, 4>& model_view,
-                                       const Matrix<T, 4, 4>& projection,
-                                       const float window_width,
-                                       const float window_height) {
-    Vector<T, 3> result;
-    UnProjectHelper(window_coord, model_view, projection, window_width,
-                    window_height, result);
-    return result;
-  }
-
-  /// @brief Multiply a Vector by a Matrix.
-  ///
-  /// @param v Vector to multiply.
-  /// @param m Matrix to multiply.
-  /// @return Matrix containing the result.
-  friend inline Vector<T, columns> operator*(
-      const Vector<T, rows>& v, const Matrix<T, rows, columns>& m) {
-    const int d = columns;
-    MATHFU_VECTOR_OPERATOR((Vector<T, rows>::DotProduct(m.data_[i], v)));
-  }
-
-  // Dimensions of the matrix.
-  /// Number of rows in the matrix.
-  static const int kRows = rows;
-  /// Number of columns in the matrix.
-  static const int kColumns = columns;
-  /// Total number of elements in the matrix.
-  static const int kElements = rows * columns;
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
- private:
-  Vector<T, rows> data_[columns];
-};
-/// @}
-
-/// @addtogroup mathfu_matrix
-/// @{
-
-/// @brief Multiply each element of a Matrix by a scalar.
-///
-/// @param s Scalar to multiply by.
-/// @param m Matrix to multiply.
-/// @return Matrix containing the result.
-/// @tparam T Type of each element in the Matrix and the scalar type.
-/// @tparam rows Number of rows in the matrix.
-/// @tparam columns Number of columns in the matrix.
-///
-/// @related mathfu::Matrix
-template <class T, int rows, int columns>
-inline Matrix<T, rows, columns> operator*(const T& s,
-                                          const Matrix<T, columns, rows>& m) {
-  return m * s;
-}
-
-/// @brief Multiply a Matrix by a Vector.
-///
-/// @note Template specialized versions are implemented for 2x2, 3x3, and 4x4
-/// matrices to increase performance.  The 3x3 float is also specialized
-/// to supported padded the 3-dimensional Vector in SIMD build configurations.
-///
-/// @param m Matrix to multiply.
-/// @param v Vector to multiply.
-/// @return Vector containing the result.
-///
-/// @related mathfu::Matrix
-template <class T, int rows, int columns>
-inline Vector<T, rows> operator*(const Matrix<T, rows, columns>& m,
-                                 const Vector<T, columns>& v) {
-  const Vector<T, rows> result(0);
-  int offset = 0;
-  for (int column = 0; column < columns; column++) {
-    for (int row = 0; row < rows; row++) {
-      result[row] += m[offset + row] * v[column];
-    }
-    offset += rows;
-  }
-  return result;
-}
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline Vector<T, 2> operator*(const Matrix<T, 2, 2>& m, const Vector<T, 2>& v) {
-  return Vector<T, 2>(m[0] * v[0] + m[2] * v[1], m[1] * v[0] + m[3] * v[1]);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline Vector<T, 3> operator*(const Matrix<T, 3, 3>& m, const Vector<T, 3>& v) {
-  return Vector<T, 3>(MATHFU_MATRIX_3X3_DOT(&m[0], v, 0, 3),
-                      MATHFU_MATRIX_3X3_DOT(&m[0], v, 1, 3),
-                      MATHFU_MATRIX_3X3_DOT(&m[0], v, 2, 3));
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <>
-inline Vector<float, 3> operator*(const Matrix<float, 3, 3>& m,
-                                  const Vector<float, 3>& v) {
-  return Vector<float, 3>(
-      MATHFU_MATRIX_3X3_DOT(&m[0], v, 0, MATHFU_VECTOR_STRIDE_FLOATS(v)),
-      MATHFU_MATRIX_3X3_DOT(&m[0], v, 1, MATHFU_VECTOR_STRIDE_FLOATS(v)),
-      MATHFU_MATRIX_3X3_DOT(&m[0], v, 2, MATHFU_VECTOR_STRIDE_FLOATS(v)));
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline Vector<T, 4> operator*(const Matrix<T, 4, 4>& m, const Vector<T, 4>& v) {
-  return Vector<T, 4>(
-      MATHFU_MATRIX_4X4_DOT(&m[0], v, 0), MATHFU_MATRIX_4X4_DOT(&m[0], v, 1),
-      MATHFU_MATRIX_4X4_DOT(&m[0], v, 2), MATHFU_MATRIX_4X4_DOT(&m[0], v, 3));
-}
-/// @endcond
-
-/// @brief Multiply a 4x4 Matrix by a 3-dimensional Vector.
-///
-/// This is provided as a convenience and assumes the vector has a fourth
-/// component equal to 1.
-///
-/// @param m 4x4 Matrix.
-/// @param v 3-dimensional Vector.
-/// @return 3-dimensional Vector result.
-///
-/// @related mathfu::Matrix
-template <class T>
-inline Vector<T, 3> operator*(const Matrix<T, 4, 4>& m, const Vector<T, 3>& v) {
-  Vector<T, 4> v4(v[0], v[1], v[2], 1);
-  v4 = m * v4;
-  return Vector<T, 3>(v4[0] / v4[3], v4[1] / v4[3], v4[2] / v4[3]);
-}
-
-/// @cond MATHFU_INTERNAL
-/// @brief Multiply a Matrix with another Matrix.
-///
-/// @note Template specialized versions are implemented for 2x2, 3x3, and 4x4
-/// matrices to improve performance. 3x3 float is also specialized because if
-/// SIMD is used the vectors of this type of length 4.
-///
-/// @param m1 Matrix to multiply.
-/// @param m2 Matrix to multiply.
-/// @param out_m Pointer to a Matrix which receives the result.
-///
-/// @tparam T Type of each element in the returned Matrix.
-/// @tparam size1 Number of rows in the returned Matrix and columns in m1.
-/// @tparam size2 Number of columns in the returned Matrix and rows in m2.
-/// @tparam size3 Number of columns in m3.
-template <class T, int size1, int size2, int size3>
-inline void TimesHelper(const Matrix<T, size1, size2>& m1,
-                        const Matrix<T, size2, size3>& m2,
-                        Matrix<T, size1, size3>* out_m) {
-  for (int i = 0; i < size1; i++) {
-    for (int j = 0; j < size3; j++) {
-      Vector<T, size2> row;
-      for (int k = 0; k < size2; k++) {
-        row[k] = m1(i, k);
-      }
-      (*out_m)(i, j) = Vector<T, size2>::DotProduct(m2.GetColumn(j), row);
-    }
-  }
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline void TimesHelper(const Matrix<T, 2, 2>& m1, const Matrix<T, 2, 2>& m2,
-                        Matrix<T, 2, 2>* out_m) {
-  Matrix<T, 2, 2>& out = *out_m;
-  out[0] = m1[0] * m2[0] + m1[2] * m2[1];
-  out[1] = m1[1] * m2[0] + m1[3] * m2[1];
-  out[2] = m1[0] * m2[2] + m1[2] * m2[3];
-  out[3] = m1[1] * m2[2] + m1[3] * m2[3];
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <typename T>
-inline void TimesHelper(const Matrix<T, 3, 3>& m1, const Matrix<T, 3, 3>& m2,
-                        Matrix<T, 3, 3>* out_m) {
-  Matrix<T, 3, 3>& out = *out_m;
-  {
-    Vector<T, 3> row(m1[0], m1[3], m1[6]);
-    out[0] = Vector<T, 3>::DotProduct(m2.GetColumn(0), row);
-    out[3] = Vector<T, 3>::DotProduct(m2.GetColumn(1), row);
-    out[6] = Vector<T, 3>::DotProduct(m2.GetColumn(2), row);
-  }
-  {
-    Vector<T, 3> row(m1[1], m1[4], m1[7]);
-    out[1] = Vector<T, 3>::DotProduct(m2.GetColumn(0), row);
-    out[4] = Vector<T, 3>::DotProduct(m2.GetColumn(1), row);
-    out[7] = Vector<T, 3>::DotProduct(m2.GetColumn(2), row);
-  }
-  {
-    Vector<T, 3> row(m1[2], m1[5], m1[8]);
-    out[2] = Vector<T, 3>::DotProduct(m2.GetColumn(0), row);
-    out[5] = Vector<T, 3>::DotProduct(m2.GetColumn(1), row);
-    out[8] = Vector<T, 3>::DotProduct(m2.GetColumn(2), row);
-  }
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline void TimesHelper(const Matrix<T, 4, 4>& m1, const Matrix<T, 4, 4>& m2,
-                        Matrix<T, 4, 4>* out_m) {
-  Matrix<T, 4, 4>& out = *out_m;
-  {
-    Vector<T, 4> row(m1[0], m1[4], m1[8], m1[12]);
-    out[0] = Vector<T, 4>::DotProduct(m2.GetColumn(0), row);
-    out[4] = Vector<T, 4>::DotProduct(m2.GetColumn(1), row);
-    out[8] = Vector<T, 4>::DotProduct(m2.GetColumn(2), row);
-    out[12] = Vector<T, 4>::DotProduct(m2.GetColumn(3), row);
-  }
-  {
-    Vector<T, 4> row(m1[1], m1[5], m1[9], m1[13]);
-    out[1] = Vector<T, 4>::DotProduct(m2.GetColumn(0), row);
-    out[5] = Vector<T, 4>::DotProduct(m2.GetColumn(1), row);
-    out[9] = Vector<T, 4>::DotProduct(m2.GetColumn(2), row);
-    out[13] = Vector<T, 4>::DotProduct(m2.GetColumn(3), row);
-  }
-  {
-    Vector<T, 4> row(m1[2], m1[6], m1[10], m1[14]);
-    out[2] = Vector<T, 4>::DotProduct(m2.GetColumn(0), row);
-    out[6] = Vector<T, 4>::DotProduct(m2.GetColumn(1), row);
-    out[10] = Vector<T, 4>::DotProduct(m2.GetColumn(2), row);
-    out[14] = Vector<T, 4>::DotProduct(m2.GetColumn(3), row);
-  }
-  {
-    Vector<T, 4> row(m1[3], m1[7], m1[11], m1[15]);
-    out[3] = Vector<T, 4>::DotProduct(m2.GetColumn(0), row);
-    out[7] = Vector<T, 4>::DotProduct(m2.GetColumn(1), row);
-    out[11] = Vector<T, 4>::DotProduct(m2.GetColumn(2), row);
-    out[15] = Vector<T, 4>::DotProduct(m2.GetColumn(3), row);
-  }
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// @brief Compute the identity matrix.
-///
-/// @note There are template specializations for 2x2, 3x3, and 4x4 matrices to
-/// increase performance.
-///
-/// @return Identity Matrix.
-/// @tparam T Type of each element in the returned Matrix.
-/// @tparam rows Number of rows in the returned Matrix.
-/// @tparam columns Number of columns in the returned Matrix.
-template <class T, int rows, int columns>
-inline Matrix<T, rows, columns> IdentityHelper() {
-  Matrix<T, rows, columns> return_matrix(0.f);
-  int min_d = rows < columns ? rows : columns;
-  for (int i = 0; i < min_d; ++i) return_matrix(i, i) = 1;
-  return return_matrix;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline Matrix<T, 2, 2> IdentityHelper() {
-  return Matrix<T, 2, 2>(1, 0, 0, 1);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline Matrix<T, 3, 3> IdentityHelper() {
-  return Matrix<T, 3, 3>(1, 0, 0, 0, 1, 0, 0, 0, 1);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline Matrix<T, 4, 4> IdentityHelper() {
-  return Matrix<T, 4, 4>(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// @brief Compute the outer product of two vectors.
-///
-/// @note There are template specialization for 2x2, 3x3, and 4x4 matrices to
-/// increase performance.
-template <class T, int rows, int columns>
-static inline Matrix<T, rows, columns> OuterProductHelper(
-    const Vector<T, rows>& v1, const Vector<T, columns>& v2) {
-  Matrix<T, rows, columns> result(0);
-  int offset = 0;
-  for (int column = 0; column < columns; column++) {
-    for (int row = 0; row < rows; row++) {
-      result[row + offset] = v1[row] * v2[column];
-    }
-    offset += rows;
-  }
-  return result;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-static inline Matrix<T, 2, 2> OuterProductHelper(const Vector<T, 2>& v1,
-                                                 const Vector<T, 2>& v2) {
-  return Matrix<T, 2, 2>(v1[0] * v2[0], v1[1] * v2[0], v1[0] * v2[1],
-                         v1[1] * v2[1]);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-static inline Matrix<T, 3, 3> OuterProductHelper(const Vector<T, 3>& v1,
-                                                 const Vector<T, 3>& v2) {
-  return Matrix<T, 3, 3>(v1[0] * v2[0], v1[1] * v2[0], v1[2] * v2[0],
-                         v1[0] * v2[1], v1[1] * v2[1], v1[2] * v2[1],
-                         v1[0] * v2[2], v1[1] * v2[2], v1[2] * v2[2]);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-static inline Matrix<T, 4, 4> OuterProductHelper(const Vector<T, 4>& v1,
-                                                 const Vector<T, 4>& v2) {
-  return Matrix<T, 4, 4>(
-      v1[0] * v2[0], v1[1] * v2[0], v1[2] * v2[0], v1[3] * v2[0], v1[0] * v2[1],
-      v1[1] * v2[1], v1[2] * v2[1], v1[3] * v2[1], v1[0] * v2[2], v1[1] * v2[2],
-      v1[2] * v2[2], v1[3] * v2[2], v1[0] * v2[3], v1[1] * v2[3], v1[2] * v2[3],
-      v1[3] * v2[3]);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// Struct used for template specialization for functions that
-/// returns constants.
-template <class T>
-class Constants {
- public:
-  /// Minimum absolute value of the determinant of an invertible matrix.
-  static T GetDeterminantThreshold() {
-    // No constant defined for the general case.
-    assert(false);
-    return 0;
-  }
-};
-/// @endcond
-
-/// Functions that return constants for <code>float</code> values.
-template <>
-class Constants<float> {
- public:
-  /// @brief Minimum absolute value of the determinant of an invertible
-  /// <code>float</code> Matrix.
-  ///
-  /// <code>float</code> values have 23 bits of precision which is roughly
-  /// 1e7f, given that the final step of matrix inversion is multiplication
-  /// with the inverse of the determinant, the minimum value of the
-  /// determinant is 1e-7f before the precision too low to accurately
-  /// calculate the inverse.
-  /// @returns Minimum absolute value of the determinant of an invertible
-  /// <code>float</code> Matrix.
-  ///
-  /// @related mathfu::Matrix::InverseWithDeterminantCheck()
-  static float GetDeterminantThreshold() { return 1e-7f; }
-};
-
-/// Functions that return constants for <code>double</code> values.
-template <>
-class Constants<double> {
- public:
-  /// @brief Minimum absolute value of the determinant of an invertible
-  /// <code>double</code> Matrix.
-  ///
-  /// <code>double</code> values have 46 bits of precision which is roughly
-  /// 1e15, given that the final step of matrix inversion is multiplication
-  /// with the inverse of the determinant, the minimum value of the
-  /// determinant is 1e-15 before the precision too low to accurately
-  /// calculate the inverse.
-  /// @returns Minimum absolute value of the determinant of an invertible
-  /// <code>double</code> Matrix.
-  ///
-  /// @related mathfu::Matrix::InverseWithDeterminantCheck()
-  static double GetDeterminantThreshold() { return 1e-15; }
-};
-
-/// @cond MATHFU_INTERNAL
-/// @brief Compute the inverse of a matrix.
-///
-/// There is template specialization  for 2x2, 3x3, and 4x4 matrices to
-/// increase performance. Inverse is not implemented for dense matrices that
-/// are not of size 2x2, 3x3, and 4x4.  If check_invertible is true the
-/// determine of the matrix is compared with
-/// Constants<T>::GetDeterminantThreshold() to roughly determine whether the
-/// Matrix is invertible.
-template <bool check_invertible, class T, int rows, int columns>
-inline bool InverseHelper(const Matrix<T, rows, columns>& m,
-                          Matrix<T, rows, columns>* const inverse) {
-  assert(false);
-  (void)m;
-  *inverse = T::Identity();
-  return false;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <bool check_invertible, class T>
-inline bool InverseHelper(const Matrix<T, 2, 2>& m,
-                          Matrix<T, 2, 2>* const inverse) {
-  T determinant = m[0] * m[3] - m[1] * m[2];
-  if (check_invertible &&
-      fabs(determinant) < Constants<T>::GetDeterminantThreshold()) {
-    return false;
-  }
-  T inverseDeterminant = 1 / determinant;
-  (*inverse)[0] = inverseDeterminant * m[3];
-  (*inverse)[1] = -inverseDeterminant * m[1];
-  (*inverse)[2] = -inverseDeterminant * m[2];
-  (*inverse)[3] = inverseDeterminant * m[0];
-  return true;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <bool check_invertible, class T>
-inline bool InverseHelper(const Matrix<T, 3, 3>& m,
-                          Matrix<T, 3, 3>* const inverse) {
-  // Find determinant of matrix.
-  T sub11 = m[4] * m[8] - m[5] * m[7], sub12 = -m[1] * m[8] + m[2] * m[7],
-    sub13 = m[1] * m[5] - m[2] * m[4];
-  T determinant = m[0] * sub11 + m[3] * sub12 + m[6] * sub13;
-  if (check_invertible &&
-      fabs(determinant) < Constants<T>::GetDeterminantThreshold()) {
-    return false;
-  }
-  // Find determinants of 2x2 submatrices for the elements of the inverse.
-  *inverse = Matrix<T, 3, 3>(
-      sub11, sub12, sub13, m[6] * m[5] - m[3] * m[8], m[0] * m[8] - m[6] * m[2],
-      m[3] * m[2] - m[0] * m[5], m[3] * m[7] - m[6] * m[4],
-      m[6] * m[1] - m[0] * m[7], m[0] * m[4] - m[3] * m[1]);
-  *(inverse) *= 1 / determinant;
-  return true;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-inline int FindLargestPivotElem(const Matrix<T, 4, 4>& m) {
-  Vector<T, 4> fabs_column(fabs(m[0]), fabs(m[1]), fabs(m[2]), fabs(m[3]));
-  if (fabs_column[0] > fabs_column[1]) {
-    if (fabs_column[0] > fabs_column[2]) {
-      if (fabs_column[0] > fabs_column[3]) {
-        return 0;
-      } else {
-        return 3;
-      }
-    } else if (fabs_column[2] > fabs_column[3]) {
-      return 2;
-    } else {
-      return 3;
-    }
-  } else if (fabs_column[1] > fabs_column[2]) {
-    if (fabs_column[1] > fabs_column[3]) {
-      return 1;
-    } else {
-      return 3;
-    }
-  } else if (fabs_column[2] > fabs_column[3]) {
-    return 2;
-  } else {
-    return 3;
-  }
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <bool check_invertible, class T>
-bool InverseHelper(const Matrix<T, 4, 4>& m, Matrix<T, 4, 4>* const inverse) {
-  // This will find the pivot element.
-  int pivot_elem = FindLargestPivotElem(m);
-  // This will perform the pivot and find the row, column, and 3x3 submatrix
-  // for this pivot.
-  Vector<T, 3> row, column;
-  Matrix<T, 3> matrix;
-  if (pivot_elem == 0) {
-    row = Vector<T, 3>(m[4], m[8], m[12]);
-    column = Vector<T, 3>(m[1], m[2], m[3]);
-    matrix =
-        Matrix<T, 3>(m[5], m[6], m[7], m[9], m[10], m[11], m[13], m[14], m[15]);
-  } else if (pivot_elem == 1) {
-    row = Vector<T, 3>(m[5], m[9], m[13]);
-    column = Vector<T, 3>(m[0], m[2], m[3]);
-    matrix =
-        Matrix<T, 3>(m[4], m[6], m[7], m[8], m[10], m[11], m[12], m[14], m[15]);
-  } else if (pivot_elem == 2) {
-    row = Vector<T, 3>(m[6], m[10], m[14]);
-    column = Vector<T, 3>(m[0], m[1], m[3]);
-    matrix =
-        Matrix<T, 3>(m[4], m[5], m[7], m[8], m[9], m[11], m[12], m[13], m[15]);
-  } else {
-    row = Vector<T, 3>(m[7], m[11], m[15]);
-    column = Vector<T, 3>(m[0], m[1], m[2]);
-    matrix =
-        Matrix<T, 3>(m[4], m[5], m[6], m[8], m[9], m[10], m[12], m[13], m[14]);
-  }
-  T pivot_value = m[pivot_elem];
-  if (check_invertible &&
-      fabs(pivot_value) < Constants<T>::GetDeterminantThreshold()) {
-    return false;
-  }
-  // This will compute the inverse using the row, column, and 3x3 submatrix.
-  T inv = -1 / pivot_value;
-  row *= inv;
-  matrix += Matrix<T, 3>::OuterProduct(column, row);
-  Matrix<T, 3> mat_inverse;
-  if (!InverseHelper<check_invertible>(matrix, &mat_inverse) &&
-      check_invertible) {
-    return false;
-  }
-  Vector<T, 3> col_inverse = mat_inverse * (column * inv);
-  Vector<T, 3> row_inverse = row * mat_inverse;
-  T pivot_inverse = Vector<T, 3>::DotProduct(row, col_inverse) - inv;
-  if (pivot_elem == 0) {
-    *inverse = Matrix<T, 4, 4>(
-        pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2],
-        row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
-        row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
-        row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8]);
-  } else if (pivot_elem == 1) {
-    *inverse = Matrix<T, 4, 4>(
-        row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
-        pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2],
-        row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
-        row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8]);
-  } else if (pivot_elem == 2) {
-    *inverse = Matrix<T, 4, 4>(
-        row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
-        row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
-        pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2],
-        row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8]);
-  } else {
-    *inverse = Matrix<T, 4, 4>(
-        row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
-        row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
-        row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8],
-        pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2]);
-  }
-  return true;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// Create a 4x4 perpective matrix.
-template <class T>
-inline Matrix<T, 4, 4> PerspectiveHelper(T fovy, T aspect, T znear, T zfar,
-                                         T handedness) {
-  const T y = 1 / std::tan(fovy * static_cast<T>(.5));
-  const T x = y / aspect;
-  const T zdist = (znear - zfar);
-  const T zfar_per_zdist = zfar / zdist;
-  return Matrix<T, 4, 4>(x, 0, 0, 0, 0, y, 0, 0, 0, 0,
-                         zfar_per_zdist * handedness, -1 * handedness, 0, 0,
-                         2.0f * znear * zfar_per_zdist, 0);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// Create a 4x4 orthographic matrix.
-template <class T>
-static inline Matrix<T, 4, 4> OrthoHelper(T left, T right, T bottom, T top,
-                                          T znear, T zfar, T handedness) {
-  return Matrix<T, 4, 4>(static_cast<T>(2) / (right - left), 0, 0, 0, 0,
-                         static_cast<T>(2) / (top - bottom), 0, 0, 0, 0,
-                         -handedness * static_cast<T>(2) / (zfar - znear), 0,
-                         -(right + left) / (right - left),
-                         -(top + bottom) / (top - bottom),
-                         -(zfar + znear) / (zfar - znear), static_cast<T>(1));
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// Calculate the axes required to construct a 3-dimensional camera matrix that
-/// looks at "at" from eye position "eye" with the up vector "up".  The axes
-/// are returned in a 4 element "axes" array.
-template <class T>
-static void LookAtHelperCalculateAxes(const Vector<T, 3>& at,
-                                      const Vector<T, 3>& eye,
-                                      const Vector<T, 3>& up, T handedness,
-                                      Vector<T, 3>* const axes) {
-  // Notice that y-axis is always the same regardless of handedness.
-  axes[2] = (at - eye).Normalized();
-  axes[0] = Vector<T, 3>::CrossProduct(up, axes[2]).Normalized();
-  axes[1] = Vector<T, 3>::CrossProduct(axes[2], axes[0]);
-  axes[3] = Vector<T, 3>(handedness * Vector<T, 3>::DotProduct(axes[0], eye),
-                         -Vector<T, 3>::DotProduct(axes[1], eye),
-                         handedness * Vector<T, 3>::DotProduct(axes[2], eye));
-
-  // Default calculation is left-handed (i.e. handedness=-1).
-  // Negate x and z axes for right-handed (i.e. handedness=+1) case.
-  const T neg = -handedness;
-  axes[0] *= neg;
-  axes[2] *= neg;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// Create a 3-dimensional camera matrix.
-template <class T>
-static inline Matrix<T, 4, 4> LookAtHelper(const Vector<T, 3>& at,
-                                           const Vector<T, 3>& eye,
-                                           const Vector<T, 3>& up,
-                                           T handedness) {
-  Vector<T, 3> axes[4];
-  LookAtHelperCalculateAxes(at, eye, up, handedness, axes);
-  const Vector<T, 4> column0(axes[0][0], axes[1][0], axes[2][0], 0);
-  const Vector<T, 4> column1(axes[0][1], axes[1][1], axes[2][1], 0);
-  const Vector<T, 4> column2(axes[0][2], axes[1][2], axes[2][2], 0);
-  const Vector<T, 4> column3(axes[3], 1);
-  return Matrix<T, 4, 4>(column0, column1, column2, column3);
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-/// Get the 3D position in object space from a window coordinate.
-template <class T>
-static inline bool UnProjectHelper(const Vector<T, 3>& window_coord,
-                                   const Matrix<T, 4, 4>& model_view,
-                                   const Matrix<T, 4, 4>& projection,
-                                   const float window_width,
-                                   const float window_height,
-                                   Vector<T, 3>& result) {
-  if (window_coord.z < static_cast<T>(0) ||
-      window_coord.z > static_cast<T>(1)) {
-    // window_coord.z should be with in [0, 1]
-    // 0: near plane
-    // 1: far plane
-    return false;
-  }
-  Matrix<T, 4, 4> matrix = (projection * model_view).Inverse();
-  Vector<T, 4> standardized = Vector<T, 4>(
-      static_cast<T>(2) * (window_coord.x - window_width) / window_width +
-          static_cast<T>(1),
-      static_cast<T>(2) * (window_coord.y - window_height) / window_height +
-          static_cast<T>(1),
-      static_cast<T>(2) * window_coord.z - static_cast<T>(1),
-      static_cast<T>(1));
-
-  Vector<T, 4> multiply = matrix * standardized;
-  if (multiply.w == static_cast<T>(0)) {
-    return false;
-  }
-  result = multiply.xyz() / multiply.w;
-  return true;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <typename T, int rows, int columns, typename CompatibleT>
-static inline Matrix<T, rows, columns> FromTypeHelper(const CompatibleT& compatible) {
-// C++11 is required for constructed unions.
-#if __cplusplus >= 201103L
-  // Use a union instead of reinterpret_cast to avoid aliasing bugs.
-  union ConversionUnion {
-    ConversionUnion() {}  // C++11.
-    CompatibleT compatible;
-    VectorPacked<T, rows> packed[columns];
-  } u;
-  static_assert(sizeof(u.compatible) == sizeof(u.packed), "Conversion size mismatch.");
-
-  // The read of `compatible` and write to `u.compatible` gets optimized away,
-  // and this becomes essentially a safe reinterpret_cast.
-  u.compatible = compatible;
-
-  // Call the packed vector constructor with the `compatible` data.
-  return Matrix<T, rows, columns>(u.packed);
-#else
-  // Use the less-desirable memcpy technique if C++11 is not available.
-  // Most compilers understand memcpy deep enough to avoid replace the function
-  // call with a series of load/stores, which should then get optimized away,
-  // however in the worst case the optimize away may not happen.
-  // Note: Memcpy avoids aliasing bugs because it operates via unsigned char*,
-  // which is allowed to alias any type.
-  // See:
-  // http://stackoverflow.com/questions/15745030/type-punning-with-void-without-breaking-the-strict-aliasing-rule-in-c99
-  Matrix<T, rows, columns> m;
-  assert(sizeof(m) == sizeof(compatible));
-  memcpy(&m, &compatible, sizeof(m));
-  return m;
-#endif  // __cplusplus >= 201103L
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <typename T, int rows, int columns, typename CompatibleT>
-static inline CompatibleT ToTypeHelper(const Matrix<T, rows, columns>& m) {
-// See FromTypeHelper() for comments.
-#if __cplusplus >= 201103L
-  union ConversionUnion {
-    ConversionUnion() {}
-    CompatibleT compatible;
-    VectorPacked<T, rows> packed[columns];
-  } u;
-  static_assert(sizeof(u.compatible) == sizeof(u.packed), "Conversion size mismatch.");
-  m.Pack(u.packed);
-  return u.compatible;
-#else
-  CompatibleT compatible;
-  assert(sizeof(m) == sizeof(compatible));
-  memcpy(&compatible, &m, sizeof(compatible));
-  return compatible;
-#endif  // __cplusplus >= 201103L
-}
-/// @endcond
-
-/// @typedef AffineTransform
-///
-/// @brief A typedef representing a 4x3 float affine transformation.
-/// Since the last row ('w' row) of an affine transformation is fixed,
-/// this data type only includes the variable information for the transform.
-typedef Matrix<float, 4, 3> AffineTransform;
-/// @}
-
-}  // namespace mathfu
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-// Include the specializations to avoid template errors.
-// See includes at bottom of vector.h for further explanation.
-#include "mathfu/matrix_4x4.h"
-
-#endif  // MATHFU_MATRIX_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/matrix_4x4.h b/third_party/mathfu-1.1.0/include/mathfu/matrix_4x4.h
deleted file mode 100644
index 0635662..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/matrix_4x4.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-* Copyright 2016 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_MATRIX_4X4_H_
-#define MATHFU_MATRIX_4X4_H_
-
-// Prefer including matrix.h directly, since it includes specializations.
-#include "mathfu/matrix.h"
-
-#endif  // MATHFU_MATRIX_4X4_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/quaternion.h b/third_party/mathfu-1.1.0/include/mathfu/quaternion.h
deleted file mode 100644
index 0046f2c..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/quaternion.h
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_QUATERNION_H_
-#define MATHFU_QUATERNION_H_
-
-#ifdef _WIN32
-#if !defined(_USE_MATH_DEFINES)
-#define _USE_MATH_DEFINES  // For M_PI.
-#endif                     // !defined(_USE_MATH_DEFINES)
-#endif                     // _WIN32
-
-#include "mathfu/matrix.h"
-#include "mathfu/vector.h"
-
-#include <math.h>
-
-/// @file mathfu/quaternion.h
-/// @brief Quaternion class and functions.
-/// @addtogroup mathfu_quaternion
-///
-/// MathFu provides a Quaternion class that utilizes SIMD optimized
-/// Matrix and Vector classes.
-
-namespace mathfu {
-
-/// @addtogroup mathfu_quaternion
-/// @{
-/// @class Quaternion
-///
-/// @brief Stores a Quaternion of type T and provides a set of utility
-/// operations on each Quaternion.
-/// @tparam T Type of each element in the Quaternion.
-template <class T>
-class Quaternion {
- public:
-  /// @brief Construct an uninitialized Quaternion.
-  inline Quaternion() {}
-
-  /// @brief Construct a Quaternion from a copy.
-  /// @param q Quaternion to copy.
-  inline Quaternion(const Quaternion<T>& q) {
-    s_ = q.s_;
-    v_ = q.v_;
-  }
-
-  /// @brief Construct a Quaternion using scalar values to initialize each
-  /// element.
-  ///
-  /// @param s1 Scalar component.
-  /// @param s2 First element of the Vector component.
-  /// @param s3 Second element of the Vector component.
-  /// @param s4 Third element of the Vector component.
-  inline Quaternion(const T& s1, const T& s2, const T& s3, const T& s4) {
-    s_ = s1;
-    v_ = Vector<T, 3>(s2, s3, s4);
-  }
-
-  /// @brief Construct a quaternion from a scalar and 3-dimensional Vector.
-  ///
-  /// @param s1 Scalar component.
-  /// @param v1 Vector component.
-  inline Quaternion(const T& s1, const Vector<T, 3>& v1) {
-    s_ = s1;
-    v_ = v1;
-  }
-
-  /// @brief Return the scalar component of the quaternion.
-  ///
-  /// @return The scalar component
-  inline T& scalar() { return s_; }
-
-  /// @brief Return the scalar component of the quaternion.
-  ///
-  /// @return The scalar component
-  inline const T& scalar() const { return s_; }
-
-  /// @brief Set the scalar component of the quaternion.
-  ///
-  /// @param s Scalar component.
-  inline void set_scalar(const T& s) { s_ = s; }
-
-  /// @brief Return the vector component of the quaternion.
-  ///
-  /// @return The scalar component
-  inline Vector<T, 3>& vector() { return v_; }
-
-  /// @brief Return the vector component of the quaternion.
-  ///
-  /// @return The scalar component
-  inline const Vector<T, 3>& vector() const { return v_; }
-
-  /// @brief Set the vector component of the quaternion.
-  ///
-  /// @param v Vector component.
-  inline void set_vector(const Vector<T, 3>& v) { v_ = v; }
-
-  /// @brief Calculate the inverse Quaternion.
-  ///
-  /// This calculates the inverse such that <code>(q * q).Inverse()</code>
-  /// is the identity.
-  ///
-  /// @return Quaternion containing the result.
-  inline Quaternion<T> Inverse() const { return Quaternion<T>(s_, -v_); }
-
-  /// @brief Multiply this Quaternion with another Quaternion.
-  ///
-  /// @note This is equivalent to
-  /// <code>FromMatrix(ToMatrix() * q.ToMatrix()).</code>
-  /// @param q Quaternion to multiply with.
-  /// @return Quaternion containing the result.
-  inline Quaternion<T> operator*(const Quaternion<T>& q) const {
-    return Quaternion<T>(
-        s_ * q.s_ - Vector<T, 3>::DotProduct(v_, q.v_),
-        s_ * q.v_ + q.s_ * v_ + Vector<T, 3>::CrossProduct(v_, q.v_));
-  }
-
-  /// @brief Multiply this Quaternion by a scalar.
-  ///
-  /// This multiplies the angle of the rotation by a scalar factor.
-  /// @param s1 Scalar to multiply with.
-  /// @return Quaternion containing the result.
-  inline Quaternion<T> operator*(const T& s1) const {
-    T angle;
-    Vector<T, 3> axis;
-    ToAngleAxis(&angle, &axis);
-    angle *= s1;
-    return Quaternion<T>(cos(0.5f * angle),
-                         axis.Normalized() * static_cast<T>(sin(0.5f * angle)));
-  }
-
-  /// @brief Multiply a Vector by this Quaternion.
-  ///
-  /// This will rotate the specified vector by the rotation specified by this
-  /// Quaternion.
-  ///
-  /// @param v1 Vector to multiply by this Quaternion.
-  /// @return Rotated Vector.
-  inline Vector<T, 3> operator*(const Vector<T, 3>& v1) const {
-    T ss = s_ + s_;
-    return ss * Vector<T, 3>::CrossProduct(v_, v1) + (ss * s_ - 1) * v1 +
-           2 * Vector<T, 3>::DotProduct(v_, v1) * v_;
-  }
-
-  /// @brief Normalize this quaterion (in-place).
-  ///
-  /// @return Length of the quaternion.
-  inline T Normalize() {
-    T length = sqrt(s_ * s_ + Vector<T, 3>::DotProduct(v_, v_));
-    T scale = (1 / length);
-    s_ *= scale;
-    v_ *= scale;
-    return length;
-  }
-
-  /// @brief Calculate the normalized version of this quaternion.
-  ///
-  /// @return The normalized quaternion.
-  inline Quaternion<T> Normalized() const {
-    Quaternion<T> q(*this);
-    q.Normalize();
-    return q;
-  }
-
-  /// @brief Convert this Quaternion to an Angle and axis.
-  ///
-  /// The returned  angle is the size of the rotation in radians about the
-  /// axis represented by this Quaternion.
-  ///
-  /// @param angle Receives the angle.
-  /// @param axis Receives the normalized axis.
-  inline void ToAngleAxis(T* angle, Vector<T, 3>* axis) const {
-    *axis = s_ > 0 ? v_ : -v_;
-    *angle = 2 * atan2(axis->Normalize(), s_ > 0 ? s_ : -s_);
-  }
-
-  /// @brief Convert this Quaternion to 3 Euler Angles.
-  ///
-  /// @return 3-dimensional Vector where each element is a angle of rotation
-  /// (in radians) around the x, y, and z axes.
-  inline Vector<T, 3> ToEulerAngles() const {
-    Matrix<T, 3> m(ToMatrix());
-    T cos2 = m[0] * m[0] + m[1] * m[1];
-    if (cos2 < 1e-6f) {
-      return Vector<T, 3>(
-          0,
-          m[2] < 0 ? static_cast<T>(0.5 * M_PI) : static_cast<T>(-0.5 * M_PI),
-          -std::atan2(m[3], m[4]));
-    } else {
-      return Vector<T, 3>(std::atan2(m[5], m[8]),
-                          std::atan2(-m[2], std::sqrt(cos2)),
-                          std::atan2(m[1], m[0]));
-    }
-  }
-
-  /// @brief Convert to a 3x3 Matrix.
-  ///
-  /// @return 3x3 rotation Matrix.
-  inline Matrix<T, 3> ToMatrix() const {
-    const T x2 = v_[0] * v_[0], y2 = v_[1] * v_[1], z2 = v_[2] * v_[2];
-    const T sx = s_ * v_[0], sy = s_ * v_[1], sz = s_ * v_[2];
-    const T xz = v_[0] * v_[2], yz = v_[1] * v_[2], xy = v_[0] * v_[1];
-    return Matrix<T, 3>(1 - 2 * (y2 + z2), 2 * (xy + sz), 2 * (xz - sy),
-                        2 * (xy - sz), 1 - 2 * (x2 + z2), 2 * (sx + yz),
-                        2 * (sy + xz), 2 * (yz - sx), 1 - 2 * (x2 + y2));
-  }
-
-  /// @brief Convert to a 4x4 Matrix.
-  ///
-  /// @return 4x4 transform Matrix.
-  inline Matrix<T, 4> ToMatrix4() const {
-    const T x2 = v_[0] * v_[0], y2 = v_[1] * v_[1], z2 = v_[2] * v_[2];
-    const T sx = s_ * v_[0], sy = s_ * v_[1], sz = s_ * v_[2];
-    const T xz = v_[0] * v_[2], yz = v_[1] * v_[2], xy = v_[0] * v_[1];
-    return Matrix<T, 4>(1 - 2 * (y2 + z2), 2 * (xy + sz), 2 * (xz - sy), 0.0f,
-                        2 * (xy - sz), 1 - 2 * (x2 + z2), 2 * (sx + yz), 0.0f,
-                        2 * (sy + xz), 2 * (yz - sx), 1 - 2 * (x2 + y2), 0.0f,
-                        0.0f, 0.0f, 0.0f, 1.0f);
-  }
-
-  /// @brief Create a Quaternion from an angle and axis.
-  ///
-  /// @param angle Angle in radians to rotate by.
-  /// @param axis Axis in 3D space to rotate around.
-  /// @return Quaternion containing the result.
-  static Quaternion<T> FromAngleAxis(const T& angle, const Vector<T, 3>& axis) {
-    const T halfAngle = static_cast<T>(0.5) * angle;
-    Vector<T, 3> localAxis(axis);
-    return Quaternion<T>(
-        cos(halfAngle),
-        localAxis.Normalized() * static_cast<T>(sin(halfAngle)));
-  }
-
-  /// @brief Create a quaternion from 3 euler angles.
-  ///
-  /// @param angles 3-dimensional Vector where each element contains an
-  /// angle in radius to rotate by about the x, y and z axes.
-  /// @return Quaternion containing the result.
-  static Quaternion<T> FromEulerAngles(const Vector<T, 3>& angles) {
-    const Vector<T, 3> halfAngles(static_cast<T>(0.5) * angles[0],
-                                  static_cast<T>(0.5) * angles[1],
-                                  static_cast<T>(0.5) * angles[2]);
-    const T sinx = std::sin(halfAngles[0]);
-    const T cosx = std::cos(halfAngles[0]);
-    const T siny = std::sin(halfAngles[1]);
-    const T cosy = std::cos(halfAngles[1]);
-    const T sinz = std::sin(halfAngles[2]);
-    const T cosz = std::cos(halfAngles[2]);
-    return Quaternion<T>(cosx * cosy * cosz + sinx * siny * sinz,
-                         sinx * cosy * cosz - cosx * siny * sinz,
-                         cosx * siny * cosz + sinx * cosy * sinz,
-                         cosx * cosy * sinz - sinx * siny * cosz);
-  }
-
-  /// @brief Create a quaternion from a rotation Matrix.
-  ///
-  /// @param m 3x3 rotation Matrix.
-  /// @return Quaternion containing the result.
-  static Quaternion<T> FromMatrix(const Matrix<T, 3>& m) {
-    const T trace = m(0, 0) + m(1, 1) + m(2, 2);
-    if (trace > 0) {
-      const T s = sqrt(trace + 1) * 2;
-      const T oneOverS = 1 / s;
-      return Quaternion<T>(static_cast<T>(0.25) * s, (m[5] - m[7]) * oneOverS,
-                           (m[6] - m[2]) * oneOverS, (m[1] - m[3]) * oneOverS);
-    } else if (m[0] > m[4] && m[0] > m[8]) {
-      const T s = sqrt(m[0] - m[4] - m[8] + 1) * 2;
-      const T oneOverS = 1 / s;
-      return Quaternion<T>((m[5] - m[7]) * oneOverS, static_cast<T>(0.25) * s,
-                           (m[3] + m[1]) * oneOverS, (m[6] + m[2]) * oneOverS);
-    } else if (m[4] > m[8]) {
-      const T s = sqrt(m[4] - m[0] - m[8] + 1) * 2;
-      const T oneOverS = 1 / s;
-      return Quaternion<T>((m[6] - m[2]) * oneOverS, (m[3] + m[1]) * oneOverS,
-                           static_cast<T>(0.25) * s, (m[5] + m[7]) * oneOverS);
-    } else {
-      const T s = sqrt(m[8] - m[0] - m[4] + 1) * 2;
-      const T oneOverS = 1 / s;
-      return Quaternion<T>((m[1] - m[3]) * oneOverS, (m[6] + m[2]) * oneOverS,
-                           (m[5] + m[7]) * oneOverS, static_cast<T>(0.25) * s);
-    }
-  }
-
-  /// @brief Calculate the dot product of two Quaternions.
-  ///
-  /// @param q1 First quaternion.
-  /// @param q2 Second quaternion
-  /// @return The scalar dot product of both Quaternions.
-  static inline T DotProduct(const Quaternion<T>& q1, const Quaternion<T>& q2) {
-    return q1.s_ * q2.s_ + Vector<T, 3>::DotProduct(q1.v_, q2.v_);
-  }
-
-  /// @brief Calculate the spherical linear interpolation between two
-  /// Quaternions.
-  ///
-  /// @param q1 Start Quaternion.
-  /// @param q2 End Quaternion.
-  /// @param s1 The scalar value determining how far from q1 and q2 the
-  /// resulting quaternion should be.  A value of 0 corresponds to q1 and a
-  /// value of 1 corresponds to q2.
-  /// @result Quaternion containing the result.
-  static inline Quaternion<T> Slerp(const Quaternion<T>& q1,
-                                    const Quaternion<T>& q2, const T& s1) {
-    if (q1.s_ * q2.s_ + Vector<T, 3>::DotProduct(q1.v_, q2.v_) > 0.999999f)
-      return Quaternion<T>(q1.s_ * (1 - s1) + q2.s_ * s1,
-                           q1.v_ * (1 - s1) + q2.v_ * s1);
-    return q1 * ((q1.Inverse() * q2) * s1);
-  }
-
-  /// @brief Access an element of the quaternion.
-  ///
-  /// @param i Index of the element to access.
-  /// @return A reference to the accessed data that can be modified by the
-  /// caller.
-  inline T& operator[](const int i) {
-    if (i == 0) return s_;
-    return v_[i - 1];
-  }
-
-  /// @brief Access an element of the quaternion.
-  ///
-  /// @param i Index of the element to access.
-  /// @return A const reference to the accessed.
-  inline const T& operator[](const int i) const {
-    return const_cast<Quaternion<T>*>(this)->operator[](i);
-  }
-
-  /// @brief Returns a vector that is perpendicular to the supplied vector.
-  ///
-  /// @param v1 An arbitrary vector
-  /// @return A vector perpendicular to v1.  Normally this will just be
-  /// the cross product of v1, v2.  If they are parallel or opposite though,
-  /// the routine will attempt to pick a vector.
-  static inline Vector<T, 3> PerpendicularVector(const Vector<T, 3>& v) {
-    // We start out by taking the cross product of the vector and the x-axis to
-    // find something parallel to the input vectors.  If that cross product
-    // turns out to be length 0 (i. e. the vectors already lie along the x axis)
-    // then we use the y-axis instead.
-    Vector<T, 3> axis = Vector<T, 3>::CrossProduct(
-        Vector<T, 3>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0)),
-        v);
-    // We use a fairly high epsilon here because we know that if this number
-    // is too small, the axis we'll get from a cross product with the y axis
-    // will be much better and more numerically stable.
-    if (axis.LengthSquared() < static_cast<T>(0.05)) {
-      axis = Vector<T, 3>::CrossProduct(
-          Vector<T, 3>(static_cast<T>(0), static_cast<T>(1), static_cast<T>(0)),
-          v);
-    }
-    return axis;
-  }
-
-  /// @brief Returns the a Quaternion that rotates from start to end.
-  ///
-  /// @param v1 The starting vector
-  /// @param v2 The vector to rotate to
-  /// @param preferred_axis the axis to use, if v1 and v2 are parallel.
-  /// @return A Quaternion describing the rotation from v1 to v2
-  /// See the comment on RotateFromToWithAxis for an explanation of the math.
-  static inline Quaternion<T> RotateFromToWithAxis(
-      const Vector<T, 3>& v1, const Vector<T, 3>& v2,
-      const Vector<T, 3>& preferred_axis) {
-    Vector<T, 3> start = v1.Normalized();
-    Vector<T, 3> end = v2.Normalized();
-
-    T dot_product = Vector<T, 3>::DotProduct(start, end);
-    // Any rotation < 0.1 degrees is treated as no rotation
-    // in order to avoid division by zero errors.
-    // So we early-out in cases where it's less then 0.1 degrees.
-    // cos( 0.1 degrees) = 0.99999847691
-    if (dot_product >= static_cast<T>(0.99999847691)) {
-      return Quaternion<T>::identity;
-    }
-    // If the vectors point in opposite directions, return a 180 degree
-    // rotation, on the axis that they asked for.
-    if (dot_product <= static_cast<T>(-0.99999847691)) {
-      return Quaternion<T>(static_cast<T>(0), preferred_axis);
-    }
-    // Degenerate cases have been handled, so if we're here, we have to
-    // actually compute the angle we want:
-    Vector<T, 3> cross_product = Vector<T, 3>::CrossProduct(start, end);
-
-    return Quaternion<T>(static_cast<T>(1.0) + dot_product, cross_product)
-        .Normalized();
-  }
-
-  /// @brief Returns the a Quaternion that rotates from start to end.
-  ///
-  /// @param v1 The starting vector
-  /// @param v2 The vector to rotate to
-  /// @return A Quaternion describing the rotation from v1 to v2.  In the case
-  /// where the vectors are parallel, it returns the identity.  In the case
-  /// where
-  /// they point in opposite directions, it picks an arbitrary axis.  (Since
-  /// there
-  /// are technically infinite possible quaternions to represent a 180 degree
-  /// rotation.)
-  ///
-  /// The final equation used here is fairly elegant, but its derivation is
-  /// not obvious:  We want to find the quaternion that represents the angle
-  /// between Start and End.
-  ///
-  /// The angle can be expressed as a quaternion with the values:
-  ///  angle: ArcCos(dotproduct(start, end) / (|start|*|end|)
-  ///  axis: crossproduct(start, end).normalized * sin(angle/2)
-  ///
-  /// or written as:
-  ///  quaternion(cos(angle/2), axis * sin(angle/2))
-  ///
-  /// Using the trig identity:
-  ///  sin(angle * 2) = 2 * sin(angle) * cos*angle)
-  /// Via substitution, we can turn this into:
-  ///  sin(angle/2) = 0.5 * sin(angle)/cos(angle/2)
-  ///
-  /// Using this substitution, we get:
-  ///  quaternion( cos(angle/2),
-  ///             0.5 * crossproduct(start, end).normalized
-  ///                 * sin(angle) / cos(angle/2))
-  ///
-  /// If we scale the whole thing up by 2 * cos(angle/2) then we get:
-  ///  quaternion(2 * cos(angle/2) * cos(angle/2),
-  ///             crossproduct(start, end).normalized * sin(angle))
-  ///
-  /// (Note that the quaternion is no longer normalized after this scaling)
-  ///
-  /// Another trig identity:
-  ///   cos(angle/2) = sqrt((1 + cos(angle) / 2)
-  ///
-  /// Substituting this in, we can simplify the quaternion scalar:
-  ///
-  ///  quaternion(1 + cos(angle),
-  ///             crossproduct(start, end).normalized * sin(angle))
-  ///
-  /// Because cross(start, end) has a magnitude of |start|*|end|*sin(angle),
-  ///  crossproduct(start,end).normalized
-  /// is equivalent to
-  ///  crossproduct(start,end) / |start| * |end| * sin(angle)
-  /// So after that substitution:
-  ///
-  ///  quaternion(1 + cos(angle),
-  ///             crossproduct(start, end) / (|start| * |end|))
-  ///
-  /// dotproduct(start, end) has the value of |start| * |end| * cos(angle),
-  /// so by algebra,
-  ///  cos(angle) = dotproduct(start, end) / (|start| * |end|)
-  /// we can replace our quaternion scalar here also:
-  ///
-  ///  quaternion(1 + dotproduct(start, end) / (|start| * |end|),
-  ///             crossproduct(start, end) / (|start| * |end|))
-  ///
-  /// If start and end are normalized, then |start| * |end| = 1, giving us a
-  /// final quaternion of:
-  ///
-  /// quaternion(1 + dotproduct(start, end), crossproduct(start, end))
-  static inline Quaternion<T> RotateFromTo(const Vector<T, 3>& v1,
-                                           const Vector<T, 3>& v2) {
-    Vector<T, 3> start = v1.Normalized();
-    Vector<T, 3> end = v2.Normalized();
-
-    T dot_product = Vector<T, 3>::DotProduct(start, end);
-    // Any rotation < 0.1 degrees is treated as no rotation
-    // in order to avoid division by zero errors.
-    // So we early-out in cases where it's less then 0.1 degrees.
-    // cos( 0.1 degrees) = 0.99999847691
-    if (dot_product >= static_cast<T>(0.99999847691)) {
-      return Quaternion<T>::identity;
-    }
-    // If the vectors point in opposite directions, return a 180 degree
-    // rotation, on an arbitrary axis.
-    if (dot_product <= static_cast<T>(-0.99999847691)) {
-      return Quaternion<T>(0, PerpendicularVector(start));
-    }
-    // Degenerate cases have been handled, so if we're here, we have to
-    // actually compute the angle we want:
-    Vector<T, 3> cross_product = Vector<T, 3>::CrossProduct(start, end);
-
-    return Quaternion<T>(static_cast<T>(1.0) + dot_product, cross_product)
-        .Normalized();
-  }
-
-  /// @brief Contains a quaternion doing the identity transform.
-  static Quaternion<T> identity;
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
- private:
-  T s_;
-  Vector<T, 3> v_;
-};
-
-template <typename T>
-Quaternion<T> Quaternion<T>::identity = Quaternion<T>(1, 0, 0, 0);
-/// @}
-
-/// @addtogroup mathfu_quaternion
-/// @{
-
-/// @brief Multiply a Quaternion by a scalar.
-///
-/// This multiplies the angle of the rotation of the specified Quaternion
-/// by a scalar factor.
-/// @param s Scalar to multiply with.
-/// @param q Quaternion to scale.
-/// @return Quaternion containing the result.
-///
-/// @related Quaternion
-template <class T>
-inline Quaternion<T> operator*(const T& s, const Quaternion<T>& q) {
-  return q * s;
-}
-/// @}
-
-}  // namespace mathfu
-#endif  // MATHFU_QUATERNION_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/rect.h b/third_party/mathfu-1.1.0/include/mathfu/rect.h
deleted file mode 100644
index 04d3738..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/rect.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-* Copyright 2016 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_RECT_H_
-#define MATHFU_RECT_H_
-
-#include "mathfu/vector.h"
-
-namespace mathfu {
-
-/// @addtogroup mathfu_rect
-/// @{
-/// @class Rect "mathfu/rect.h"
-/// @brief Rect of type T containing position (pos) and width.
-///
-/// Rect contains two 2D <b>Vector</b>s of type <b>T</b> representing position
-/// (pos) and size.
-///
-/// @tparam T type of Rect elements.
-template <class T>
-struct Rect {
-  Vector<T, 2> pos;
-  Vector<T, 2> size;
-
-  /// @brief Create a rect from a vector4 of the same type.
-  ///
-  /// @param v Vector that the data will be copied from.
-  explicit Rect(const Vector<T, 4>& v)
-      : pos(v.x, v.y), size(v.z, v.w) {}
-
-  /// @brief Create a rect from x, y, width and height values.
-  ///
-  /// @param x the given x value.
-  /// @param y the given y value.
-  /// @param width the given width value.
-  /// @param height the given height value.
-  inline Rect(T x = static_cast<T>(0), T y = static_cast<T>(0),
-              T width = static_cast<T>(0), T height = static_cast<T>(0))
-      : pos(x, y), size(width, height) {}
-
-  /// @brief Create a rect from two vector2 representing position and size.
-  ///
-  /// @param pos Vector representing the position vector (x and y values).
-  /// @param size Vector represening the size vector (width and height values).
-  inline Rect(const Vector<T, 2>& pos, const Vector<T, 2>& size)
-      : pos(pos), size(size) {}
-};
-/// @}
-
-/// @brief Check if two rects are identical.
-///
-/// @param r1 Rect to be tested.
-/// @param r2 Other rect to be tested.
-template <class T>
-bool operator==(const Rect<T>& r1, const Rect<T>& r2) {
-  return (r1.pos == r2.pos && r1.size == r2.size);
-}
-
-/// @brief Check if two rects are <b>not</b> identical.
-///
-/// @param r1 Rect to be tested.
-/// @param r2 Other rect to be tested.
-template <class T>
-bool operator!=(const Rect<T>& r1, const Rect<T>& r2) {
-  return !(r1 == r2);
-}
-
-}  // namespace mathfu
-
-#endif  // MATHFU_RECT_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/utilities.h b/third_party/mathfu-1.1.0/include/mathfu/utilities.h
deleted file mode 100644
index 21dd52e..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/utilities.h
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_UTILITIES_H_
-#define MATHFU_UTILITIES_H_
-
-#include <assert.h>
-#include <math.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <memory>
-
-/// @file mathfu/utilities.h Utilities
-/// @brief Utility macros and functions.
-
-/// @addtogroup mathfu_build_config
-///
-/// By default MathFu will attempt to build with SIMD optimizations enabled
-/// based upon the target architecture and compiler options.  However, it's
-/// possible to change the default build configuration using the following
-/// macros:
-///
-/// @li @ref MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
-/// @li @ref MATHFU_COMPILE_FORCE_PADDING
-///
-/// <table>
-/// <tr>
-///   <th>MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT</th>
-///   <th>MATHFU_COMPILE_FORCE_PADDING</th>
-///   <th>Configuration</th>
-/// </tr>
-/// <tr>
-///   <td><em>undefined</em></td>
-///   <td><em>undefined</em> or 1</td>
-///   <td>Default build configuration, SIMD optimization is enabled based upon
-///       the target architecture, compiler options and MathFu library
-///       support.</td>
-/// </tr>
-/// <tr>
-///   <td><em>undefined</em></td>
-///   <td>0</td>
-///   <td>If SIMD is supported, padding of data structures is disabled.  See
-///       @ref MATHFU_COMPILE_FORCE_PADDING for more information.</td>
-/// </tr>
-/// <tr>
-///   <td><em>defined</em></td>
-///   <td><em>undefined/0/1</em></td>
-///   <td>Builds MathFu with explicit SIMD optimization disabled.  The compiler
-///       could still potentially optimize some code paths with SIMD
-///       instructions based upon the compiler options.</td>
-/// </tr>
-/// </table>
-
-#ifdef DOXYGEN
-/// @addtogroup mathfu_build_config
-/// @{
-/// @def MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
-/// @brief Disable SIMD build configuration.
-///
-/// When defined, this macro <b>disables</b> the default behavior of trying to
-/// build the library with SIMD enabled  based upon the target architecture
-/// and compiler options.
-///
-/// To use this build option, this macro <b>must</b> be defined in all modules
-/// of the project.
-#define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
-/// @}
-#endif  // DOXYGEN
-#if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
-#if defined(__SSE__)
-#define MATHFU_COMPILE_WITH_SIMD
-#elif defined(__ARM_NEON__)
-#define MATHFU_COMPILE_WITH_SIMD
-#elif defined(_M_IX86_FP)  // MSVC
-#if _M_IX86_FP >= 1        // SSE enabled
-#define MATHFU_COMPILE_WITH_SIMD
-#endif  // _M_IX86_FP >= 1
-#endif
-#endif  // !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
-
-#ifdef DOXYGEN
-/// @addtogroup mathfu_build_config
-/// @{
-/// @def MATHFU_COMPILE_FORCE_PADDING
-/// @brief Enable / disable padding of data structures.
-///
-/// By default, when @ref MATHFU_COMPILE_FORCE_PADDING is <b>not</b> defined,
-/// data structures are padded when SIMD is enabled
-/// (i.e when @ref MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT is also not defined).
-///
-/// If @ref MATHFU_COMPILE_FORCE_PADDING is defined as <b>1</b>, all data
-/// structures are padded to a power of 2 size which enables more efficient
-/// SIMD operations.  This  is the default build configuration when SIMD is
-/// enabled.
-///
-/// If @ref MATHFU_COMPILE_FORCE_PADDING is defined as <b>0</b>, all data
-/// structures are packed by the compiler (with no padding) even when the SIMD
-/// build configuration is enabled.  This build option can be useful in the
-/// rare occasion an application is CPU memory bandwidth constrained, at the
-/// expense of additional instructions to copy to / from SIMD registers.
-///
-/// To use this build option, this macro <b>must</b> be defined in all modules
-/// of the project.
-///
-/// @see MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
-#define MATHFU_COMPILE_FORCE_PADDING
-/// @}
-#endif  // DOXYGEN
-
-#ifdef MATHFU_COMPILE_WITH_SIMD
-/// @cond MATHFU_INTERNAL
-/// @addtogroup mathfu_build_config
-/// @{
-/// @def MATHFU_COMPILE_WITH_PADDING
-/// @brief Enable padding of data structures to be efficient with SIMD.
-///
-/// When defined, this option enables padding of some data structures (e.g
-/// @ref vec3) to be more efficient with SIMD operations.  This option is
-/// only applicable when @ref MATHFU_COMPILE_WITHOUT_SIMD is not defined and
-/// the target architecture and compiler support SIMD.
-///
-/// To use this build option, this macro <b>must</b> be defined in all modules
-/// of the project.
-/// @see MATHFU_COMPILE_FORCE_PADDING
-#define MATHFU_COMPILE_WITH_PADDING
-/// @}
-#if defined(MATHFU_COMPILE_FORCE_PADDING)
-#if MATHFU_COMPILE_FORCE_PADDING == 1
-#if !defined(MATHFU_COMPILE_WITH_PADDING)
-#define MATHFU_COMPILE_WITH_PADDING
-#endif  // !defined(MATHFU_COMPILE_WITH_PADDING)
-#else
-#if defined(MATHFU_COMPILE_WITH_PADDING)
-#undef MATHFU_COMPILE_WITH_PADDING
-#endif  // MATHFU_COMPILE_WITH_PADDING
-#endif  // MATHFU_COMPILE_FORCE_PADDING == 1
-#endif  // MATHFU_COMPILE_FORCE_PADDING
-/// @endcond
-#endif  // MATHFU_COMPILE_WITH_SIMD
-
-/// @addtogroup mathfu_version
-/// @{
-
-/// @def MATHFU_VERSION_MAJOR
-/// @brief Major version number of the library.
-/// @see kMathFuVersionString
-#define MATHFU_VERSION_MAJOR 1
-/// @def MATHFU_VERSION_MINOR
-/// @brief Minor version number of the library.
-/// @see kMathFuVersionString
-#define MATHFU_VERSION_MINOR 1
-/// @def MATHFU_VERSION_REVISION
-/// @brief Revision number of the library.
-/// @see kMathFuVersionString
-#define MATHFU_VERSION_REVISION 0
-
-/// @}
-
-/// @cond MATHFU_INTERNAL
-#define MATHFU_STRING_EXPAND(X) #X
-#define MATHFU_STRING(X) MATHFU_STRING_EXPAND(X)
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-// Generate string which contains build options for the library.
-#if defined(MATHFU_COMPILE_WITH_SIMD)
-#define MATHFU_BUILD_OPTIONS_SIMD "[simd]"
-#else
-#define MATHFU_BUILD_OPTIONS_SIMD "[no simd]"
-#endif  // defined(MATHFU_COMPILE_WITH_SIMD)
-#if defined(MATHFU_COMPILE_WITH_PADDING)
-#define MATHFU_BUILD_OPTIONS_PADDING "[padding]"
-#else
-#define MATHFU_BUILD_OPTIONS_PADDING "[no padding]"
-#endif  // defined(MATHFU_COMPILE_WITH_PADDING)
-/// @endcond
-
-/// @addtogroup mathfu_version
-/// @{
-/// @def MATHFU_BUILD_OPTIONS_STRING
-/// @brief String that describes the library's build configuration.
-#define MATHFU_BUILD_OPTIONS_STRING \
-  (MATHFU_BUILD_OPTIONS_SIMD " " MATHFU_BUILD_OPTIONS_PADDING)
-/// @}
-
-// Weak linkage is culled by VS & doesn't work on cygwin.
-#if !defined(_WIN32) && !defined(__CYGWIN__)
-
-extern volatile __attribute__((weak)) const char *kMathFuVersionString;
-/// @addtogroup mathfu_version
-/// @{
-
-/// @var kMathFuVersionString
-/// @brief String which identifies the current version of MathFu.
-///
-/// @ref kMathFuVersionString is used by Google developers to identify which
-/// applications uploaded to Google Play are using this library.  This allows
-/// the development team at Google to determine the popularity of the library.
-/// How it works: Applications that are uploaded to the Google Play Store are
-/// scanned for this version string.  We track which applications are using it
-/// to measure popularity.  You are free to remove it (of course) but we would
-/// appreciate if you left it in.
-///
-/// @see MATHFU_VERSION_MAJOR
-/// @see MATHFU_VERSION_MINOR
-/// @see MATHFU_VERSION_REVISION
-volatile __attribute__((weak)) const char *kMathFuVersionString =
-    "MathFu " MATHFU_STRING(MATHFU_VERSION_MAJOR) "." MATHFU_STRING(
-        MATHFU_VERSION_MINOR) "." MATHFU_STRING(MATHFU_VERSION_REVISION);
-/// @}
-
-#endif  // !defined(_WIN32) && !defined(__CYGWIN__)
-
-/// @cond MATHFU_INTERNAL
-template <bool>
-struct static_assert_util;
-template <>
-struct static_assert_util<true> {};
-/// @endcond
-
-/// @addtogroup mathfu_utilities
-/// @{
-/// @def MATHFU_STATIC_ASSERT
-/// @brief Compile time assert for pre-C++11 compilers.
-///
-/// For example:
-/// <blockquote><code>
-/// MATHFU_STATIC_ASSERT(0 == 1);
-/// </code></blockquote> will result in a compile error.
-#define MATHFU_STATIC_ASSERT(x) static_assert_util<(x)>()
-/// @}
-
-/// @cond MATHFU_INTERNAL
-/// Unroll an loop up to 4 iterations, where iterator is the identifier
-/// used in each operation (e.g "i"), number_of_iterations is a constant which
-/// specifies the number of times to perform the operation and "operation" is
-/// the statement to execute for each iteration of the loop (e.g data[i] = v).
-#define MATHFU_UNROLLED_LOOP(iterator, number_of_iterations, operation) \
-  {                                                                     \
-    const int iterator = 0;                                             \
-    { operation; }                                                      \
-    if ((number_of_iterations) > 1) {                                   \
-      const int iterator = 1;                                           \
-      { operation; }                                                    \
-      if ((number_of_iterations) > 2) {                                 \
-        const int iterator = 2;                                         \
-        { operation; }                                                  \
-        if ((number_of_iterations) > 3) {                               \
-          const int iterator = 3;                                       \
-          { operation; }                                                \
-          if ((number_of_iterations) > 4) {                             \
-            for (int iterator = 4; iterator < (number_of_iterations);   \
-                 ++iterator) {                                          \
-              operation;                                                \
-            }                                                           \
-          }                                                             \
-        }                                                               \
-      }                                                                 \
-    }                                                                   \
-  }
-/// @endcond
-
-namespace mathfu {
-
-/// @addtogroup mathfu_utilities
-/// @{
-
-/// @brief Clamp x within [lower, upper].
-/// @anchor mathfu_Clamp
-///
-/// @note Results are undefined if lower > upper.
-///
-/// @param x Value to clamp.
-/// @param lower Lower value of the range.
-/// @param upper Upper value of the range.
-/// @returns Clamped value.
-template <class T>
-T Clamp(const T &x, const T &lower, const T &upper) {
-  return std::max<T>(lower, std::min<T>(x, upper));
-}
-
-/// @brief Linearly interpolate between range_start and range_end, based on
-/// percent.
-/// @anchor mathfu_Lerp
-///
-/// @param range_start Start of the range.
-/// @param range_end End of the range.
-/// @param percent Value between 0.0 and 1.0 used to interpolate between
-/// range_start and range_end.  Where a value of 0.0 results in a return
-/// value of range_start and 1.0 results in a return value of range_end.
-/// @return Value between range_start and range_end.
-///
-/// @tparam T Type of the range to interpolate over.
-/// @tparam T2 Type of the value used to perform interpolation
-///         (e.g float or double).
-template <class T, class T2>
-T Lerp(const T &range_start, const T &range_end, const T2 &percent) {
-  const T2 one_minus_percent = static_cast<T2>(1.0) - percent;
-  return range_start * one_minus_percent + range_end * percent;
-}
-
-/// @brief Linearly interpolate between range_start and range_end, based on
-/// percent.
-/// @anchor mathfu_Lerp2
-///
-/// @param range_start Start of the range.
-/// @param range_end End of the range.
-/// @param percent Value between 0.0 and 1.0 used to interpolate between
-/// range_start and range_end.  Where a value of 0.0 results in a return
-/// value of range_start and 1.0 results in a return value of range_end.
-/// @return Value between range_start and range_end.
-///
-/// @tparam T Type of the range to interpolate over.
-template <class T>
-T Lerp(const T &range_start, const T &range_end, const T &percent) {
-  return Lerp<T, T>(range_start, range_end, percent);
-}
-
-/// @brief Check if val is within [range_start..range_end).
-/// @anchor mathfu_InRange
-///
-/// @param val Value to be tested.
-/// @param range_start Starting point of the range (inclusive).
-/// @param range_end Ending point of the range (non-inclusive).
-/// @return Bool indicating success.
-///
-/// @tparam T Type of values to test.
-template <class T>
-bool InRange(T val, T range_start, T range_end) {
-  return val >= range_start && val < range_end;
-}
-
-/// @brief  Generate a random value of type T.
-/// @anchor mathfu_Random
-///
-/// This method generates a random value of type T, greater than or equal to
-/// 0.0 and less than 1.0.
-///
-/// This function uses the standard C library function rand() from math.h to
-/// generate the random number.
-///
-/// @returns Random number greater than or equal to 0.0 and less than 1.0.
-///
-/// @see RandomRange()
-/// @see RandomInRange()
-template <class T>
-inline T Random() {
-  return static_cast<T>(rand()) / static_cast<T>(RAND_MAX);
-}
-
-/// @cond MATHFU_INTERNAL
-template <>
-inline float Random() {
-  return static_cast<float>(rand() >> 8) /
-         (static_cast<float>((RAND_MAX >> 8) + 1));
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <>
-inline double Random() {
-  return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX + 1LL));
-}
-/// @endcond
-
-/// @brief Generate a random value of type T in the range -range...+range
-/// @anchor mathfu_RandomRange
-///
-/// This function uses the standard C library function rand() from math.h to
-/// generate the random number.
-///
-/// @param range Range of the random value to generate.
-/// @return Random value in the range -range to +range
-///
-/// @see Random()
-template <class T>
-inline T RandomRange(T range) {
-  return (Random<T>() * range * 2) - range;
-}
-
-/// @brief Generate a random number between [range_start, range_end]
-/// @anchor mathfu_RandomInRange
-///
-/// This function uses the standard C library function rand() from math.h to
-/// generate the random number.
-///
-/// @param range_start Minimum value.
-/// @param range_end Maximum value.
-/// @return Random value in the range [range_start, range_end].
-///
-/// @see Lerp()
-/// @see Random()
-template <class T>
-inline T RandomInRange(T range_start, T range_end) {
-  return Lerp(range_start, range_end, Random<T>());
-}
-
-/// @cond MATHFU_INTERNAL
-template <>
-inline int RandomInRange<int>(int range_start, int range_end) {
-  return static_cast<int>(RandomInRange<float>(static_cast<float>(range_start),
-                                               static_cast<float>(range_end)));
-}
-/// @endcond
-
-/// @brief Round a value up to the nearest power of 2.
-///
-/// @param x Value to round up.
-/// @returns Value rounded up to the nearest power of 2.
-template <class T>
-T RoundUpToPowerOf2(T x) {
-  return static_cast<T>(
-      pow(static_cast<T>(2), ceil(log(x) / log(static_cast<T>(2)))));
-}
-
-/// @brief Specialized version of RoundUpToPowerOf2 for int32_t.
-template <>
-inline int32_t RoundUpToPowerOf2<>(int32_t x) {
-  x--;
-  x |= x >> 1;
-  x |= x >> 2;
-  x |= x >> 4;
-  x |= x >> 8;
-  x |= x >> 16;
-  x++;
-  return x;
-}
-
-/// @brief Round a value up to the type's size boundary.
-///
-/// @param v Value to round up.
-/// @returns Value rounded up to the type's size boundary.
-template <typename T>
-uint32_t RoundUpToTypeBoundary(uint32_t v) {
-  return (v + sizeof(T) - 1) & ~(sizeof(T) - 1);
-}
-
-/// @}
-
-/// @addtogroup mathfu_allocator
-///
-/// If you use MathFu with SIMD (SSE in particular), you need to have all
-/// your allocations be 16-byte aligned (which isn't the case with the default
-/// allocators on most platforms except OS X).
-///
-/// You can either use simd_allocator, which solves the problem for
-/// any STL containers, but not for manual dynamic allocations or the
-/// new/delete override MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE will
-/// solve it for all allocations, at the cost of MATHFU_ALIGNMENT bytes per
-/// allocation.
-
-/// @addtogroup mathfu_allocator
-/// @{
-
-/// @def MATHFU_ALIGNMENT
-/// @brief Alignment (in bytes) of memory allocated by AllocateAligned.
-///
-/// @see mathfu::AllocateAligned()
-/// @see mathfu::simd_allocator
-#define MATHFU_ALIGNMENT 16
-
-/// @brief Allocate an aligned block of memory.
-/// @anchor mathfu_AllocateAligned
-///
-/// This function allocates a block of memory aligned to MATHFU_ALIGNMENT
-/// bytes.
-///
-/// @param n Size of memory to allocate.
-/// @return Pointer to aligned block of allocated memory or NULL if
-/// allocation failed.
-inline void *AllocateAligned(size_t n) {
-#if defined(_MSC_VER) && _MSC_VER >= 1900  // MSVC 2015
-  return _aligned_malloc(n, MATHFU_ALIGNMENT);
-#else
-  // We need to allocate extra bytes to guarantee alignment,
-  // and to store the pointer to the original buffer.
-  uint8_t *buf = reinterpret_cast<uint8_t *>(malloc(n + MATHFU_ALIGNMENT));
-  if (!buf) return NULL;
-  // Align to next higher multiple of MATHFU_ALIGNMENT.
-  uint8_t *aligned_buf = reinterpret_cast<uint8_t *>(
-      (reinterpret_cast<size_t>(buf) + MATHFU_ALIGNMENT) &
-      ~(MATHFU_ALIGNMENT - 1));
-  // Write out original buffer pointer before aligned buffer.
-  // The assert will fail if the allocator granularity is less than the pointer
-  // size, or if MATHFU_ALIGNMENT doesn't fit two pointers.
-  assert(static_cast<size_t>(aligned_buf - buf) > sizeof(void *));
-  *(reinterpret_cast<uint8_t **>(aligned_buf) - 1) = buf;
-  return aligned_buf;
-#endif  // defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
-}
-
-/// @brief Deallocate a block of memory allocated with AllocateAligned().
-/// @anchor mathfu_FreeAligned
-///
-/// @param p Pointer to memory to deallocate.
-inline void FreeAligned(void *p) {
-#if defined(_MSC_VER) && _MSC_VER >= 1900  // MSVC 2015
-  _aligned_free(p);
-#else
-  if (p == NULL) return;
-  free(*(reinterpret_cast<uint8_t **>(p) - 1));
-#endif  // defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
-}
-
-/// @brief SIMD-safe memory allocator, for use with STL types like std::vector.
-///
-/// For example:
-/// <blockquote><code><pre>
-/// std::vector<vec4, mathfu::simd_allocator<vec4>> myvector;
-/// </pre></code></blockquote>
-///
-/// @see MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
-/// @tparam T type allocated by this object.
-template <typename T>
-class simd_allocator : public std::allocator<T> {
- public:
-  /// Size type.
-  typedef size_t size_type;
-  /// Pointer of type T.
-  typedef T *pointer;
-  /// Const pointer of type T.
-  typedef const T *const_pointer;
-
-  /// Constructs a simd_allocator.
-  simd_allocator() throw() : std::allocator<T>() {}
-  /// @brief Constructs and copies a simd_allocator.
-  ///
-  /// @param a Allocator to copy.
-  simd_allocator(const simd_allocator &a) throw() : std::allocator<T>(a) {}
-  /// @brief Constructs and copies a simd_allocator.
-  ///
-  /// @param a Allocator to copy.
-  /// @tparam U type of the object allocated by the allocator to copy.
-  template <class U>
-  simd_allocator(const simd_allocator<U> &a) throw() : std::allocator<T>(a) {}
-  /// @brief Destructs a simd_allocator.
-  ~simd_allocator() throw() {}
-
-  /// @brief Obtains an allocator of a different type.
-  ///
-  /// @tparam  _Tp1 type of the new allocator.
-  template <typename _Tp1>
-  struct rebind {
-    /// @brief Allocator of type _Tp1.
-    typedef simd_allocator<_Tp1> other;
-  };
-
-  /// @brief Allocate memory for object T.
-  ///
-  /// @param n Number of types to allocate.
-  /// @return Pointer to the newly allocated memory.
-  pointer allocate(size_type n) {
-    return reinterpret_cast<pointer>(AllocateAligned(n * sizeof(T)));
-  }
-
-  /// Deallocate memory referenced by pointer p.
-  ///
-  /// @param p Pointer to memory to deallocate.
-  void deallocate(pointer p, size_type) { FreeAligned(p); }
-};
-
-#if defined(_MSC_VER)
-#if _MSC_VER <= 1800  // MSVC 2013
-#if !defined(noexcept)
-#define noexcept
-#endif  // !defined(noexcept)
-#endif  // _MSC_VER <= 1800
-#endif  //  defined(_MSC_VER)
-
-/// @def MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
-/// @brief Macro which overrides the default new and delete allocators.
-///
-/// To globally override new and delete, simply add the line:
-/// <blockquote><code><pre>
-/// MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
-/// </pre></code></blockquote>
-/// to the end of your main .cpp file.
-#define MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE                           \
-  void *operator new(std::size_t n) { return mathfu::AllocateAligned(n); }   \
-  void *operator new[](std::size_t n) { return mathfu::AllocateAligned(n); } \
-  void operator delete(void *p) noexcept { mathfu::FreeAligned(p); }         \
-  void operator delete[](void *p) noexcept { mathfu::FreeAligned(p); }
-
-/// @def MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-/// @brief Macro which defines the new and delete for MathFu classes.
-#define MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE                       \
-  static void *operator new(std::size_t n) {                            \
-    return mathfu::AllocateAligned(n);                                  \
-  }                                                                     \
-  static void *operator new[](std::size_t n) {                          \
-    return mathfu::AllocateAligned(n);                                  \
-  }                                                                     \
-  static void *operator new(std::size_t /*n*/, void *p) { return p; }   \
-  static void *operator new[](std::size_t /*n*/, void *p) { return p; } \
-  static void operator delete(void *p) { mathfu::FreeAligned(p); }      \
-  static void operator delete[](void *p) { mathfu::FreeAligned(p); }    \
-  static void operator delete(void * /*p*/, void * /*place*/) {}        \
-  static void operator delete[](void * /*p*/, void * /*place*/) {}
-
-/// @}
-
-}  // namespace mathfu
-
-#endif  // MATHFU_UTILITIES_H_
diff --git a/third_party/mathfu-1.1.0/include/mathfu/vector.h b/third_party/mathfu-1.1.0/include/mathfu/vector.h
deleted file mode 100644
index 4d1625e..0000000
--- a/third_party/mathfu-1.1.0/include/mathfu/vector.h
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_VECTOR_H_
-#define MATHFU_VECTOR_H_
-
-#include "mathfu/utilities.h"
-
-#include <math.h>
-
-/// @file mathfu/vector.h Vector
-/// @brief Vector class and functions.
-/// @addtogroup mathfu_vector
-
-// Disable spurious warnings generated by MATHFU_VECTOR_OPERATION().
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4127)  // conditional expression is constant
-#if _MSC_VER >= 1900             // MSVC 2015
-#pragma warning(disable : 4456)  // allow shadowing in unrolled loops
-#endif                           // _MSC_VER >= 1900
-#elif defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warray-bounds"
-#endif
-
-/// @cond MATHFU_INTERNAL
-#define MATHFU_VECTOR_OPERATION(OP) MATHFU_UNROLLED_LOOP(i, d, OP)
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-#define MATHFU_VECTOR_OPERATOR(OP)           \
-  {                                          \
-    Vector<T, d> result;                     \
-    MATHFU_VECTOR_OPERATION(result[i] = OP); \
-    return result;                           \
-  }
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-#define MATHFU_VECTOR_SELF_OPERATOR(OP) \
-  {                                     \
-    MATHFU_VECTOR_OPERATION(OP);        \
-    return *this;                       \
-  }
-/// @endcond
-
-namespace mathfu {
-
-template <class T, int d>
-class Vector;
-
-/// @cond MATHFU_INTERNAL
-template <class T, int d>
-static inline T DotProductHelper(const Vector<T, d>& v1,
-                                 const Vector<T, d>& v2);
-template <class T>
-static inline T DotProductHelper(const Vector<T, 2>& v1,
-                                 const Vector<T, 2>& v2);
-template <class T>
-static inline T DotProductHelper(const Vector<T, 3>& v1,
-                                 const Vector<T, 3>& v2);
-template <class T>
-static inline T DotProductHelper(const Vector<T, 4>& v1,
-                                 const Vector<T, 4>& v2);
-
-template <typename T, int d, typename CompatibleT>
-static inline Vector<T, d> FromTypeHelper(const CompatibleT& compatible);
-
-template <typename T, int d, typename CompatibleT>
-static inline CompatibleT ToTypeHelper(const Vector<T, d>& v);
-/// @endcond
-
-/// @addtogroup mathfu_vector
-/// @{
-
-/// @class VectorPacked "mathfu/vector.h"
-/// @brief Packed N-dimensional vector.
-///
-/// Some Vector classes are padded so that it's possible to use the data
-/// structures with SIMD instructions.  This structure can be used in
-/// conjunction with unpacked Vector classes to pack data
-/// into flat arrays suitable for sending to a GPU (e.g vertex buffers).
-///
-/// <p>
-/// For example, to pack (store) an unpacked to packed vector:<br>
-/// <blockquote><code><pre>
-/// VectorPacked<float, 3> packed;
-/// Vector<float, 3> vector(3, 2, 1);
-/// vector.Pack(&packed);
-/// </pre></code></blockquote>
-/// or<br>
-/// <blockquote><code><pre>
-/// Vector<float, 3> vector(3, 2, 1);
-/// VectorPacked<float, 3> packed = vector;
-/// </pre></code></blockquote>
-/// </p>
-///
-/// <p>
-/// To initialize a vector from a packed vector:<br>
-/// <blockquote><code><pre>
-/// VectorPacked<float, 3> packed = { 3, 2, 1 };
-/// Vector<float, 3> vector(packed);
-/// </pre></code></blockquote>
-///
-/// @tparam T type of VectorPacked elements.
-/// @tparam d dimensions (number of elements) in the VectorPacked structure.
-template <class T, int d>
-struct VectorPacked {
-  /// Create an uninitialized VectorPacked.
-  VectorPacked() {}
-
-  /// Create a VectorPacked from a Vector.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to create the VectorPacked from.
-  explicit VectorPacked(const Vector<T, d>& vector) { vector.Pack(this); }
-
-  /// Copy a Vector to a VectorPacked.
-  ///
-  /// Both VectorPacked and Vector must have the same number of dimensions.
-  /// @param vector Vector to copy to the VectorPacked.
-  /// @returns A reference to this VectorPacked.
-  VectorPacked& operator=(const Vector<T, d>& vector) {
-    vector.Pack(this);
-    return *this;
-  }
-
-  /// Elements of the packed vector one per dimension.
-  T data[d];
-};
-/// @}
-
-/// @addtogroup mathfu_vector
-/// @{
-/// @class Vector "mathfu/vector.h"
-/// @brief Vector of d elements with type T
-///
-/// Vector stores <b>d</b> elements of type <b>T</b> and provides a set
-/// functions to perform operations on the set of elements.
-///
-/// @tparam T type of Vector elements.
-/// @tparam d dimensions (number of elements) in the Vector structure.
-template <class T, int d>
-class Vector {
- public:
-  /// @brief Element type to enable reference by other classes.
-  typedef T Scalar;
-
-  /// @brief Create an uninitialized Vector.
-  inline Vector() {}
-
-  /// @brief Create a vector from another vector copying each element.
-  ///
-  /// @param v Vector that the data will be copied from.
-  inline Vector(const Vector<T, d>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
-  }
-
-  /// @brief Create a vector from another vector of a different type.
-  ///
-  /// This copies each element of a Vector which makes it possible to between
-  /// vectors of different types, for example
-  /// <code>float/double/int</code> vectors.
-  /// @param v Vector that the data will be copied from.
-  /// @tparam U type of Vector elements to copy.
-  template <typename U>
-  explicit inline Vector(const Vector<U, d>& v) {
-    MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
-  }
-
-  /// @brief Create a vector from a single float.
-  ///
-  /// Each elements is set to be equal to the value given.
-  /// @param s Scalar value that the vector will be initialized to.
-  explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
-
-  /// @brief Create a vector form the first d elements of an array.
-  ///
-  /// @param a Array of values that the vector will be iniitlized to.
-  explicit inline Vector(const T* a) {
-    MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
-  }
-
-  /// @brief Create a vector from two values.
-  ///
-  /// @note This method only works when the vector is of size two.
-  ///
-  /// @param s1 Scalar value for the first element of the vector.
-  /// @param s2 Scalar value for the second element of the vector.
-  inline Vector(const T& s1, const T& s2) {
-    MATHFU_STATIC_ASSERT(d == 2);
-    data_[0] = s1;
-    data_[1] = s2;
-  }
-
-  /// @brief Create a vector from three values.
-  ///
-  /// @note This method only works when the vector is of size three.
-  ///
-  /// @param s1 Scalar value for the first element of the vector.
-  /// @param s2 Scalar value for the second element of the vector.
-  /// @param s3 Scalar value for the third element of the vector.
-  inline Vector(const T& s1, const T& s2, const T& s3) {
-    MATHFU_STATIC_ASSERT(d == 3);
-    data_[0] = s1;
-    data_[1] = s2;
-    data_[2] = s3;
-  }
-
-  /// @brief Create a vector from a 2 component vector and a third value.
-  ///
-  /// @note This method only works when the vector is of size three.
-  ///
-  /// @param v12 Vector containing the first 2 values.
-  /// @param s3 Scalar value for the third element of the vector.
-  inline Vector(const Vector<T, 2>& v12, const T& s3) {
-    MATHFU_STATIC_ASSERT(d == 3);
-    data_[0] = v12[0];
-    data_[1] = v12[1];
-    data_[2] = s3;
-  }
-
-  /// @brief Create a vector from four values.
-  ///
-  /// @note This method only works when the vector is of size four.
-  ///
-  /// @param s1 Scalar value for the first element of the vector.
-  /// @param s2 Scalar value for the second element of the vector.
-  /// @param s3 Scalar value for the third element of the vector.
-  /// @param s4 Scalar value for the forth element of the vector.
-  inline Vector(const T& s1, const T& s2, const T& s3, const T& s4) {
-    MATHFU_STATIC_ASSERT(d == 4);
-    data_[0] = s1;
-    data_[1] = s2;
-    data_[2] = s3;
-    data_[3] = s4;
-  }
-
-  /// @brief Create a 4-dimensional vector from a Vector<T, 3>.
-  ///
-  /// The last element is initialized to the specified value.
-  /// @note This method only works with 4 element vectors.
-  ///
-  /// @param vector3 Vector used to initialize the first 3 elements.
-  /// @param value Value used to set the last element of the vector.
-  inline Vector(const Vector<T, 3>& vector3, const T& value) {
-    MATHFU_STATIC_ASSERT(d == 4);
-    data_[0] = vector3[0];
-    data_[1] = vector3[1];
-    data_[2] = vector3[2];
-    data_[3] = value;
-  }
-
-  /// @brief Create a vector from two 2 component vectors.
-  ///
-  /// @note This method only works when the vector is of size four.
-  ///
-  /// @param v12 Vector containing the first 2 values.
-  /// @param v34 Vector containing the last 2 values.
-  inline Vector(const Vector<T, 2>& v12, const Vector<T, 2>& v34) {
-    MATHFU_STATIC_ASSERT(d == 4);
-    data_[0] = v12[0];
-    data_[1] = v12[1];
-    data_[2] = v34[0];
-    data_[3] = v34[1];
-  }
-
-  /// @brief Create a vector from packed vector (VectorPacked).
-  ///
-  /// @param vector Packed vector used to initialize an unpacked.
-  explicit inline Vector(const VectorPacked<T, d>& vector) {
-    MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
-  }
-
-  /// @brief Access an element of the vector.
-  ///
-  /// @param i Index of the element to access.
-  /// @return A reference to the accessed data that can be modified by the
-  /// caller.
-  inline T& operator()(const int i) { return data_[i]; }
-
-  /// @brief Access an element of the vector.
-  ///
-  /// @param i Index of the element to access.
-  /// @return A reference to the accessed data.
-  inline const T& operator()(const int i) const { return data_[i]; }
-
-  /// @brief Access an element of the vector.
-  ///
-  /// @param i Index of the element to access.
-  /// @return A reference to the accessed data that can be modified by the
-  /// caller.
-  inline T& operator[](const int i) { return data_[i]; }
-
-  /// @brief Access an element of the vector.
-  ///
-  /// @param i Index of the element to access.
-  /// @return A const reference to the accessed.
-  inline const T& operator[](const int i) const { return data_[i]; }
-
-  /// @brief GLSL style 3 element accessor.
-  ///
-  /// This only works with vectors that contain more than 3 elements.
-  /// @returns A 3-dimensional Vector containing the first 3 elements of
-  // this Vector.
-  inline Vector<T, 3> xyz() {
-    MATHFU_STATIC_ASSERT(d > 3);
-    return Vector<T, 3>(data_[0], data_[1], data_[2]);
-  }
-
-  /// @brief GLSL style 3 element accessor.
-  ///
-  /// This only works with vectors that contain more than 3 elements.
-  /// @returns A 3-dimensional Vector containing the first 3 elements of
-  // this Vector.
-  inline const Vector<T, 3> xyz() const {
-    MATHFU_STATIC_ASSERT(d > 3);
-    return Vector<T, 3>(data_[0], data_[1], data_[2]);
-  }
-
-  /// @brief GLSL style 2 element accessor.
-  ///
-  /// This only works with vectors that contain more than 2 elements.
-  /// @returns A 2-dimensional Vector with the first 2 elements of this Vector.
-  inline Vector<T, 2> xy() {
-    MATHFU_STATIC_ASSERT(d > 2);
-    return Vector<T, 2>(data_[0], data_[1]);
-  }
-
-  /// @brief GLSL style 2 element accessor.
-  ///
-  /// This only works with vectors that contain more than 2 elements.
-  /// @returns A 2-dimensional Vector with the first 2 elements of this Vector.
-  inline const Vector<T, 2> xy() const {
-    MATHFU_STATIC_ASSERT(d > 2);
-    return Vector<T, 2>(data_[0], data_[1]);
-  }
-
-  /// @brief GLSL style 2 element accessor.
-  ///
-  /// This only works with vectors that contain 4 elements.
-  /// @returns A 2-dimensional Vector with the last 2 elements of this Vector.
-  inline Vector<T, 2> zw() {
-    MATHFU_STATIC_ASSERT(d == 4);
-    return Vector<T, 2>(data_[2], data_[3]);
-  }
-
-  /// @brief GLSL style 2 element accessor.
-  ///
-  /// This only works with vectors that contain 4 elements.
-  /// @returns A 2-dimensional Vector with the last 2 elements of this Vector.
-  inline const Vector<T, 2> zw() const {
-    MATHFU_STATIC_ASSERT(d == 4);
-    return Vector<T, 2>(data_[2], data_[3]);
-  }
-
-  /// @brief Pack a Vector to a packed "d" element vector structure.
-  ///
-  /// @param vector Packed "d" element vector to write to.
-  inline void Pack(VectorPacked<T, d>* const vector) const {
-    MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
-  }
-
-  /// @brief Calculate the squared length of this vector.
-  ///
-  /// @return The length of this vector squared.
-  inline T LengthSquared() const { return LengthSquaredHelper(*this); }
-
-  /// @brief Calculate the length of this vector.
-  ///
-  /// @return The length of this vector.
-  inline T Length() const { return LengthHelper(*this); }
-
-  /// @brief Normalize this vector in-place.
-  ///
-  /// @return The length of this vector.
-  inline T Normalize() { return NormalizeHelper(*this); }
-
-  /// @brief Calculate the normalized version of this vector.
-  ///
-  /// @return The normalized vector.
-  inline Vector<T, d> Normalized() const { return NormalizedHelper(*this); }
-
-  /// @brief Load from any type that is some formulation of a length d array of
-  ///        type T.
-  ///
-  /// Essentially this is just a type cast and a load, but it happens safely
-  /// so that we avoid aliasing bugs.
-  ///
-  /// @return `compatible` cast to `Vector<T,d>` and dereferenced.
-  template <typename CompatibleT>
-  static inline Vector<T, d> FromType(const CompatibleT& compatible) {
-    return FromTypeHelper<T, d, CompatibleT>(compatible);
-  }
-
-  /// @brief Load into any type that is some formulation of a length d array of
-  ///        type T.
-  ///
-  /// Essentially this is just a type cast and a load, but it happens safely
-  /// so that we avoid aliasing bugs.
-  ///
-  /// @return `v` cast to `CompatibleT` and dereferenced.
-  template <typename CompatibleT>
-  static inline CompatibleT ToType(const Vector<T, d>& v) {
-    return ToTypeHelper<T, d, CompatibleT>(v);
-  }
-
-  /// @brief Calculate the dot product of two vectors.
-  ///
-  /// @param v1 First vector.
-  /// @param v2 Second vector.
-  /// @return The dot product of v1 and v2.
-  static inline T DotProduct(const Vector<T, d>& v1, const Vector<T, d>& v2) {
-    return DotProductHelper(v1, v2);
-  }
-
-  /// @brief Calculate the hadamard or componentwise product of two vectors.
-  ///
-  /// @param v1 First vector.
-  /// @param v2 Second vector.
-  /// @return The hadamard product of v1 and v2.
-  static inline Vector<T, d> HadamardProduct(const Vector<T, d>& v1,
-                                             const Vector<T, d>& v2) {
-    return HadamardProductHelper(v1, v2);
-  }
-
-  /// @brief Calculate the cross product of two vectors.
-  ///
-  /// Note that this function is only defined for 3-dimensional Vectors.
-  /// @param v1 First vector.
-  /// @param v2 Second vector.
-  /// @return The cross product of v1 and v2.
-  static inline Vector<T, 3> CrossProduct(const Vector<T, 3>& v1,
-                                          const Vector<T, 3>& v2) {
-    return CrossProductHelper(v1, v2);
-  }
-
-  /// @brief Linearly interpolate two vectors.
-  ///
-  /// @param v1 First vector.
-  /// @param v2 Second vector.
-  /// @param percent Percentage from v1 to v2 in range 0.0...1.0.
-  /// @return The hadamard product of v1 and v2.
-  static inline Vector<T, d> Lerp(const Vector<T, d>& v1,
-                                  const Vector<T, d>& v2, const T percent) {
-    return LerpHelper(v1, v2, percent);
-  }
-
-  /// @brief Generates a random vector.
-  ///
-  /// The range of each component is bounded by min and max.
-  /// @param min Minimum value of the vector.
-  /// @param max Maximum value of the vector.
-  static inline Vector<T, d> RandomInRange(const Vector<T, d>& min,
-                                           const Vector<T, d>& max) {
-    return RandomInRangeHelper(min, max);
-  }
-
-  /// @brief Compare each component and returns max values.
-  ///
-  /// @param v1 First vector.
-  /// @param v2 Second vector.
-  /// @return Max value of v1 and v2.
-  static inline Vector<T, d> Max(const Vector<T, d>& v1,
-                                 const Vector<T, d>& v2) {
-    return MaxHelper(v1, v2);
-  }
-
-  /// @brief Compare each component and returns min values.
-  ///
-  /// @param v1 First vector.
-  /// @param v2 Second vector.
-  /// @return Min value of v1 and v2.
-  static inline Vector<T, d> Min(const Vector<T, d>& v1,
-                                 const Vector<T, d>& v2) {
-    return MinHelper(v1, v2);
-  }
-
-  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
-
-  /// Elements of the vector.
-  T data_[d];
-};
-/// @}
-
-/// @addtogroup mathfu_vector
-/// @{
-
-/// @brief Compare 2 Vectors of the same size for equality.
-///
-/// @note: The likelyhood of two float values being the same is very small.
-/// Instead consider comparing the difference between two float vectors using
-/// LengthSquared() with an epsilon value.
-/// For example, v1.LengthSquared(v2) < epsilon.
-///
-/// @return true if the 2 vectors contains the same value, false otherwise.
-template <class T, int d>
-inline bool operator==(const Vector<T, d>& lhs, const Vector<T, d>& rhs) {
-  for (int i = 0; i < d; ++i) {
-    if (lhs[i] != rhs[i]) return false;
-  }
-  return true;
-}
-
-/// @brief Compare 2 Vectors of the same size for inequality.
-///
-/// @return true if the elements of two vectors differ, false otherwise.
-template <class T, int d>
-inline bool operator!=(const Vector<T, d>& lhs, const Vector<T, d>& rhs) {
-  return !(lhs == rhs);
-}
-
-/// @brief Negate all elements of the Vector.
-///
-/// @return A new Vector containing the result.
-template <class T, int d>
-inline Vector<T, d> operator-(const Vector<T, d>& v) {
-  MATHFU_VECTOR_OPERATOR(-v.data_[i]);
-}
-
-/// @brief Multiply a Vector by a scalar.
-///
-/// Multiplies each component of the specified Vector with a scalar.
-///
-/// @param s scalar to multiply.
-/// @param v Vector to multiply.
-/// @return Vector containing the result.
-/// @related Vector
-template <class T, int d>
-inline Vector<T, d> operator*(const T& s, const Vector<T, d>& v) {
-  MATHFU_VECTOR_OPERATOR(v.data_[i] * s);
-}
-
-/// @brief Divide a Vector by a scalar.
-///
-/// Divides each component of the specified Vector by a scalar.
-///
-/// @param v Vector to be divided.
-/// @param s scalar to divide the vector by.
-/// @return Vector containing the result.
-/// @related Vector
-template <class T, int d>
-inline Vector<T, d> operator/(const Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATOR(v.data_[i] / s);
-}
-
-/// @brief Add a scalar to each element of a Vector.
-///
-/// @param s scalar to add to each element of a Vector.
-/// @param v Vector to add the scalar to.
-/// @return Vector containing the result.
-/// @related Vector
-template <class T, int d>
-inline Vector<T, d> operator+(const T& s, const Vector<T, d>& v) {
-  MATHFU_VECTOR_OPERATOR(v.data_[i] + s);
-}
-
-/// @brief Subtract a scalar from each element of a Vector.
-///
-/// @param s scalar to subtract from each element of a Vector.
-/// @param v Vector to subtract the scalar from.
-/// @return Vector containing the result.
-/// @related Vector
-template <class T, int d>
-inline Vector<T, d> operator-(const T& s, const Vector<T, d>& v) {
-  MATHFU_VECTOR_OPERATOR(v.data_[i] - s);
-}
-
-/// @brief Multiply a vector by another Vector.
-///
-/// In line with GLSL, this performs component-wise multiplication.
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to multiply by.
-/// @return A new Vector containing the result.
-template <class T, int d>
-inline Vector<T, d> operator*(const Vector<T, d>& lhs,
-                              const Vector<T, d>& rhs) {
-  return HadamardProductHelper(lhs, rhs);
-}
-
-/// @brief Divide a vector by another Vector.
-///
-/// In line with GLSL, this performs component-wise division.
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to divide by.
-/// @return A new Vector containing the result.
-template <class T, int d>
-inline Vector<T, d> operator/(const Vector<T, d>& lhs,
-                              const Vector<T, d>& rhs) {
-  MATHFU_VECTOR_OPERATOR(lhs.data_[i] / rhs[i]);
-}
-
-/// @brief Add a vector with another Vector.
-///
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to add by.
-/// @return A new vector containing the result.
-template <class T, int d>
-inline Vector<T, d> operator+(const Vector<T, d>& lhs,
-                              const Vector<T, d>& rhs) {
-  MATHFU_VECTOR_OPERATOR(lhs.data_[i] + rhs[i]);
-}
-
-/// @brief subtract a vector with another Vector.
-///
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to subtract by.
-/// @return A new vector containing the result.
-template <class T, int d>
-inline Vector<T, d> operator-(const Vector<T, d>& lhs,
-                              const Vector<T, d>& rhs) {
-  MATHFU_VECTOR_OPERATOR(lhs.data_[i] - rhs[i]);
-}
-
-/// @brief Multiply a vector with a scalar.
-///
-/// @param v Vector for the operation.
-/// @param s A scalar to multiply the vector with.
-/// @return A new vector containing the result.
-template <class T, int d>
-inline Vector<T, d> operator*(const Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATOR(v.data_[i] * s);
-}
-
-/// @brief Add a scalar to all elements of a vector.
-///
-/// @param v Vector for the operation.
-/// @param s A scalar to add to the vector.
-/// @return A new vector containing the result.
-template <class T, int d>
-inline Vector<T, d> operator+(const Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATOR(v.data_[i] + s);
-}
-
-/// @brief Subtract a scalar from all elements of a vector.
-///
-/// @param v Vector for the operation.
-/// @param s A scalar to subtract from a vector.
-/// @return A new vector that stores the result.
-template <class T, int d>
-inline Vector<T, d> operator-(const Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATOR(v.data_[i] - s);
-}
-
-/// @brief Multiply (in-place) a vector with another Vector.
-///
-/// In line with GLSL, this performs component-wise multiplication.
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to multiply by.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator*=(Vector<T, d>& lhs, const Vector<T, d>& rhs) {
-  MATHFU_VECTOR_OPERATION(lhs.data_[i] *= rhs[i]);
-  return lhs;
-}
-
-/// @brief Divide (in-place) a vector by another Vector.
-///
-/// In line with GLSL, this performs component-wise division.
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to divide by.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator/=(Vector<T, d>& lhs, const Vector<T, d>& rhs) {
-  MATHFU_VECTOR_OPERATION(lhs.data_[i] /= rhs[i]);
-  return lhs;
-}
-
-/// @brief Add (in-place) a vector with another Vector.
-///
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to add.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator+=(Vector<T, d>& lhs, const Vector<T, d>& rhs) {
-  MATHFU_VECTOR_OPERATION(lhs.data_[i] += rhs[i]);
-  return lhs;
-}
-
-/// @brief Subtract (in-place) another Vector from a vector.
-///
-/// @param lhs First vector to use as a starting point.
-/// @param rhs Second vector to subtract by.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator-=(Vector<T, d>& lhs, const Vector<T, d>& rhs) {
-  MATHFU_VECTOR_OPERATION(lhs.data_[i] -= rhs[i]);
-  return lhs;
-}
-
-/// @brief Multiply (in-place) each element of a vector with a scalar.
-///
-/// @param v Vector for the operation.
-/// @param s A scalar to multiply the vector with.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator*=(Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATION(v.data_[i] *= s);
-  return v;
-}
-
-/// @brief Divide (in-place) each element of a vector by a scalar.
-///
-/// @param v Vector for the operation.
-/// @param s A scalar to divide the vector by.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator/=(Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATION(v.data_[i] /= s);
-  return v;
-}
-
-/// @brief Add (in-place) a scalar to each element of a vector.
-///
-/// @param v Vector for the operation.
-/// @param s A scalar to add the vector to.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator+=(Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATION(v.data_[i] += s);
-  return v;
-}
-
-/// @brief Subtract (in-place) a scalar from each element of a vector.
-///
-/// @param v Vector for the operation.
-/// @param s A scalar to subtract from the vector.
-/// @return A reference to the input <b>v</b> vector.
-template <class T, int d>
-inline Vector<T, d>& operator-=(Vector<T, d>& v, const T& s) {
-  MATHFU_VECTOR_OPERATION(v.data_[i] -= s);
-  return v;
-}
-
-/// @brief Calculate the hadamard or componentwise product of two vectors.
-///
-/// @param v1 First vector.
-/// @param v2 Second vector.
-/// @return The hadamard product of v1 and v2.
-template <class T, int d>
-inline Vector<T, d> HadamardProductHelper(const Vector<T, d>& v1,
-                                          const Vector<T, d>& v2) {
-  MATHFU_VECTOR_OPERATOR(v1[i] * v2[i]);
-}
-
-/// @brief Calculate the cross product of two vectors.
-///
-/// Note that this function is only defined for 3-dimensional Vectors.
-/// @param v1 First vector.
-/// @param v2 Second vector.
-/// @return The cross product of v1 and v2.
-template <class T>
-inline Vector<T, 3> CrossProductHelper(const Vector<T, 3>& v1,
-                                       const Vector<T, 3>& v2) {
-  return Vector<T, 3>(v1[1] * v2[2] - v1[2] * v2[1],
-                      v1[2] * v2[0] - v1[0] * v2[2],
-                      v1[0] * v2[1] - v1[1] * v2[0]);
-}
-
-/// @brief Calculate the squared length of a vector.
-///
-/// @param v Vector to get the squared length of.
-/// @return The length of the vector squared.
-template <class T, int d>
-inline T LengthSquaredHelper(const Vector<T, d>& v) {
-  return DotProductHelper(v, v);
-}
-
-/// @brief Calculate the length of a vector.
-///
-/// @param v Vector to get the squared length of.
-/// @return The length of the vector.
-template <class T, int d>
-inline T LengthHelper(const Vector<T, d>& v) {
-  return sqrt(LengthSquaredHelper(v));
-}
-
-/// @brief Normalize a vector in-place.
-///
-/// @param v Vector to get the squared length of.
-/// @return The length of the vector.
-template <class T, int d>
-inline T NormalizeHelper(Vector<T, d>& v) {
-  const T length = LengthHelper(v);
-  v *= (T(1) / length);
-  return length;
-}
-
-/// @brief Calculate the normalized version of a vector.
-///
-/// @param v Vector to get the squared length of.
-/// @return The normalized vector.
-template <class T, int d>
-inline Vector<T, d> NormalizedHelper(const Vector<T, d>& v) {
-  return v * (T(1) / LengthHelper(v));
-}
-
-/// @brief Linearly interpolate two vectors.
-///
-/// @param v1 First vector.
-/// @param v2 Second vector.
-/// @param percent Percentage from v1 to v2 in range 0.0...1.0.
-/// @return The hadamard product of v1 and v2.
-template <class T, int d>
-inline Vector<T, d> LerpHelper(const Vector<T, d>& v1, const Vector<T, d>& v2,
-                               const T percent) {
-  const T one_minus_percent = static_cast<T>(1.0) - percent;
-  MATHFU_VECTOR_OPERATOR(one_minus_percent * v1[i] + percent * v2[i]);
-}
-
-/// @brief Generates a random vector.
-///
-/// The range of each component is bounded by min and max.
-/// @param min Minimum value of the vector.
-/// @param max Maximum value of the vector.
-template <class T, int d>
-inline Vector<T, d> RandomInRangeHelper(const Vector<T, d>& min,
-                                        const Vector<T, d>& max) {
-  Vector<T, d> result;
-  MATHFU_VECTOR_OPERATION(result[i] = mathfu::RandomInRange<T>(min[i], max[i]));
-  return result;
-}
-
-/// @brief Compare each component and returns max values.
-///
-/// @param v1 First vector.
-/// @param v2 Second vector.
-/// @return Max value of v1 and v2.
-template <class T, int d>
-inline Vector<T, d> MaxHelper(const Vector<T, d>& v1, const Vector<T, d>& v2) {
-  Vector<T, d> result;
-  MATHFU_VECTOR_OPERATION(result[i] = std::max(v1[i], v2[i]));
-  return result;
-}
-
-/// @brief Compare each component and returns min values.
-///
-/// @param v1 First vector.
-/// @param v2 Second vector.
-/// @return Min value of v1 and v2.
-template <class T, int d>
-inline Vector<T, d> MinHelper(const Vector<T, d>& v1, const Vector<T, d>& v2) {
-  Vector<T, d> result;
-  MATHFU_VECTOR_OPERATION(result[i] = std::min(v1[i], v2[i]));
-  return result;
-}
-
-/// @brief Check if val is within [range_start..range_end), denoting a
-/// rectangular area.
-///
-/// @param val 2D vector to be tested.
-/// @param range_start Starting point of the range (inclusive).
-/// @param range_end Ending point of the range (non-inclusive).
-/// @return Bool indicating success.
-///
-/// @tparam T Type of vector components to test.
-template <class T>
-bool InRange2D(const mathfu::Vector<T, 2>& val,
-               const mathfu::Vector<T, 2>& range_start,
-               const mathfu::Vector<T, 2>& range_end) {
-  return InRange(val[0], range_start[0], range_end[0]) &&
-         InRange(val[1], range_start[1], range_end[1]);
-}
-
-/// @cond MATHFU_INTERNAL
-/// @brief Calculate the dot product of two vectors.
-///
-/// @param v1 First vector.
-/// @param v2 Second vector.
-/// @return The dot product of v1 and v2.
-/// @related Vector
-template <class T, int d>
-static inline T DotProductHelper(const Vector<T, d>& v1,
-                                 const Vector<T, d>& v2) {
-  T result = 0;
-  MATHFU_VECTOR_OPERATION(result += v1[i] * v2[i]);
-  return result;
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-static inline T DotProductHelper(const Vector<T, 2>& v1,
-                                 const Vector<T, 2>& v2) {
-  return v1[0] * v2[0] + v1[1] * v2[1];
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-static inline T DotProductHelper(const Vector<T, 3>& v1,
-                                 const Vector<T, 3>& v2) {
-  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <class T>
-static inline T DotProductHelper(const Vector<T, 4>& v1,
-                                 const Vector<T, 4>& v2) {
-  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3];
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <typename T, int d, typename CompatibleT>
-static inline Vector<T, d> FromTypeHelper(const CompatibleT& compatible) {
-// C++11 is required for constructed unions.
-#if __cplusplus >= 201103L
-  // Use a union instead of reinterpret_cast to avoid aliasing bugs.
-  union ConversionUnion {
-    ConversionUnion() {}  // C++11.
-    CompatibleT compatible;
-    VectorPacked<T, d> packed;
-  } u;
-  static_assert(sizeof(u.compatible) == d * sizeof(T),
-                "Conversion size mismatch.");
-
-  // The read of `compatible` and write to `u.compatible` gets optimized away,
-  // and this becomes essentially a safe reinterpret_cast.
-  u.compatible = compatible;
-
-  // Call the packed vector constructor with the `compatible` data.
-  return Vector<T, d>(u.packed);
-#else
-  // Use the less-desirable memcpy technique if C++11 is not available.
-  // Most compilers understand memcpy deep enough to avoid replace the function
-  // call with a series of load/stores, which should then get optimized away,
-  // however in the worst case the optimize away may not happen.
-  // Note: Memcpy avoids aliasing bugs because it operates via unsigned char*,
-  // which is allowed to alias any type.
-  // See:
-  // http://stackoverflow.com/questions/15745030/type-punning-with-void-without-breaking-the-strict-aliasing-rule-in-c99
-  Vector<T, d> v;
-  assert(sizeof(compatible) == d * sizeof(T));
-  memcpy(&v, &compatible, sizeof(compatible));
-  return v;
-#endif  // __cplusplus >= 201103L
-}
-/// @endcond
-
-/// @cond MATHFU_INTERNAL
-template <typename T, int d, typename CompatibleT>
-static inline CompatibleT ToTypeHelper(const Vector<T, d>& v) {
-// See FromTypeHelper() for comments.
-#if __cplusplus >= 201103L
-  union ConversionUnion {
-    ConversionUnion() {}
-    CompatibleT compatible;
-    VectorPacked<T, d> packed;
-  } u;
-  static_assert(sizeof(u.compatible) == d * sizeof(T), "Conversion size mismatch.");
-  v.Pack(&u.packed);
-  return u.compatible;
-#else
-  CompatibleT compatible;
-  assert(sizeof(compatible) == d * sizeof(T));
-  memcpy(&compatible, &v, sizeof(compatible));
-  return compatible;
-#endif  // __cplusplus >= 201103L
-}
-/// @endcond
-
-/// @}
-
-/// @addtogroup mathfu_utilities
-/// @{
-
-/// @brief Specialized version of RoundUpToPowerOf2 for vector.
-template <typename T, int d>
-inline Vector<T, d> RoundUpToPowerOf2(const Vector<T, d>& v) {
-  Vector<T, d> ret;
-  MATHFU_VECTOR_OPERATION(ret(i) = RoundUpToPowerOf2(v(i)));
-  return ret;
-}
-/// @}
-
-}  // namespace mathfu
-
-// Include the specializations to avoid template errors.
-// For example, if you include vector.h, use Vector<float, 3>, and then
-// include vector_3.h, you the compiler will generate an error since you're
-// specializing something that has already been instantiated.
-#include "mathfu/internal/vector_2_simd.h"
-#include "mathfu/internal/vector_3_simd.h"
-#include "mathfu/internal/vector_4_simd.h"
-
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#elif defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-#endif  // MATHFU_VECTOR_H_
diff --git a/third_party/mathfu-1.1.0/jni/Android.mk b/third_party/mathfu-1.1.0/jni/Android.mk
deleted file mode 100644
index c66faf4..0000000
--- a/third_party/mathfu-1.1.0/jni/Android.mk
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:=$(call my-dir)/..
-
-MATHFU_DIR?=$(LOCAL_PATH)
-include $(LOCAL_PATH)/android_config.mk
-
-# Conditionally include libstlport (so include path is added to CFLAGS) if
-# it's not being built using the NDK build process.
-define add-stlport-includes
-$(eval \
-  ifeq ($(NDK_PROJECT_PATH),)
-  include external/stlport/libstlport.mk
-  endif)
-endef
-
-# mathfu-cflags: disable_simd force_padding debug
-# Expands to the compiler flags for applications or libraries that use MathFu.
-# Where disable_simd specifies whether SIMD code should be disabled,
-# force_padding specifies whether padding should be added to data structures
-# in SIMD mode (-1 = default, 0 = padding off, 1 = padding on).
-#
-# NOTE: armeabi-v7a-hard has been deprecated.  For more information see,
-#  https://android.googlesource.com/platform/ndk/+/master/docs/HardFloatAbi.md
-define mathfu-cflags
-  $(if $(subst 0,,$(strip $(1))),-DMATHFU_COMPILE_WITHOUT_SIMD_SUPPORT,\
-    $(if $(subst -1,,$(strip $(2))),\
-               -DMATHFU_COMPILE_FORCE_PADDING=$(strip $(2)),)) \
-  $(if $(APP_DEBUG),-DDEBUG=1,-DDEBUG=0) \
-  $(if $(filter armeabi-v7a-hard,$(TARGET_ARCH_ABI)),\
-             -mfpu=neon -mhard-float -mfloat-abi=hard) \
-  $(if $(filter x86,$(TARGET_ARCH_ABI)),-msse) \
-  $(if $(filter x86_64,$(TARGET_ARCH_ABI)),-msse4.1)
-endef
-
-
-# Configure common local variables to build mathfu adding $(1) to the end of
-# the build target's name.
-define mathfu-module
-$(eval \
-  LOCAL_MODULE:=libmathfu$(1)
-  LOCAL_MODULE_TAGS:=optional
-  LOCAL_COPY_HEADERS_TO:=mathfu$(1))
-endef
-
-# Configure local variables to build mathfu adding $(1) to the end of the
-# build target's name, disabling SIMD depending upon the value of $(2) (see
-# mathfu-cflags $(1)) and configuring padding (see mathfu-cflags $(2))
-# with $(3).
-define mathfu-build
-$(eval \
-  $$(call mathfu-module,$(1))
-  LOCAL_SRC_FILES:=
-  LOCAL_COPY_HEADERS:=\
-    $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/include/mathfu/*.h))
-  LOCAL_CFLAGS:=$$(call mathfu-cflags,$(2),$(3))
-  LOCAL_EXPORT_CFLAGS:=$$(LOCAL_CFLAGS)
-  LOCAL_EXPORT_C_INCLUDES:=\
-	$(LOCAL_PATH)/include \
-	$(DEPENDENCIES_VECTORIAL_DIR)/include
-  LOCAL_EXPORT_LDLIBS:=-lm
-  LOCAL_ARM_MODE:=arm
-  LOCAL_ARM_NEON:=$(if $(filter \
-    armeabi-v7a armeabi-v7a-hard,$(TARGET_ARCH_ABI)),true,)
-  $$(call add-stlport-includes))
-endef
-
-# --- libmathfu ---
-# Target which builds an empty static library so that it's possible for
-# projects using this module to add the appropriate flags and includes to
-# their compile command line.  This builds mathfu using the default build
-# configuration specified in ${mathfu}/android_config.mk
-include $(CLEAR_VARS)
-$(call mathfu-build,,$(MATHFU_DISABLE_SIMD),$(MATHFU_FORCE_PADDING))
-include $(BUILD_STATIC_LIBRARY)
-
-# --- libmathfu_no_simd ---
-# Builds an empty static library (similar to libmathfu).
-# This build configuration has SIMD disabled.
-include $(CLEAR_VARS)
-$(call mathfu-build,_no_simd,1,-1)
-include $(BUILD_STATIC_LIBRARY)
-
-# --- libmathfu_simd ---
-# Builds an empty static library (similar to libmathfu).
-# This build configuration has SIMD enabled and padding enabled.
-include $(CLEAR_VARS)
-$(call mathfu-build,_simd_padding,0,1)
-include $(BUILD_STATIC_LIBRARY)
-
-# --- libmathfu_simd_no_padding ---
-# Builds an empty static library (similar to libmathfu).
-# This build configuration has SIMD enabled and padding disabled.
-include $(CLEAR_VARS)
-$(call mathfu-build,_simd_no_padding,0,0)
-include $(BUILD_STATIC_LIBRARY)
-
-mathfu_cflags:=
diff --git a/third_party/mathfu-1.1.0/jni/Application.mk b/third_party/mathfu-1.1.0/jni/Application.mk
deleted file mode 100644
index 472bcc2..0000000
--- a/third_party/mathfu-1.1.0/jni/Application.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:=$(call my-dir)
-
-APP_PLATFORM:=android-10
-APP_ABI:=armeabi-v7a armeabi x86 x86_64 mips mips64
-APP_STL:=c++_static
-APP_MODULES:=libmathfu
-
diff --git a/third_party/mathfu-1.1.0/jni/find_fplutil.mk b/third_party/mathfu-1.1.0/jni/find_fplutil.mk
deleted file mode 100644
index 928e254..0000000
--- a/third_party/mathfu-1.1.0/jni/find_fplutil.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2016 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Find the fplutil directory and set it in `FPLUTIL_DIR`.
-#
-# We search some standard locations, such as
-# (1) the variable $(DEPENDENCIES_ROOT), which can be specified
-#     in an environment variable,
-# (2) the "dependencies" directory that gets created when cloning from GitHub,
-# (3) several levels up in the directory tree.
-#
-# Notes
-# -----
-# - fplutil is the project where we keep all our shared code, so the code in
-#   this file (which locates fplutil) can unfortunately not be shared.
-# - Since this file is duplicated in all FPL projects (except fplutil itself),
-#   please copy new versions to all FPL projects whenever you make a change.
-
-FIND_FPLUTIL_DIR:=$(call my-dir)
-
-$(foreach dir,$(wildcard $(DEPENDENCIES_ROOT)) \
-              $(wildcard $(FIND_FPLUTIL_DIR)/../dependencies/fplutil) \
-              $(wildcard $(FIND_FPLUTIL_DIR)/../../dependencies/fplutil) \
-              $(wildcard $(FIND_FPLUTIL_DIR)/../fplutil) \
-              $(wildcard $(FIND_FPLUTIL_DIR)/../../fplutil) \
-              $(wildcard $(FIND_FPLUTIL_DIR)/../../../fplutil) \
-              $(wildcard $(FIND_FPLUTIL_DIR)/../../../../fplutil),\
-  $(eval FPLUTIL_DIR?=$(dir)))
-
-ifeq ($(FPLUTIL_DIR),)
-  ifndef (FIND_FPLUTIL_OK_IF_NOT_FOUND)
-    $(error "Cannot file fplutil project.")
-  endif
-endif
diff --git a/third_party/mathfu-1.1.0/readme.md b/third_party/mathfu-1.1.0/readme.md
deleted file mode 100644
index 2613569..0000000
--- a/third_party/mathfu-1.1.0/readme.md
+++ /dev/null
@@ -1,58 +0,0 @@
-MathFu Version 1.1.0    {#mathfu_readme}
-====================
-
-MathFu is a C++ math library developed primarily for games focused on
-simplicity and efficiency.
-
-It provides a suite of [vector][], [matrix][] and [quaternion][] classes
-to perform basic [geometry][] suitable for game developers.  This functionality
-can be used to construct geometry for graphics libraries like [OpenGL][] or
-perform calculations for animation or physics systems.
-
-The library is written in portable C++ with [SIMD][] compiler intrinsics and
-has been tested on the following platforms:
-
-   * [Android][]
-   * [Linux][] (x86_64)
-   * [OS X][]
-   * [Windows][]
-
-Go to our [landing page][] to browse our documentation and see some examples.
-
-   * Discuss MathFu with other developers and users on the
-     [MathFu Google Group][].
-   * File issues on the [MathFu Issues Tracker][]
-   * Post your questions to [stackoverflow.com][] with a mention of
-     **mathfu**.
-
-**Important**: MathFu uses submodules to reference other components it depends
-upon so download the source using:
-
-    git clone --recursive https://github.com/google/mathfu.git
-
-To contribute to this project see [CONTRIBUTING][].
-
-For applications on Google Play that integrate this tool, usage is tracked.
-This tracking is done automatically using the embedded version string
-(kMathFuVersionString), and helps us continue to optimize it. Aside from
-consuming a few extra bytes in your application binary, it shouldn't affect
-your application at all. We use this information to let us know if MathFu
-is useful and if we should continue to invest in it. Since this is open
-source, you are free to remove the version string but we would appreciate if
-you would leave it in.
-
-  [Android]: http://www.android.com
-  [Linux]: http://en.m.wikipedia.org/wiki/Linux
-  [MathFu Google Group]: http://groups.google.com/group/mathfulib
-  [MathFu Issues Tracker]: http://github.com/google/mathfu/issues
-  [OS X]: http://www.apple.com/osx/
-  [OpenGL]: http://www.opengl.org/
-  [SIMD]: http://en.wikipedia.org/wiki/SIMD
-  [Windows]: http://windows.microsoft.com/
-  [geometry]: http://en.wikipedia.org/wiki/Geometry
-  [landing page]: http://google.github.io/mathfu
-  [matrix]: http://en.wikipedia.org/wiki/Matrix_(mathematics)
-  [quaternion]: http://en.wikipedia.org/wiki/Quaternion
-  [stackoverflow.com]: http://stackoverflow.com/search?q=mathfu
-  [vector]: http://en.wikipedia.org/wiki/Euclidean_vector
-  [CONTRIBUTING]: http://github.com/google/mathfu/blob/master/CONTRIBUTING
diff --git a/third_party/mathfu-1.1.0/unit_tests/CMakeLists.txt b/third_party/mathfu-1.1.0/unit_tests/CMakeLists.txt
deleted file mode 100644
index 4310f29..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/CMakeLists.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-cmake_minimum_required(VERSION 2.8)
-
-set_compiler_flags_for_external_libraries()
-add_subdirectory(${dependencies_gtest_dir} googletest)
-restore_compiler_flags()
-
-set(gtest_incdir ${dependencies_gtest_dir}/include)
-if(EXISTS "${dependencies_gtest_dir}/../../third_party")
-  set(gtest_hack_incdir "${dependencies_gtest_dir}/../..")
-endif()
-set(gtest_libdir ${dependencies_gtest_dir})
-
-# Include helper functions and macros used by Google Test.
-include(${gtest_libdir}/cmake/internal_utils.cmake)
-config_compiler_and_linker()
-string(REPLACE "-W4" "-W3" cxx_default "${cxx_default}")
-string(REPLACE "-Wshadow" "" cxx_default "${cxx_default}")
-string(REPLACE "-Wextra" "" cxx_default "${cxx_default}")
-
-# This is the directory into which the executables are built.
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-
-include_directories(${gtest_incdir}
-                    ${gtest_hack_incdir}
-                    ${CMAKE_CURRENT_LIST_DIR}
-                    ${CMAKE_CURRENT_LIST_DIR}/..)
-
-# Common libraries for tests.
-if(NOT MSVC)
-  find_package(Threads)
-endif()
-set(COMMON_LIBS "gtest;${CMAKE_THREAD_LIBS_INIT}")
-
-# Generate a rule to build a unit test executable ${test_name} with
-# source file ${source}.  For details of additional arguments, see
-# mathfu_configure_flags().
-function(test_executable test_name source)
-  cxx_executable_with_flags(${test_name} "${cxx_default}" "${COMMON_LIBS}"
-    ${source} ${MATHFU_HEADERS})
-  mathfu_configure_flags(${test_name} ${ARGN})
-  mathfu_enable_warnings(${test_name})
-endfunction()
-
-# Generate a rule to build unit test executables.  This only builds
-# ${test_name}_tests if SIMD is disabled (see ${mathfu_enable_simd}) or
-# ${test_name}_tests and ${test_name}_no_simd_tests if SIMD is enabled where
-# the no_simd_tests binary has SIMD disabled.
-function(test_executables test_name source)
-  # Default build options for the target architecture.
-  test_executable(${test_name}_tests ${source})
-  if(mathfu_enable_simd)
-    # NOTE: A build configuration below will deliberately duplicate the
-    # default build configuration, since these configs could result in
-    # different compile time preprocessor code paths.
-    # SIMD enabled and padding enabled.
-    test_executable(${test_name}_simd_padding_tests ${source} TRUE TRUE)
-    # SIMD enabled and padding disabled.
-    test_executable(${test_name}_simd_no_padding_tests ${source} TRUE FALSE)
-    # SIMD disabled.
-    test_executable(${test_name}_no_simd_tests ${source} FALSE)
-  endif()
-endfunction()
-
-test_executables(vector vector_test/vector_test.cpp)
-test_executables(quaternion quaternion_test/quaternion_test.cpp)
-test_executables(matrix matrix_test/matrix_test.cpp)
diff --git a/third_party/mathfu-1.1.0/unit_tests/android_common.mk b/third_party/mathfu-1.1.0/unit_tests/android_common.mk
deleted file mode 100644
index 34cfc8d..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/android_common.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(CLEAR_VARS)
-
-# Configure the locations of MathFu's dependencies.
-MATHFU_DIR:=$(LOCAL_PATH)/../..
-MATHFU_DIR_BASENAME:=$(notdir $(abspath $(MATHFU_DIR)))
-TEST_DIR:=$(LOCAL_PATH)
-include $(MATHFU_DIR)/android_config.mk
-
-namespace:=$(if $(NDK_PROJECT_PATH),,_mathfu)
-LOCAL_MODULE:=$(LOCAL_TEST_NAME)${namespace}
-LOCAL_MODULE_TAGS:=optional
-LOCAL_SRC_FILES:=$(notdir $(abspath $(TEST_DIR))).cpp
-LOCAL_C_INCLUDES:=$(MATHFU_DIR)/unit_tests
-LOCAL_LDLIBS:=-llog -landroid
-LOCAL_WHOLE_STATIC_LIBRARIES:=\
-	libfplutil_main \
-	libfplutil_print
-# MATHFU_LIB (by default libmathfu) is used to select the build configuration
-# for the target using mathfu.
-LOCAL_STATIC_LIBRARIES:=\
-	android_native_app_glue \
-	libgtest \
-	$(MATHFU_LIB)
-LOCAL_CFLAGS:=-Wall -Werror
-LOCAL_ARM_MODE:=arm
-include $(BUILD_SHARED_LIBRARY)
-
-$(call import-add-path,$(abspath $(MATHFU_DIR)/..))
-$(call import-add-path,$(abspath $(DEPENDENCIES_FPLUTIL_DIR)))
-$(call import-add-path,$(abspath $(DEPENDENCIES_GTEST_DIR)/..))
-
-$(call import-module,$(MATHFU_DIR_BASENAME)/jni)
-$(call import-module,libfplutil/jni)
-$(call import-module,googletest)
-$(call import-module,android/native_app_glue)
-
-LOCAL_TEST_NAME:=
-MATHFU_DIR:=
-TEST_DIR:=
diff --git a/third_party/mathfu-1.1.0/unit_tests/application_common.mk b/third_party/mathfu-1.1.0/unit_tests/application_common.mk
deleted file mode 100644
index 760c907..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/application_common.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-APP_PLATFORM:=android-10
-APP_ABI:=armeabi-v7a armeabi x86 x86_64 mips mips64
-APP_STL:=c++_static
-
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/AndroidManifest.xml
deleted file mode 100644
index 6f0a3db..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/jni/Android.mk
deleted file mode 100644
index efef5f9..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=matrix_test
-MATHFU_LIB:=libmathfu
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/jni/Application.mk
deleted file mode 100644
index 7702145..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/res/values/strings.xml
deleted file mode 100644
index 22e57e5..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/default/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/matrix_test.cpp b/third_party/mathfu-1.1.0/unit_tests/matrix_test/matrix_test.cpp
deleted file mode 100644
index 10a13e6..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/matrix_test.cpp
+++ /dev/null
@@ -1,1147 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "mathfu/matrix.h"
-#include "mathfu/matrix_4x4.h"
-#include "mathfu/quaternion.h"
-#include "mathfu/utilities.h"
-#include "mathfu/vector.h"
-
-#include <cmath>
-#include <sstream>
-#include <string>
-
-#include "gtest/gtest.h"
-
-#include "precision.h"
-static const float kUnProjectFloatPrecision = 0.0012f;
-static const double kLookAtDoublePrecision = 1e-8;
-class MatrixTests : public ::testing::Test {
- protected:
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-template <class T, int rows, int columns>
-struct MatrixExpectation {
-  const char* description;
-  mathfu::Matrix<T, rows, columns> calculated;
-  mathfu::Matrix<T, rows, columns> expected;
-};
-
-// This will automatically generate tests for each template parameter.
-#define TEST_ALL_F(MY_TEST, FLOAT_PRECISION_VALUE, DOUBLE_PRECISION_VALUE) \
-  TEST_F(MatrixTests, MY_TEST##_float_2) {                                 \
-    MY_TEST##_Test<float, 2>(FLOAT_PRECISION_VALUE);                       \
-  }                                                                        \
-  TEST_F(MatrixTests, MY_TEST##_double_2) {                                \
-    MY_TEST##_Test<double, 2>(DOUBLE_PRECISION_VALUE);                     \
-  }                                                                        \
-  TEST_F(MatrixTests, MY_TEST##_float_3) {                                 \
-    MY_TEST##_Test<float, 3>(FLOAT_PRECISION_VALUE);                       \
-  }                                                                        \
-  TEST_F(MatrixTests, MY_TEST##_double_3) {                                \
-    MY_TEST##_Test<double, 3>(DOUBLE_PRECISION_VALUE);                     \
-  }                                                                        \
-  TEST_F(MatrixTests, MY_TEST##_float_4) {                                 \
-    MY_TEST##_Test<float, 4>(FLOAT_PRECISION_VALUE);                       \
-  }                                                                        \
-  TEST_F(MatrixTests, MY_TEST##_double_4) {                                \
-    MY_TEST##_Test<double, 4>(DOUBLE_PRECISION_VALUE);                     \
-  }
-
-// This will automatically generate tests for each scalar template parameter.
-#define TEST_SCALAR_F(MY_TEST, FLOAT_PRECISION_VALUE, DOUBLE_PRECISION_VALUE) \
-  TEST_F(MatrixTests, MY_TEST##_float) {                                      \
-    MY_TEST##_Test<float>(FLOAT_PRECISION_VALUE);                             \
-  }                                                                           \
-  TEST_F(MatrixTests, MY_TEST##_double) {                                     \
-    MY_TEST##_Test<double>(DOUBLE_PRECISION_VALUE);                           \
-  }
-
-// This will test initialization by passing in values. The template paramter d
-// corresponds to the number of rows and columns.
-template <class T, int d>
-void Initialize_Test(const T& precision) {
-  // This will test initialization of the matrix using a random single value.
-  // The expected result is that all entries equal the given value.
-  mathfu::Matrix<T, d> matrix_splat(static_cast<T>(3.1));
-  for (int i = 0; i < d * d; ++i) {
-    EXPECT_NEAR(3.1, matrix_splat[i], precision);
-  }
-  // This will verify that the value is correct when using the (i, j) form
-  // of indexing.
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(3.1, matrix_splat(i, j), precision);
-    }
-  }
-  // This will test initialization of the matrix using a c style array of
-  // values.
-  T x[d * d];
-  for (int i = 0; i < d * d; ++i) {
-    x[i] = rand() / static_cast<T>(RAND_MAX) * 100.f;
-  }
-  mathfu::Matrix<T, d> matrix_arr(x);
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(x[i + d * j], matrix_arr(i, j), precision);
-    }
-  }
-  // This will test the copy constructor making sure that the new matrix
-  // equals the old one.
-  mathfu::Matrix<T, d> matrix_copy(matrix_arr);
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(x[i + d * j], matrix_copy(i, j), precision);
-    }
-  }
-  // This will verify that the copy was deep and changing the values of the
-  // copied matrix does not effect the original.
-  matrix_copy = matrix_copy - mathfu::Matrix<T, d>(1);
-  EXPECT_NE(matrix_copy(0, 0), matrix_arr(0, 0));
-  // This will test creation of the identity matrix.
-  mathfu::Matrix<T, d> identity(mathfu::Matrix<T, d>::Identity());
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(i == j ? 1 : 0, identity(i, j), precision);
-    }
-  }
-}
-TEST_ALL_F(Initialize, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// This will test initialization by specifying all values explicitly.
-template <class T>
-void InitializePerDimension_Test(const T& precision) {
-  mathfu::Matrix<T, 2> matrix_f2x2(static_cast<T>(4.5), static_cast<T>(3.4),
-                                   static_cast<T>(2.6), static_cast<T>(9.8));
-  EXPECT_NEAR(4.5, matrix_f2x2(0, 0), precision);
-  EXPECT_NEAR(3.4, matrix_f2x2(1, 0), precision);
-  EXPECT_NEAR(2.6, matrix_f2x2(0, 1), precision);
-  EXPECT_NEAR(9.8, matrix_f2x2(1, 1), precision);
-  mathfu::Matrix<T, 3> matrix_f3x3(
-      static_cast<T>(3.7), static_cast<T>(2.4), static_cast<T>(6.4),
-      static_cast<T>(1.1), static_cast<T>(5.2), static_cast<T>(6.4),
-      static_cast<T>(2.7), static_cast<T>(7.4), static_cast<T>(0.1));
-  EXPECT_NEAR(3.7, matrix_f3x3(0, 0), precision);
-  EXPECT_NEAR(2.4, matrix_f3x3(1, 0), precision);
-  EXPECT_NEAR(6.4, matrix_f3x3(2, 0), precision);
-  EXPECT_NEAR(1.1, matrix_f3x3(0, 1), precision);
-  EXPECT_NEAR(5.2, matrix_f3x3(1, 1), precision);
-  EXPECT_NEAR(6.4, matrix_f3x3(2, 1), precision);
-  EXPECT_NEAR(2.7, matrix_f3x3(0, 2), precision);
-  EXPECT_NEAR(7.4, matrix_f3x3(1, 2), precision);
-  EXPECT_NEAR(0.1, matrix_f3x3(2, 2), precision);
-  mathfu::Matrix<T, 4> matrix_f4x4(
-      static_cast<T>(4.1), static_cast<T>(8.4), static_cast<T>(7.2),
-      static_cast<T>(4.8), static_cast<T>(0.9), static_cast<T>(7.8),
-      static_cast<T>(5.6), static_cast<T>(8.7), static_cast<T>(2.3),
-      static_cast<T>(4.2), static_cast<T>(6.1), static_cast<T>(2.7),
-      static_cast<T>(0.1), static_cast<T>(1.4), static_cast<T>(9.4),
-      static_cast<T>(3.6));
-  EXPECT_NEAR(4.1, matrix_f4x4(0, 0), precision);
-  EXPECT_NEAR(8.4, matrix_f4x4(1, 0), precision);
-  EXPECT_NEAR(7.2, matrix_f4x4(2, 0), precision);
-  EXPECT_NEAR(4.8, matrix_f4x4(3, 0), precision);
-  EXPECT_NEAR(0.9, matrix_f4x4(0, 1), precision);
-  EXPECT_NEAR(7.8, matrix_f4x4(1, 1), precision);
-  EXPECT_NEAR(5.6, matrix_f4x4(2, 1), precision);
-  EXPECT_NEAR(8.7, matrix_f4x4(3, 1), precision);
-  EXPECT_NEAR(2.3, matrix_f4x4(0, 2), precision);
-  EXPECT_NEAR(4.2, matrix_f4x4(1, 2), precision);
-  EXPECT_NEAR(6.1, matrix_f4x4(2, 2), precision);
-  EXPECT_NEAR(2.7, matrix_f4x4(3, 2), precision);
-  EXPECT_NEAR(0.1, matrix_f4x4(0, 3), precision);
-  EXPECT_NEAR(1.4, matrix_f4x4(1, 3), precision);
-  EXPECT_NEAR(9.4, matrix_f4x4(2, 3), precision);
-  EXPECT_NEAR(3.6, matrix_f4x4(3, 3), precision);
-}
-TEST_SCALAR_F(InitializePerDimension, FLOAT_PRECISION, DOUBLE_PRECISION)
-
-// Test initialization of a matrix from an array of packed vectors.
-template <class T, int d>
-void InitializePacked_Test(const T& precision) {
-  (void)precision;
-  mathfu::VectorPacked<T, d> packed[d];
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      packed[i].data[j] = static_cast<T>((i * d) + j);
-    }
-  }
-  mathfu::Matrix<T, d> matrix(packed);
-  for (int i = 0; i < d * d; ++i) {
-    EXPECT_NEAR(packed[i / d].data[i % d], matrix[i], static_cast<T>(0))
-        << "Element " << i;
-  }
-}
-TEST_ALL_F(InitializePacked, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test serialization to a packed array of vectors.
-template <class T, int d>
-void PackedSerialization_Test(const T& precision) {
-  (void)precision;
-  mathfu::Matrix<T, d> matrix;
-  for (int i = 0; i < d * d; ++i) {
-    matrix[i] = static_cast<T>(i);
-  }
-  mathfu::VectorPacked<T, d> packed[d];
-  matrix.Pack(packed);
-  for (int i = 0; i < d * d; ++i) {
-    EXPECT_NEAR(matrix[i], packed[i / d].data[i % d], static_cast<T>(0))
-        << "Element " << i;
-  }
-}
-TEST_ALL_F(PackedSerialization, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// This will test the Addition and Subtraction of matrices. The template
-// parameter d corresponds to the number of rows and columns.
-template <class T, int d>
-void AddSub_Test(const T& precision) {
-  T x1[d * d], x2[d * d];
-  for (int i = 0; i < d * d; ++i) {
-    x1[i] = rand() / static_cast<T>(RAND_MAX) * 100.f;
-  }
-  for (int i = 0; i < d * d; ++i) {
-    x2[i] = rand() / static_cast<T>(RAND_MAX) * 100.f;
-  }
-  mathfu::Matrix<T, d> matrix1(x1), matrix2(x2);
-  // This will test the negation of a matrix and verify that each element
-  // is negated.
-  mathfu::Matrix<T, d> neg_mat1(-matrix1);
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(-x1[i + d * j], neg_mat1(i, j), precision);
-    }
-  }
-  // This will test the addition of two matrices and verify that each element
-  // equal to the sum of the input values.
-  mathfu::Matrix<T, d> matrix_add(matrix1 + matrix2);
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(x1[i + d * j] + x2[i + d * j], matrix_add(i, j), precision);
-    }
-  }
-  // This will test the subtraction of two matrices and verify that each
-  // element equal to the difference of the input values.
-  mathfu::Matrix<T, d> matrix_sub(matrix1 - matrix2);
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(x1[i + d * j] - x2[i + d * j], matrix_sub(i, j), precision);
-    }
-  }
-}
-TEST_ALL_F(AddSub, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// This will test the multiplication of matrices by matrices, vectors,
-// and scalars. The template parameter d corresponds to the number of rows and
-// columns.
-template <class T, int d>
-void Mult_Test(const T& precision) {
-  T x1[d * d], x2[d * d];
-  for (int i = 0; i < d * d; ++i) x1[i] = rand() / static_cast<T>(RAND_MAX);
-  for (int i = 0; i < d * d; ++i) x2[i] = rand() / static_cast<T>(RAND_MAX);
-  mathfu::Matrix<T, d> matrix1(x1), matrix2(x2);
-  // This will test scalar matrix multiplication and verify that each element
-  // is equal to multiplication by the scalar.
-  mathfu::Matrix<T, d> matrix_mults(matrix1 * static_cast<T>(1.1));
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(x1[i + d * j] * 1.1, matrix_mults(i, j), precision);
-    }
-  }
-  T v[d];
-  for (int i = 0; i < d; ++i) v[i] = rand() / static_cast<T>(RAND_MAX);
-  mathfu::Vector<T, d> vector(v);
-  // This will test matrix vector multiplication and verify that the resulting
-  // vector is mathematically correct.
-  mathfu::Vector<T, d> vector_multv(matrix1 * vector);
-  for (int i = 0; i < d; ++i) {
-    T v1[d];
-    for (int k = 0; k < d; ++k) v1[k] = matrix1(i, k);
-    mathfu::Vector<T, d> vec1(v1);
-    T dot = mathfu::Vector<T, d>::DotProduct(vec1, vector);
-    EXPECT_NEAR(dot, vector_multv[i], precision);
-  }
-  // This will test matrix multiplication and verify that the resulting
-  // matrix is mathematically correct.
-  mathfu::Matrix<T, d> matrix_multm(matrix1 * matrix2);
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      T v1[d], v2[d];
-      for (int k = 0; k < d; ++k) v1[k] = matrix1(i, k);
-      for (int k = 0; k < d; ++k) v2[k] = matrix2(k, j);
-      mathfu::Vector<T, d> vec1(v1), vec2(v2);
-      T dot = mathfu::Vector<T, d>::DotProduct(vec1, vec2);
-      EXPECT_NEAR(dot, matrix_multm(i, j), precision);
-    }
-  }
-}
-TEST_ALL_F(Mult, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// This will test the outer product of two vectors. The template parameter d
-// corresponds to the number of rows and columns.
-template <class T, int d>
-void OuterProduct_Test(const T& precision) {
-  T x1[d], x2[d];
-  for (int i = 0; i < d; ++i) x1[i] = rand() / static_cast<T>(RAND_MAX);
-  for (int i = 0; i < d; ++i) x2[i] = rand() / static_cast<T>(RAND_MAX);
-  mathfu::Vector<T, d> vector1(x1), vector2(x2);
-  mathfu::Matrix<T, d> matrix(
-      mathfu::Matrix<T, d>::OuterProduct(vector1, vector2));
-  // This will verify that each element is mathematically correct.
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(vector1[i] * vector2[j], matrix(i, j), precision);
-    }
-  }
-}
-TEST_ALL_F(OuterProduct, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Print the specified matrix to output_string in the form.
-template <class T, int rows, int columns>
-std::string MatrixToString(const mathfu::Matrix<T, rows, columns>& matrix) {
-  std::stringstream ss;
-  ss.flags(std::ios::fixed);
-  ss.precision(4);
-  for (int col = 0; col < columns; ++col) {
-    for (int row = 0; row < rows; ++row) {
-      ss << (T)matrix(col, row) << " ";
-    }
-    ss << "\n";
-  }
-  return ss.str();
-}
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4127)  // conditional expression is constant
-#endif                           // _MSC_VER
-
-// Test the inverse of a set of noninvertible matrices.
-template <class T, int d>
-void InverseNonInvertible_Test(const T& precision) {
-  (void)precision;
-  T m[d * d];
-  const size_t matrix_size = sizeof(m) / sizeof(m[0]);
-  static const T kDeterminantThreshold =
-      mathfu::Constants<T>::GetDeterminantThreshold();
-  static const T kDeterminantThresholdInverse = 1 / kDeterminantThreshold;
-  static const T kDeterminantThresholdSmall =
-      kDeterminantThresholdInverse / 100;
-  static const T kDeterminantThresholdInverseLarge =
-      kDeterminantThresholdInverse * 100;
-  // Create a matrix with all zeros.
-  for (size_t i = 0; i < matrix_size; ++i) m[i] = 0;
-  // Verify that it's not possible to invert the matrix.
-  {
-    mathfu::Matrix<T, d> matrix(m);
-    mathfu::Matrix<T, d> inverse_matrix;
-    EXPECT_FALSE(matrix.InverseWithDeterminantCheck(&inverse_matrix));
-  }
-  // Check a matrix with all elements at the determinant threshold.
-  for (size_t i = 0; i < matrix_size; ++i) m[i] = kDeterminantThreshold;
-  {
-    mathfu::Matrix<T, d> matrix(m);
-    mathfu::Matrix<T, d> inverse_matrix;
-    EXPECT_FALSE(matrix.InverseWithDeterminantCheck(&inverse_matrix));
-  }
-  // Check a matrix with all very large elements.
-  for (size_t i = 0; i < matrix_size - 1; ++i) {
-    m[i] = kDeterminantThresholdInverse;
-  }
-  m[matrix_size - 1] = kDeterminantThresholdInverseLarge;
-  // NOTE: Due to precision, this case will pass the determinant check with a
-  // 2x2 matrix since the determinant of the matrix will be calculated as 1.
-  if (d != 2) {
-    // Create a matrix with all elements at the determinant threshold and one
-    // large value in the matrix.
-    for (size_t i = 0; i < matrix_size - 1; ++i) {
-      m[i] = kDeterminantThresholdSmall;
-    }
-    m[matrix_size - 1] = kDeterminantThresholdInverseLarge;
-    {
-      mathfu::Matrix<T, d> matrix(m);
-      mathfu::Matrix<T, d> inverse_matrix;
-      EXPECT_FALSE(matrix.InverseWithDeterminantCheck(&inverse_matrix));
-    }
-  }
-}
-TEST_ALL_F(InverseNonInvertible, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif  // _MSC_VER
-
-// This will test calculating the inverse of a matrix. The template parameter d
-// corresponds to the number of rows and columns.
-template <class T, int d>
-void Inverse_Test(const T& precision) {
-  T x[d * d];
-  for (int iterations = 0; iterations < 1000; ++iterations) {
-    // NOTE: This assumes that matrices generated here are invertible since
-    // there is a tiny probability that a randomly generated matrix will be
-    // noninvertible.  This does mean that this test can be flakey by
-    // occasionally generating noninvertible matrices.
-    for (int i = 0; i < mathfu::Matrix<T, d>::kElements; ++i) {
-      x[i] = mathfu::RandomRange<T>(1);
-    }
-    mathfu::Matrix<T, d> matrix(x);
-    std::string error_string = MatrixToString(matrix);
-    error_string += "\n";
-    mathfu::Matrix<T, d> inverse_matrix(matrix.Inverse());
-    mathfu::Matrix<T, d> identity_matrix(matrix * inverse_matrix);
-
-    error_string += MatrixToString(inverse_matrix);
-    error_string += "\n";
-    error_string += MatrixToString(identity_matrix);
-
-    // This will verify that M * Minv is equal to the identity.
-    for (int i = 0; i < d; ++i) {
-      for (int j = 0; j < d; ++j) {
-        EXPECT_NEAR(i == j ? 1 : 0, identity_matrix(i, j), 100 * precision)
-            << error_string << " row=" << i << " column=" << j;
-      }
-    }
-  }
-}
-// Due to the number of operations involved and the random numbers used to
-// generate the test matrices, the precision the inverse matrix is calculated
-// to is relatively low.
-TEST_ALL_F(Inverse, 1e-4f, 1e-8);
-
-// This will test converting from a translation into a matrix and back again.
-template <class T>
-void TranslationVector3D_Test(const T& precision) {
-  (void)precision;
-  const mathfu::Vector<T, 3> trans(static_cast<T>(-100.0), static_cast<T>(0.0),
-                                   static_cast<T>(0.00003));
-  const mathfu::Matrix<T, 4> trans_matrix =
-      mathfu::Matrix<T, 4>::FromTranslationVector(trans);
-  const mathfu::Vector<T, 3> trans_back = trans_matrix.TranslationVector3D();
-
-  // This will verify that the translation vector has not changed.
-  for (int i = 0; i < 3; ++i) {
-    EXPECT_EQ(trans[i], trans_back[i]);
-  }
-}
-TEST_SCALAR_F(TranslationVector3D, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// This will test converting from a translation into a matrix and back again.
-template <class T>
-void TranslationVector2D_Test(const T& precision) {
-  (void)precision;
-  const mathfu::Vector<T, 2> trans(static_cast<T>(-100.0),
-                                   static_cast<T>(0.00003));
-  const mathfu::Matrix<T, 3> trans_matrix =
-      mathfu::Matrix<T, 3>::FromTranslationVector(trans);
-  const mathfu::Vector<T, 2> trans_back = trans_matrix.TranslationVector2D();
-
-  // This will verify that the translation vector has not changed.
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_EQ(trans[i], trans_back[i]);
-  }
-}
-TEST_SCALAR_F(TranslationVector2D, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// This will test converting from a scale into a matrix, then multiply by
-// a vector of 1's, which should produce the original scale again.
-template <class T, int d>
-void FromScaleVector_Test(const T& precision) {
-  mathfu::Vector<T, d> ones(static_cast<T>(1));
-  mathfu::Vector<T, d - 1> v;
-
-  // Tests that the scale vector is placed in the correct order in the matrix.
-  for (int i = 0; i < d - 1; ++i) {
-    v[i] = static_cast<T>(i + 10);
-  }
-  mathfu::Matrix<T, d> m = mathfu::Matrix<T, d>::FromScaleVector(v);
-
-  // Ensure that the v is on the diagonal.
-  for (int i = 0; i < d - 1; ++i) {
-    EXPECT_NEAR(v[i], m(i, i), precision);
-  }
-
-  // Ensure that the last diagonal element is one.
-  EXPECT_NEAR(m(d - 1, d - 1), 1, precision);
-
-  // Ensure that all non-diagonal elements are zero.
-  for (int i = 0; i < d - 1; ++i) {
-    for (int j = 0; j < d - 1; ++j) {
-      if (i == j) continue;
-      EXPECT_NEAR(m(i, j), 0, precision);
-    }
-  }
-}
-// Precision is zero. Results must be perfect for this test.
-TEST_ALL_F(FromScaleVector, 0.0f, 0.0);
-
-// Compare a set of Matrix<T, rows, columns> with expected values.
-template <class T, int rows, int columns>
-void VerifyMatrixExpectations(
-    const MatrixExpectation<T, rows, columns>* test_cases,
-    const size_t number_of_test_cases, const T& precision) {
-  for (size_t i = 0; i < number_of_test_cases; ++i) {
-    const MatrixExpectation<T, rows, columns>& test = test_cases[i];
-    for (int j = 0; j < mathfu::Matrix<T, rows, columns>::kElements; ++j) {
-      const mathfu::Matrix<T, rows, columns>& calculated = test.calculated;
-      const mathfu::Matrix<T, rows, columns>& expected = test.expected;
-      EXPECT_NEAR(calculated[j], expected[j], precision)
-          << "element " << j << " (" << (j / columns) << ", " << (j % columns)
-          << "), case " << test.description << "\n"
-          << MatrixToString(calculated) << "vs expected\n"
-          << MatrixToString(expected);
-    }
-  }
-}
-
-// Test perspective matrix calculation.
-template <class T>
-void Perspective_Test(const T& precision) {
-  // clang-format off
-  static const MatrixExpectation<T, 4, 4> kTestCases[] = {
-    {
-      "normalized handedness=1",
-      mathfu::Matrix<T, 4>::Perspective(
-          atan(static_cast<T>(1)) * 2, 1, 0, 1, 1),
-      mathfu::Matrix<T, 4>(1, 0, 0, 0,
-                           0, 1, 0, 0,
-                           0, 0, -1, -1,
-                           0, 0, 0, 0),
-    },
-    {
-      "normalized handedness=-1",
-      mathfu::Matrix<T, 4>::Perspective(
-          atan(static_cast<T>(1)) * 2, 1, 0, 1, -1),
-      mathfu::Matrix<T, 4>(1, 0, 0, 0,
-                           0, 1, 0, 0,
-                           0, 0, 1, 1,
-                           0, 0, 0, 0),
-    },
-    {
-      "widefov",
-      mathfu::Matrix<T, 4>::Perspective(
-          atan(static_cast<T>(2)) * 2, 1, 0, 1, 1),
-      mathfu::Matrix<T, 4>(0.5, 0, 0, 0,
-                           0, 0.5, 0, 0,
-                           0, 0, -1, -1,
-                           0, 0, 0, 0),
-    },
-    {
-      "narrowfov",
-      mathfu::Matrix<T, 4>::Perspective(
-          atan(static_cast<T>(0.1)) * 2, 1, 0, 1, 1),
-      mathfu::Matrix<T, 4>(10, 0, 0, 0,
-                           0, 10, 0, 0,
-                           0, 0, -1, -1,
-                           0, 0, 0, 0),
-    },
-    {
-      "2:1 aspect ratio",
-      mathfu::Matrix<T, 4>::Perspective(
-          atan(static_cast<T>(1)) * 2, 0.5, 0, 1, 1),
-      mathfu::Matrix<T, 4>(2, 0, 0, 0,
-                           0, 1, 0, 0,
-                           0, 0, -1, -1,
-                           0, 0, 0, 0),
-    },
-    {
-      "deeper view frustrum",
-      mathfu::Matrix<T, 4>::Perspective(
-          atan(static_cast<T>(1)) * 2, 1, -2, 2, 1),
-      mathfu::Matrix<T, 4>(1, 0, 0, 0,
-                           0, 1, 0, 0,
-                           0, 0, -0.5, -1,
-                           0, 0, 2, 0),
-    },
-  };
-  // clang-format on
-  VerifyMatrixExpectations(
-      kTestCases, sizeof(kTestCases) / sizeof(kTestCases[0]), precision);
-}
-TEST_SCALAR_F(Perspective, FLOAT_PRECISION, DOUBLE_PRECISION * 10);
-
-// Test orthographic matrix calculation.
-template <class T>
-void Ortho_Test(const T& precision) {
-  // clang-format off
-  static const MatrixExpectation<T, 4, 4> kTestCases[] = {
-    {
-      "normalized",
-      mathfu::Matrix<T, 4, 4>::Ortho(0, 2, 0, 2, 2, 0),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              -1, -1, 1, 1),
-    },
-    {
-      "normalized RH",
-      mathfu::Matrix<T, 4, 4>::Ortho(0, 2, 0, 2, 2, 0, 1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              -1, -1, 1, 1),
-    },
-    {
-      "narrow RH",
-      mathfu::Matrix<T, 4, 4>::Ortho(1, 3, 0, 2, 2, 0, 1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              -2, -1, 1, 1),
-
-    },
-    {
-      "squat RH",
-      mathfu::Matrix<T, 4, 4>::Ortho(0, 2, 1, 3, 2, 0, 1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              -1, -2, 1, 1),
-
-    },
-    {
-      "deep RH",
-      mathfu::Matrix<T, 4, 4>::Ortho(0, 2, 0, 2, 3, 1, 1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              -1, -1, 2, 1),
-
-    },
-    {
-      "normalized LH",
-      mathfu::Matrix<T, 4, 4>::Ortho(0, 2, 0, 2, 2, 0, -1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, -1, 0,
-                              -1, -1, 1, 1),
-    },
-    {
-      "Canonical LH",
-      mathfu::Matrix<T, 4, 4>::Ortho(1, 3, 1, 3, 1, 3, -1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                             -2,-2,-2, 1),
-
-    },
-  };
-  // clang-format on
-  VerifyMatrixExpectations(
-      kTestCases, sizeof(kTestCases) / sizeof(kTestCases[0]), precision);
-}
-TEST_SCALAR_F(Ortho, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test look-at matrix calculation.
-template <class T>
-void LookAt_Test(const T& precision) {
-  // clang-format off
-  static const MatrixExpectation<T, 4, 4> kTestCases[] = {
-    {
-      "origin along z",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(0, 0, 1), mathfu::Vector<T, 3>(0, 0, 0),
-          mathfu::Vector<T, 3>(0, 1, 0)),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              0, 0, 0, 1),
-    },
-    {
-      "origin along diagonal",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(0, 0, 0), mathfu::Vector<T, 3>(1, 1, 1),
-          mathfu::Vector<T, 3>(0, 1, 0), -1),
-      mathfu::Matrix<T, 4, 4>(
-          static_cast<T>(-0.707106781), static_cast<T>(-0.408248290),
-              static_cast<T>(-0.577350269), 0,
-          0, static_cast<T>(0.816496580), static_cast<T>(-0.577350269), 0,
-          static_cast<T>(0.707106781), static_cast<T>(-0.408248290),
-              static_cast<T>(-0.577350269), 0,
-          0, 0, static_cast<T>(1.732050808), 1),
-    },
-    {
-      "origin along z",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(0, 0, 2), mathfu::Vector<T, 3>(0, 0, 0),
-          mathfu::Vector<T, 3>(0, 1, 0), -1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              0, 0, 0, 1),
-    },
-    {
-      "origin along x",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(1, 0, 0), mathfu::Vector<T, 3>(0, 0, 0),
-          mathfu::Vector<T, 3>(0, 1, 0), -1),
-      mathfu::Matrix<T, 4, 4>(0, 0, 1, 0,
-                              0, 1, 0, 0,
-                              -1, 0, 0, 0,
-                              0, 0, 0, 1),
-    },
-    {
-      "origin along y",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(0, 1, 0), mathfu::Vector<T, 3>(0, 0, 0),
-          mathfu::Vector<T, 3>(1, 0, 0), -1),
-      mathfu::Matrix<T, 4, 4>(0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              1, 0, 0, 0,
-                              0, 0, 0, 1),
-    },
-    {
-      "translated eye, looking along z",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(1, 1, 2), mathfu::Vector<T, 3>(1, 1, 1),
-          mathfu::Vector<T, 3>(0, 1, 0), -1),
-      mathfu::Matrix<T, 4, 4>(1, 0, 0, 0,
-                              0, 1, 0, 0,
-                              0, 0, 1, 0,
-                              -1, -1, -1, 1),
-    },
-    {
-      "right-handed diagonal along diagonal",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(0, 0, 0), mathfu::Vector<T, 3>(1, 1, 1),
-          mathfu::Vector<T, 3>(0, 1, 0), 1),
-      mathfu::Matrix<T, 4, 4>(
-          static_cast<T>(0.707106781), static_cast<T>(-0.408248290),
-              static_cast<T>(0.577350269), 0,
-          0, static_cast<T>(0.816496581), static_cast<T>(0.577350269), 0,
-          static_cast<T>(-0.707106781), static_cast<T>(-0.408248290),
-              static_cast<T>(0.577350269), 0,
-          0, 0, static_cast<T>(-1.732050808), 1),
-    },
-    {
-      "right-handed origin along z",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(0, 0, 1), mathfu::Vector<T, 3>(0, 0, 0),
-          mathfu::Vector<T, 3>(0, 1, 0), 1),
-      mathfu::Matrix<T, 4, 4>(-1, 0, 0, 0,
-                               0, 1, 0, 0,
-                               0, 0, -1,0,
-                               0, 0, 0, 1),
-    },
-    {
-      "right-handed origin along x",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(1, 0, 0), mathfu::Vector<T, 3>(0, 0, 0),
-          mathfu::Vector<T, 3>(0, 1, 0), 1),
-      mathfu::Matrix<T, 4, 4>(0, 0, -1, 0,
-                              0, 1, 0, 0,
-                              1, 0, 0, 0,
-                              0, 0, 0, 1),
-    },
-    {
-      "right-handed origin along y",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(0, 1, 0), mathfu::Vector<T, 3>(0, 0, 0),
-          mathfu::Vector<T, 3>(1, 0, 0), 1),
-      mathfu::Matrix<T, 4, 4>(0, 1, 0, 0,
-                              0, 0, -1, 0,
-                              -1, 0, 0, 0,
-                              0,  0, 0, 1),
-    },
-    {
-      "right-handed translated eye along x",
-      mathfu::Matrix<T, 4, 4>::LookAt(
-          mathfu::Vector<T, 3>(2, 1, 1), mathfu::Vector<T, 3>(1, 1, 1),
-          mathfu::Vector<T, 3>(0, 1, 0), 1),
-      mathfu::Matrix<T, 4, 4>(0, 0, -1, 0,
-                              0, 1, 0, 0,
-                              1, 0, 0, 0,
-                             -1,-1, 1, 1),
-    },
-  };
-  // clang-format on
-  VerifyMatrixExpectations(
-      kTestCases, sizeof(kTestCases) / sizeof(kTestCases[0]), precision);
-}
-TEST_SCALAR_F(LookAt, FLOAT_PRECISION, kLookAtDoublePrecision);
-
-// Test UnProject calculation.
-template <class T>
-void UnProject_Test(const T& precision) {
-  // clang-format off
-  mathfu::Matrix<T, 4, 4> modelView =
-      mathfu::Matrix<T, 4, 4>(-1, 0,                   0, 0,
-                               0, 1,                   0, 0,
-                               0, 0,                  -1, 0,
-                               0, 0, static_cast<T>(-10), 1);
-  mathfu::Matrix<T, 4, 4> projection =
-      mathfu::Matrix<T, 4, 4>(
-          static_cast<T>(1.81066),  0,                            0,   0,
-                        0, static_cast<T>(2.41421342),            0,   0,
-                        0,          0,   static_cast<T>(-1.00001991), -1,
-                        0,          0,  static_cast<T>(-0.200001985),  0);
-  // clang-format on
-  mathfu::Vector<T, 3> result = mathfu::Matrix<T, 4, 4>::UnProject(
-      mathfu::Vector<T, 3>(754, 1049, 1), modelView, projection, 1600, 1200);
-  EXPECT_NEAR(result.x, 319.00242400912055, 300.0 * precision);
-  EXPECT_NEAR(result.y, 3113.7409399625253, 3000.0 * precision);
-  EXPECT_NEAR(result.z, 10035.303114023569, 10000.0 * precision);
-}
-TEST_SCALAR_F(UnProject, kUnProjectFloatPrecision, DOUBLE_PRECISION);
-
-// Test matrix transposition.
-template <class T, int d>
-void Transpose_Test(const T& precision) {
-  (void)precision;
-  mathfu::Matrix<T, d> matrix;
-  for (int i = 0; i < d * d; ++i) {
-    matrix[i] = static_cast<T>(i);
-  }
-  mathfu::Matrix<T, d> transpose = matrix.Transpose();
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(matrix(i, j), transpose(j, i), static_cast<T>(0));
-    }
-  }
-}
-
-TEST_ALL_F(Transpose, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Return one of the numbers:
-//   offset, offset + width/d, offset + 2*width/d, ... , offset + (d-1)*width/d
-// For each i=0..d-1, the number returned is different.
-//
-// The order of the numbers is determined by 'prime' which should be a prime
-// number > d.
-template <class T, int d>
-static T WellSpacedNumber(int i, int prime, T width, T offset) {
-  // Reorder the i's from 0..(d-1) by using a prime number.
-  // The numbers get reordered (i.e. no duplicates) because 'd' and 'prime' are
-  // relatively prime.
-  const int remapped = ((i + 1) * prime) % d;
-
-  // Map to [0,1) range. That is, inclusive of 0, exclusive of 1.
-  const T zero_to_one = static_cast<T>(remapped) / static_cast<T>(d);
-
-  // Map to [offset, offset + width) range.
-  const T offset_and_scaled = zero_to_one * width + offset;
-  return offset_and_scaled;
-}
-
-// Generate a (probably) invertable matrix. I haven't gone through the math
-// to verify that it's actually invertable for all d, but for small d it is.
-//
-// We adjusting each element of an identity matrix by a small amount.
-// The amount must be small so that the matrix stays reasonably close to
-// the identity. Matrices become progressively less numerically stable the
-// further the get from identity.
-template <class T, int d>
-static mathfu::Matrix<T, d> InvertableMatrix() {
-  mathfu::Matrix<T, d> invertable = mathfu::Matrix<T, d>::Identity();
-
-  for (int i = 0; i < d; ++i) {
-    // The width and offset constants are arbitrary. We do want to keep the
-    // pseudo-random values centered near 0 though.
-    const T rand_i = WellSpacedNumber<T, d>(i, 7, 0.8f, -0.33f);
-
-    for (int j = 0; j < d; ++j) {
-      const T rand_j = WellSpacedNumber<T, d>(j, 13, 0.6f, -0.4f);
-      invertable(i, j) += rand_i * rand_j;
-    }
-  }
-  return invertable;
-}
-
-template <class T, int d>
-static void ExpectEqualMatrices(const mathfu::Matrix<T, d>& a,
-                                const mathfu::Matrix<T, d>& b, T precision) {
-  for (int i = 0; i < d; ++i) {
-    for (int j = 0; j < d; ++j) {
-      EXPECT_NEAR(a(i, j), b(i, j), precision);
-    }
-  }
-}
-
-// Test matrix operator*() by multiplying an invertable matrix by its
-// inverse. Should end up with identity.
-template <class T, int d>
-void MultiplyOperatorInverse_Test(const T& precision) {
-  typedef typename mathfu::Matrix<T, d> Mat;
-  const Mat identity = Mat::Identity();
-  const Mat invertable = InvertableMatrix<T, d>();
-
-  // Use operator*() to go way from the identity and then get back to it.
-  Mat product = identity;
-  product *= invertable;
-  product *= invertable.Inverse();
-
-  // Test that operator*() gets is back to where we need to go.
-  ExpectEqualMatrices(product, identity, precision);
-}
-
-TEST_ALL_F(MultiplyOperatorInverse, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test static operator*(a, b) by multiplying an invertable matrix by its
-// inverse. Should end up with identity.
-template <class T, int d>
-void ExternalMultiplyOperatorInverse_Test(const T& precision) {
-  typedef typename mathfu::Matrix<T, d> Mat;
-  const Mat identity = Mat::Identity();
-  const Mat invertable = InvertableMatrix<T, d>();
-
-  // Use operator*() to go way from the identity and then get back to it.
-  Mat product = identity;
-  product = product * invertable;
-  product = product * invertable.Inverse();
-
-  // Test that operator*() gets is back to where we need to go.
-  ExpectEqualMatrices(product, identity, precision);
-}
-
-TEST_ALL_F(ExternalMultiplyOperatorInverse, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test matrix operator*() by multiplying a non-zero matrix by identity.
-// Should be no change.
-template <class T, int d>
-void MultiplyOperatorIdentity_Test(const T& precision) {
-  typedef typename mathfu::Matrix<T, d> Mat;
-  const Mat identity = Mat::Identity();
-  const Mat invertable = InvertableMatrix<T, d>();
-
-  // Use operator*() to multipy by the identity.
-  Mat product = invertable;
-  product *= identity;
-
-  // Test that operator*() didn't change anything when multiplying by identity.
-  ExpectEqualMatrices(product, invertable, precision);
-}
-
-TEST_ALL_F(MultiplyOperatorIdentity, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test static operator*(a, b) by multiplying a non-zero matrix by identity.
-// Should be no change.
-template <class T, int d>
-void ExternalMultiplyOperatorIdentity_Test(const T& precision) {
-  typedef typename mathfu::Matrix<T, d> Mat;
-  const Mat identity = Mat::Identity();
-  const Mat invertable = InvertableMatrix<T, d>();
-
-  // Use operator*() to multipy by the identity.
-  const Mat product = invertable * identity;
-
-  // Test that operator*() didn't change anything when multiplying by identity.
-  ExpectEqualMatrices(product, invertable, precision);
-}
-
-TEST_ALL_F(ExternalMultiplyOperatorIdentity, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test matrix operator*() by multiplying a non-zero matrix by zero.
-// Should be no change.
-template <class T, int d>
-void MultiplyOperatorZero_Test(const T& precision) {
-  typedef typename mathfu::Matrix<T, d> Mat;
-  const Mat zero(static_cast<T>(0));
-  const Mat invertable = InvertableMatrix<T, d>();
-
-  // Use operator*() to multipy by the zero.
-  Mat product = invertable;
-  product *= zero;
-
-  // Test that operator*() didn't change anything when multiplying by zero.
-  ExpectEqualMatrices(product, zero, precision);
-}
-
-TEST_ALL_F(MultiplyOperatorZero, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test static operator*(a, b) by multiplying a non-zero matrix by zero.
-// Should be no change.
-template <class T, int d>
-void ExternalMultiplyOperatorZero_Test(const T& precision) {
-  typedef typename mathfu::Matrix<T, d> Mat;
-  const Mat zero(static_cast<T>(0));
-  const Mat invertable = InvertableMatrix<T, d>();
-
-  // Use operator*() to multipy by the zero.
-  const Mat product = invertable * zero;
-
-  // Test that operator*() didn't change anything when multiplying by zero.
-  ExpectEqualMatrices(product, zero, precision);
-}
-
-TEST_ALL_F(ExternalMultiplyOperatorZero, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test Matrix<>::ToAffineTransform().
-template <class T>
-void Mat4ToAffine_Test(const T&) {
-  typedef typename mathfu::Matrix<T, 4> Mat4;
-  typedef typename mathfu::Matrix<T, 4, 3> Affine;
-  const Mat4 indices4(0, 1, 2, 0, 4, 5, 6, 0, 8, 9, 10, 0, 12, 13, 14, 1);
-  const Affine indices_affine(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14);
-
-  const Affine to_affine = Mat4::ToAffineTransform(indices4);
-  for (int i = 0; i < 4; i++) {
-    for (int j = 0; j < 3; j++) {
-      EXPECT_EQ(to_affine(i, j), indices_affine(i, j));
-    }
-  }
-}
-
-TEST_SCALAR_F(Mat4ToAffine, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test Matrix<>::FromAffineTransform().
-template <class T>
-void Mat4FromAffine_Test(const T&) {
-  typedef typename mathfu::Matrix<T, 4> Mat4;
-  typedef typename mathfu::Matrix<T, 4, 3> Affine;
-  const Mat4 indices4(0, 1, 2, 0, 4, 5, 6, 0, 8, 9, 10, 0, 12, 13, 14, 1);
-  const Affine indices_affine(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14);
-
-  const Mat4 to_mat4 = Mat4::FromAffineTransform(indices_affine);
-  ExpectEqualMatrices(to_mat4, indices4, static_cast<T>(0));
-}
-
-TEST_SCALAR_F(Mat4FromAffine, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// Test converting back and forth via Matrix<>::To/FromAffineTransform().
-template <class T>
-void Mat4ToAndFromAffine_Test(const T&) {
-  typedef typename mathfu::Matrix<T, 4> Mat4;
-  typedef typename mathfu::Matrix<T, 4, 3> Affine;
-  const Mat4 indices4(0, 1, 2, 0, 4, 5, 6, 0, 8, 9, 10, 0, 12, 13, 14, 1);
-  const Affine indices_affine(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14);
-
-  // Convert to/from AffineTransform and check to ensure the result is the same
-  // as the original.
-  const Mat4 converted =
-      Mat4::FromAffineTransform(Mat4::ToAffineTransform(indices4));
-
-  ExpectEqualMatrices(indices4, converted, static_cast<T>(0));
-
-  // Perform a normal mat4 * mat4 multiplication and compare its result with
-  // multiplications involving conversions.
-  const Mat4 mat4_multiplication = indices4 * indices4;
-  const Mat4 affine_multiplication = Mat4::FromAffineTransform(indices_affine) *
-                                     Mat4::FromAffineTransform(indices_affine);
-  const Mat4 affine_and_mat4_multiplication =
-      indices4 * Mat4::FromAffineTransform(indices_affine);
-
-  ExpectEqualMatrices(mat4_multiplication, affine_multiplication,
-                      static_cast<T>(0));
-  ExpectEqualMatrices(mat4_multiplication, affine_and_mat4_multiplication,
-                      static_cast<T>(0));
-
-  // Ensure that the result from the multiplication produces the expected
-  // AffineTransform result.
-  const Affine expected_result(20, 68, 116, 176, 23, 83, 143, 216, 26, 98, 170,
-                               256);
-  const Affine affine_result = Mat4::ToAffineTransform(affine_multiplication);
-
-  for (int i = 0; i < 4; i++) {
-    for (int j = 0; j < 3; j++) {
-      EXPECT_EQ(expected_result(i, j), affine_result(i, j));
-    }
-  }
-}
-
-TEST_SCALAR_F(Mat4ToAndFromAffine, FLOAT_PRECISION, DOUBLE_PRECISION);
-
-// This will test converting from a translation into a matrix and back again.
-// Test the compilation of basic matrix operations given in the sample file.
-// This will test transforming a vector with a matrix.
-TEST_F(MatrixTests, MatrixSample) {
-  using namespace mathfu;
-  /// @doxysnippetstart Chapter04_Matrices.md Matrix_Sample
-  Vector<float, 3> trans(3.f, 2.f, 8.f);
-  Vector<float, 3> rotation(0.4f, 1.4f, 0.33f);
-  Vector<float, 3> vector(4.f, 8.f, 1.f);
-
-  Quaternion<float> rotQuat = Quaternion<float>::FromEulerAngles(rotation);
-  Matrix<float, 3> rotMatrix = rotQuat.ToMatrix();
-  Matrix<float, 4> transMatrix = Matrix<float, 4>::FromTranslationVector(trans);
-  Matrix<float, 4> rotHMatrix = Matrix<float, 4>::FromRotationMatrix(rotMatrix);
-
-  Matrix<float, 4> matrix = transMatrix * rotHMatrix;
-  Vector<float, 3> rotatedVector = matrix * vector;
-  /// @doxysnippetend
-  const float precision = 1e-2f;
-  EXPECT_NEAR(5.14f, rotatedVector[0], precision);
-  EXPECT_NEAR(10.11f, rotatedVector[1], precision);
-  EXPECT_NEAR(4.74f, rotatedVector[2], precision);
-}
-
-// Simple class that represents a possible compatible type for a vector.
-// That is, it's just an array of T of length d, so can be loaded and
-// stored from mathfu::Vector<T,d> using ToType() and FromType().
-template <class T, int d>
-struct SimpleMatrix {
-  T values[d * d];
-};
-
-// This will test the FromType() conversion functions.
-template <class T, int d>
-void FromType_Test(const T& precision) {
-  typedef SimpleMatrix<T, d> CompatibleT;
-  typedef mathfu::Matrix<T, d> MatrixT;
-
-  CompatibleT compatible;
-  for (int i = 0; i < d * d; ++i) {
-    compatible.values[i] = static_cast<T>(i * precision);
-  }
-
-#ifdef MATHFU_COMPILE_WITH_PADDING
-  // With padding, vec3s take up 4-floats worth of memory, so byte-wise
-  // conversion won't work.
-  if (sizeof(CompatibleT) != sizeof(MatrixT)) {
-    EXPECT_EQ(d, 3);
-    return;
-  }
-#endif  // MATHFU_COMPILE_WITH_PADDING
-
-  const MatrixT matrix = MatrixT::FromType(compatible);
-
-  for (int i = 0; i < d * d; ++i) {
-    EXPECT_EQ(compatible.values[i], matrix[i]);
-  }
-}
-TEST_ALL_F(FromType, 0.0f, 0.0);
-
-// This will test the ToType() conversion functions.
-template <class T, int d>
-void ToType_Test(const T& precision) {
-  typedef SimpleMatrix<T, d> CompatibleT;
-  typedef mathfu::Matrix<T, d> MatrixT;
-
-  MatrixT matrix;
-  for (int i = 0; i < d * d; ++i) {
-    matrix[i] = static_cast<T>(i * precision);
-  }
-
-#ifdef MATHFU_COMPILE_WITH_PADDING
-  // With padding, vec3s take up 4-floats worth of memory, so byte-wise
-  // conversion won't work.
-  if (sizeof(CompatibleT) != sizeof(MatrixT)) {
-    EXPECT_EQ(d, 3);
-    return;
-  }
-#endif  // MATHFU_COMPILE_WITH_PADDING
-
-  const CompatibleT compatible = MatrixT::template ToType<CompatibleT>(matrix);
-
-  for (int i = 0; i < d * d; ++i) {
-    EXPECT_EQ(compatible.values[i], matrix[i]);
-  }
-}
-TEST_ALL_F(ToType, 0.0f, 0.0);
-
-int main(int argc, char** argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  printf("%s (%s)\n", argv[0], MATHFU_BUILD_OPTIONS_STRING);
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/AndroidManifest.xml
deleted file mode 100644
index 6e4344a..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_no_simd_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_no_simd_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/jni/Android.mk
deleted file mode 100644
index 889586f..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=matrix_no_simd_test
-MATHFU_LIB:=libmathfu_no_simd
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/jni/Application.mk
deleted file mode 100644
index 6c9a709..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_no_simd_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/res/values/strings.xml
deleted file mode 100644
index d7871ac..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/no_simd/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_no_simd_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/AndroidManifest.xml
deleted file mode 100644
index d8c08ce..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_simd_no_padding_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_simd_no_padding_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/jni/Android.mk
deleted file mode 100644
index ce77885..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=matrix_simd_no_padding_test
-MATHFU_LIB:=libmathfu_simd_no_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/jni/Application.mk
deleted file mode 100644
index f9c088a..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_simd_no_padding_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/res/values/strings.xml
deleted file mode 100644
index d683b22..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_no_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_simd_no_padding_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/AndroidManifest.xml
deleted file mode 100644
index 6d0bddd..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.matrix_simd_padding_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="matrix_simd_padding_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/jni/Android.mk
deleted file mode 100644
index 2376654..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=matrix_simd_padding_test
-MATHFU_LIB:=libmathfu_simd_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/jni/Application.mk
deleted file mode 100644
index 8f725fd..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=matrix_simd_padding_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/res/values/strings.xml
deleted file mode 100644
index cec9192..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/matrix_test/simd_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">matrix_simd_padding_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/precision.h b/third_party/mathfu-1.1.0/unit_tests/precision.h
deleted file mode 100644
index 72a89e2..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/precision.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef MATHFU_UNITTESTS_PRECISION_H_
-#define MATHFU_UNITTESTS_PRECISION_H_
-
-// Precision for floats and doubles
-#define FLOAT_PRECISION 1e-6f
-#define DOUBLE_PRECISION 1e-15
-
-#endif  // MATHFU_UNITTESTS_PRECISION_H_
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/AndroidManifest.xml
deleted file mode 100644
index a3122ca..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.quaternion_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="quaternion_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/jni/Android.mk
deleted file mode 100644
index abb56ea..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=quaternion_test
-MATHFU_LIB:=libmathfu
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/jni/Application.mk
deleted file mode 100644
index d6575ed..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=quaternion_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/res/values/strings.xml
deleted file mode 100644
index 634ce16..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/default/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">quaternion_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/AndroidManifest.xml
deleted file mode 100644
index 2cdeadb..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.quaternion_no_simd_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="quaternion_no_simd_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/jni/Android.mk
deleted file mode 100644
index b844150..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=quaternion_no_simd_test
-MATHFU_LIB:=libmathfu_no_simd
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/jni/Application.mk
deleted file mode 100644
index 790e89f..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=quaternion_no_simd_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/res/values/strings.xml
deleted file mode 100644
index 70588b0..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/no_simd/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">quaternion_no_simd_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/quaternion_test.cpp b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/quaternion_test.cpp
deleted file mode 100644
index d1ba26d..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/quaternion_test.cpp
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "mathfu/quaternion.h"
-#include "mathfu/constants.h"
-
-#include <math.h>
-
-#include "gtest/gtest.h"
-
-#include "precision.h"
-
-class QuaternionTests : public ::testing::Test {
- protected:
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-// This will automatically generate tests for each template parameter.
-#define TEST_ALL_F(MY_TEST)                   \
-  TEST_F(QuaternionTests, MY_TEST) {          \
-    MY_TEST##_Test<float>(FLOAT_PRECISION);   \
-    MY_TEST##_Test<double>(DOUBLE_PRECISION); \
-  }
-
-// helper macro for comparing vectors
-#define EXPECT_NEAR_VEC3(v1, v2, precision)   \
-  {                                           \
-    EXPECT_NEAR((v1)[0], (v2)[0], precision); \
-    EXPECT_NEAR((v1)[1], (v2)[1], precision); \
-    EXPECT_NEAR((v1)[2], (v2)[2], precision); \
-  }
-#define EXPECT_EQ_QUAT(q1, q2)               \
-  {                                          \
-    EXPECT_EQ((q1).scalar(), (q2).scalar()); \
-    EXPECT_EQ((q1).vector(), (q2).vector()); \
-  }
-
-// Test accessing elements of the quaternion using the const array accessor.
-template <class T>
-void ConstAccessor_Test(const T& precision) {
-  (void)precision;
-  const mathfu::Quaternion<T> quaternion(
-      static_cast<T>(0.50), static_cast<T>(0.76), static_cast<T>(0.38),
-      static_cast<T>(0.19));
-  EXPECT_EQ(static_cast<T>(0.50), quaternion[0]);
-  EXPECT_EQ(static_cast<T>(0.76), quaternion[1]);
-  EXPECT_EQ(static_cast<T>(0.38), quaternion[2]);
-  EXPECT_EQ(static_cast<T>(0.19), quaternion[3]);
-}
-TEST_ALL_F(ConstAccessor);
-
-// Test updating elements of the quaternion using the array accessor.
-template <class T>
-void NonConstAccessor_Test(const T& precision) {
-  (void)precision;
-  mathfu::Quaternion<T> quaternion(static_cast<T>(0.19), static_cast<T>(0.38),
-                                   static_cast<T>(0.76), static_cast<T>(0.50));
-  quaternion[0] = static_cast<T>(0.50);
-  quaternion[1] = static_cast<T>(0.76);
-  quaternion[2] = static_cast<T>(0.38);
-  quaternion[3] = static_cast<T>(0.19);
-  EXPECT_EQ(static_cast<T>(0.50), quaternion[0]);
-  EXPECT_EQ(static_cast<T>(0.76), quaternion[1]);
-  EXPECT_EQ(static_cast<T>(0.38), quaternion[2]);
-  EXPECT_EQ(static_cast<T>(0.19), quaternion[3]);
-}
-TEST_ALL_F(NonConstAccessor);
-
-// Test accessing the scalar component of the quaternion using the scalar
-// accessor.
-template <class T>
-void ScalarAccessor_Test(const T& precision) {
-  (void)precision;
-  mathfu::Quaternion<T> quaternion(static_cast<T>(0.50), static_cast<T>(0.76),
-                                   static_cast<T>(0.38), static_cast<T>(0.19));
-  EXPECT_EQ(static_cast<T>(0.50), quaternion.scalar());
-}
-TEST_ALL_F(ScalarAccessor);
-
-// Test accessing the scalar component of the quaternion using the const scalar
-// accessor.
-template <class T>
-void ConstScalarAccessor_Test(const T& precision) {
-  (void)precision;
-  const mathfu::Quaternion<T> quaternion(
-      static_cast<T>(0.50), static_cast<T>(0.76), static_cast<T>(0.38),
-      static_cast<T>(0.19));
-  EXPECT_EQ(static_cast<T>(0.50), quaternion.scalar());
-}
-TEST_ALL_F(ConstScalarAccessor);
-
-// Test mutating the scalar component of the quaternion using the scalar
-// mutator.
-template <class T>
-void ScalarMutator_Test(const T& precision) {
-  (void)precision;
-  mathfu::Quaternion<T> quaternion;
-  quaternion.set_scalar(static_cast<T>(0.38));
-  EXPECT_EQ(static_cast<T>(0.38), quaternion[0]);
-}
-TEST_ALL_F(ScalarMutator);
-
-// Test accessing elements of the quaternion using the vector accessor.
-template <class T>
-void VectorAccessor_Test(const T& precision) {
-  (void)precision;
-  mathfu::Quaternion<T> quaternion(static_cast<T>(0.50), static_cast<T>(0.76),
-                                   static_cast<T>(0.38), static_cast<T>(0.19));
-  EXPECT_EQ(static_cast<T>(0.76), quaternion.vector()[0]);
-  EXPECT_EQ(static_cast<T>(0.38), quaternion.vector()[1]);
-  EXPECT_EQ(static_cast<T>(0.19), quaternion.vector()[2]);
-}
-TEST_ALL_F(VectorAccessor);
-
-// Test accessing elements of the quaternion using the const vector accessor.
-template <class T>
-void ConstVectorAccessor_Test(const T& precision) {
-  (void)precision;
-  const mathfu::Quaternion<T> quaternion(
-      static_cast<T>(0.50), static_cast<T>(0.76), static_cast<T>(0.38),
-      static_cast<T>(0.19));
-  EXPECT_EQ(static_cast<T>(0.76), quaternion.vector()[0]);
-  EXPECT_EQ(static_cast<T>(0.38), quaternion.vector()[1]);
-  EXPECT_EQ(static_cast<T>(0.19), quaternion.vector()[2]);
-}
-TEST_ALL_F(ConstVectorAccessor);
-
-// Test mutating the vector component of the quaternion using the vector
-// mutator.
-template <class T>
-void VectorMutator_Test(const T& precision) {
-  (void)precision;
-  mathfu::Quaternion<T> quaternion;
-  quaternion.set_vector(mathfu::Vector<T, 3>(
-      static_cast<T>(0.38), static_cast<T>(0.76), static_cast<T>(0.50)));
-  EXPECT_EQ(static_cast<T>(0.38), quaternion.vector()[0]);
-  EXPECT_EQ(static_cast<T>(0.76), quaternion.vector()[1]);
-  EXPECT_EQ(static_cast<T>(0.50), quaternion.vector()[2]);
-}
-TEST_ALL_F(VectorMutator);
-
-// This will test converting a Quaternion to and from Angle/Axis,
-// Euler Angles, and Matrices
-template <class T>
-void Conversion_Test(const T& precision) {
-  mathfu::Vector<T, 3> angles(static_cast<T>(1.5), static_cast<T>(2.3),
-                              static_cast<T>(0.6));
-  // This will create a Quaternion from Euler Angles, convert back to
-  // Euler Angles, and verify that they match
-  mathfu::Quaternion<T> qea(mathfu::Quaternion<T>::FromEulerAngles(angles));
-  mathfu::Vector<T, 3> convertedAngles(qea.ToEulerAngles());
-  EXPECT_NEAR(angles[0], M_PI + convertedAngles[0], precision);
-  EXPECT_NEAR(angles[1], M_PI - convertedAngles[1], precision);
-  EXPECT_NEAR(angles[2], M_PI + convertedAngles[2], precision);
-  // This will create a Quaternion from Axis Angle, convert back to
-  // Axis Angle, and verify that they match.
-  mathfu::Vector<T, 3> axis(static_cast<T>(4.3), static_cast<T>(7.6),
-                            static_cast<T>(1.2));
-  axis.Normalize();
-  T angle = static_cast<T>(1.2);
-  mathfu::Quaternion<T> qaa(mathfu::Quaternion<T>::FromAngleAxis(angle, axis));
-  mathfu::Vector<T, 3> convertedAxis;
-  T convertedAngle;
-  qaa.ToAngleAxis(&convertedAngle, &convertedAxis);
-  EXPECT_NEAR(angle, convertedAngle, precision);
-  EXPECT_NEAR(axis[0], convertedAxis[0], precision);
-  EXPECT_NEAR(axis[1], convertedAxis[1], precision);
-  EXPECT_NEAR(axis[2], convertedAxis[2], precision);
-  // This will create a Quaternion from a Matrix, convert back to a Matrix,
-  // and verify that they match.
-  mathfu::Matrix<T, 3> rx(1, 0, 0, 0, cos(angles[0]), sin(angles[0]), 0,
-                          -sin(angles[0]), cos(angles[0]));
-  mathfu::Matrix<T, 3> ry(cos(angles[1]), 0, -sin(angles[1]), 0, 1, 0,
-                          sin(angles[1]), 0, cos(angles[1]));
-  mathfu::Matrix<T, 3> rz(cos(angles[2]), sin(angles[2]), 0, -sin(angles[2]),
-                          cos(angles[2]), 0, 0, 0, 1);
-  mathfu::Matrix<T, 3> m(rz * ry * rx);
-  mathfu::Quaternion<T> qm(mathfu::Quaternion<T>::FromMatrix(m));
-  mathfu::Matrix<T, 3> convertedM(qm.ToMatrix());
-  for (int i = 0; i < 9; ++i) EXPECT_NEAR(m[i], convertedM[i], precision);
-}
-TEST_ALL_F(Conversion);
-
-// This will test inverting a quaternion and verify that their combination
-// corresponds to a rotation of 0.
-template <class T>
-void Inverse_Test(const T& precision) {
-  mathfu::Quaternion<T> q(static_cast<T>(1.4), static_cast<T>(6.3),
-                          static_cast<T>(8.5), static_cast<T>(5.9));
-  mathfu::Vector<T, 3> v((q.Inverse() * q).ToEulerAngles());
-  EXPECT_NEAR(0, v[0], precision);
-  EXPECT_NEAR(0, v[1], precision);
-  EXPECT_NEAR(0, v[2], precision);
-}
-TEST_ALL_F(Inverse);
-
-// This will test the multiplication of quaternions.
-template <class T>
-void Mult_Test(const T& precision) {
-  mathfu::Vector<T, 3> axis(static_cast<T>(4.3), static_cast<T>(7.6),
-                            static_cast<T>(1.2));
-  axis.Normalize();
-  T angle1 = static_cast<T>(1.2), angle2 = static_cast<T>(0.7),
-    angle3 = angle2 + precision * 10;
-  mathfu::Quaternion<T> qaa1(
-      mathfu::Quaternion<T>::FromAngleAxis(angle1, axis));
-  mathfu::Quaternion<T> qaa2(
-      mathfu::Quaternion<T>::FromAngleAxis(angle2, axis));
-  mathfu::Quaternion<T> qaa3(
-      mathfu::Quaternion<T>::FromAngleAxis(angle3, axis));
-  mathfu::Vector<T, 3> convertedAxis;
-  T convertedAngle;
-  // This will verify that multiplying two quaternions corresponds to the sum
-  // of the rotations.
-  (qaa1 * qaa2).ToAngleAxis(&convertedAngle, &convertedAxis);
-  EXPECT_NEAR(angle1 + angle2, convertedAngle, precision);
-  // This will verify that multiplying a quaternions with a scalar corresponds
-  // to scaling the rotation.
-  (qaa1 * 2).ToAngleAxis(&convertedAngle, &convertedAxis);
-  EXPECT_NEAR(angle1 * 2, convertedAngle, precision);
-  mathfu::Vector<T, 3> v(3.5f, 6.4f, 7.0f);
-  mathfu::Vector<T, 4> v4(3.5f, 6.4f, 7.0f, 0.0f);
-  // This will verify that multiplying by a vector corresponds to applying
-  // the rotation to that vector.
-  mathfu::Vector<T, 3> quatRotatedV(qaa1 * v);
-  mathfu::Vector<T, 3> matRotatedV(qaa1.ToMatrix() * v);
-  mathfu::Vector<T, 4> mat4RotatedV(qaa1.ToMatrix4() * v4);
-  EXPECT_NEAR(quatRotatedV[0], matRotatedV[0], 10 * precision);
-  EXPECT_NEAR(quatRotatedV[1], matRotatedV[1], 10 * precision);
-  EXPECT_NEAR(quatRotatedV[2], matRotatedV[2], 10 * precision);
-
-  EXPECT_NEAR(quatRotatedV[0], mat4RotatedV[0], 10 * precision);
-  EXPECT_NEAR(quatRotatedV[1], mat4RotatedV[1], 10 * precision);
-  EXPECT_NEAR(quatRotatedV[2], mat4RotatedV[2], 10 * precision);
-  // This will verify that interpolating two quaternions corresponds to
-  // interpolating the angle.
-  mathfu::Quaternion<T> slerp1(mathfu::Quaternion<T>::Slerp(qaa1, qaa2, 0.5));
-  slerp1.ToAngleAxis(&convertedAngle, &convertedAxis);
-  EXPECT_NEAR(.5 * (angle1 + angle2), convertedAngle, precision);
-  mathfu::Quaternion<T> slerp2(mathfu::Quaternion<T>::Slerp(qaa2, qaa3, 0.5));
-  slerp2.ToAngleAxis(&convertedAngle, &convertedAxis);
-  EXPECT_NEAR(.5 * (angle2 + angle3), convertedAngle, precision);
-  mathfu::Quaternion<T> slerp3(mathfu::Quaternion<T>::Slerp(qaa2, qaa2, 0.5));
-  slerp3.ToAngleAxis(&convertedAngle, &convertedAxis);
-  EXPECT_NEAR(angle2, convertedAngle, precision);
-}
-TEST_ALL_F(Mult);
-
-// This will test the dot product of quaternions.
-template <class T>
-void Dot_Test(const T& precision) {
-  mathfu::Vector<T, 3> axis(static_cast<T>(4.3), static_cast<T>(7.6),
-                            static_cast<T>(1.2));
-  axis.Normalize();
-  T angle1 = static_cast<T>(1.2), angle2 = static_cast<T>(angle1 + M_PI / 2.0),
-    angle3 = static_cast<T>(angle1 + M_PI), angle4 = static_cast<T>(0.7);
-  mathfu::Quaternion<T> qaa1(
-      mathfu::Quaternion<T>::FromAngleAxis(angle1, axis));
-  mathfu::Quaternion<T> qaa2(
-      mathfu::Quaternion<T>::FromAngleAxis(angle2, axis));
-  mathfu::Quaternion<T> qaa3(
-      mathfu::Quaternion<T>::FromAngleAxis(angle3, axis));
-  mathfu::Quaternion<T> qaa4(
-      mathfu::Quaternion<T>::FromAngleAxis(angle4, axis));
-
-  // This will verify that Dotting two quaternions works correctly.
-  EXPECT_NEAR(mathfu::Quaternion<T>::DotProduct(qaa1, qaa1), 1.0, precision);
-  EXPECT_NEAR(mathfu::Quaternion<T>::DotProduct(qaa1, qaa2), sqrt(2.0) / 2.0,
-              precision);
-  EXPECT_NEAR(mathfu::Quaternion<T>::DotProduct(qaa1, qaa3), 0.0, precision);
-  // 2 x acos(dot) should be the angle between two quaternions:
-  EXPECT_NEAR(acos(mathfu::Quaternion<T>::DotProduct(qaa1, qaa4)) * 2.0,
-              angle1 - angle4, precision);
-}
-TEST_ALL_F(Dot);
-
-// This will test normalization of quaternions.
-template <class T>
-void Normalize_Test(const T& precision) {
-  mathfu::Quaternion<T> quat_1(static_cast<T>(12), static_cast<T>(0),
-                               static_cast<T>(0), static_cast<T>(0));
-  const mathfu::Quaternion<T> const_quat_1 = quat_1;
-  const mathfu::Quaternion<T> normalized_quat_1 = const_quat_1.Normalized();
-  quat_1.Normalize();
-  mathfu::Quaternion<T> reference_quat_1(static_cast<T>(1), static_cast<T>(0),
-                                         static_cast<T>(0), static_cast<T>(0));
-  EXPECT_NEAR(reference_quat_1[0], quat_1[0], precision);
-  EXPECT_NEAR(reference_quat_1[1], quat_1[1], precision);
-  EXPECT_NEAR(reference_quat_1[2], quat_1[2], precision);
-  EXPECT_NEAR(reference_quat_1[3], quat_1[3], precision);
-  EXPECT_NEAR(reference_quat_1[0], normalized_quat_1[0], precision);
-  EXPECT_NEAR(reference_quat_1[1], normalized_quat_1[1], precision);
-  EXPECT_NEAR(reference_quat_1[2], normalized_quat_1[2], precision);
-  EXPECT_NEAR(reference_quat_1[3], normalized_quat_1[3], precision);
-
-  mathfu::Quaternion<T> quat_2(static_cast<T>(123), static_cast<T>(123),
-                               static_cast<T>(123), static_cast<T>(123));
-  mathfu::Quaternion<T> normalized_quat_2 = quat_2.Normalized();
-  quat_2.Normalize();
-  mathfu::Quaternion<T> reference_quat_2(
-      static_cast<T>(sqrt(.25)), static_cast<T>(sqrt(.25)),
-      static_cast<T>(sqrt(.25)), static_cast<T>(sqrt(.25)));
-  EXPECT_NEAR(reference_quat_2[0], quat_2[0], precision);
-  EXPECT_NEAR(reference_quat_2[1], quat_2[1], precision);
-  EXPECT_NEAR(reference_quat_2[2], quat_2[2], precision);
-  EXPECT_NEAR(reference_quat_2[3], quat_2[3], precision);
-  EXPECT_NEAR(reference_quat_2[0], normalized_quat_2[0], precision);
-  EXPECT_NEAR(reference_quat_2[1], normalized_quat_2[1], precision);
-  EXPECT_NEAR(reference_quat_2[2], normalized_quat_2[2], precision);
-  EXPECT_NEAR(reference_quat_2[3], normalized_quat_2[3], precision);
-}
-TEST_ALL_F(Normalize);
-
-// This will test normalization of quaternions.
-template <class T>
-void RotateFromTo_Test(const T& precision) {
-  mathfu::Vector<T, 3> x_axis = mathfu::Vector<T, 3>(
-      static_cast<T>(1), static_cast<T>(0), static_cast<T>(0));
-  mathfu::Vector<T, 3> y_axis = mathfu::Vector<T, 3>(
-      static_cast<T>(0), static_cast<T>(1), static_cast<T>(0));
-  mathfu::Vector<T, 3> z_axis = mathfu::Vector<T, 3>(
-      static_cast<T>(0), static_cast<T>(0), static_cast<T>(1));
-
-  mathfu::Quaternion<T> x_to_y =
-      mathfu::Quaternion<T>::RotateFromTo(x_axis, y_axis);
-  mathfu::Quaternion<T> y_to_z =
-      mathfu::Quaternion<T>::RotateFromTo(y_axis, z_axis);
-  mathfu::Quaternion<T> z_to_x =
-      mathfu::Quaternion<T>::RotateFromTo(z_axis, x_axis);
-
-  // Check some axis rotations:
-  // By definition, rotateFromTo(v1, v2) * v2 should always equal v2.
-  // if v1 and v2 are 90 degrees apart (as they are in the case of axes)
-  // then applying the same rotation twice should invert the vector.
-  mathfu::Vector<T, 3> x_to_y_result = x_to_y * x_axis;
-  mathfu::Vector<T, 3> x_to_y_twice_result = x_to_y * x_to_y * x_axis;
-  EXPECT_NEAR_VEC3(x_to_y_result, y_axis, precision);
-  EXPECT_NEAR_VEC3(x_to_y_twice_result, -x_axis, precision);
-
-  mathfu::Vector<T, 3> y_to_z_result = y_to_z * y_axis;
-  mathfu::Vector<T, 3> y_to_z_twice_result = y_to_z * y_to_z * y_axis;
-  EXPECT_NEAR_VEC3(y_to_z_result, z_axis, precision);
-  EXPECT_NEAR_VEC3(y_to_z_twice_result, -y_axis, precision);
-
-  mathfu::Vector<T, 3> z_to_x_result = z_to_x * z_axis;
-  mathfu::Vector<T, 3> z_to_x_twice_result = z_to_x * z_to_x * z_axis;
-  EXPECT_NEAR_VEC3(z_to_x_result, x_axis, precision);
-  EXPECT_NEAR_VEC3(z_to_x_twice_result, -z_axis, precision);
-
-  // Try some weirder vectors:
-  mathfu::Vector<T, 3> arbitrary_1 = mathfu::Vector<T, 3>(
-      static_cast<T>(2), static_cast<T>(-5), static_cast<T>(9));
-  mathfu::Vector<T, 3> arbitrary_2 = mathfu::Vector<T, 3>(
-      static_cast<T>(-1), static_cast<T>(3), static_cast<T>(16));
-
-  mathfu::Quaternion<T> arbitrary_to_arbitrary =
-      mathfu::Quaternion<T>::RotateFromTo(arbitrary_1, arbitrary_2);
-
-  mathfu::Vector<T, 3> arbitrary_1_to_2 = arbitrary_to_arbitrary * arbitrary_1;
-  arbitrary_1_to_2.Normalize();
-  mathfu::Vector<T, 3> arbitrary_2_normalized = arbitrary_2.Normalized();
-
-  EXPECT_NEAR_VEC3(arbitrary_1_to_2, arbitrary_2_normalized, precision);
-
-  // Using RotateFromTo on one vector should give us the identity quaternion:
-  mathfu::Quaternion<T> identity =
-      mathfu::Quaternion<T>::RotateFromTo(arbitrary_1, arbitrary_1);
-
-  mathfu::Vector<T, 3> arbitrary_2_identity = identity * arbitrary_2;
-  EXPECT_NEAR_VEC3(arbitrary_2_identity, arbitrary_2, precision);
-
-  // Using RotateFromTo on an inverted vector should give a 180 degree rotation:
-  mathfu::Quaternion<T> reverse =
-      mathfu::Quaternion<T>::RotateFromTo(arbitrary_1, -arbitrary_1);
-
-  // Relaxing the precision slightly, because there are a lot of chained
-  // float operations in here.
-  mathfu::Vector<T, 3> arbitrary_1_reversed = reverse * arbitrary_1;
-  EXPECT_NEAR_VEC3(arbitrary_1_reversed, -arbitrary_1, precision * 2.0);
-}
-TEST_ALL_F(RotateFromTo);
-
-// Test the compilation of basic quaternion operations given in the sample
-// file. This will test interpolating two rotations.
-TEST_F(QuaternionTests, QuaternionSample) {
-  using namespace mathfu;
-  /// @doxysnippetstart Chapter03_Quaternions.md Quaternion_Sample
-  // Use radians for angles
-  Vector<float, 3> angles1(0.66f, 1.3f, 0.76f);
-  Vector<float, 3> angles2(0.85f, 0.33f, 1.6f);
-
-  Quaternion<float> quat1 = Quaternion<float>::FromEulerAngles(angles1);
-  Quaternion<float> quat2 = Quaternion<float>::FromEulerAngles(angles2);
-
-  Quaternion<float> quatSlerp = Quaternion<float>::Slerp(quat1, quat2, 0.5);
-  Vector<float, 3> angleSlerp = quatSlerp.ToEulerAngles();
-  /// @doxysnippetend
-  const float precision = 1e-2f;
-  EXPECT_NEAR(0.93f, angleSlerp[0], precision);
-  EXPECT_NEAR(0.82f, angleSlerp[1], precision);
-  EXPECT_NEAR(1.33f, angleSlerp[2], precision);
-}
-
-// Test that the quaternion identity constants give the identity transform.
-TEST_F(QuaternionTests, IdentityConst) {
-  EXPECT_EQ_QUAT(mathfu::kQuatIdentityf, mathfu::Quaternion<float>::identity);
-  EXPECT_EQ_QUAT(mathfu::kQuatIdentityf,
-                 mathfu::Quaternion<float>(1.0f, 0.0f, 0.0f, 0.0f));
-  EXPECT_EQ(mathfu::kQuatIdentityf.ToEulerAngles(), mathfu::kZeros3f);
-
-  EXPECT_EQ_QUAT(mathfu::kQuatIdentityd, mathfu::Quaternion<double>::identity);
-  EXPECT_EQ_QUAT(mathfu::kQuatIdentityd,
-                 mathfu::Quaternion<double>(1.0, 0.0, 0.0, 0.0));
-  EXPECT_EQ(mathfu::kQuatIdentityd.ToEulerAngles(), mathfu::kZeros3d);
-}
-
-int main(int argc, char** argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  printf("%s (%s)\n", argv[0], MATHFU_BUILD_OPTIONS_STRING);
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/AndroidManifest.xml
deleted file mode 100644
index 6b0e4f5..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.quaternion_simd_no_padding_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="quaternion_simd_no_padding_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/jni/Android.mk
deleted file mode 100644
index a77075b..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=quaternion_simd_no_padding_test
-MATHFU_LIB:=libmathfu_simd_no_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/jni/Application.mk
deleted file mode 100644
index 4cdf33f..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=quaternion_simd_no_padding_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/res/values/strings.xml
deleted file mode 100644
index b7c7203..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_no_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">quaternion_simd_no_padding_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/AndroidManifest.xml
deleted file mode 100644
index fcbc69e..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.quaternion_simd_padding_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="quaternion_simd_padding_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/jni/Android.mk
deleted file mode 100644
index 79b5f54..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=quaternion_simd_padding_test
-MATHFU_LIB:=libmathfu_simd_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/jni/Application.mk
deleted file mode 100644
index fd9be72..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=quaternion_simd_padding_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/res/values/strings.xml
deleted file mode 100644
index 4d5f984..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/quaternion_test/simd_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">quaternion_simd_padding_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/default/AndroidManifest.xml
deleted file mode 100644
index 24fb417..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/default/jni/Android.mk
deleted file mode 100644
index 5182147..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=vector_test
-MATHFU_LIB:=libmathfu
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/default/jni/Application.mk
deleted file mode 100644
index 2c644a6..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/default/res/values/strings.xml
deleted file mode 100644
index 6267e13..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/default/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/AndroidManifest.xml
deleted file mode 100644
index 4da1282..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_no_simd_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_no_simd_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/jni/Android.mk
deleted file mode 100644
index 3143cda..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=vector_no_simd_test
-MATHFU_LIB:=libmathfu_no_simd
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/jni/Application.mk
deleted file mode 100644
index 1b85978..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_no_simd_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/res/values/strings.xml
deleted file mode 100644
index b0a23fb..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/no_simd/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_no_simd_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/AndroidManifest.xml
deleted file mode 100644
index 27760b5..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_simd_no_padding_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_simd_no_padding_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/jni/Android.mk
deleted file mode 100644
index 57d3920..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=vector_simd_no_padding_test
-MATHFU_LIB:=libmathfu_simd_no_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/jni/Application.mk
deleted file mode 100644
index a13b45d..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_simd_no_padding_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/res/values/strings.xml
deleted file mode 100644
index f5c3260..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_no_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_simd_no_padding_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/AndroidManifest.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/AndroidManifest.xml
deleted file mode 100644
index 93f9828..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<!-- BEGIN_INCLUDE(manifest) -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.google.fpl.mathfu.vector_simd_padding_test"
-          android:versionCode="1"
-          android:versionName="1.0">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-
-    <!-- This .apk has no Java code itself, so set hasCode to false. -->
-    <application android:label="@string/app_name" android:hasCode="false">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name"
-                  android:screenOrientation="landscape"
-                  android:configChanges="orientation|keyboardHidden">
-            <!-- Tell NativeActivity the name of the .so -->
-            <meta-data android:name="android.app.lib_name"
-                       android:value="vector_simd_padding_test" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
-<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/jni/Android.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/jni/Android.mk
deleted file mode 100644
index 3f0f75e..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/jni/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-LOCAL_PATH:=$(call my-dir)/../..
-LOCAL_TEST_NAME:=vector_simd_padding_test
-MATHFU_LIB:=libmathfu_simd_padding
-include $(LOCAL_PATH)/../android_common.mk
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/jni/Application.mk b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/jni/Application.mk
deleted file mode 100644
index 1efc1c5..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/jni/Application.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-include $(NDK_PROJECT_PATH)/../../application_common.mk
-APP_MODULES:=vector_simd_padding_test
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/res/values/strings.xml b/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/res/values/strings.xml
deleted file mode 100644
index ba084f3..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/simd_padding/res/values/strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2014 Google Inc. All rights reserved.
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-<resources>
-    <string name="app_name">vector_simd_padding_test</string>
-</resources>
diff --git a/third_party/mathfu-1.1.0/unit_tests/vector_test/vector_test.cpp b/third_party/mathfu-1.1.0/unit_tests/vector_test/vector_test.cpp
deleted file mode 100644
index b1676f6..0000000
--- a/third_party/mathfu-1.1.0/unit_tests/vector_test/vector_test.cpp
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
-* Copyright 2014 Google Inc. All rights reserved.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "mathfu/vector.h"
-#include "mathfu/constants.h"
-
-#include "gtest/gtest.h"
-
-#include "precision.h"
-
-#include <sstream>
-#include <string>
-
-class VectorTests : public ::testing::Test {
- protected:
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-// This will automatically generate tests for each template parameter.
-#define TEST_ALL_F(MY_TEST)                      \
-  TEST_F(VectorTests, MY_TEST##_float_2) {       \
-    MY_TEST##_Test<float, 2>(FLOAT_PRECISION);   \
-  }                                              \
-  TEST_F(VectorTests, MY_TEST##_double_2) {      \
-    MY_TEST##_Test<double, 2>(DOUBLE_PRECISION); \
-  }                                              \
-  TEST_F(VectorTests, MY_TEST##_float_3) {       \
-    MY_TEST##_Test<float, 3>(FLOAT_PRECISION);   \
-  }                                              \
-  TEST_F(VectorTests, MY_TEST##_double_3) {      \
-    MY_TEST##_Test<double, 3>(DOUBLE_PRECISION); \
-  }                                              \
-  TEST_F(VectorTests, MY_TEST##_float_4) {       \
-    MY_TEST##_Test<float, 4>(FLOAT_PRECISION);   \
-  }                                              \
-  TEST_F(VectorTests, MY_TEST##_double_4) {      \
-    MY_TEST##_Test<double, 4>(DOUBLE_PRECISION); \
-  }                                              \
-  TEST_F(VectorTests, MY_TEST##_float_5) {       \
-    MY_TEST##_Test<float, 5>(FLOAT_PRECISION);   \
-  }                                              \
-  TEST_F(VectorTests, MY_TEST##_double_5) {      \
-    MY_TEST##_Test<double, 5>(DOUBLE_PRECISION); \
-  }
-
-#define TEST_ALL_INTS_F(MY_INT_TEST)                                      \
-  TEST_F(VectorTests, MY_INT_TEST##_2) { MY_INT_TEST##_Test<int, 2>(0); } \
-  TEST_F(VectorTests, MY_INT_TEST##_3) { MY_INT_TEST##_Test<int, 3>(0); } \
-  TEST_F(VectorTests, MY_INT_TEST##_4) { MY_INT_TEST##_Test<int, 4>(0); } \
-  TEST_F(VectorTests, MY_INT_TEST##_5) { MY_INT_TEST##_Test<int, 5>(0); }
-
-// This will automatically generate tests for each scalar template parameter.
-#define TEST_SCALAR_F(MY_TEST)                \
-  TEST_F(VectorTests, MY_TEST##_float) {      \
-    MY_TEST##_Test<float>(FLOAT_PRECISION);   \
-  }                                           \
-  TEST_F(VectorTests, MY_TEST##_double) {     \
-    MY_TEST##_Test<double>(DOUBLE_PRECISION); \
-  }
-
-// This will automatically generate tests for each scalar template parameter.
-#define TEST_SCALAR_AND_INT_F(MY_TEST)        \
-  TEST_F(VectorTests, MY_TEST##_float) {      \
-    MY_TEST##_Test<float>(FLOAT_PRECISION);   \
-  }                                           \
-  TEST_F(VectorTests, MY_TEST##_double) {     \
-    MY_TEST##_Test<double>(DOUBLE_PRECISION); \
-  }                                           \
-  TEST_F(VectorTests, MY_TEST##_int) { MY_TEST##_Test<int>(0); }
-
-// Tests float, double, and integer constants in one line.
-#define VECTOR_TEST_CONSTANT_EQ(kConst, index, value)                       \
-  EXPECT_FLOAT_EQ(mathfu::kConst##f[(index)], static_cast<float>(value));   \
-  EXPECT_DOUBLE_EQ(mathfu::kConst##d[(index)], static_cast<double>(value)); \
-  EXPECT_EQ(mathfu::kConst##i[(index)], static_cast<int>(value))
-
-template <class T, int d>
-std::string FormatVector(const char* expr, const mathfu::Vector<T, d>& v) {
-  std::string ret(expr);
-  ret += "(";
-  for (int32_t i = 0; i < d; ++i) {
-    std::stringstream ss;
-    ss << v[i];
-    ret += ss.str();
-    if (i != d - 1) ret += ", ";
-  }
-  ret += ")";
-  return ret;
-}
-
-// A predicate-formatter for asserting that compares 2 vectors are equal.
-template <class T, int d>
-::testing::AssertionResult AssertVectorEqual(const char* m_expr,
-                                             const char* n_expr,
-                                             const mathfu::Vector<T, d>& v1,
-                                             const mathfu::Vector<T, d>& v2) {
-  for (int32_t i = 0; i < d; ++i) {
-    if (v1[i] != v2[i]) {
-      return ::testing::AssertionFailure()
-             << FormatVector(m_expr, v1) << " and " << FormatVector(n_expr, v2)
-             << " are not same value.";
-    }
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-// A predicate-formatter for asserting that compares 2 vectors are nealy equal
-// with an error of abs_error.
-template <class T, int d>
-::testing::AssertionResult AssertVectorNear(const char* expr1,
-                                            const char* expr2,
-                                            const char* abs_error_expr,
-                                            const mathfu::Vector<T, d>& v1,
-                                            const mathfu::Vector<T, d>& v2,
-                                            const T abs_error) {
-  T diff;
-  for (int32_t i = 0; i < d; ++i) {
-    diff = fabs(v1[i] - v2[i]);
-    if (diff > abs_error) {
-      return ::testing::AssertionFailure()
-             << "The difference between " << FormatVector(expr1, v1) << " and "
-             << FormatVector(expr2, v2) << " is " << diff << ", which exceeds "
-             << abs_error_expr;
-    }
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-// This will test initialization by passing in values. The template parameter d
-// corresponds to the size of the vector.
-template <class T, int d>
-void Initialization_Test(const T& precision) {
-  // This will test initialization of the vector using a random single value.
-  // The expected result is that all entries equal the given value.
-  mathfu::Vector<T, d> vector_splat(static_cast<T>(3.1));
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(3.1, vector_splat[i], precision);
-  }
-  T x[d];
-  for (int i = 0; i < d; ++i) {
-    x[i] = rand() / static_cast<T>(RAND_MAX) * 100.f;
-  }
-  // This will test initialization of the vector using a c style array of
-  // values.
-  mathfu::Vector<T, d> vector_arr(x);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x[i], vector_arr[i], precision);
-  }
-  // This will test copy constructor making sure that the new matrix equals
-  // the old one.
-  mathfu::Vector<T, d> vector_copy(vector_arr);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x[i], vector_copy[i], precision);
-  }
-  // This will make sure the copy was deep and changing the values of the
-  // copied matrix does not effect the original.
-  vector_copy -= mathfu::Vector<T, d>(1);
-  EXPECT_NE(vector_copy[0], vector_arr[0]);
-
-  // Construct a vector from an integer vector.
-  mathfu::Vector<int, d> integer_vector;
-  for (int i = 0; i < d; ++i) {
-    integer_vector[i] = i;
-  }
-  mathfu::Vector<T, d> other_vector(integer_vector);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_EQ(static_cast<int>(other_vector[i]), integer_vector[i]);
-  }
-}
-TEST_ALL_F(Initialization)
-
-// This will test initialization by specifying all values explicitly.
-template <class T>
-void InitializationPerDimension_Test(const T& precision) {
-  mathfu::Vector<T, 2> f2_vector(static_cast<T>(5.3), static_cast<T>(7.1));
-  EXPECT_NEAR(5.3, f2_vector[0], precision);
-  EXPECT_NEAR(7.1, f2_vector[1], precision);
-  mathfu::Vector<T, 3> f3_vector(static_cast<T>(4.3), static_cast<T>(1.1),
-                                 static_cast<T>(3.2));
-  EXPECT_NEAR(4.3, f3_vector[0], precision);
-  EXPECT_NEAR(1.1, f3_vector[1], precision);
-  EXPECT_NEAR(3.2, f3_vector[2], precision);
-  mathfu::Vector<T, 4> f4_vector(static_cast<T>(2.3), static_cast<T>(4.6),
-                                 static_cast<T>(9.2), static_cast<T>(15.5));
-  EXPECT_NEAR(2.3, f4_vector[0], precision);
-  EXPECT_NEAR(4.6, f4_vector[1], precision);
-  EXPECT_NEAR(9.2, f4_vector[2], precision);
-  EXPECT_NEAR(15.5, f4_vector[3], precision);
-}
-TEST_SCALAR_F(InitializationPerDimension);
-
-// Test initialization from a packed vector.
-template <class T, int d>
-void InitializationPacked_Test(const T& precision) {
-  (void)precision;
-  mathfu::VectorPacked<T, d> packed;
-  for (int i = 0; i < d; ++i) {
-    packed.data[i] = static_cast<T>(i);
-  }
-  mathfu::Vector<T, d> unpacked(packed);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(packed.data[i], unpacked[i], static_cast<T>(0)) << "Element "
-                                                                << i;
-  }
-}
-TEST_ALL_F(InitializationPacked);
-
-// Test vector packing.
-template <class T, int d>
-void PackedSerialization_Test(const T& precision) {
-  (void)precision;
-  mathfu::Vector<T, d> unpacked;
-  for (int i = 0; i < d; ++i) {
-    unpacked[i] = static_cast<T>(i);
-  }
-
-  mathfu::VectorPacked<T, d> packed_construction(unpacked);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(unpacked[i], packed_construction.data[i], static_cast<T>(0))
-        << "Element " << i;
-  }
-
-  mathfu::VectorPacked<T, d> packed_assignment;
-  packed_assignment = unpacked;
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(unpacked[i], packed_assignment.data[i], static_cast<T>(0))
-        << "Element " << i;
-  }
-}
-TEST_ALL_F(PackedSerialization);
-
-// This will test the Addition and Subtraction of vectors. The template
-// parameter d corresponds to the size of the vector.
-template <class T, int d>
-void AddSub_Test(const T& precision) {
-  T x1[d], x2[d];
-  for (int i = 0; i < d; ++i) {
-    x1[i] = rand() / static_cast<T>(RAND_MAX) * 100.f;
-  }
-  for (int i = 0; i < d; ++i) {
-    x2[i] = rand() / static_cast<T>(RAND_MAX) * 100.f;
-  }
-  mathfu::Vector<T, d> vector1(x1), vector2(x2);
-  // This will test the negation of a vector and make sure each element is
-  // negated.
-  mathfu::Vector<T, d> neg_vector1(-vector1);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(-x1[i], neg_vector1[i], precision);
-  }
-  // This will test the addition of vectors and make such each element is
-  // equal to the sum of the input values.
-  mathfu::Vector<T, d> sum_vector(vector1 + vector2);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x1[i] + x2[i], sum_vector[i], precision);
-  }
-  // This will test the subtraction of vectors and make such each element is
-  // equal to the difference of the input values.
-  mathfu::Vector<T, d> diff_vector(vector1 - vector2);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x1[i] - x2[i], diff_vector[i], precision);
-  }
-}
-TEST_ALL_F(AddSub)
-
-// This will test the multiplication of vectors by vectors and scalars. The
-// template parameter d corresponds to the size of the vector.
-template <class T, int d>
-void Mult_Test(const T& precision) {
-  T x1[d], x2[d], scalar(static_cast<T>(1.4));
-  for (int i = 0; i < d; ++i) x1[i] = rand() / static_cast<T>(RAND_MAX);
-  for (int i = 0; i < d; ++i) x2[i] = rand() / static_cast<T>(RAND_MAX);
-  mathfu::Vector<T, d> vector1(x1), vector2(x2);
-  // This will test the Hadamard Product of two vectors and verify that each
-  // element is the product of the input elements.
-  mathfu::Vector<T, d> mult_vec(
-      mathfu::Vector<T, d>::HadamardProduct(vector1, vector2));
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x1[i] * x2[i], mult_vec[i], precision);
-  }
-  // This will test multiplication by a scalar and verify that each
-  // element is the input element multiplied by the scalar.
-  mathfu::Vector<T, d> smult_vec1(vector1 * scalar);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x1[i] * 1.4, smult_vec1[i], precision);
-  }
-  mathfu::Vector<T, d> smult_vec2(scalar * vector2);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x2[i] * 1.4, smult_vec2[i], precision);
-  }
-  // This will test the dot product of two vectors and verify the result
-  // is mathematically correct.
-  T my_dot = 0;
-  for (int i = 0; i < d; ++i) my_dot += x1[i] * x2[i];
-  T vec_dot = mathfu::Vector<T, d>::DotProduct(vector1, vector2);
-  EXPECT_NEAR(my_dot, vec_dot, precision);
-}
-TEST_ALL_F(Mult)
-
-// This will test the division of vectors by vectors and scalars.  The template
-// parameter d coorresponds to the size of the vector.
-template <class T, int d>
-void Division_Test(const T& precision) {
-  T x1[d], x2[d], scalar(static_cast<T>(1.4));
-  for (int i = 0; i < d; ++i) x1[i] = (rand() / static_cast<T>(RAND_MAX)) + 1;
-  for (int i = 0; i < d; ++i) x2[i] = (rand() / static_cast<T>(RAND_MAX)) + 1;
-  mathfu::Vector<T, d> vector1(x1), vector2(x2);
-  // Test vector division.
-  mathfu::Vector<T, d> divided_component_wise(vector1 / vector2);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x1[i] / x2[i], divided_component_wise[i], precision);
-  }
-  // Test division by a scalar.
-  mathfu::Vector<T, d> divided_by_scalar(vector1 / scalar);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x1[i] / scalar, divided_by_scalar[i], precision);
-  }
-}
-TEST_ALL_F(Division)
-
-// This will test normalizing a vector. The template parameter d corresponds to
-// the size of the vector.
-template <class T, int d>
-void Norm_Test(const T& precision) {
-  T x[d];
-  for (int i = 0; i < d; ++i) x[i] = rand() / static_cast<T>(RAND_MAX);
-  mathfu::Vector<T, d> vector(x);
-  vector.Normalize();
-  // This will verify that the dot product is 1.
-  T dot = mathfu::Vector<T, d>::DotProduct(vector, vector);
-  EXPECT_NEAR(dot, 1, precision);
-}
-TEST_ALL_F(Norm)
-
-// This will test the cross product of two vectors.
-template <class T>
-void Cross_Test(const T& precision) {
-  mathfu::Vector<T, 3> f1_vector(static_cast<T>(1.1), static_cast<T>(4.5),
-                                 static_cast<T>(9.8));
-  mathfu::Vector<T, 3> f2_vector(-static_cast<T>(1.4), static_cast<T>(9.5),
-                                 static_cast<T>(3.2));
-  f1_vector.Normalize();
-  f2_vector.Normalize();
-  mathfu::Vector<T, 3> fcross_vector(
-      mathfu::Vector<T, 3>::CrossProduct(f1_vector, f2_vector));
-  // This will verify that v1*(v1xv2) and v2*(v1xv2) are 0.
-  T f1_dot = mathfu::Vector<T, 3>::DotProduct(fcross_vector, f1_vector);
-  T f2_dot = mathfu::Vector<T, 3>::DotProduct(fcross_vector, f2_vector);
-  EXPECT_NEAR(f1_dot, 0, precision * 10);
-  EXPECT_NEAR(f2_dot, 0, precision * 10);
-}
-TEST_SCALAR_F(Cross)
-
-// Create a vector with random values between 0~1.
-template <class T, int d>
-mathfu::Vector<T, d> RandomVector() {
-  T x[d];
-  for (int i = 0; i < d; ++i) {
-    x[i] = rand() / static_cast<T>(RAND_MAX);
-  }
-  return mathfu::Vector<T, d>(x);
-}
-
-// This will test an equal lerp of two vectors gives their average.
-template <class T, int d>
-void LerpHalf_Test(const T& precision) {
-  mathfu::Vector<T, d> vector1(RandomVector<T, d>());
-  mathfu::Vector<T, d> vector2(RandomVector<T, d>());
-  mathfu::Vector<T, d> flerp_vector(
-      mathfu::Vector<T, d>::Lerp(vector1, vector2, static_cast<T>(0.5)));
-  // This will verify f1_vector.x + f2_vector.x == 2 * flerp_vector
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(vector1[i] + vector2[i], static_cast<T>(2.0) * flerp_vector[i],
-                precision * 10);
-  }
-}
-TEST_ALL_F(LerpHalf)
-
-// This will test that lerp with weight 0 returns the first vector.
-template <class T, int d>
-void Lerp0_Test(const T& precision) {
-  mathfu::Vector<T, d> vector1(RandomVector<T, d>());
-  mathfu::Vector<T, d> vector2(RandomVector<T, d>());
-  mathfu::Vector<T, d> flerp_vector(
-      mathfu::Vector<T, d>::Lerp(vector1, vector2, static_cast<T>(0.0)));
-  // This will verify f1_vector.x + f2_vector.x == 2 * flerp_vector
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(vector1[i], flerp_vector[i], precision * 10);
-  }
-}
-TEST_ALL_F(Lerp0)
-
-// This will test that lerp with weight 1 returns the second vector.
-template <class T, int d>
-void Lerp1_Test(const T& precision) {
-  mathfu::Vector<T, d> vector1(RandomVector<T, d>());
-  mathfu::Vector<T, d> vector2(RandomVector<T, d>());
-  mathfu::Vector<T, d> flerp_vector(
-      mathfu::Vector<T, d>::Lerp(vector1, vector2, static_cast<T>(1.0)));
-  // This will verify f1_vector.x + f2_vector.x == 2 * flerp_vector
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(vector2[i], flerp_vector[i], precision * 10);
-  }
-}
-TEST_ALL_F(Lerp1)
-
-// This will test initialization by specifying all values explicitly.
-template <class T>
-void Clamp_Test() {
-  const T min = static_cast<T>(-1);
-  const T max = static_cast<T>(8);
-  const T inside = static_cast<T>(7);
-  const T above = static_cast<T>(9);
-  const T below = static_cast<T>(-11);
-
-  EXPECT_EQ(mathfu::Clamp<T>(inside, min, max), inside);
-  EXPECT_EQ(mathfu::Clamp<T>(above, min, max), max);
-  EXPECT_EQ(mathfu::Clamp<T>(below, min, max), min);
-  EXPECT_EQ(mathfu::Clamp<T>(max, min, max), max);
-  EXPECT_EQ(mathfu::Clamp<T>(min, min, max), min);
-}
-TEST_F(VectorTests, Clamp) {
-  Clamp_Test<float>();
-  Clamp_Test<double>();
-  Clamp_Test<int>();
-}
-
-// Tests for int/float/double based lerp.  (i. e. not part of a vector)
-template <class T>
-void Numeric_Lerp_Test(const T& precision) {
-  const T zero = static_cast<T>(0);
-  const T one = static_cast<T>(1);
-
-  const T a = static_cast<T>(10);
-  const T b = static_cast<T>(20);
-  const T midpoint = static_cast<T>(0.5);
-  const T two_fifths = static_cast<T>(0.4);
-  const T seven_tenths = static_cast<T>(0.7);
-  const T midpoint_result = static_cast<T>(15);
-  const T two_fifths_result = static_cast<T>(14);
-  const T seven_tenths_result = static_cast<T>(17);
-
-  EXPECT_EQ(mathfu::Lerp<T>(a, b, zero), a);
-  EXPECT_EQ(mathfu::Lerp<T>(a, b, one), b);
-  EXPECT_EQ(mathfu::Lerp<T>(-a, b, zero), -a);
-  EXPECT_EQ(mathfu::Lerp<T>(-a, b, one), b);
-  EXPECT_EQ(mathfu::Lerp<T>(a, -b, zero), a);
-  EXPECT_EQ(mathfu::Lerp<T>(a, -b, one), -b);
-  EXPECT_EQ(mathfu::Lerp<T>(-a, -b, zero), -a);
-  EXPECT_EQ(mathfu::Lerp<T>(-a, -b, one), -b);
-
-  EXPECT_NE(mathfu::Lerp<T>(a, b, midpoint), a);
-
-  EXPECT_NEAR(mathfu::Lerp<T>(a, b, midpoint), midpoint_result, precision);
-  EXPECT_NEAR(mathfu::Lerp<T>(a, b, two_fifths), two_fifths_result, precision);
-  EXPECT_NEAR(mathfu::Lerp<T>(a, b, seven_tenths), seven_tenths_result,
-              precision);
-}
-TEST_SCALAR_F(Numeric_Lerp)
-
-// Tests the random-in-range function for vectors.
-// Given a pair of vectors, it should return a third vector whose elements
-// are bounded by the corresponding elements in the argument vectors.
-template <class T, int d>
-void Vector_RandomInRange_Test(const T& precision) {
-  (void)precision;
-  mathfu::Vector<T, d> min, max, result1, result2;
-
-  for (int count = 0; count < 100; count++) {
-    for (int i = 0; i < d; i++) {
-      min[i] = -i - 10;
-      max[i] = i * 2 + 2;
-    }
-    result1 = mathfu::Vector<T, d>::RandomInRange(min, max);
-    result2 = mathfu::Vector<T, d>::RandomInRange(max, min);
-    for (int i = 0; i < d; i++) {
-      EXPECT_GE(result1[i], min[i]);
-      EXPECT_LE(result1[i], max[i]);
-
-      EXPECT_GE(result2[i], min[i]);
-      EXPECT_LE(result2[i], max[i]);
-    }
-  }
-}
-TEST_ALL_INTS_F(Vector_RandomInRange)
-
-// Tests the generic Random in Range function in Mathfu.
-template <class T>
-void RandomInRange_Test(const T& precision) {
-  (void)precision;
-  for (int count = 0; count < 100; count++) {
-    T result = mathfu::RandomInRange(static_cast<T>(0), static_cast<T>(100));
-    EXPECT_GE(result, 0);
-    EXPECT_LT(result, 100);
-  }
-  for (int count = 0; count < 100; count++) {
-    T result = mathfu::RandomInRange(static_cast<T>(-100), static_cast<T>(0));
-    EXPECT_GE(result, -100);
-    EXPECT_LE(result, 0);
-  }
-  EXPECT_EQ(0, mathfu::RandomInRange(0, 0));
-  EXPECT_EQ(-5, mathfu::RandomInRange(-5, -5));
-  EXPECT_EQ(23, mathfu::RandomInRange(23, 23));
-}
-TEST_SCALAR_AND_INT_F(RandomInRange)
-
-// This will test initialization by passing in values. The template parameter d
-// corresponds to the size of the vector.
-template <class T, int d>
-void Accessor_Test(const T& precision) {
-  (void)precision;
-  T x[d];
-  for (int i = 0; i < d; ++i) {
-    x[i] = rand() / static_cast<T>(RAND_MAX) * 100.f;
-  }
-
-  mathfu::Vector<T, d> vector(x);
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x[i], vector[i], static_cast<T>(0));
-  }
-  for (int i = 0; i < d; ++i) {
-    EXPECT_NEAR(x[i], vector(i), static_cast<T>(0));
-  }
-}
-TEST_ALL_F(Accessor)
-
-// This will test initialization by passing in values. The template parameter d
-// corresponds to the size of the vector.
-template <class T, int d>
-void Max_Test(const T& precision) {
-  (void)precision;
-  T value1[] = {0, 0, 0, 0, 0};
-  T value2[] = {1, 2, 3, 4, 5};
-  mathfu::Vector<T, d> v1(value1);
-  mathfu::Vector<T, d> v2(value2);
-
-  // vs. zero vector.
-  mathfu::Vector<T, d> v3 = mathfu::Vector<T, d>::Max(v1, v2);
-
-  // Comparing to {1, 2, 3, 4, 5}
-  mathfu::Vector<T, d> r1(value2);
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v3, r1);
-
-  // inverse vs. zero vector.
-  mathfu::Vector<T, d> v4 = mathfu::Vector<T, d>::Max(v2, v1);
-
-  // Comparing to {1, 2, 3, 4, 5}
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v4, r1);
-
-  // vs. negative vector.
-  T negative_value[] = {-1, -2, -3, -4, -5};
-  v2 = mathfu::Vector<T, d>(negative_value);
-  mathfu::Vector<T, d> v5 = mathfu::Vector<T, d>::Max(v1, v2);
-
-  // Comparing to {0, 0, 0, 0, 0}
-  mathfu::Vector<T, d> r2(value1);
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v5, r2);
-
-  // vs. interleaving 2 vectors.
-  T value3[] = {0, 2, 0, 4, 0};
-  T value4[] = {1, 0, 3, 0, 5};
-  v1 = mathfu::Vector<T, d>(value3);
-  v2 = mathfu::Vector<T, d>(value4);
-  mathfu::Vector<T, d> v6 = mathfu::Vector<T, d>::Max(v1, v2);
-
-  // Comparing to {1, 2, 3, 4, 5}
-  mathfu::Vector<T, d> r3(value2);
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v6, r3);
-}
-TEST_ALL_F(Max)
-
-// This will test initialization by passing in values. The template parameter d
-// corresponds to the size of the vector.
-template <class T, int d>
-void Min_Test(const T& precision) {
-  (void)precision;
-  T value1[] = {0, 0, 0, 0, 0};
-  T value2[] = {1, 2, 3, 4, 5};
-  mathfu::Vector<T, d> v1(value1);
-  mathfu::Vector<T, d> v2(value2);
-
-  // vs. zero vector.
-  mathfu::Vector<T, d> v3 = mathfu::Vector<T, d>::Min(v1, v2);
-
-  // Comparing to {0, 0, 0, 0, 0}
-  mathfu::Vector<T, d> r1(value1);
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v3, r1);
-
-  // inverse vs. zero vector.
-  mathfu::Vector<T, d> v4 = mathfu::Vector<T, d>::Min(v2, v1);
-
-  // Comparing to {0, 0, 0, 0, 0}
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v4, r1);
-
-  // vs. negative vector.
-  T negative_value[] = {-1, -2, -3, -4, -5};
-  v2 = mathfu::Vector<T, d>(negative_value);
-  mathfu::Vector<T, d> v5 = mathfu::Vector<T, d>::Min(v1, v2);
-
-  // Comparing to {-1, -2, -3, -4, -5}
-  mathfu::Vector<T, d> r2(negative_value);
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v5, r2);
-
-  // vs. interleaving 2 vectors.
-  T value3[] = {0, 2, 0, 4, 0};
-  T value4[] = {1, 0, 3, 0, 5};
-  v1 = mathfu::Vector<T, d>(value3);
-  v2 = mathfu::Vector<T, d>(value4);
-  mathfu::Vector<T, d> v6 = mathfu::Vector<T, d>::Min(v1, v2);
-
-  // Comparing to {0, 0, 0, 0, 0}
-  EXPECT_PRED_FORMAT2(AssertVectorEqual, v6, r1);
-}
-TEST_ALL_F(Min)
-
-// Tests the RoundUpToPowerOf2 function for vectors.
-// Given a vector, it should return a vector whose elements are rounded up to
-// the nearest power of 2.
-template <class T, int d>
-void Vector_RoundUpToPowerOf2_Test(const T& precision) {
-  (void)precision;
-  mathfu::Vector<T, d> powof2, result;
-
-  for (int count = 0; count < 1024; count++) {
-    for (int i = 0; i < d; i++) {
-      powof2[i] = static_cast<T>(count);
-    }
-    result = mathfu::RoundUpToPowerOf2(powof2);
-    T expected = static_cast<T>(mathfu::RoundUpToPowerOf2(count));
-    for (int i = 0; i < d; i++) {
-      EXPECT_EQ(result[i], expected);
-    }
-  }
-}
-TEST_ALL_INTS_F(Vector_RoundUpToPowerOf2)
-TEST_ALL_F(Vector_RoundUpToPowerOf2)
-
-// Test the compilation of basic vector opertations given in the sample file.
-// This will test creation of two vectors and computing their cross product.
-TEST_F(VectorTests, SampleTest) {
-  using namespace mathfu;
-  /// @doxysnippetstart Chapter02_Vectors.md Vector_Sample
-  Vector<float, 3> point1(0.5f, 0.4f, 0.1f);
-  Vector<float, 3> point2(0.4f, 0.9f, 0.1f);
-  Vector<float, 3> point3(0.1f, 0.8f, 0.6f);
-
-  Vector<float, 3> vector1 = point2 - point1;
-  Vector<float, 3> vector2 = point3 - point1;
-
-  Vector<float, 3> normal = Vector<float, 3>::CrossProduct(vector2, vector1);
-  /// @doxysnippetend
-  const float precision = 1e-2f;
-  EXPECT_NEAR(-0.25f, normal[0], precision);
-  EXPECT_NEAR(-0.05f, normal[1], precision);
-  EXPECT_NEAR(-0.16f, normal[2], precision);
-}
-
-// This will test that the constants have the correct values.
-TEST_F(VectorTests, ConstantTest) {
-  // Check values of various kinds of Vector2s.
-  for (int i = 0; i < 2; ++i) {
-    VECTOR_TEST_CONSTANT_EQ(kZeros2, i, 0);
-    VECTOR_TEST_CONSTANT_EQ(kOnes2, i, 1);
-    VECTOR_TEST_CONSTANT_EQ(kAxisX2, i, i == 0 ? 1 : 0);
-    VECTOR_TEST_CONSTANT_EQ(kAxisY2, i, i == 1 ? 1 : 0);
-  }
-
-  // Check values of various kinds of Vector3s.
-  for (int i = 0; i < 3; ++i) {
-    VECTOR_TEST_CONSTANT_EQ(kZeros3, i, 0);
-    VECTOR_TEST_CONSTANT_EQ(kOnes3, i, 1);
-    VECTOR_TEST_CONSTANT_EQ(kAxisX3, i, i == 0 ? 1 : 0);
-    VECTOR_TEST_CONSTANT_EQ(kAxisY3, i, i == 1 ? 1 : 0);
-    VECTOR_TEST_CONSTANT_EQ(kAxisZ3, i, i == 2 ? 1 : 0);
-  }
-
-  // Check values of various kinds of Vector4s.
-  for (int i = 0; i < 4; ++i) {
-    VECTOR_TEST_CONSTANT_EQ(kZeros4, i, 0);
-    VECTOR_TEST_CONSTANT_EQ(kOnes4, i, 1);
-    VECTOR_TEST_CONSTANT_EQ(kAxisX4, i, i == 0 ? 1 : 0);
-    VECTOR_TEST_CONSTANT_EQ(kAxisY4, i, i == 1 ? 1 : 0);
-    VECTOR_TEST_CONSTANT_EQ(kAxisZ4, i, i == 2 ? 1 : 0);
-    VECTOR_TEST_CONSTANT_EQ(kAxisW4, i, i == 3 ? 1 : 0);
-  }
-}
-
-// This will test the == vectors operator.
-template <class T, int d>
-void Equal_Test(const T& precision) {
-  mathfu::Vector<T, d> expected;
-  for (int i = 0; i < d; ++i) {
-    expected[i] = static_cast<T>(i * precision);
-  }
-  mathfu::Vector<T, d> copy(expected);
-  EXPECT_TRUE(expected == copy);
-
-  mathfu::Vector<T, d> close(expected - static_cast<T>(1));
-  EXPECT_FALSE(expected == close);
-}
-TEST_ALL_F(Equal);
-TEST_ALL_INTS_F(Equal);
-
-// This will test the != vectors operator.
-template <class T, int d>
-void NotEqual_Test(const T& precision) {
-  mathfu::Vector<T, d> expected;
-  for (int i = 0; i < d; ++i) {
-    expected[i] = static_cast<T>(i * precision);
-  }
-  mathfu::Vector<T, d> copy(expected);
-  EXPECT_FALSE(expected != copy);
-
-  mathfu::Vector<T, d> close(expected - static_cast<T>(1));
-  EXPECT_TRUE(expected != close);
-}
-TEST_ALL_F(NotEqual);
-TEST_ALL_INTS_F(NotEqual);
-
-// Simple class that represents a possible compatible type for a vector.
-// That is, it's just an array of T of length d, so can be loaded and
-// stored from mathfu::Vector<T,d> using ToType() and FromType().
-template <class T, int d>
-struct SimpleVector {
-  T values[d];
-};
-
-// This will test the FromType() conversion functions.
-template <class T, int d>
-void FromType_Test(const T& precision) {
-  SimpleVector<T, d> compatible;
-  for (int i = 0; i < d; ++i) {
-    compatible.values[i] = static_cast<T>(i * precision);
-  }
-
-  const mathfu::Vector<T, d> vector = mathfu::Vector<T, d>::FromType(compatible);
-
-  for (int i = 0; i < d; ++i) {
-    EXPECT_EQ(compatible.values[i], vector[i]);
-  }
-}
-TEST_ALL_F(FromType);
-TEST_ALL_INTS_F(FromType);
-
-// This will test the ToType() conversion functions.
-template <class T, int d>
-void ToType_Test(const T& precision) {
-  typedef SimpleVector<T, d> CompatibleT;
-  typedef mathfu::Vector<T, d> VectorT;
-
-  VectorT vector;
-  for (int i = 0; i < d; ++i) {
-    vector[i] = static_cast<T>(i * precision);
-  }
-
-  const CompatibleT compatible = VectorT::template ToType<CompatibleT>(vector);
-
-  for (int i = 0; i < d; ++i) {
-    EXPECT_EQ(compatible.values[i], vector[i]);
-  }
-}
-TEST_ALL_F(ToType);
-TEST_ALL_INTS_F(ToType);
-
-int main(int argc, char** argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  printf("%s (%s)\n", argv[0], MATHFU_BUILD_OPTIONS_STRING);
-  return RUN_ALL_TESTS();
-}
diff --git a/tools/VmaDumpVis/README.md b/tools/VmaDumpVis/README.md
index fee2392..97a396b 100644
--- a/tools/VmaDumpVis/README.md
+++ b/tools/VmaDumpVis/README.md
@@ -28,7 +28,15 @@
 ## Legend

 

 * ![Free space](README_files/Legend_Bkg.png "Free space") Light gray without border - a space in Vulkan device memory block unused by any allocation.

-* ![Buffer](README_files/Legend_Buffer.png "Buffer") Yellow rectangle - buffer.

-* ![Image Optimal](README_files/Legend_ImageOptimal.png "Image Optimal") Aqua rectangle - image with TILING_OPTIMAL.

-* ![Image Linear](README_files/Legend_ImageLinear.png "Image Linear") Green rectangle - image with TILING_LINEAR.

-* ![Details](README_files/Legend_Details.png "Details") Black bar or rectangle - one or more allocations of any kind too small to be visualized as filled rectangles.

+* ![Buffer 1](README_files/Legend_Buffer_1.png "Buffer 1") Buffer with usage containing INDIRECT_BUFFER, VERTEX_BUFFER, or INDEX_BUFFER.

+* ![Buffer 2](README_files/Legend_Buffer_2.png "Buffer 2") Buffer with usage containing STORAGE_BUFFER or STORAGE_TEXEL_BUFFER.

+* ![Buffer 3](README_files/Legend_Buffer_3.png "Buffer 3") Buffer with usage containing UNIFORM_BUFFER or UNIFORM_TEXEL_BUFFER.

+* ![Buffer 4](README_files/Legend_Buffer_4.png "Buffer 4") Other buffer.

+* ![Image 1](README_files/Legend_Image_1.png "Image 1") Image with OPTIMAL tiling and usage containing DEPTH_STENCIL_ATTACHMENT.

+* ![Image 2](README_files/Legend_Image_2.png "Image 2") Image with OPTIMAL tiling and usage containing INPUT_ATTACHMENT, TRANSIENT_ATTACHMENT, or COLOR_ATTACHMENT.

+* ![Image 3](README_files/Legend_Image_3.png "Image 3") Image with OPTIMAL tiling and usage containing SAMPLED.

+* ![Image 4](README_files/Legend_Image_4.png "Image 4") Other image with OPTIMAL tiling.

+* ![Image Linear](README_files/Legend_Image_Linear.png "Image Linear") Image with LINEAR tiling.

+* ![Image Unknown](README_files/Legend_Image_Unknown.png "Image Unknown") Image with tiling unknown to the allocator.

+* ![Unknown](README_files/Legend_Unknown.png "Unknown") Allocation of unknown type.

+* ![Details](README_files/Legend_Details.png "Details") Black bar - one or more allocations of any kind too small to be visualized as filled rectangles.

diff --git a/tools/VmaDumpVis/README_files/ExampleOutput.png b/tools/VmaDumpVis/README_files/ExampleOutput.png
index 0aba87e..2646ed2 100644
--- a/tools/VmaDumpVis/README_files/ExampleOutput.png
+++ b/tools/VmaDumpVis/README_files/ExampleOutput.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Buffer.png b/tools/VmaDumpVis/README_files/Legend_Buffer.png
deleted file mode 100644
index 3acc825..0000000
--- a/tools/VmaDumpVis/README_files/Legend_Buffer.png
+++ /dev/null
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Buffer_1.png b/tools/VmaDumpVis/README_files/Legend_Buffer_1.png
new file mode 100644
index 0000000..3805225
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Buffer_1.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Buffer_2.png b/tools/VmaDumpVis/README_files/Legend_Buffer_2.png
new file mode 100644
index 0000000..bc3773f
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Buffer_2.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Buffer_3.png b/tools/VmaDumpVis/README_files/Legend_Buffer_3.png
new file mode 100644
index 0000000..992d8b2
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Buffer_3.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Buffer_4.png b/tools/VmaDumpVis/README_files/Legend_Buffer_4.png
new file mode 100644
index 0000000..d29f54e
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Buffer_4.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Details.png b/tools/VmaDumpVis/README_files/Legend_Details.png
index 450c7c7..a9c8535 100644
--- a/tools/VmaDumpVis/README_files/Legend_Details.png
+++ b/tools/VmaDumpVis/README_files/Legend_Details.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_ImageLinear.png b/tools/VmaDumpVis/README_files/Legend_ImageLinear.png
deleted file mode 100644
index 4bd3672..0000000
--- a/tools/VmaDumpVis/README_files/Legend_ImageLinear.png
+++ /dev/null
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_ImageOptimal.png b/tools/VmaDumpVis/README_files/Legend_ImageOptimal.png
deleted file mode 100644
index 8d74288..0000000
--- a/tools/VmaDumpVis/README_files/Legend_ImageOptimal.png
+++ /dev/null
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Image_1.png b/tools/VmaDumpVis/README_files/Legend_Image_1.png
new file mode 100644
index 0000000..dc180af
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Image_1.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Image_2.png b/tools/VmaDumpVis/README_files/Legend_Image_2.png
new file mode 100644
index 0000000..fc35c7c
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Image_2.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Image_3.png b/tools/VmaDumpVis/README_files/Legend_Image_3.png
new file mode 100644
index 0000000..b69849d
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Image_3.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Image_4.png b/tools/VmaDumpVis/README_files/Legend_Image_4.png
new file mode 100644
index 0000000..7f3980e
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Image_4.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Image_Linear.png b/tools/VmaDumpVis/README_files/Legend_Image_Linear.png
new file mode 100644
index 0000000..36d8be5
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Image_Linear.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Image_Unknown.png b/tools/VmaDumpVis/README_files/Legend_Image_Unknown.png
new file mode 100644
index 0000000..f3f40ec
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Image_Unknown.png
Binary files differ
diff --git a/tools/VmaDumpVis/README_files/Legend_Unknown.png b/tools/VmaDumpVis/README_files/Legend_Unknown.png
new file mode 100644
index 0000000..3053726
--- /dev/null
+++ b/tools/VmaDumpVis/README_files/Legend_Unknown.png
Binary files differ
diff --git a/tools/VmaDumpVis/VmaDumpVis.py b/tools/VmaDumpVis/VmaDumpVis.py
index 5bf3d5b..d033b28 100644
--- a/tools/VmaDumpVis/VmaDumpVis.py
+++ b/tools/VmaDumpVis/VmaDumpVis.py
@@ -32,7 +32,7 @@
 MAP_SIZE = 24

 COLOR_TEXT_H1 = (0, 0, 0, 255)

 COLOR_TEXT_H2 = (150, 150, 150, 255)

-COLOR_OUTLINE = (160, 160, 160, 255)

+COLOR_OUTLINE = (155, 155, 155, 255)

 COLOR_OUTLINE_HARD = (0, 0, 0, 255)

 COLOR_GRID_LINE = (224, 224, 224, 255)

 

@@ -46,13 +46,15 @@
 data = {}

 

 

-def ProcessBlock(dstBlockList, objBlock):

+def ProcessBlock(dstBlockList, iBlockId, objBlock, bLinearAlgorithm):

     iBlockSize = int(objBlock['TotalBytes'])

-    arrSuballocs  = objBlock['Suballocations']

-    dstBlockObj = {'Size':iBlockSize, 'Suballocations':[]}

-    dstBlockList.append(dstBlockObj)

+    arrSuballocs = objBlock['Suballocations']

+    dstBlockObj = {'ID': iBlockId, 'Size':iBlockSize, 'Suballocations':[]}

+    if bLinearAlgorithm:

+        dstBlockObj['LinearAlgorithm'] = True

     for objSuballoc in arrSuballocs:

-        dstBlockObj['Suballocations'].append((objSuballoc['Type'], int(objSuballoc['Size'])))

+        dstBlockObj['Suballocations'].append((objSuballoc['Type'], int(objSuballoc['Size']), int(objSuballoc['Usage']) if ('Usage' in objSuballoc) else 0))

+    dstBlockList.append(dstBlockObj)

 

 

 def GetDataForMemoryType(iMemTypeIndex):

@@ -60,7 +62,7 @@
     if iMemTypeIndex in data:

         return data[iMemTypeIndex]

     else:

-        newMemTypeData = {'DedicatedAllocations':[], 'DefaultPoolBlocks':[], 'CustomPoolBlocks':[]}

+        newMemTypeData = {'DedicatedAllocations':[], 'DefaultPoolBlocks':[], 'CustomPools':{}}

         data[iMemTypeIndex] = newMemTypeData

         return newMemTypeData

 

@@ -75,44 +77,66 @@
     iMaxBlockSize = 0

     for dictMemType in data.values():

         iImgSizeY += IMG_MARGIN + FONT_SIZE

-        iImgSizeY += len(dictMemType['DedicatedAllocations']) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)

-        for tDedicatedAlloc in dictMemType['DedicatedAllocations']:

+        lDedicatedAllocations = dictMemType['DedicatedAllocations']

+        iImgSizeY += len(lDedicatedAllocations) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)

+        for tDedicatedAlloc in lDedicatedAllocations:

             iMaxBlockSize = max(iMaxBlockSize, tDedicatedAlloc[1])

-        iImgSizeY += len(dictMemType['DefaultPoolBlocks']) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)

-        for objBlock in dictMemType['DefaultPoolBlocks']:

+        lDefaultPoolBlocks = dictMemType['DefaultPoolBlocks']

+        iImgSizeY += len(lDefaultPoolBlocks) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)

+        for objBlock in lDefaultPoolBlocks:

             iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])

-        iImgSizeY += len(dictMemType['CustomPoolBlocks']) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)

-        for objBlock in dictMemType['CustomPoolBlocks']:

-            iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])

+        dCustomPools = dictMemType['CustomPools']

+        for lBlocks in dCustomPools.values():

+            iImgSizeY += len(lBlocks) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)

+            for objBlock in lBlocks:

+                iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])

     fPixelsPerByte = (IMG_SIZE_X - IMG_MARGIN * 2) / float(iMaxBlockSize)

     return iImgSizeY, fPixelsPerByte

 

 

-def TypeToColor(sType):

+def TypeToColor(sType, iUsage):

     if sType == 'FREE':

         return 220, 220, 220, 255

     elif sType == 'BUFFER':

-        return 255, 255, 0, 255

+        if (iUsage & 0x1C0) != 0: # INDIRECT_BUFFER | VERTEX_BUFFER | INDEX_BUFFER

+            return 255, 148, 148, 255 # Red

+        elif (iUsage & 0x28) != 0: # STORAGE_BUFFER | STORAGE_TEXEL_BUFFER

+            return 255, 187, 121, 255 # Orange

+        elif (iUsage & 0x14) != 0: # UNIFORM_BUFFER | UNIFORM_TEXEL_BUFFER

+            return 255, 255, 0, 255 # Yellow

+        else:

+            return 255, 255, 165, 255 # Light yellow

     elif sType == 'IMAGE_OPTIMAL':

-        return 128, 255, 255, 255

+        if (iUsage & 0x20) != 0: # DEPTH_STENCIL_ATTACHMENT

+            return 246, 128, 255, 255 # Pink

+        elif (iUsage & 0xD0) != 0: # INPUT_ATTACHMENT | TRANSIENT_ATTACHMENT | COLOR_ATTACHMENT

+            return 179, 179, 255, 255 # Blue

+        elif (iUsage & 0x4) != 0: # SAMPLED

+            return 0, 255, 255, 255 # Aqua

+        else:

+            return 183, 255, 255, 255 # Light aqua

     elif sType == 'IMAGE_LINEAR':

-        return 64, 255, 64, 255

+        return 0, 255, 0, 255 # Green

+    elif sType == 'IMAGE_UNKNOWN':

+        return 0, 255, 164, 255 # Green/aqua

+    elif sType == 'UNKNOWN':

+        return 175, 175, 175, 255 # Gray

     assert False

     return 0, 0, 0, 255

 

 

-def DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc):

+def DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc): 

     global fPixelsPerByte

     iSizeBytes = tDedicatedAlloc[1]

     iSizePixels = int(iSizeBytes * fPixelsPerByte)

-    draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor(tDedicatedAlloc[0]), outline=COLOR_OUTLINE)

+    draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor(tDedicatedAlloc[0], tDedicatedAlloc[2]), outline=COLOR_OUTLINE)

 

 

 def DrawBlock(draw, y, objBlock):

     global fPixelsPerByte

     iSizeBytes = objBlock['Size']

     iSizePixels = int(iSizeBytes * fPixelsPerByte)

-    draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor('FREE'), outline=None)

+    draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor('FREE', 0), outline=None)

     iByte = 0

     iX = 0

     iLastHardLineX = -1

@@ -122,7 +146,8 @@
         iXEnd = int(iByteEnd * fPixelsPerByte)

         if sType != 'FREE':

             if iXEnd > iX + 1:

-                draw.rectangle([IMG_MARGIN + iX, y, IMG_MARGIN + iXEnd, y + MAP_SIZE], fill=TypeToColor(sType), outline=COLOR_OUTLINE)

+                iUsage = tSuballoc[2]

+                draw.rectangle([IMG_MARGIN + iX, y, IMG_MARGIN + iXEnd, y + MAP_SIZE], fill=TypeToColor(sType, iUsage), outline=COLOR_OUTLINE)

                 # Hard line was been overwritten by rectangle outline: redraw it.

                 if iLastHardLineX == iX:

                     draw.line([IMG_MARGIN + iX, y, IMG_MARGIN + iX, y + MAP_SIZE], fill=COLOR_OUTLINE_HARD)

@@ -154,24 +179,26 @@
         iType = int(sType[5:])

         typeData = GetDataForMemoryType(iType)

         for objAlloc in tType[1]:

-            typeData['DedicatedAllocations'].append((objAlloc['Type'], int(objAlloc['Size'])))

+            typeData['DedicatedAllocations'].append((objAlloc['Type'], int(objAlloc['Size']), int(objAlloc['Usage']) if ('Usage' in objAlloc) else 0))

 if 'DefaultPools' in jsonSrc:

     for tType in jsonSrc['DefaultPools'].items():

         sType = tType[0]

         assert sType[:5] == 'Type '

         iType = int(sType[5:])

         typeData = GetDataForMemoryType(iType)

-        for objBlock in tType[1]['Blocks']:

-            ProcessBlock(typeData['DefaultPoolBlocks'], objBlock)

+        for sBlockId, objBlock in tType[1]['Blocks'].items():

+            ProcessBlock(typeData['DefaultPoolBlocks'], int(sBlockId), objBlock, False)

 if 'Pools' in jsonSrc:

-    arrPools = jsonSrc['Pools']

-    for objPool in arrPools:

+    objPools = jsonSrc['Pools']

+    for sPoolId, objPool in objPools.items():

         iType = int(objPool['MemoryTypeIndex'])

         typeData = GetDataForMemoryType(iType)

-        arrBlocks = objPool['Blocks']

-        for objBlock in arrBlocks:

-            ProcessBlock(typeData['CustomPoolBlocks'], objBlock)

-            

+        objBlocks = objPool['Blocks']

+        bLinearAlgorithm = 'LinearAlgorithm' in objPool and objPool['LinearAlgorithm']

+        dstBlockArray = []

+        typeData['CustomPools'][int(sPoolId)] = dstBlockArray

+        for sBlockId, objBlock in objBlocks.items():

+            ProcessBlock(dstBlockArray, int(sBlockId), objBlock, bLinearAlgorithm)

 

 iImgSizeY, fPixelsPerByte = CalcParams()

 

@@ -212,20 +239,23 @@
         DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc)

         y += MAP_SIZE + IMG_MARGIN

         index += 1

-    index = 0

     for objBlock in dictMemType['DefaultPoolBlocks']:

-        draw.text((IMG_MARGIN, y), "Default pool block %d" % index, fill=COLOR_TEXT_H2, font=font)

+        draw.text((IMG_MARGIN, y), "Default pool block %d" % objBlock['ID'], fill=COLOR_TEXT_H2, font=font)

         y += FONT_SIZE + IMG_MARGIN

         DrawBlock(draw, y, objBlock)

         y += MAP_SIZE + IMG_MARGIN

-        index += 1

     index = 0

-    for objBlock in dictMemType['CustomPoolBlocks']:

-        draw.text((IMG_MARGIN, y), "Custom pool block %d" % index, fill=COLOR_TEXT_H2, font=font)

-        y += FONT_SIZE + IMG_MARGIN

-        DrawBlock(draw, y, objBlock)

-        y += MAP_SIZE + IMG_MARGIN

-        index += 1

+    for iPoolId, listPool in dictMemType['CustomPools'].items():

+        for objBlock in listPool:

+            if 'LinearAlgorithm' in objBlock:

+                linearAlgorithmStr = ' (linear algorithm)';

+            else:

+                linearAlgorithmStr = '';

+            draw.text((IMG_MARGIN, y), "Custom pool %d%s block %d" % (iPoolId, linearAlgorithmStr, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)

+            y += FONT_SIZE + IMG_MARGIN

+            DrawBlock(draw, y, objBlock)

+            y += MAP_SIZE + IMG_MARGIN

+            index += 1

 del draw

 img.save(args.output)

 

@@ -234,10 +264,15 @@
 - Fixed key 'DedicatedAllocations'. Value is list of tuples, each containing:

     - [0]: Type : string

     - [1]: Size : integer

+    - [2]: Usage : integer (0 if unknown)

 - Fixed key 'DefaultPoolBlocks'. Value is list of objects, each containing dictionary with:

+    - Fixed key 'ID'. Value is int.

     - Fixed key 'Size'. Value is int.

     - Fixed key 'Suballocations'. Value is list of tuples as above.

-- Fixed key 'CustomPoolBlocks'. Value is list of objects, each containing dictionary with:

+- Fixed key 'CustomPools'. Value is dictionary.

+  - Key is integer pool ID. Value is list of objects representing memory blocks, each containing dictionary with:

+    - Fixed key 'ID'. Value is int.

     - Fixed key 'Size'. Value is int.

+    - Fixed key 'LinearAlgorithm'. Optional. Value is True.

     - Fixed key 'Suballocations'. Value is list of tuples as above.

 """