Merge branch 'master' into MemoryBudget
diff --git a/docs/Recording file format.md b/docs/Recording file format.md
index 64e3c35..42d3bc3 100644
--- a/docs/Recording file format.md
+++ b/docs/Recording file format.md
@@ -23,7 +23,7 @@
 VmaReplay application supports all older versions.

 Current version is:

 

-    1,6

+    1,7

 

 # Configuration

 

@@ -243,6 +243,11 @@
 

 - context : pointer

 

+**vmaSetPoolName** (min format version: 1.7)

+

+- pool : pointer

+- pName : string (may contain additional commas)

+

 # Data types

 

 **bool**

@@ -271,7 +276,7 @@
 # Example file

 

     Vulkan Memory Allocator,Calls recording

-    1,6

+    1,7

     Config,Begin

     PhysicalDevice,apiVersion,4198477

     PhysicalDevice,driverVersion,8388653

diff --git a/src/Doxyfile b/src/Doxyfile
index 2823bd8..3efbdb9 100644
--- a/src/Doxyfile
+++ b/src/Doxyfile
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.13

+# Doxyfile 1.8.16

 

 # This file describes the settings to be used by the documentation system

 # doxygen (www.doxygen.org) for a project.

@@ -17,11 +17,11 @@
 # 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.

+# This tag specifies the encoding used for all characters in the configuration

+# 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

+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.

 # The default value is: UTF-8.

 

 DOXYFILE_ENCODING      = UTF-8

@@ -93,6 +93,14 @@
 

 OUTPUT_LANGUAGE        = English

 

+# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all

+# documentation generated by doxygen is written. Doxygen will use this

+# information to generate all generated output in the proper direction.

+# Possible values are: None, LTR, RTL and Context.

+# The default value is: None.

+

+OUTPUT_TEXT_DIRECTION  = None

+

 # 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.

@@ -189,6 +197,16 @@
 

 JAVADOC_AUTOBRIEF      = NO

 

+# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line

+# such as

+# /***************

+# as being the beginning of a Javadoc-style comment "banner". If set to NO, the

+# Javadoc-style will behave just like regular comments and it will not be

+# interpreted by doxygen.

+# The default value is: NO.

+

+JAVADOC_BANNER         = 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

@@ -236,7 +254,12 @@
 # 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.

+# newlines (in the resulting output). You can put ^^ in the value part of an

+# alias to insert a newline as if a physical newline was in the original file.

+# When you need a literal { or } or , in the value part of an alias you have to

+# escape them by means of a backslash (\), this can lead to conflicts with the

+# commands \{ and \} for these it is advised to use the version @{ and @} or use

+# a double escape (\\{ and \\})

 

 ALIASES                =

 

@@ -274,17 +297,26 @@
 

 OPTIMIZE_OUTPUT_VHDL   = NO

 

+# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice

+# sources only. Doxygen will then generate output that is more tailored for that

+# language. For instance, namespaces will be presented as modules, types will be

+# separated into more groups, etc.

+# The default value is: NO.

+

+OPTIMIZE_OUTPUT_SLICE  = 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 (fixed format Fortran:

-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:

-# Fortran. In the later case the parser tries to guess whether the code is fixed

-# or free formatted code, this is the default for Fortran type files), 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.

+# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,

+# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:

+# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser

+# tries to guess whether the code is fixed or free formatted code, this is the

+# default for Fortran type files), VHDL, tcl. 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.

 #

@@ -295,7 +327,7 @@
 

 # 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.

+# documentation. See https://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.

@@ -307,7 +339,7 @@
 # to that level are automatically included in the table of contents, even if

 # they do not have an id attribute.

 # Note: This feature currently applies only to Markdown headings.

-# Minimum value: 0, maximum value: 99, default value: 0.

+# Minimum value: 0, maximum value: 99, default value: 5.

 # This tag requires that the tag MARKDOWN_SUPPORT is set to YES.

 

 TOC_INCLUDE_HEADINGS   = 0

@@ -337,7 +369,7 @@
 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

+# https://www.riverbankcomputing.com/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.

@@ -443,6 +475,12 @@
 

 EXTRACT_PRIVATE        = NO

 

+# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual

+# methods of a class will be included in the documentation.

+# The default value is: NO.

+

+EXTRACT_PRIV_VIRTUAL   = 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.

@@ -521,7 +559,7 @@
 # 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.

+# (including Cygwin) ands Mac users are advised to set this option to NO.

 # The default value is: system dependent.

 

 CASE_SENSE_NAMES       = NO

@@ -708,7 +746,7 @@
 # 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.

+# to be installed. See also https://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. See also \cite for info how to create references.

@@ -753,7 +791,8 @@
 # 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.

+# parameter documentation, but not about the absence of documentation. If

+# EXTRACT_ALL is set to YES then this flag will automatically be disabled.

 # The default value is: NO.

 

 WARN_NO_PARAMDOC       = NO

@@ -795,7 +834,7 @@
 # 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

+# documentation (see: https://www.gnu.org/software/libiconv/) for the list of

 # possible encodings.

 # The default value is: UTF-8.

 

@@ -813,7 +852,7 @@
 # *.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, *.pyw, *.f90, *.f95, *.f03, *.f08,

-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.

+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.

 

 FILE_PATTERNS          = *.c \

                          *.cc \

@@ -1011,7 +1050,7 @@
 STRIP_CODE_COMMENTS    = YES

 

 # If the REFERENCED_BY_RELATION tag is set to YES then for each documented

-# function all documented functions referencing it will be listed.

+# entity all documented functions referencing it will be listed.

 # The default value is: NO.

 

 REFERENCED_BY_RELATION = NO

@@ -1043,12 +1082,12 @@
 # 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

+# (see https://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

+# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file

 # - Make sure the INPUT points to the root of the source tree

 # - Run doxygen as normal

 #

@@ -1076,7 +1115,7 @@
 # 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

-# generated with the -Duse-libclang=ON option for CMake.

+# generated with the -Duse_libclang=ON option for CMake.

 # The default value is: NO.

 

 CLANG_ASSISTED_PARSING = NO

@@ -1089,6 +1128,16 @@
 

 CLANG_OPTIONS          =

 

+# If clang assisted parsing is enabled you can provide the clang parser with the

+# path to the compilation database (see:

+# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files

+# were built. This is equivalent to specifying the "-p" option to a clang tool,

+# such as clang-check. These options will then be passed to the parser.

+# Note: The availability of this option depends on whether or not doxygen was

+# generated with the -Duse_libclang=ON option for CMake.

+

+CLANG_DATABASE_PATH    =

+

 #---------------------------------------------------------------------------

 # Configuration options related to the alphabetical class index

 #---------------------------------------------------------------------------

@@ -1207,7 +1256,7 @@
 # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen

 # will adjust the colors in the style sheet 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

+# https://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.

@@ -1243,6 +1292,17 @@
 

 HTML_TIMESTAMP         = NO

 

+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML

+# documentation will contain a main index with vertical navigation menus that

+# are dynamically created via Javascript. If disabled, the navigation index will

+# consists of multiple levels of tabs that are statically embedded in every HTML

+# page. Disable this option to support browsers that do not have Javascript,

+# like the Qt help browser.

+# The default value is: YES.

+# This tag requires that the tag GENERATE_HTML is set to YES.

+

+HTML_DYNAMIC_MENUS     = 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.

@@ -1266,13 +1326,13 @@
 

 # 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

+# environment (see: https://developer.apple.com/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.

+# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy

+# genXcode/_index.html for more information.

 # The default value is: NO.

 # This tag requires that the tag GENERATE_HTML is set to YES.

 

@@ -1311,7 +1371,7 @@
 # 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

+# (see: https://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

@@ -1387,7 +1447,7 @@
 

 # 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).

+# (see: https://doc.qt.io/archives/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.

 

@@ -1395,7 +1455,7 @@
 

 # 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 (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-

 # folders).

 # The default value is: doc.

 # This tag requires that the tag GENERATE_QHP is set to YES.

@@ -1404,7 +1464,7 @@
 

 # 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 (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-

 # filters).

 # This tag requires that the tag GENERATE_QHP is set to YES.

 

@@ -1412,7 +1472,7 @@
 

 # 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 (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-

 # filters).

 # This tag requires that the tag GENERATE_QHP is set to YES.

 

@@ -1420,7 +1480,7 @@
 

 # 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).

+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).

 # This tag requires that the tag GENERATE_QHP is set to YES.

 

 QHP_SECT_FILTER_ATTRS  =

@@ -1513,7 +1573,7 @@
 

 FORMULA_FONTSIZE       = 10

 

-# Use the FORMULA_TRANPARENT tag to determine whether or not the images

+# Use the FORMULA_TRANSPARENT 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.

 #

@@ -1525,7 +1585,7 @@
 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

+# https://www.mathjax.org) which uses client side Javascript for the rendering

 # instead of using pre-rendered 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

@@ -1552,8 +1612,8 @@
 # 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.

+# MathJax from https://www.mathjax.org before deployment.

+# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.

 # This tag requires that the tag USE_MATHJAX is set to YES.

 

 MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest

@@ -1614,7 +1674,7 @@
 #

 # 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/).

+# Xapian (see: https://xapian.org/).

 #

 # See the section "External Indexing and Searching" for details.

 # The default value is: NO.

@@ -1627,7 +1687,7 @@
 #

 # 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

+# Xapian (see: https://xapian.org/). See the section "External Indexing and

 # Searching" for details.

 # This tag requires that the tag SEARCHENGINE is set to YES.

 

@@ -1679,21 +1739,35 @@
 # 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.

+# Note that when not enabling USE_PDFLATEX the default is latex when enabling

+# USE_PDFLATEX the default is pdflatex and when in the later case latex is

+# chosen this is overwritten by pdflatex. For specific output languages the

+# default can have been set differently, this depends on the implementation of

+# the output language.

 # 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.

+# Note: This tag is used in the Makefile / make.bat.

+# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file

+# (.tex).

 # The default file is: makeindex.

 # This tag requires that the tag GENERATE_LATEX is set to YES.

 

 MAKEINDEX_CMD_NAME     = makeindex

 

+# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to

+# generate index for LaTeX. In case there is no backslash (\) as first character

+# it will be automatically added in the LaTeX code.

+# Note: This tag is used in the generated output file (.tex).

+# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.

+# The default value is: makeindex.

+# This tag requires that the tag GENERATE_LATEX is set to YES.

+

+LATEX_MAKEINDEX_CMD    = 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.

@@ -1814,7 +1888,7 @@
 

 # 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.

+# https://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.

 

@@ -1828,6 +1902,14 @@
 

 LATEX_TIMESTAMP        = NO

 

+# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)

+# path from which the emoji images will be read. If a relative path is entered,

+# it will be relative to the LATEX_OUTPUT directory. If left blank the

+# LATEX_OUTPUT directory will be used.

+# This tag requires that the tag GENERATE_LATEX is set to YES.

+

+LATEX_EMOJI_DIRECTORY  =

+

 #---------------------------------------------------------------------------

 # Configuration options related to the RTF output

 #---------------------------------------------------------------------------

@@ -1867,9 +1949,9 @@
 

 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.

+# Load stylesheet definitions from file. Syntax is similar to doxygen's

+# configuration 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.

@@ -1878,8 +1960,8 @@
 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.

+# similar to doxygen's configuration 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    =

@@ -1965,6 +2047,13 @@
 

 XML_PROGRAMLISTING     = YES

 

+# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include

+# namespace members in file scope as well, matching the HTML output.

+# The default value is: NO.

+# This tag requires that the tag GENERATE_XML is set to YES.

+

+XML_NS_MEMB_FILE_SCOPE = NO

+

 #---------------------------------------------------------------------------

 # Configuration options related to the DOCBOOK output

 #---------------------------------------------------------------------------

@@ -1997,9 +2086,9 @@
 #---------------------------------------------------------------------------

 

 # 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.

+# AutoGen Definitions (see http://autogen.sourceforge.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

@@ -2166,12 +2255,6 @@
 

 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

 #---------------------------------------------------------------------------

@@ -2185,15 +2268,6 @@
 

 CLASS_DIAGRAMS         = YES

 

-# 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            =

-

 # You can include diagrams made with dia in doxygen documentation. Doxygen will

 # then run dia to produce the diagram and insert it in the documentation. The

 # DIA_PATH tag allows you to specify the directory where the dia binary resides.

diff --git a/src/Tests.cpp b/src/Tests.cpp
index b2fea21..82100fd 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -1988,8 +1988,8 @@
 

 void TestHeapSizeLimit()

 {

-    const VkDeviceSize HEAP_SIZE_LIMIT = 1ull * 1024 * 1024 * 1024; // 1 GB

-    const VkDeviceSize BLOCK_SIZE      = 128ull * 1024 * 1024;      // 128 MB

+    const VkDeviceSize HEAP_SIZE_LIMIT = 200ull * 1024 * 1024; // 200 MB

+    const VkDeviceSize BLOCK_SIZE      =  20ull * 1024 * 1024; // 20 MB

 

     VkDeviceSize heapSizeLimit[VK_MAX_MEMORY_HEAPS];

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

@@ -3111,6 +3111,18 @@
     res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);

     TEST(res == VK_SUCCESS);

 

+    // Test pool name

+    {

+        static const char* const POOL_NAME = "Pool name";

+        vmaSetPoolName(g_hAllocator, pool, POOL_NAME);

+

+        const char* fetchedPoolName = nullptr;

+        vmaGetPoolName(g_hAllocator, pool, &fetchedPoolName);

+        TEST(strcmp(fetchedPoolName, POOL_NAME) == 0);

+

+        vmaSetPoolName(g_hAllocator, pool, nullptr);

+    }

+

     vmaSetCurrentFrameIndex(g_hAllocator, 1);

 

     VmaAllocationCreateInfo allocInfo = {};

diff --git a/src/VmaReplay/Common.h b/src/VmaReplay/Common.h
index fa2dfe9..5d52e5c 100644
--- a/src/VmaReplay/Common.h
+++ b/src/VmaReplay/Common.h
@@ -173,9 +173,16 @@
     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] };

+        if(index < m_Count)

+        {

+            return StrRange {

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

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

+        }

+        else

+        {

+            return StrRange{0, 0};

+        }

     }

 

 private:

diff --git a/src/VmaReplay/Constants.cpp b/src/VmaReplay/Constants.cpp
index e353f49..6258117 100644
--- a/src/VmaReplay/Constants.cpp
+++ b/src/VmaReplay/Constants.cpp
@@ -54,6 +54,7 @@
     "vmaResizeAllocation",

     "vmaDefragmentationBegin",

     "vmaDefragmentationEnd",

+    "vmaSetPoolName",

 };

 static_assert(

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

diff --git a/src/VmaReplay/Constants.h b/src/VmaReplay/Constants.h
index e479168..4dcea82 100644
--- a/src/VmaReplay/Constants.h
+++ b/src/VmaReplay/Constants.h
@@ -87,6 +87,7 @@
     ResizeAllocation,

     DefragmentationBegin,

     DefragmentationEnd,

+    SetPoolName,

     Count

 };

 extern const char* VMA_FUNCTION_NAMES[];

diff --git a/src/VmaReplay/VmaReplay.cpp b/src/VmaReplay/VmaReplay.cpp
index 4ed29f8..57251fb 100644
--- a/src/VmaReplay/VmaReplay.cpp
+++ b/src/VmaReplay/VmaReplay.cpp
@@ -688,7 +688,7 @@
 static bool ValidateFileVersion()

 {

     if(GetVersionMajor(g_FileVersion) == 1 &&

-        GetVersionMinor(g_FileVersion) <= 6)

+        GetVersionMinor(g_FileVersion) <= 7)

     {

         return true;

     }

@@ -1665,6 +1665,7 @@
     void ExecuteResizeAllocation(size_t lineNumber, const CsvSplit& csvSplit);

     void ExecuteDefragmentationBegin(size_t lineNumber, const CsvSplit& csvSplit);

     void ExecuteDefragmentationEnd(size_t lineNumber, const CsvSplit& csvSplit);

+    void ExecuteSetPoolName(size_t lineNumber, const CsvSplit& csvSplit);

 

     void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit, const char* functionName);

 

@@ -1819,6 +1820,8 @@
             ExecuteDefragmentationBegin(lineNumber, csvSplit);

         else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DefragmentationEnd]))

             ExecuteDefragmentationEnd(lineNumber, csvSplit);

+        else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::SetPoolName]))

+            ExecuteSetPoolName(lineNumber, csvSplit);

         else

         {

             if(IssueWarning())

@@ -3863,6 +3866,48 @@
     }

 }

 

+void Player::ExecuteSetPoolName(size_t lineNumber, const CsvSplit& csvSplit)

+{

+    m_Stats.RegisterFunctionCall(VMA_FUNCTION::SetPoolName);

+

+    if(!g_UserDataEnabled)

+    {

+        return;

+    }

+

+    if(ValidateFunctionParameterCount(lineNumber, csvSplit, 2, true))

+    {

+        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())

+                {

+                    std::string poolName;

+                    csvSplit.GetRange(FIRST_PARAM_INDEX + 1).to_str(poolName);

+                    vmaSetPoolName(m_Allocator, it->second.pool, !poolName.empty() ? poolName.c_str() : nullptr);

+                }

+                else

+                {

+                    if(IssueWarning())

+                    {

+                        printf("Line %zu: Pool %llX not found.\n", lineNumber, origPtr);

+                    }

+                }

+            }

+        }

+        else

+        {

+            if(IssueWarning())

+            {

+                printf("Line %zu: Invalid parameters for vmaSetPoolName.\n", lineNumber);

+            }

+        }

+    }

+}

+

 ////////////////////////////////////////////////////////////////////////////////

 // Main functions

 

diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp
index 0865bdb..8a533a3 100644
--- a/src/VulkanSample.cpp
+++ b/src/VulkanSample.cpp
@@ -26,6 +26,7 @@
 #include "Tests.h"

 #include "VmaUsage.h"

 #include "Common.h"

+#include <atomic>

 

 static const char* const SHADER_PATH1 = "./";

 static const char* const SHADER_PATH2 = "../bin/";

@@ -37,7 +38,7 @@
 static const bool VSYNC = true;

 static const uint32_t COMMAND_BUFFER_COUNT = 2;

 static void* const CUSTOM_CPU_ALLOCATION_CALLBACK_USER_DATA = (void*)(intptr_t)43564544;

-static const bool USE_CUSTOM_CPU_ALLOCATION_CALLBACKS = false;

+static const bool USE_CUSTOM_CPU_ALLOCATION_CALLBACKS = true;

 

 VkPhysicalDevice g_hPhysicalDevice;

 VkDevice g_hDevice;

@@ -111,12 +112,19 @@
 static VmaAllocation g_hTextureImageAlloc;

 static VkImageView g_hTextureImageView;

 

+static std::atomic_uint32_t g_CpuAllocCount;

+

 static void* CustomCpuAllocation(

     void* pUserData, size_t size, size_t alignment,

     VkSystemAllocationScope allocationScope)

 {

     assert(pUserData == CUSTOM_CPU_ALLOCATION_CALLBACK_USER_DATA);

-    return _aligned_malloc(size, alignment);

+    void* const result = _aligned_malloc(size, alignment);

+    if(result)

+    {

+        ++g_CpuAllocCount;

+    }

+    return result;

 }

 

 static void* CustomCpuReallocation(

@@ -124,13 +132,27 @@
     VkSystemAllocationScope allocationScope)

 {

     assert(pUserData == CUSTOM_CPU_ALLOCATION_CALLBACK_USER_DATA);

-    return _aligned_realloc(pOriginal, size, alignment);

+    void* const result = _aligned_realloc(pOriginal, size, alignment);

+    if(pOriginal && !result)

+    {

+        --g_CpuAllocCount;

+    }

+    else if(!pOriginal && result)

+    {

+        ++g_CpuAllocCount;

+    }

+    return result;

 }

 

 static void CustomCpuFree(void* pUserData, void* pMemory)

 {

     assert(pUserData == CUSTOM_CPU_ALLOCATION_CALLBACK_USER_DATA);

-    _aligned_free(pMemory);

+    if(pMemory)

+    {

+        const uint32_t oldAllocCount = g_CpuAllocCount.fetch_sub(1);

+        TEST(oldAllocCount > 0);

+        _aligned_free(pMemory);

+    }

 }

 

 static const VkAllocationCallbacks g_CpuAllocationCallbacks = {

@@ -1873,6 +1895,8 @@
             DrawFrame();

     }

 

+    TEST(g_CpuAllocCount.load() == 0);

+

     return 0;

 }

 

diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index 0dace24..952fe24 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -2679,6 +2679,27 @@
 */

 VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool);

 

+/** \brief Retrieves name of a custom pool.

+

+After the call `ppName` is either null or points to an internally-owned null-terminated string

+containing name of the pool that was previously set. The pointer becomes invalid when the pool is

+destroyed or its name is changed using vmaSetPoolName().

+*/

+VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char** ppName);

+

+/** \brief Sets name of a custom pool.

+

+`pName` can be either null or pointer to a null-terminated string with new name for the pool.

+Function makes internal copy of the string, so it can be changed or freed immediately after this call.

+*/

+VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char* pName);

+

 /** \struct VmaAllocation

 \brief Represents single memory allocation.

 

@@ -4205,6 +4226,30 @@
     }

 }

 

+static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr)

+{

+    if(srcStr != VMA_NULL)

+    {

+        const size_t len = strlen(srcStr);

+        char* const result = vma_new_array(allocs, char, len + 1);

+        memcpy(result, srcStr, len + 1);

+        return result;

+    }

+    else

+    {

+        return VMA_NULL;

+    }

+}

+

+static void VmaFreeString(const VkAllocationCallbacks* allocs, char* str)

+{

+    if(str != VMA_NULL)

+    {

+        const size_t len = strlen(str);

+        vma_delete_array(allocs, str, len + 1);

+    }

+}

+

 // STL-compatible allocator.

 template<typename T>

 class VmaStlAllocator

@@ -6154,14 +6199,15 @@
         size_t maxBlockCount,

         VkDeviceSize bufferImageGranularity,

         uint32_t frameInUseCount,

-        bool isCustomPool,

         bool explicitBlockSize,

         uint32_t algorithm);

     ~VmaBlockVector();

 

     VkResult CreateMinBlocks();

 

+    VmaAllocator GetAllocator() const { return m_hAllocator; }

     VmaPool GetParentPool() const { return m_hParentPool; }

+    bool IsCustomPool() const { return m_hParentPool != VMA_NULL; }

     uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }

     VkDeviceSize GetPreferredBlockSize() const { return m_PreferredBlockSize; }

     VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; }

@@ -6226,7 +6272,6 @@
     const size_t m_MaxBlockCount;

     const VkDeviceSize m_BufferImageGranularity;

     const uint32_t m_FrameInUseCount;

-    const bool m_IsCustomPool;

     const bool m_ExplicitBlockSize;

     const uint32_t m_Algorithm;

     /* There can be at most one allocation that is completely empty - a

@@ -6301,12 +6346,16 @@
     uint32_t GetId() const { return m_Id; }

     void SetId(uint32_t id) { VMA_ASSERT(m_Id == 0); m_Id = id; }

 

+    const char* GetName() const { return m_Name; }

+    void SetName(const char* pName);

+

 #if VMA_STATS_STRING_ENABLED

     //void PrintDetailedMap(class VmaStringBuilder& sb);

 #endif

 

 private:

     uint32_t m_Id;

+    char* m_Name;

 };

 

 /*

@@ -6818,6 +6867,9 @@
         VmaDefragmentationContext ctx);

     void RecordDefragmentationEnd(uint32_t frameIndex,

         VmaDefragmentationContext ctx);

+    void RecordSetPoolName(uint32_t frameIndex,

+        VmaPool pool,

+        const char* name);

 

 private:

     struct CallParams

@@ -7597,11 +7649,7 @@
 

         if(pUserData != VMA_NULL)

         {

-            const char* const newStrSrc = (char*)pUserData;

-            const size_t newStrLen = strlen(newStrSrc);

-            char* const newStrDst = vma_new_array(hAllocator, char, newStrLen + 1);

-            memcpy(newStrDst, newStrSrc, newStrLen + 1);

-            m_pUserData = newStrDst;

+            m_pUserData = VmaCreateStringCopy(hAllocator->GetAllocationCallbacks(), (const char*)pUserData);

         }

     }

     else

@@ -7804,13 +7852,8 @@
 void VmaAllocation_T::FreeUserDataString(VmaAllocator hAllocator)

 {

     VMA_ASSERT(IsUserDataString());

-    if(m_pUserData != VMA_NULL)

-    {

-        char* const oldStr = (char*)m_pUserData;

-        const size_t oldStrLen = strlen(oldStr);

-        vma_delete_array(hAllocator, oldStr, oldStrLen + 1);

-        m_pUserData = VMA_NULL;

-    }

+    VmaFreeString(hAllocator->GetAllocationCallbacks(), (char*)m_pUserData);

+    m_pUserData = VMA_NULL;

 }

 

 void VmaAllocation_T::BlockAllocMap()

@@ -11613,10 +11656,10 @@
         createInfo.maxBlockCount,

         (createInfo.flags & VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT) != 0 ? 1 : hAllocator->GetBufferImageGranularity(),

         createInfo.frameInUseCount,

-        true, // isCustomPool

         createInfo.blockSize != 0, // explicitBlockSize

         createInfo.flags & VMA_POOL_CREATE_ALGORITHM_MASK), // algorithm

-    m_Id(0)

+    m_Id(0),

+    m_Name(VMA_NULL)

 {

 }

 

@@ -11624,6 +11667,21 @@
 {

 }

 

+void VmaPool_T::SetName(const char* pName)

+{

+    const VkAllocationCallbacks* allocs = m_BlockVector.GetAllocator()->GetAllocationCallbacks();

+    VmaFreeString(allocs, m_Name);

+    

+    if(pName != VMA_NULL)

+    {

+        m_Name = VmaCreateStringCopy(allocs, pName);

+    }

+    else

+    {

+        m_Name = VMA_NULL;

+    }

+}

+

 #if VMA_STATS_STRING_ENABLED

 

 #endif // #if VMA_STATS_STRING_ENABLED

@@ -11637,7 +11695,6 @@
     size_t maxBlockCount,

     VkDeviceSize bufferImageGranularity,

     uint32_t frameInUseCount,

-    bool isCustomPool,

     bool explicitBlockSize,

     uint32_t algorithm) :

     m_hAllocator(hAllocator),

@@ -11648,7 +11705,6 @@
     m_MaxBlockCount(maxBlockCount),

     m_BufferImageGranularity(bufferImageGranularity),

     m_FrameInUseCount(frameInUseCount),

-    m_IsCustomPool(isCustomPool),

     m_ExplicitBlockSize(explicitBlockSize),

     m_Algorithm(algorithm),

     m_HasEmptyBlock(false),

@@ -12601,8 +12657,15 @@
 

     json.BeginObject();

 

-    if(m_IsCustomPool)

+    if(IsCustomPool())

     {

+        const char* poolName = m_hParentPool->GetName();

+        if(poolName != VMA_NULL && poolName[0] != '\0')

+        {

+            json.WriteString("Name");

+            json.WriteString(poolName);

+        }

+

         json.WriteString("MemoryTypeIndex");

         json.WriteNumber(m_MemoryTypeIndex);

 

@@ -13830,7 +13893,7 @@
 

     // Write header.

     fprintf(m_File, "%s\n", "Vulkan Memory Allocator,Calls recording");

-    fprintf(m_File, "%s\n", "1,6");

+    fprintf(m_File, "%s\n", "1,7");

 

     return VK_SUCCESS;

 }

@@ -14263,6 +14326,19 @@
     Flush();

 }

 

+void VmaRecorder::RecordSetPoolName(uint32_t frameIndex,

+    VmaPool pool,

+    const char* name)

+{

+    CallParams callParams;

+    GetBasicParams(callParams);

+

+    VmaMutexLock lock(m_FileMutex, m_UseMutex);

+    fprintf(m_File, "%u,%.3f,%u,vmaSetPoolName,%p,%s\n", callParams.threadId, callParams.time, frameIndex,

+        pool, name != VMA_NULL ? name : "");

+    Flush();

+}

+

 VmaRecorder::UserDataString::UserDataString(VmaAllocationCreateFlags allocFlags, const void* pUserData)

 {

     if(pUserData != VMA_NULL)

@@ -14490,7 +14566,6 @@
             SIZE_MAX,

             GetBufferImageGranularity(),

             pCreateInfo->frameInUseCount,

-            false, // isCustomPool

             false, // explicitBlockSize

             false); // linearAlgorithm

         // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here,

@@ -16626,6 +16701,41 @@
     return allocator->CheckPoolCorruption(pool);

 }

 

+VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char** ppName)

+{

+    VMA_ASSERT(allocator && pool);

+    

+    VMA_DEBUG_LOG("vmaGetPoolName");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    *ppName = pool->GetName();

+}

+

+VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char* pName)

+{

+    VMA_ASSERT(allocator && pool);

+

+    VMA_DEBUG_LOG("vmaSetPoolName");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    pool->SetName(pName);

+

+#if VMA_RECORDING_ENABLED

+    if(allocator->GetRecorder() != VMA_NULL)

+    {

+        allocator->GetRecorder()->RecordSetPoolName(allocator->GetCurrentFrameIndex(), pool, pName);

+    }

+#endif

+}

+

 VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory(

     VmaAllocator allocator,

     const VkMemoryRequirements* pVkMemoryRequirements,

diff --git a/tools/VmaDumpVis/VmaDumpVis.py b/tools/VmaDumpVis/VmaDumpVis.py
index 9b6298b..c71d04b 100644
--- a/tools/VmaDumpVis/VmaDumpVis.py
+++ b/tools/VmaDumpVis/VmaDumpVis.py
@@ -194,8 +194,13 @@
         typeData = GetDataForMemoryType(iType)

         objBlocks = objPool['Blocks']

         sAlgorithm = objPool.get('Algorithm', '')

+        sName = objPool.get('Name', None)

+        if sName:

+            sFullName = sPoolId + ' "' + sName + '"'

+        else:

+            sFullName = sPoolId

         dstBlockArray = []

-        typeData['CustomPools'][int(sPoolId)] = dstBlockArray

+        typeData['CustomPools'][sFullName] = dstBlockArray

         for sBlockId, objBlock in objBlocks.items():

             ProcessBlock(dstBlockArray, int(sBlockId), objBlock, sAlgorithm)

 

@@ -249,13 +254,13 @@
         DrawBlock(draw, y, objBlock)

         y += MAP_SIZE + IMG_MARGIN

     index = 0

-    for iPoolId, listPool in dictMemType['CustomPools'].items():

+    for sPoolName, listPool in dictMemType['CustomPools'].items():

         for objBlock in listPool:

             if 'Algorithm' in objBlock and objBlock['Algorithm']:

                 sAlgorithm = ' (Algorithm: %s)' % (objBlock['Algorithm'])

             else:

                 sAlgorithm = ''

-            draw.text((IMG_MARGIN, y), "Custom pool %d%s block %d" % (iPoolId, sAlgorithm, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)

+            draw.text((IMG_MARGIN, y), "Custom pool %s%s block %d" % (sPoolName, sAlgorithm, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)

             y += FONT_SIZE + IMG_MARGIN

             DrawBlock(draw, y, objBlock)

             y += MAP_SIZE + IMG_MARGIN

@@ -274,7 +279,7 @@
     - Fixed key 'Size'. Value is int.

     - Fixed key 'Suballocations'. Value is list of tuples as above.

 - Fixed key 'CustomPools'. Value is dictionary.

-  - Key is integer pool ID. Value is list of objects representing memory blocks, each containing dictionary with:

+  - Key is string with pool ID/name. 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 'Algorithm'. Optional. Value is string.