VmaReplay: Extended by detailed statistics for parameters of structures like VmaAllocationCreateInfo, VkImageCreateInfo etc.
diff --git a/src/VmaReplay/Common.h b/src/VmaReplay/Common.h
index a78524b..d0548bf 100644
--- a/src/VmaReplay/Common.h
+++ b/src/VmaReplay/Common.h
@@ -35,6 +35,11 @@
 {

     return (x+y-1) / y;

 }

+template <typename T>

+inline T round_div(T x, T y)

+{

+    return (x+y/(T)2) / y;

+}

 

 template <typename T>

 inline T align_up(T val, T align)

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

+#include "Constants.h"

+

+const int RESULT_EXCEPTION          = -1000;

+const int RESULT_ERROR_COMMAND_LINE = -1;

+const int RESULT_ERROR_SOURCE_FILE  = -2;

+const int RESULT_ERROR_FORMAT       = -3;

+const int RESULT_ERROR_VULKAN       = -4;

+

+const char* VMA_FUNCTION_NAMES[] = {

+    "vmaCreatePool",

+    "vmaDestroyPool",

+    "vmaSetAllocationUserData",

+    "vmaCreateBuffer",

+    "vmaDestroyBuffer",

+    "vmaCreateImage",

+    "vmaDestroyImage",

+    "vmaFreeMemory",

+    "vmaFreeMemoryPages",

+    "vmaCreateLostAllocation",

+    "vmaAllocateMemory",

+    "vmaAllocateMemoryPages",

+    "vmaAllocateMemoryForBuffer",

+    "vmaAllocateMemoryForImage",

+    "vmaMapMemory",

+    "vmaUnmapMemory",

+    "vmaFlushAllocation",

+    "vmaInvalidateAllocation",

+    "vmaTouchAllocation",

+    "vmaGetAllocationInfo",

+    "vmaMakePoolAllocationsLost",

+    "vmaResizeAllocation",

+    "vmaDefragmentationBegin",

+    "vmaDefragmentationEnd",

+};

+static_assert(

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

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

+

+const char* VMA_POOL_CREATE_FLAG_NAMES[] = {

+    "VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT",

+    "VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT",

+    "VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT",

+};

+const uint32_t VMA_POOL_CREATE_FLAG_VALUES[] = {

+    VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT,

+    VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT,

+    VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT,

+};

+const size_t VMA_POOL_CREATE_FLAG_COUNT = _countof(VMA_POOL_CREATE_FLAG_NAMES);

+static_assert(

+    _countof(VMA_POOL_CREATE_FLAG_NAMES) == _countof(VMA_POOL_CREATE_FLAG_VALUES),

+    "VMA_POOL_CREATE_FLAG_NAMES array doesn't match VMA_POOL_CREATE_FLAG_VALUES.");

+

+const char* VK_BUFFER_CREATE_FLAG_NAMES[] = {

+    "VK_BUFFER_CREATE_SPARSE_BINDING_BIT",

+    "VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT",

+    "VK_BUFFER_CREATE_SPARSE_ALIASED_BIT",

+    "VK_BUFFER_CREATE_PROTECTED_BIT",

+};

+const uint32_t VK_BUFFER_CREATE_FLAG_VALUES[] = {

+    VK_BUFFER_CREATE_SPARSE_BINDING_BIT,

+    VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,

+    VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,

+    VK_BUFFER_CREATE_PROTECTED_BIT,

+};

+const size_t VK_BUFFER_CREATE_FLAG_COUNT = _countof(VK_BUFFER_CREATE_FLAG_NAMES);

+static_assert(

+    _countof(VK_BUFFER_CREATE_FLAG_NAMES) == _countof(VK_BUFFER_CREATE_FLAG_VALUES),

+    "VK_BUFFER_CREATE_FLAG_NAMES array doesn't match VK_BUFFER_CREATE_FLAG_VALUES.");

+

+const char* VK_BUFFER_USAGE_FLAG_NAMES[] = {

+    "VK_BUFFER_USAGE_TRANSFER_SRC_BIT",

+    "VK_BUFFER_USAGE_TRANSFER_DST_BIT",

+    "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT",

+    "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT",

+    "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT",

+    "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT",

+    "VK_BUFFER_USAGE_INDEX_BUFFER_BIT",

+    "VK_BUFFER_USAGE_VERTEX_BUFFER_BIT",

+    "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT",

+    "VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT",

+    "VK_BUFFER_USAGE_RAYTRACING_BIT_NVX",

+};

+const uint32_t VK_BUFFER_USAGE_FLAG_VALUES[] = {

+    VK_BUFFER_USAGE_TRANSFER_SRC_BIT,

+    VK_BUFFER_USAGE_TRANSFER_DST_BIT,

+    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,

+    VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,

+    VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,

+    VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,

+    VK_BUFFER_USAGE_INDEX_BUFFER_BIT,

+    VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,

+    VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,

+    VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT,

+    VK_BUFFER_USAGE_RAYTRACING_BIT_NVX,

+};

+const size_t VK_BUFFER_USAGE_FLAG_COUNT = _countof(VK_BUFFER_USAGE_FLAG_NAMES);

+static_assert(

+    _countof(VK_BUFFER_USAGE_FLAG_NAMES) == _countof(VK_BUFFER_USAGE_FLAG_VALUES),

+    "VK_BUFFER_USAGE_FLAG_NAMES array doesn't match VK_BUFFER_USAGE_FLAG_VALUES.");

+

+const char* VK_SHARING_MODE_NAMES[] = {

+    "VK_SHARING_MODE_EXCLUSIVE",

+    "VK_SHARING_MODE_CONCURRENT",

+};

+const size_t VK_SHARING_MODE_COUNT = _countof(VK_SHARING_MODE_NAMES);

+

+const char* VK_IMAGE_CREATE_FLAG_NAMES[] = {

+    "VK_IMAGE_CREATE_SPARSE_BINDING_BIT",

+    "VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT",

+    "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT",

+    "VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT",

+    "VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT",

+    "VK_IMAGE_CREATE_ALIAS_BIT",

+    "VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT",

+    "VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT",

+    "VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT",

+    "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT",

+    "VK_IMAGE_CREATE_PROTECTED_BIT",

+    "VK_IMAGE_CREATE_DISJOINT_BIT",

+    "VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV",

+    "VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT",

+};

+const uint32_t VK_IMAGE_CREATE_FLAG_VALUES[] = {

+    VK_IMAGE_CREATE_SPARSE_BINDING_BIT,

+    VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,

+    VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,

+    VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,

+    VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,

+    VK_IMAGE_CREATE_ALIAS_BIT,

+    VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT,

+    VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT,

+    VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT,

+    VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,

+    VK_IMAGE_CREATE_PROTECTED_BIT,

+    VK_IMAGE_CREATE_DISJOINT_BIT,

+    VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV,

+    VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT,

+};

+const size_t VK_IMAGE_CREATE_FLAG_COUNT = _countof(VK_IMAGE_CREATE_FLAG_NAMES);

+static_assert(

+    _countof(VK_IMAGE_CREATE_FLAG_NAMES) == _countof(VK_IMAGE_CREATE_FLAG_VALUES),

+    "VK_IMAGE_CREATE_FLAG_NAMES array doesn't match VK_IMAGE_CREATE_FLAG_VALUES.");

+

+const char* VK_IMAGE_TYPE_NAMES[] = {

+    "VK_IMAGE_TYPE_1D",

+    "VK_IMAGE_TYPE_2D",

+    "VK_IMAGE_TYPE_3D",

+};

+const size_t VK_IMAGE_TYPE_COUNT = _countof(VK_IMAGE_TYPE_NAMES);

+

+const char* VK_FORMAT_NAMES[] = {

+    "VK_FORMAT_UNDEFINED",

+    "VK_FORMAT_R4G4_UNORM_PACK8",

+    "VK_FORMAT_R4G4B4A4_UNORM_PACK16",

+    "VK_FORMAT_B4G4R4A4_UNORM_PACK16",

+    "VK_FORMAT_R5G6B5_UNORM_PACK16",

+    "VK_FORMAT_B5G6R5_UNORM_PACK16",

+    "VK_FORMAT_R5G5B5A1_UNORM_PACK16",

+    "VK_FORMAT_B5G5R5A1_UNORM_PACK16",

+    "VK_FORMAT_A1R5G5B5_UNORM_PACK16",

+    "VK_FORMAT_R8_UNORM",

+    "VK_FORMAT_R8_SNORM",

+    "VK_FORMAT_R8_USCALED",

+    "VK_FORMAT_R8_SSCALED",

+    "VK_FORMAT_R8_UINT",

+    "VK_FORMAT_R8_SINT",

+    "VK_FORMAT_R8_SRGB",

+    "VK_FORMAT_R8G8_UNORM",

+    "VK_FORMAT_R8G8_SNORM",

+    "VK_FORMAT_R8G8_USCALED",

+    "VK_FORMAT_R8G8_SSCALED",

+    "VK_FORMAT_R8G8_UINT",

+    "VK_FORMAT_R8G8_SINT",

+    "VK_FORMAT_R8G8_SRGB",

+    "VK_FORMAT_R8G8B8_UNORM",

+    "VK_FORMAT_R8G8B8_SNORM",

+    "VK_FORMAT_R8G8B8_USCALED",

+    "VK_FORMAT_R8G8B8_SSCALED",

+    "VK_FORMAT_R8G8B8_UINT",

+    "VK_FORMAT_R8G8B8_SINT",

+    "VK_FORMAT_R8G8B8_SRGB",

+    "VK_FORMAT_B8G8R8_UNORM",

+    "VK_FORMAT_B8G8R8_SNORM",

+    "VK_FORMAT_B8G8R8_USCALED",

+    "VK_FORMAT_B8G8R8_SSCALED",

+    "VK_FORMAT_B8G8R8_UINT",

+    "VK_FORMAT_B8G8R8_SINT",

+    "VK_FORMAT_B8G8R8_SRGB",

+    "VK_FORMAT_R8G8B8A8_UNORM",

+    "VK_FORMAT_R8G8B8A8_SNORM",

+    "VK_FORMAT_R8G8B8A8_USCALED",

+    "VK_FORMAT_R8G8B8A8_SSCALED",

+    "VK_FORMAT_R8G8B8A8_UINT",

+    "VK_FORMAT_R8G8B8A8_SINT",

+    "VK_FORMAT_R8G8B8A8_SRGB",

+    "VK_FORMAT_B8G8R8A8_UNORM",

+    "VK_FORMAT_B8G8R8A8_SNORM",

+    "VK_FORMAT_B8G8R8A8_USCALED",

+    "VK_FORMAT_B8G8R8A8_SSCALED",

+    "VK_FORMAT_B8G8R8A8_UINT",

+    "VK_FORMAT_B8G8R8A8_SINT",

+    "VK_FORMAT_B8G8R8A8_SRGB",

+    "VK_FORMAT_A8B8G8R8_UNORM_PACK32",

+    "VK_FORMAT_A8B8G8R8_SNORM_PACK32",

+    "VK_FORMAT_A8B8G8R8_USCALED_PACK32",

+    "VK_FORMAT_A8B8G8R8_SSCALED_PACK32",

+    "VK_FORMAT_A8B8G8R8_UINT_PACK32",

+    "VK_FORMAT_A8B8G8R8_SINT_PACK32",

+    "VK_FORMAT_A8B8G8R8_SRGB_PACK32",

+    "VK_FORMAT_A2R10G10B10_UNORM_PACK32",

+    "VK_FORMAT_A2R10G10B10_SNORM_PACK32",

+    "VK_FORMAT_A2R10G10B10_USCALED_PACK32",

+    "VK_FORMAT_A2R10G10B10_SSCALED_PACK32",

+    "VK_FORMAT_A2R10G10B10_UINT_PACK32",

+    "VK_FORMAT_A2R10G10B10_SINT_PACK32",

+    "VK_FORMAT_A2B10G10R10_UNORM_PACK32",

+    "VK_FORMAT_A2B10G10R10_SNORM_PACK32",

+    "VK_FORMAT_A2B10G10R10_USCALED_PACK32",

+    "VK_FORMAT_A2B10G10R10_SSCALED_PACK32",

+    "VK_FORMAT_A2B10G10R10_UINT_PACK32",

+    "VK_FORMAT_A2B10G10R10_SINT_PACK32",

+    "VK_FORMAT_R16_UNORM",

+    "VK_FORMAT_R16_SNORM",

+    "VK_FORMAT_R16_USCALED",

+    "VK_FORMAT_R16_SSCALED",

+    "VK_FORMAT_R16_UINT",

+    "VK_FORMAT_R16_SINT",

+    "VK_FORMAT_R16_SFLOAT",

+    "VK_FORMAT_R16G16_UNORM",

+    "VK_FORMAT_R16G16_SNORM",

+    "VK_FORMAT_R16G16_USCALED",

+    "VK_FORMAT_R16G16_SSCALED",

+    "VK_FORMAT_R16G16_UINT",

+    "VK_FORMAT_R16G16_SINT",

+    "VK_FORMAT_R16G16_SFLOAT",

+    "VK_FORMAT_R16G16B16_UNORM",

+    "VK_FORMAT_R16G16B16_SNORM",

+    "VK_FORMAT_R16G16B16_USCALED",

+    "VK_FORMAT_R16G16B16_SSCALED",

+    "VK_FORMAT_R16G16B16_UINT",

+    "VK_FORMAT_R16G16B16_SINT",

+    "VK_FORMAT_R16G16B16_SFLOAT",

+    "VK_FORMAT_R16G16B16A16_UNORM",

+    "VK_FORMAT_R16G16B16A16_SNORM",

+    "VK_FORMAT_R16G16B16A16_USCALED",

+    "VK_FORMAT_R16G16B16A16_SSCALED",

+    "VK_FORMAT_R16G16B16A16_UINT",

+    "VK_FORMAT_R16G16B16A16_SINT",

+    "VK_FORMAT_R16G16B16A16_SFLOAT",

+    "VK_FORMAT_R32_UINT",

+    "VK_FORMAT_R32_SINT",

+    "VK_FORMAT_R32_SFLOAT",

+    "VK_FORMAT_R32G32_UINT",

+    "VK_FORMAT_R32G32_SINT",

+    "VK_FORMAT_R32G32_SFLOAT",

+    "VK_FORMAT_R32G32B32_UINT",

+    "VK_FORMAT_R32G32B32_SINT",

+    "VK_FORMAT_R32G32B32_SFLOAT",

+    "VK_FORMAT_R32G32B32A32_UINT",

+    "VK_FORMAT_R32G32B32A32_SINT",

+    "VK_FORMAT_R32G32B32A32_SFLOAT",

+    "VK_FORMAT_R64_UINT",

+    "VK_FORMAT_R64_SINT",

+    "VK_FORMAT_R64_SFLOAT",

+    "VK_FORMAT_R64G64_UINT",

+    "VK_FORMAT_R64G64_SINT",

+    "VK_FORMAT_R64G64_SFLOAT",

+    "VK_FORMAT_R64G64B64_UINT",

+    "VK_FORMAT_R64G64B64_SINT",

+    "VK_FORMAT_R64G64B64_SFLOAT",

+    "VK_FORMAT_R64G64B64A64_UINT",

+    "VK_FORMAT_R64G64B64A64_SINT",

+    "VK_FORMAT_R64G64B64A64_SFLOAT",

+    "VK_FORMAT_B10G11R11_UFLOAT_PACK32",

+    "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32",

+    "VK_FORMAT_D16_UNORM",

+    "VK_FORMAT_X8_D24_UNORM_PACK32",

+    "VK_FORMAT_D32_SFLOAT",

+    "VK_FORMAT_S8_UINT",

+    "VK_FORMAT_D16_UNORM_S8_UINT",

+    "VK_FORMAT_D24_UNORM_S8_UINT",

+    "VK_FORMAT_D32_SFLOAT_S8_UINT",

+    "VK_FORMAT_BC1_RGB_UNORM_BLOCK",

+    "VK_FORMAT_BC1_RGB_SRGB_BLOCK",

+    "VK_FORMAT_BC1_RGBA_UNORM_BLOCK",

+    "VK_FORMAT_BC1_RGBA_SRGB_BLOCK",

+    "VK_FORMAT_BC2_UNORM_BLOCK",

+    "VK_FORMAT_BC2_SRGB_BLOCK",

+    "VK_FORMAT_BC3_UNORM_BLOCK",

+    "VK_FORMAT_BC3_SRGB_BLOCK",

+    "VK_FORMAT_BC4_UNORM_BLOCK",

+    "VK_FORMAT_BC4_SNORM_BLOCK",

+    "VK_FORMAT_BC5_UNORM_BLOCK",

+    "VK_FORMAT_BC5_SNORM_BLOCK",

+    "VK_FORMAT_BC6H_UFLOAT_BLOCK",

+    "VK_FORMAT_BC6H_SFLOAT_BLOCK",

+    "VK_FORMAT_BC7_UNORM_BLOCK",

+    "VK_FORMAT_BC7_SRGB_BLOCK",

+    "VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK",

+    "VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK",

+    "VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK",

+    "VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK",

+    "VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK",

+    "VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK",

+    "VK_FORMAT_EAC_R11_UNORM_BLOCK",

+    "VK_FORMAT_EAC_R11_SNORM_BLOCK",

+    "VK_FORMAT_EAC_R11G11_UNORM_BLOCK",

+    "VK_FORMAT_EAC_R11G11_SNORM_BLOCK",

+    "VK_FORMAT_ASTC_4x4_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_4x4_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_5x4_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_5x4_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_5x5_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_5x5_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_6x5_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_6x5_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_6x6_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_6x6_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_8x5_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_8x5_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_8x6_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_8x6_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_8x8_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_8x8_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_10x5_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_10x5_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_10x6_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_10x6_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_10x8_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_10x8_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_10x10_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_10x10_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_12x10_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_12x10_SRGB_BLOCK",

+    "VK_FORMAT_ASTC_12x12_UNORM_BLOCK",

+    "VK_FORMAT_ASTC_12x12_SRGB_BLOCK",

+    "VK_FORMAT_G8B8G8R8_422_UNORM",

+    "VK_FORMAT_B8G8R8G8_422_UNORM",

+    "VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM",

+    "VK_FORMAT_G8_B8R8_2PLANE_420_UNORM",

+    "VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM",

+    "VK_FORMAT_G8_B8R8_2PLANE_422_UNORM",

+    "VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM",

+    "VK_FORMAT_R10X6_UNORM_PACK16",

+    "VK_FORMAT_R10X6G10X6_UNORM_2PACK16",

+    "VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16",

+    "VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16",

+    "VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16",

+    "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16",

+    "VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16",

+    "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16",

+    "VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16",

+    "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16",

+    "VK_FORMAT_R12X4_UNORM_PACK16",

+    "VK_FORMAT_R12X4G12X4_UNORM_2PACK16",

+    "VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16",

+    "VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16",

+    "VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16",

+    "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16",

+    "VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16",

+    "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16",

+    "VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16",

+    "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16",

+    "VK_FORMAT_G16B16G16R16_422_UNORM",

+    "VK_FORMAT_B16G16R16G16_422_UNORM",

+    "VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM",

+    "VK_FORMAT_G16_B16R16_2PLANE_420_UNORM",

+    "VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM",

+    "VK_FORMAT_G16_B16R16_2PLANE_422_UNORM",

+    "VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM",

+    "VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG",

+    "VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG",

+    "VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG",

+    "VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG",

+    "VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG",

+    "VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG",

+    "VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG",

+    "VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG",

+};

+const uint32_t VK_FORMAT_VALUES[] = {

+    VK_FORMAT_UNDEFINED,

+    VK_FORMAT_R4G4_UNORM_PACK8,

+    VK_FORMAT_R4G4B4A4_UNORM_PACK16,

+    VK_FORMAT_B4G4R4A4_UNORM_PACK16,

+    VK_FORMAT_R5G6B5_UNORM_PACK16,

+    VK_FORMAT_B5G6R5_UNORM_PACK16,

+    VK_FORMAT_R5G5B5A1_UNORM_PACK16,

+    VK_FORMAT_B5G5R5A1_UNORM_PACK16,

+    VK_FORMAT_A1R5G5B5_UNORM_PACK16,

+    VK_FORMAT_R8_UNORM,

+    VK_FORMAT_R8_SNORM,

+    VK_FORMAT_R8_USCALED,

+    VK_FORMAT_R8_SSCALED,

+    VK_FORMAT_R8_UINT,

+    VK_FORMAT_R8_SINT,

+    VK_FORMAT_R8_SRGB,

+    VK_FORMAT_R8G8_UNORM,

+    VK_FORMAT_R8G8_SNORM,

+    VK_FORMAT_R8G8_USCALED,

+    VK_FORMAT_R8G8_SSCALED,

+    VK_FORMAT_R8G8_UINT,

+    VK_FORMAT_R8G8_SINT,

+    VK_FORMAT_R8G8_SRGB,

+    VK_FORMAT_R8G8B8_UNORM,

+    VK_FORMAT_R8G8B8_SNORM,

+    VK_FORMAT_R8G8B8_USCALED,

+    VK_FORMAT_R8G8B8_SSCALED,

+    VK_FORMAT_R8G8B8_UINT,

+    VK_FORMAT_R8G8B8_SINT,

+    VK_FORMAT_R8G8B8_SRGB,

+    VK_FORMAT_B8G8R8_UNORM,

+    VK_FORMAT_B8G8R8_SNORM,

+    VK_FORMAT_B8G8R8_USCALED,

+    VK_FORMAT_B8G8R8_SSCALED,

+    VK_FORMAT_B8G8R8_UINT,

+    VK_FORMAT_B8G8R8_SINT,

+    VK_FORMAT_B8G8R8_SRGB,

+    VK_FORMAT_R8G8B8A8_UNORM,

+    VK_FORMAT_R8G8B8A8_SNORM,

+    VK_FORMAT_R8G8B8A8_USCALED,

+    VK_FORMAT_R8G8B8A8_SSCALED,

+    VK_FORMAT_R8G8B8A8_UINT,

+    VK_FORMAT_R8G8B8A8_SINT,

+    VK_FORMAT_R8G8B8A8_SRGB,

+    VK_FORMAT_B8G8R8A8_UNORM,

+    VK_FORMAT_B8G8R8A8_SNORM,

+    VK_FORMAT_B8G8R8A8_USCALED,

+    VK_FORMAT_B8G8R8A8_SSCALED,

+    VK_FORMAT_B8G8R8A8_UINT,

+    VK_FORMAT_B8G8R8A8_SINT,

+    VK_FORMAT_B8G8R8A8_SRGB,

+    VK_FORMAT_A8B8G8R8_UNORM_PACK32,

+    VK_FORMAT_A8B8G8R8_SNORM_PACK32,

+    VK_FORMAT_A8B8G8R8_USCALED_PACK32,

+    VK_FORMAT_A8B8G8R8_SSCALED_PACK32,

+    VK_FORMAT_A8B8G8R8_UINT_PACK32,

+    VK_FORMAT_A8B8G8R8_SINT_PACK32,

+    VK_FORMAT_A8B8G8R8_SRGB_PACK32,

+    VK_FORMAT_A2R10G10B10_UNORM_PACK32,

+    VK_FORMAT_A2R10G10B10_SNORM_PACK32,

+    VK_FORMAT_A2R10G10B10_USCALED_PACK32,

+    VK_FORMAT_A2R10G10B10_SSCALED_PACK32,

+    VK_FORMAT_A2R10G10B10_UINT_PACK32,

+    VK_FORMAT_A2R10G10B10_SINT_PACK32,

+    VK_FORMAT_A2B10G10R10_UNORM_PACK32,

+    VK_FORMAT_A2B10G10R10_SNORM_PACK32,

+    VK_FORMAT_A2B10G10R10_USCALED_PACK32,

+    VK_FORMAT_A2B10G10R10_SSCALED_PACK32,

+    VK_FORMAT_A2B10G10R10_UINT_PACK32,

+    VK_FORMAT_A2B10G10R10_SINT_PACK32,

+    VK_FORMAT_R16_UNORM,

+    VK_FORMAT_R16_SNORM,

+    VK_FORMAT_R16_USCALED,

+    VK_FORMAT_R16_SSCALED,

+    VK_FORMAT_R16_UINT,

+    VK_FORMAT_R16_SINT,

+    VK_FORMAT_R16_SFLOAT,

+    VK_FORMAT_R16G16_UNORM,

+    VK_FORMAT_R16G16_SNORM,

+    VK_FORMAT_R16G16_USCALED,

+    VK_FORMAT_R16G16_SSCALED,

+    VK_FORMAT_R16G16_UINT,

+    VK_FORMAT_R16G16_SINT,

+    VK_FORMAT_R16G16_SFLOAT,

+    VK_FORMAT_R16G16B16_UNORM,

+    VK_FORMAT_R16G16B16_SNORM,

+    VK_FORMAT_R16G16B16_USCALED,

+    VK_FORMAT_R16G16B16_SSCALED,

+    VK_FORMAT_R16G16B16_UINT,

+    VK_FORMAT_R16G16B16_SINT,

+    VK_FORMAT_R16G16B16_SFLOAT,

+    VK_FORMAT_R16G16B16A16_UNORM,

+    VK_FORMAT_R16G16B16A16_SNORM,

+    VK_FORMAT_R16G16B16A16_USCALED,

+    VK_FORMAT_R16G16B16A16_SSCALED,

+    VK_FORMAT_R16G16B16A16_UINT,

+    VK_FORMAT_R16G16B16A16_SINT,

+    VK_FORMAT_R16G16B16A16_SFLOAT,

+    VK_FORMAT_R32_UINT,

+    VK_FORMAT_R32_SINT,

+    VK_FORMAT_R32_SFLOAT,

+    VK_FORMAT_R32G32_UINT,

+    VK_FORMAT_R32G32_SINT,

+    VK_FORMAT_R32G32_SFLOAT,

+    VK_FORMAT_R32G32B32_UINT,

+    VK_FORMAT_R32G32B32_SINT,

+    VK_FORMAT_R32G32B32_SFLOAT,

+    VK_FORMAT_R32G32B32A32_UINT,

+    VK_FORMAT_R32G32B32A32_SINT,

+    VK_FORMAT_R32G32B32A32_SFLOAT,

+    VK_FORMAT_R64_UINT,

+    VK_FORMAT_R64_SINT,

+    VK_FORMAT_R64_SFLOAT,

+    VK_FORMAT_R64G64_UINT,

+    VK_FORMAT_R64G64_SINT,

+    VK_FORMAT_R64G64_SFLOAT,

+    VK_FORMAT_R64G64B64_UINT,

+    VK_FORMAT_R64G64B64_SINT,

+    VK_FORMAT_R64G64B64_SFLOAT,

+    VK_FORMAT_R64G64B64A64_UINT,

+    VK_FORMAT_R64G64B64A64_SINT,

+    VK_FORMAT_R64G64B64A64_SFLOAT,

+    VK_FORMAT_B10G11R11_UFLOAT_PACK32,

+    VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,

+    VK_FORMAT_D16_UNORM,

+    VK_FORMAT_X8_D24_UNORM_PACK32,

+    VK_FORMAT_D32_SFLOAT,

+    VK_FORMAT_S8_UINT,

+    VK_FORMAT_D16_UNORM_S8_UINT,

+    VK_FORMAT_D24_UNORM_S8_UINT,

+    VK_FORMAT_D32_SFLOAT_S8_UINT,

+    VK_FORMAT_BC1_RGB_UNORM_BLOCK,

+    VK_FORMAT_BC1_RGB_SRGB_BLOCK,

+    VK_FORMAT_BC1_RGBA_UNORM_BLOCK,

+    VK_FORMAT_BC1_RGBA_SRGB_BLOCK,

+    VK_FORMAT_BC2_UNORM_BLOCK,

+    VK_FORMAT_BC2_SRGB_BLOCK,

+    VK_FORMAT_BC3_UNORM_BLOCK,

+    VK_FORMAT_BC3_SRGB_BLOCK,

+    VK_FORMAT_BC4_UNORM_BLOCK,

+    VK_FORMAT_BC4_SNORM_BLOCK,

+    VK_FORMAT_BC5_UNORM_BLOCK,

+    VK_FORMAT_BC5_SNORM_BLOCK,

+    VK_FORMAT_BC6H_UFLOAT_BLOCK,

+    VK_FORMAT_BC6H_SFLOAT_BLOCK,

+    VK_FORMAT_BC7_UNORM_BLOCK,

+    VK_FORMAT_BC7_SRGB_BLOCK,

+    VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,

+    VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,

+    VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,

+    VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,

+    VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,

+    VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,

+    VK_FORMAT_EAC_R11_UNORM_BLOCK,

+    VK_FORMAT_EAC_R11_SNORM_BLOCK,

+    VK_FORMAT_EAC_R11G11_UNORM_BLOCK,

+    VK_FORMAT_EAC_R11G11_SNORM_BLOCK,

+    VK_FORMAT_ASTC_4x4_UNORM_BLOCK,

+    VK_FORMAT_ASTC_4x4_SRGB_BLOCK,

+    VK_FORMAT_ASTC_5x4_UNORM_BLOCK,

+    VK_FORMAT_ASTC_5x4_SRGB_BLOCK,

+    VK_FORMAT_ASTC_5x5_UNORM_BLOCK,

+    VK_FORMAT_ASTC_5x5_SRGB_BLOCK,

+    VK_FORMAT_ASTC_6x5_UNORM_BLOCK,

+    VK_FORMAT_ASTC_6x5_SRGB_BLOCK,

+    VK_FORMAT_ASTC_6x6_UNORM_BLOCK,

+    VK_FORMAT_ASTC_6x6_SRGB_BLOCK,

+    VK_FORMAT_ASTC_8x5_UNORM_BLOCK,

+    VK_FORMAT_ASTC_8x5_SRGB_BLOCK,

+    VK_FORMAT_ASTC_8x6_UNORM_BLOCK,

+    VK_FORMAT_ASTC_8x6_SRGB_BLOCK,

+    VK_FORMAT_ASTC_8x8_UNORM_BLOCK,

+    VK_FORMAT_ASTC_8x8_SRGB_BLOCK,

+    VK_FORMAT_ASTC_10x5_UNORM_BLOCK,

+    VK_FORMAT_ASTC_10x5_SRGB_BLOCK,

+    VK_FORMAT_ASTC_10x6_UNORM_BLOCK,

+    VK_FORMAT_ASTC_10x6_SRGB_BLOCK,

+    VK_FORMAT_ASTC_10x8_UNORM_BLOCK,

+    VK_FORMAT_ASTC_10x8_SRGB_BLOCK,

+    VK_FORMAT_ASTC_10x10_UNORM_BLOCK,

+    VK_FORMAT_ASTC_10x10_SRGB_BLOCK,

+    VK_FORMAT_ASTC_12x10_UNORM_BLOCK,

+    VK_FORMAT_ASTC_12x10_SRGB_BLOCK,

+    VK_FORMAT_ASTC_12x12_UNORM_BLOCK,

+    VK_FORMAT_ASTC_12x12_SRGB_BLOCK,

+    VK_FORMAT_G8B8G8R8_422_UNORM,

+    VK_FORMAT_B8G8R8G8_422_UNORM,

+    VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,

+    VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,

+    VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,

+    VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,

+    VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,

+    VK_FORMAT_R10X6_UNORM_PACK16,

+    VK_FORMAT_R10X6G10X6_UNORM_2PACK16,

+    VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,

+    VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,

+    VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,

+    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,

+    VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,

+    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,

+    VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,

+    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,

+    VK_FORMAT_R12X4_UNORM_PACK16,

+    VK_FORMAT_R12X4G12X4_UNORM_2PACK16,

+    VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,

+    VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,

+    VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,

+    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,

+    VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,

+    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,

+    VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,

+    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,

+    VK_FORMAT_G16B16G16R16_422_UNORM,

+    VK_FORMAT_B16G16R16G16_422_UNORM,

+    VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,

+    VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,

+    VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,

+    VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,

+    VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,

+    VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,

+    VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG,

+    VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG,

+    VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG,

+    VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,

+    VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,

+    VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,

+    VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,

+};

+const size_t VK_FORMAT_COUNT = _countof(VK_FORMAT_NAMES);

+static_assert(

+    _countof(VK_FORMAT_NAMES) == _countof(VK_FORMAT_VALUES),

+    "VK_FORMAT_NAMES array doesn't match VK_FORMAT_VALUES.");

+

+const char* VK_SAMPLE_COUNT_NAMES[] = {

+    "VK_SAMPLE_COUNT_1_BIT",

+    "VK_SAMPLE_COUNT_2_BIT",

+    "VK_SAMPLE_COUNT_4_BIT",

+    "VK_SAMPLE_COUNT_8_BIT",

+    "VK_SAMPLE_COUNT_16_BIT",

+    "VK_SAMPLE_COUNT_32_BIT",

+    "VK_SAMPLE_COUNT_64_BIT",

+};

+const uint32_t VK_SAMPLE_COUNT_VALUES[] = {

+    VK_SAMPLE_COUNT_1_BIT,

+    VK_SAMPLE_COUNT_2_BIT,

+    VK_SAMPLE_COUNT_4_BIT,

+    VK_SAMPLE_COUNT_8_BIT,

+    VK_SAMPLE_COUNT_16_BIT,

+    VK_SAMPLE_COUNT_32_BIT,

+    VK_SAMPLE_COUNT_64_BIT,

+};

+const size_t VK_SAMPLE_COUNT_COUNT = _countof(VK_SAMPLE_COUNT_NAMES);

+static_assert(

+    _countof(VK_SAMPLE_COUNT_NAMES) == _countof(VK_SAMPLE_COUNT_VALUES),

+    "VK_SAMPLE_COUNT_NAMES array doesn't match VK_SAMPLE_COUNT_VALUES.");

+

+const char* VK_IMAGE_TILING_NAMES[] = {

+    "VK_IMAGE_TILING_OPTIMAL",

+    "VK_IMAGE_TILING_LINEAR",

+};

+const size_t VK_IMAGE_TILING_COUNT = _countof(VK_IMAGE_TILING_NAMES);

+

+const char* VK_IMAGE_USAGE_FLAG_NAMES[] = {

+    "VK_IMAGE_USAGE_TRANSFER_SRC_BIT",

+    "VK_IMAGE_USAGE_TRANSFER_DST_BIT",

+    "VK_IMAGE_USAGE_SAMPLED_BIT",

+    "VK_IMAGE_USAGE_STORAGE_BIT",

+    "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT",

+    "VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT",

+    "VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT",

+    "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT",

+    "VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV",

+};

+const uint32_t VK_IMAGE_USAGE_FLAG_VALUES[] = {

+    VK_IMAGE_USAGE_TRANSFER_SRC_BIT,

+    VK_IMAGE_USAGE_TRANSFER_DST_BIT,

+    VK_IMAGE_USAGE_SAMPLED_BIT,

+    VK_IMAGE_USAGE_STORAGE_BIT,

+    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,

+    VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,

+    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,

+    VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,

+    VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV,

+};

+const size_t VK_IMAGE_USAGE_FLAG_COUNT = _countof(VK_IMAGE_USAGE_FLAG_NAMES);

+static_assert(

+    _countof(VK_IMAGE_USAGE_FLAG_NAMES) == _countof(VK_IMAGE_USAGE_FLAG_VALUES),

+    "VK_IMAGE_USAGE_FLAG_NAMES array doesn't match VK_IMAGE_USAGE_FLAG_VALUES.");

+

+const char* VK_IMAGE_LAYOUT_NAMES[] = {

+    "VK_IMAGE_LAYOUT_UNDEFINED",

+    "VK_IMAGE_LAYOUT_GENERAL",

+    "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL",

+    "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL",

+    "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL",

+    "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL",

+    "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL",

+    "VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL",

+    "VK_IMAGE_LAYOUT_PREINITIALIZED",

+    "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL",

+    "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL",

+    "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR",

+    "VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR",

+    "VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV",

+};

+const uint32_t VK_IMAGE_LAYOUT_VALUES[] = {

+    VK_IMAGE_LAYOUT_UNDEFINED,

+    VK_IMAGE_LAYOUT_GENERAL,

+    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,

+    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,

+    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,

+    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,

+    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,

+    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,

+    VK_IMAGE_LAYOUT_PREINITIALIZED,

+    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,

+    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,

+    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,

+    VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,

+    VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV,

+};

+const size_t VK_IMAGE_LAYOUT_COUNT = _countof(VK_IMAGE_LAYOUT_NAMES);

+static_assert(

+    _countof(VK_IMAGE_LAYOUT_NAMES) == _countof(VK_IMAGE_LAYOUT_VALUES),

+    "VK_IMAGE_LAYOUT_NAMES array doesn't match VK_IMAGE_LAYOUT_VALUES.");

+

+const char* VMA_ALLOCATION_CREATE_FLAG_NAMES[] = {

+    "VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT",

+    "VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT",

+    "VMA_ALLOCATION_CREATE_MAPPED_BIT",

+    "VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT",

+    "VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT",

+    "VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT",

+    "VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT",

+    "VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT",

+    "VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT",

+    "VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT",

+};

+const uint32_t VMA_ALLOCATION_CREATE_FLAG_VALUES[] = {

+    VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,

+    VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT,

+    VMA_ALLOCATION_CREATE_MAPPED_BIT,

+    VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT,

+    VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT,

+    VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT,

+    VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT,

+    VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT,

+    VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT,

+    VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT,

+};

+const size_t VMA_ALLOCATION_CREATE_FLAG_COUNT = _countof(VMA_ALLOCATION_CREATE_FLAG_NAMES);

+static_assert(

+    _countof(VMA_ALLOCATION_CREATE_FLAG_NAMES) == _countof(VMA_ALLOCATION_CREATE_FLAG_VALUES),

+    "VMA_ALLOCATION_CREATE_FLAG_NAMES array doesn't match VMA_ALLOCATION_CREATE_FLAG_VALUES.");

+

+const char* VMA_MEMORY_USAGE_NAMES[] = {

+    "VMA_MEMORY_USAGE_UNKNOWN",

+    "VMA_MEMORY_USAGE_GPU_ONLY",

+    "VMA_MEMORY_USAGE_CPU_ONLY",

+    "VMA_MEMORY_USAGE_CPU_TO_GPU",

+    "VMA_MEMORY_USAGE_GPU_TO_CPU",

+};

+const size_t VMA_MEMORY_USAGE_COUNT = _countof(VMA_MEMORY_USAGE_NAMES);

+

+const char* VK_MEMORY_PROPERTY_FLAG_NAMES[] = {

+    "VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT",

+    "VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT",

+    "VK_MEMORY_PROPERTY_HOST_COHERENT_BIT",

+    "VK_MEMORY_PROPERTY_HOST_CACHED_BIT",

+    "VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT",

+    "VK_MEMORY_PROPERTY_PROTECTED_BIT",

+};

+const uint32_t VK_MEMORY_PROPERTY_FLAG_VALUES[] = {

+    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,

+    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,

+    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,

+    VK_MEMORY_PROPERTY_HOST_CACHED_BIT,

+    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT,

+    VK_MEMORY_PROPERTY_PROTECTED_BIT,

+};

+const size_t VK_MEMORY_PROPERTY_FLAG_COUNT = _countof(VK_MEMORY_PROPERTY_FLAG_NAMES);

+static_assert(

+    _countof(VK_MEMORY_PROPERTY_FLAG_NAMES) == _countof(VK_MEMORY_PROPERTY_FLAG_VALUES),

+    "VK_MEMORY_PROPERTY_FLAG_NAMES array doesn't match VK_MEMORY_PROPERTY_FLAG_VALUES.");

diff --git a/src/VmaReplay/Constants.h b/src/VmaReplay/Constants.h
new file mode 100644
index 0000000..2c58f68
--- /dev/null
+++ b/src/VmaReplay/Constants.h
@@ -0,0 +1,125 @@
+#pragma once

+

+extern const int RESULT_EXCEPTION;

+extern const int RESULT_ERROR_COMMAND_LINE;

+extern const int RESULT_ERROR_SOURCE_FILE;

+extern const int RESULT_ERROR_FORMAT;

+extern const int RESULT_ERROR_VULKAN;

+

+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_DEFRAGMENT_AFTER_LINE,

+    CMD_LINE_OPT_DEFRAGMENTATION_FLAGS,

+    CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE,

+};

+

+enum class VERBOSITY

+{

+    MINIMUM = 0,

+    DEFAULT,

+    MAXIMUM,

+    COUNT,

+};

+

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

+    FreeMemoryPages,

+    CreateLostAllocation,

+    AllocateMemory,

+    AllocateMemoryPages,

+    AllocateMemoryForBuffer,

+    AllocateMemoryForImage,

+    MapMemory,

+    UnmapMemory,

+    FlushAllocation,

+    InvalidateAllocation,

+    TouchAllocation,

+    GetAllocationInfo,

+    MakePoolAllocationsLost,

+    ResizeAllocation,

+    DefragmentationBegin,

+    DefragmentationEnd,

+    Count

+};

+extern const char* VMA_FUNCTION_NAMES[];

+

+extern const char* VMA_POOL_CREATE_FLAG_NAMES[];

+extern const uint32_t VMA_POOL_CREATE_FLAG_VALUES[];

+extern const size_t VMA_POOL_CREATE_FLAG_COUNT;

+

+extern const char* VK_BUFFER_CREATE_FLAG_NAMES[];

+extern const uint32_t VK_BUFFER_CREATE_FLAG_VALUES[];

+extern const size_t VK_BUFFER_CREATE_FLAG_COUNT;

+

+extern const char* VK_BUFFER_USAGE_FLAG_NAMES[];

+extern const uint32_t VK_BUFFER_USAGE_FLAG_VALUES[];

+extern const size_t VK_BUFFER_USAGE_FLAG_COUNT;

+

+extern const char* VK_SHARING_MODE_NAMES[];

+extern const size_t VK_SHARING_MODE_COUNT;

+

+extern const char* VK_IMAGE_CREATE_FLAG_NAMES[];

+extern const uint32_t VK_IMAGE_CREATE_FLAG_VALUES[];

+extern const size_t VK_IMAGE_CREATE_FLAG_COUNT;

+

+extern const char* VK_IMAGE_TYPE_NAMES[];

+extern const size_t VK_IMAGE_TYPE_COUNT;

+

+extern const char* VK_FORMAT_NAMES[];

+extern const uint32_t VK_FORMAT_VALUES[];

+extern const size_t VK_FORMAT_COUNT;

+

+extern const char* VK_SAMPLE_COUNT_NAMES[];

+extern const uint32_t VK_SAMPLE_COUNT_VALUES[];

+extern const size_t VK_SAMPLE_COUNT_COUNT;

+

+extern const char* VK_IMAGE_TILING_NAMES[];

+extern const size_t VK_IMAGE_TILING_COUNT;

+

+extern const char* VK_IMAGE_USAGE_FLAG_NAMES[];

+extern const uint32_t VK_IMAGE_USAGE_FLAG_VALUES[];

+extern const size_t VK_IMAGE_USAGE_FLAG_COUNT;

+

+extern const char* VK_IMAGE_TILING_NAMES[];

+extern const size_t VK_IMAGE_TILING_COUNT;

+

+extern const char* VK_IMAGE_LAYOUT_NAMES[];

+extern const uint32_t VK_IMAGE_LAYOUT_VALUES[];

+extern const size_t VK_IMAGE_LAYOUT_COUNT;

+

+extern const char* VMA_ALLOCATION_CREATE_FLAG_NAMES[];

+extern const uint32_t VMA_ALLOCATION_CREATE_FLAG_VALUES[];

+extern const size_t VMA_ALLOCATION_CREATE_FLAG_COUNT;

+

+extern const char* VMA_MEMORY_USAGE_NAMES[];

+extern const size_t VMA_MEMORY_USAGE_COUNT;

+

+extern const char* VK_MEMORY_PROPERTY_FLAG_NAMES[];

+extern const uint32_t VK_MEMORY_PROPERTY_FLAG_VALUES[];

+extern const size_t VK_MEMORY_PROPERTY_FLAG_COUNT;

diff --git a/src/VmaReplay/VmaReplay.cpp b/src/VmaReplay/VmaReplay.cpp
index f830176..4228009 100644
--- a/src/VmaReplay/VmaReplay.cpp
+++ b/src/VmaReplay/VmaReplay.cpp
@@ -22,104 +22,634 @@
 

 #include "VmaUsage.h"

 #include "Common.h"

+#include "Constants.h"

 #include <unordered_map>

+#include <map>

+#include <algorithm>

 

-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;

+static VERBOSITY g_Verbosity = VERBOSITY::DEFAULT;

 

-enum CMD_LINE_OPT

+namespace DetailedStats

 {

-    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_DEFRAGMENT_AFTER_LINE,

-    CMD_LINE_OPT_DEFRAGMENTATION_FLAGS,

-    CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE,

+    

+struct Flag

+{

+    uint32_t setCount = 0;

+

+    void PostValue(bool v)

+    {

+        if(v)

+        {

+            ++setCount;

+        }

+    }

+

+    void Print(uint32_t totalCount) const

+    {

+        if(setCount)

+        {

+            printf(" %u (%.2f%%)\n", setCount, (double)setCount * 100.0 / (double)totalCount);

+        }

+        else

+        {

+            printf(" 0\n");

+        }

+    }

 };

 

-static enum class VERBOSITY

+struct Enum

 {

-    MINIMUM = 0,

-    DEFAULT,

-    MAXIMUM,

-    COUNT,

-} g_Verbosity = VERBOSITY::DEFAULT;

+    Enum(size_t itemCount, const char* const* itemNames, const uint32_t* itemValues = nullptr) :

+        m_ItemCount(itemCount),

+        m_ItemNames(itemNames),

+        m_ItemValues(itemValues)

+    {

+    }

 

-enum class VULKAN_EXTENSION_REQUEST

-{

-    DISABLED,

-    ENABLED,

-    DEFAULT

+    void PostValue(uint32_t v)

+    {

+        if(v < _countof(m_BaseCount))

+        {

+            ++m_BaseCount[v];

+        }

+        else

+        {

+            auto it = m_ExtendedCount.find(v);

+            if(it != m_ExtendedCount.end())

+            {

+                ++it->second;

+            }

+            else

+            {

+                m_ExtendedCount.insert(std::make_pair(v, 1u));

+            }

+        }

+    }

+

+    void Print(uint32_t totalCount) const

+    {

+        if(totalCount &&

+            (!m_ExtendedCount.empty() || std::count_if(m_BaseCount, m_BaseCount + _countof(m_BaseCount), [](uint32_t v) { return v > 0; })))

+        {

+            printf("\n");

+            

+            for(size_t i = 0; i < _countof(m_BaseCount); ++i)

+            {

+                const uint32_t currCount = m_BaseCount[i];

+                if(currCount)

+                {

+                    PrintItem((uint32_t)i, currCount, totalCount);

+                }

+            }

+

+            for(const auto& it : m_ExtendedCount)

+            {

+                PrintItem(it.first, it.second, totalCount);

+            }

+        }

+        else

+        {

+            printf(" 0\n");

+        }

+    }

+

+private:

+    const size_t m_ItemCount;

+    const char* const* const m_ItemNames;

+    const uint32_t* const m_ItemValues;

+

+    uint32_t m_BaseCount[32] = {};

+    std::map<uint32_t, uint32_t> m_ExtendedCount;

+

+    void PrintItem(uint32_t value, uint32_t count, uint32_t totalCount) const

+    {

+        size_t itemIndex = m_ItemCount;

+        if(m_ItemValues)

+        {

+            for(itemIndex = 0; itemIndex < m_ItemCount; ++itemIndex)

+            {

+                if(m_ItemValues[itemIndex] == value)

+                {

+                    break;

+                }

+            }

+        }

+        else

+        {

+            if(value < m_ItemCount)

+            {

+                itemIndex = value;

+            }

+        }

+

+        if(itemIndex < m_ItemCount)

+        {

+            printf("        %s: ", m_ItemNames[itemIndex]);

+        }

+        else

+        {

+            printf("        0x%X: ", value);

+        }

+

+        printf("%u (%.2f%%)\n", count, (double)count * 100.0 / (double)totalCount);

+    }

 };

 

-enum class OBJECT_TYPE { BUFFER, IMAGE };

-

-enum class VMA_FUNCTION

+struct FlagSet

 {

-    CreatePool,

-    DestroyPool,

-    SetAllocationUserData,

-    CreateBuffer,

-    DestroyBuffer,

-    CreateImage,

-    DestroyImage,

-    FreeMemory,

-    FreeMemoryPages,

-    CreateLostAllocation,

-    AllocateMemory,

-    AllocateMemoryPages,

-    AllocateMemoryForBuffer,

-    AllocateMemoryForImage,

-    MapMemory,

-    UnmapMemory,

-    FlushAllocation,

-    InvalidateAllocation,

-    TouchAllocation,

-    GetAllocationInfo,

-    MakePoolAllocationsLost,

-    ResizeAllocation,

-    DefragmentationBegin,

-    DefragmentationEnd,

-    Count

+    uint32_t count[32] = {};

+

+    FlagSet(size_t count, const char* const* names, const uint32_t* values = nullptr) :

+        m_Count(count),

+        m_Names(names),

+        m_Values(values)

+    {

+    }

+

+    void PostValue(uint32_t v)

+    {

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

+        {

+            if((v & (1u << i)) != 0)

+            {

+                ++count[i];

+            }

+        }

+    }

+

+    void Print(uint32_t totalCount) const

+    {

+        if(totalCount &&

+            std::count_if(count, count + _countof(count), [](uint32_t v) { return v > 0; }))

+        {

+            printf("\n");

+            for(uint32_t bitIndex = 0; bitIndex < 32; ++bitIndex)

+            {

+                const uint32_t currCount = count[bitIndex];

+                if(currCount)

+                {

+                    size_t itemIndex = m_Count;

+                    if(m_Values)

+                    {

+                        for(itemIndex = 0; itemIndex < m_Count; ++itemIndex)

+                        {

+                            if(m_Values[itemIndex] == (1u << bitIndex))

+                            {

+                                break;

+                            }

+                        }

+                    }

+                    else

+                    {

+                        if(bitIndex < m_Count)

+                        {

+                            itemIndex = bitIndex;

+                        }

+                    }

+

+                    if(itemIndex < m_Count)

+                    {

+                        printf("        %s: ", m_Names[itemIndex]);

+                    }

+                    else

+                    {

+                        printf("        0x%X: ", 1u << bitIndex);

+                    }

+

+                    printf("%u (%.2f%%)\n", currCount, (double)currCount * 100.0 / (double)totalCount);

+                }

+            }

+        }

+        else

+        {

+            printf(" 0\n");

+        }

+    }

+

+private:

+    const size_t m_Count;

+    const char* const* const m_Names;

+    const uint32_t* const m_Values;

 };

-static const char* VMA_FUNCTION_NAMES[] = {

-    "vmaCreatePool",

-    "vmaDestroyPool",

-    "vmaSetAllocationUserData",

-    "vmaCreateBuffer",

-    "vmaDestroyBuffer",

-    "vmaCreateImage",

-    "vmaDestroyImage",

-    "vmaFreeMemory",

-    "vmaFreeMemoryPages",

-    "vmaCreateLostAllocation",

-    "vmaAllocateMemory",

-    "vmaAllocateMemoryPages",

-    "vmaAllocateMemoryForBuffer",

-    "vmaAllocateMemoryForImage",

-    "vmaMapMemory",

-    "vmaUnmapMemory",

-    "vmaFlushAllocation",

-    "vmaInvalidateAllocation",

-    "vmaTouchAllocation",

-    "vmaGetAllocationInfo",

-    "vmaMakePoolAllocationsLost",

-    "vmaResizeAllocation",

-    "vmaDefragmentationBegin",

-    "vmaDefragmentationEnd",

+

+// T should be unsigned int

+template<typename T>

+struct MinMaxAvg

+{

+    T min = std::numeric_limits<T>::max();

+    T max = 0;

+    T sum = T();

+

+    void PostValue(T v)

+    {

+        this->min = std::min(this->min, v);

+        this->max = std::max(this->max, v);

+        sum += v;

+    }

+

+    void Print(uint32_t totalCount) const

+    {

+        if(totalCount && sum > T())

+        {

+            if(this->min == this->max)

+            {

+                printf(" %llu\n", (uint64_t)this->max);

+            }

+            else

+            {

+                printf("\n        Min: %llu\n        Max: %llu\n        Avg: %llu\n",

+                    (uint64_t)this->min,

+                    (uint64_t)this->max,

+                    round_div<uint64_t>(this->sum, totalCount));

+            }

+        }

+        else

+        {

+            printf(" 0\n");

+        }

+    }

 };

-static_assert(

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

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

+

+template<typename T>

+struct BitMask

+{

+    uint32_t zeroCount = 0;

+    uint32_t maxCount = 0;

+

+    void PostValue(T v)

+    {

+        if(v)

+        {

+            if(v == std::numeric_limits<T>::max())

+            {

+                ++maxCount;

+            }

+        }

+        else

+        {

+            ++zeroCount;

+        }

+    }

+

+    void Print(uint32_t totalCount) const

+    {

+        if(totalCount > 0 && zeroCount < totalCount)

+        {

+            const uint32_t otherCount = totalCount - (zeroCount + maxCount);

+            

+            printf("\n        0: %u (%.2f%%)\n        Max: %u (%.2f%%)\n        Other: %u (%.2f%%)\n",

+                zeroCount,  (double)zeroCount  * 100.0 / (double)totalCount,

+                maxCount,   (double)maxCount   * 100.0 / (double)totalCount,

+                otherCount, (double)otherCount * 100.0 / (double)totalCount);

+        }

+        else

+        {

+            printf(" 0\n");

+        }

+    }

+};

+

+struct CountPerMemType

+{

+    uint32_t count[VK_MAX_MEMORY_TYPES] = {};

+

+    void PostValue(uint32_t v)

+    {

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

+        {

+            if((v & (1u << i)) != 0)

+            {

+                ++count[i];

+            }

+        }

+    }

+

+    void Print(uint32_t totalCount) const

+    {

+        if(totalCount)

+        {

+            printf("\n");

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

+            {

+                if(count[i])

+                {

+                    printf("        %u: %u (%.2f%%)\n", i, count[i],

+                        (double)count[i] * 100.0 / (double)totalCount);

+                }

+            }

+        }

+        else

+        {

+            printf(" 0\n");

+        }

+    }

+};

+

+struct StructureStats

+{

+    uint32_t totalCount = 0;

+};

+

+#define PRINT_FIELD(name) \

+    printf("    " #name ":"); \

+    (name).Print(totalCount);

+#define PRINT_FIELD_NAMED(name, nameStr) \

+    printf("    " nameStr ":"); \

+    (name).Print(totalCount);

+

+struct VmaPoolCreateInfoStats : public StructureStats

+{

+    CountPerMemType memoryTypeIndex;

+    FlagSet flags;

+    MinMaxAvg<VkDeviceSize> blockSize;

+    MinMaxAvg<size_t> minBlockCount;

+    MinMaxAvg<size_t> maxBlockCount;

+    Flag minMaxBlockCountEqual;

+    MinMaxAvg<uint32_t> frameInUseCount;

+

+    VmaPoolCreateInfoStats() :

+        flags(VMA_POOL_CREATE_FLAG_COUNT, VMA_POOL_CREATE_FLAG_NAMES, VMA_POOL_CREATE_FLAG_VALUES)

+    {

+    }

+

+    void PostValue(const VmaPoolCreateInfo& v)

+    {

+        ++totalCount;

+

+        memoryTypeIndex.PostValue(v.memoryTypeIndex);

+        flags.PostValue(v.flags);

+        blockSize.PostValue(v.blockSize);

+        minBlockCount.PostValue(v.minBlockCount);

+        maxBlockCount.PostValue(v.maxBlockCount);

+        minMaxBlockCountEqual.PostValue(v.minBlockCount == v.maxBlockCount);

+        frameInUseCount.PostValue(v.frameInUseCount);

+    }

+

+    void Print() const

+    {

+        if(totalCount == 0)

+        {

+            return;

+        }

+

+        printf("VmaPoolCreateInfo (%u):\n", totalCount);

+

+        PRINT_FIELD(memoryTypeIndex);

+        PRINT_FIELD(flags);

+        PRINT_FIELD(blockSize);

+        PRINT_FIELD(minBlockCount);

+        PRINT_FIELD(maxBlockCount);

+        PRINT_FIELD_NAMED(minMaxBlockCountEqual, "minBlockCount == maxBlockCount");

+        PRINT_FIELD(frameInUseCount);

+    }

+};

+

+struct VkBufferCreateInfoStats : public StructureStats

+{

+    FlagSet flags;

+    MinMaxAvg<VkDeviceSize> size;

+    FlagSet usage;

+    Enum sharingMode;

+

+    VkBufferCreateInfoStats() :

+        flags(VK_BUFFER_CREATE_FLAG_COUNT, VK_BUFFER_CREATE_FLAG_NAMES, VK_BUFFER_CREATE_FLAG_VALUES),

+        usage(VK_BUFFER_USAGE_FLAG_COUNT, VK_BUFFER_USAGE_FLAG_NAMES, VK_BUFFER_USAGE_FLAG_VALUES),

+        sharingMode(VK_SHARING_MODE_COUNT, VK_SHARING_MODE_NAMES)

+    {

+    }

+

+    void PostValue(const VkBufferCreateInfo& v)

+    {

+        ++totalCount;

+

+        flags.PostValue(v.flags);

+        size.PostValue(v.size);

+        usage.PostValue(v.usage);

+        sharingMode.PostValue(v.sharingMode);

+    }

+

+    void Print() const

+    {

+        if(totalCount == 0)

+        {

+            return;

+        }

+

+        printf("VkBufferCreateInfo (%u):\n", totalCount);

+

+        PRINT_FIELD(flags);

+        PRINT_FIELD(size);

+        PRINT_FIELD(usage);

+        PRINT_FIELD(sharingMode);

+    }

+};

+

+struct VkImageCreateInfoStats : public StructureStats

+{

+    FlagSet flags;

+    Enum imageType;

+    Enum format;

+    MinMaxAvg<uint32_t> width, height, depth, mipLevels, arrayLayers;

+    Flag depthGreaterThanOne, mipLevelsGreaterThanOne, arrayLayersGreaterThanOne;

+    Enum samples;

+    Enum tiling;

+    FlagSet usage;

+    Enum sharingMode;

+    Enum initialLayout;

+

+    VkImageCreateInfoStats() :

+        flags(VK_IMAGE_CREATE_FLAG_COUNT, VK_IMAGE_CREATE_FLAG_NAMES, VK_IMAGE_CREATE_FLAG_VALUES),

+        imageType(VK_IMAGE_TYPE_COUNT, VK_IMAGE_TYPE_NAMES),

+        format(VK_FORMAT_COUNT, VK_FORMAT_NAMES, VK_FORMAT_VALUES),

+        samples(VK_SAMPLE_COUNT_COUNT, VK_SAMPLE_COUNT_NAMES, VK_SAMPLE_COUNT_VALUES),

+        tiling(VK_IMAGE_TILING_COUNT, VK_IMAGE_TILING_NAMES),

+        usage(VK_IMAGE_USAGE_FLAG_COUNT, VK_IMAGE_USAGE_FLAG_NAMES, VK_IMAGE_USAGE_FLAG_VALUES),

+        sharingMode(VK_SHARING_MODE_COUNT, VK_SHARING_MODE_NAMES),

+        initialLayout(VK_IMAGE_LAYOUT_COUNT, VK_IMAGE_LAYOUT_NAMES, VK_IMAGE_LAYOUT_VALUES)

+    {

+    }

+

+    void PostValue(const VkImageCreateInfo& v)

+    {

+        ++totalCount;

+

+        flags.PostValue(v.flags);

+        imageType.PostValue(v.imageType);

+        format.PostValue(v.format);

+        width.PostValue(v.extent.width);

+        height.PostValue(v.extent.height);

+        depth.PostValue(v.extent.depth);

+        mipLevels.PostValue(v.mipLevels);

+        arrayLayers.PostValue(v.arrayLayers);

+        depthGreaterThanOne.PostValue(v.extent.depth > 1);

+        mipLevelsGreaterThanOne.PostValue(v.mipLevels > 1);

+        arrayLayersGreaterThanOne.PostValue(v.arrayLayers > 1);

+        samples.PostValue(v.samples);

+        tiling.PostValue(v.tiling);

+        usage.PostValue(v.usage);

+        sharingMode.PostValue(v.sharingMode);

+        initialLayout.PostValue(v.initialLayout);

+    }

+

+    void Print() const

+    {

+        if(totalCount == 0)

+        {

+            return;

+        }

+

+        printf("VkImageCreateInfo (%u):\n", totalCount);

+

+        PRINT_FIELD(flags);

+        PRINT_FIELD(imageType);

+        PRINT_FIELD(format);

+        PRINT_FIELD(width);

+        PRINT_FIELD(height);

+        PRINT_FIELD(depth);

+        PRINT_FIELD(mipLevels);

+        PRINT_FIELD(arrayLayers);

+        PRINT_FIELD_NAMED(depthGreaterThanOne, "depth > 1");

+        PRINT_FIELD_NAMED(mipLevelsGreaterThanOne, "mipLevels > 1");

+        PRINT_FIELD_NAMED(arrayLayersGreaterThanOne, "arrayLayers > 1");

+        PRINT_FIELD(samples);

+        PRINT_FIELD(tiling);

+        PRINT_FIELD(usage);

+        PRINT_FIELD(sharingMode);

+        PRINT_FIELD(initialLayout);

+    }

+};

+

+struct VmaAllocationCreateInfoStats : public StructureStats

+{

+    FlagSet flags;

+    Enum usage;

+    FlagSet requiredFlags, preferredFlags;

+    Flag requiredFlagsNotZero, preferredFlagsNotZero;

+    BitMask<uint32_t> memoryTypeBits;

+    Flag poolNotNull;

+    Flag userDataNotNull;

+

+    VmaAllocationCreateInfoStats() :

+        flags(VMA_ALLOCATION_CREATE_FLAG_COUNT, VMA_ALLOCATION_CREATE_FLAG_NAMES, VMA_ALLOCATION_CREATE_FLAG_VALUES),

+        usage(VMA_MEMORY_USAGE_COUNT, VMA_MEMORY_USAGE_NAMES),

+        requiredFlags(VK_MEMORY_PROPERTY_FLAG_COUNT, VK_MEMORY_PROPERTY_FLAG_NAMES, VK_MEMORY_PROPERTY_FLAG_VALUES),

+        preferredFlags(VK_MEMORY_PROPERTY_FLAG_COUNT, VK_MEMORY_PROPERTY_FLAG_NAMES, VK_MEMORY_PROPERTY_FLAG_VALUES)

+    {

+    }

+

+    void PostValue(const VmaAllocationCreateInfo& v, size_t count = 1)

+    {

+        totalCount += (uint32_t)count;

+

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

+        {

+            flags.PostValue(v.flags);

+            usage.PostValue(v.usage);

+            requiredFlags.PostValue(v.requiredFlags);

+            preferredFlags.PostValue(v.preferredFlags);

+            requiredFlagsNotZero.PostValue(v.requiredFlags != 0);

+            preferredFlagsNotZero.PostValue(v.preferredFlags != 0);

+            memoryTypeBits.PostValue(v.memoryTypeBits);

+            poolNotNull.PostValue(v.pool != VK_NULL_HANDLE);

+            userDataNotNull.PostValue(v.pUserData != nullptr);

+        }

+    }

+

+    void Print() const

+    {

+        if(totalCount == 0)

+        {

+            return;

+        }

+

+        printf("VmaAllocationCreateInfo (%u):\n", totalCount);

+

+        PRINT_FIELD(flags);

+        PRINT_FIELD(usage);

+        PRINT_FIELD(requiredFlags);

+        PRINT_FIELD(preferredFlags);

+        PRINT_FIELD_NAMED(requiredFlagsNotZero, "requiredFlags != 0");

+        PRINT_FIELD_NAMED(preferredFlagsNotZero, "preferredFlags != 0");

+        PRINT_FIELD(memoryTypeBits);

+        PRINT_FIELD_NAMED(poolNotNull, "pool != VK_NULL_HANDLE");

+        PRINT_FIELD_NAMED(userDataNotNull, "pUserData != nullptr");

+    }

+};

+

+struct VmaAllocateMemoryPagesStats : public StructureStats

+{

+    MinMaxAvg<size_t> allocationCount;

+

+    void PostValue(size_t allocationCount)

+    {

+        this->allocationCount.PostValue(allocationCount);

+    }

+

+    void Print() const

+    {

+        if(totalCount == 0)

+        {

+            return;

+        }

+

+        printf("vmaAllocateMemoryPages (%u):\n", totalCount);

+

+        PRINT_FIELD(allocationCount);

+    }

+};

+

+struct VmaDefragmentationInfo2Stats : public StructureStats

+{

+    BitMask<VkDeviceSize> maxCpuBytesToMove;

+    BitMask<uint32_t> maxCpuAllocationsToMove;

+    BitMask<VkDeviceSize> maxGpuBytesToMove;

+    BitMask<uint32_t> maxGpuAllocationsToMove;

+    Flag commandBufferNotNull;

+    MinMaxAvg<uint32_t> allocationCount;

+    Flag allocationCountNotZero;

+    MinMaxAvg<uint32_t> poolCount;

+    Flag poolCountNotZero;

+

+    void PostValue(const VmaDefragmentationInfo2& info)

+    {

+        ++totalCount;

+

+        maxCpuBytesToMove.PostValue(info.maxCpuBytesToMove);

+        maxCpuAllocationsToMove.PostValue(info.maxCpuAllocationsToMove);

+        maxGpuBytesToMove.PostValue(info.maxGpuBytesToMove);

+        maxGpuAllocationsToMove.PostValue(info.maxGpuAllocationsToMove);

+        commandBufferNotNull.PostValue(info.commandBuffer != VK_NULL_HANDLE);

+        allocationCount.PostValue(info.allocationCount);

+        allocationCountNotZero.PostValue(info.allocationCount != 0);

+        poolCount.PostValue(info.poolCount);

+        poolCountNotZero.PostValue(info.poolCount != 0);

+    }

+

+    void Print() const

+    {

+        if(totalCount == 0)

+        {

+            return;

+        }

+

+        printf("VmaDefragmentationInfo2 (%u):\n", totalCount);

+

+        PRINT_FIELD(maxCpuBytesToMove);

+        PRINT_FIELD(maxCpuAllocationsToMove);

+        PRINT_FIELD(maxGpuBytesToMove);

+        PRINT_FIELD(maxGpuAllocationsToMove);

+        PRINT_FIELD_NAMED(commandBufferNotNull, "commandBuffer != VK_NULL_HANDLE");

+        PRINT_FIELD(allocationCount);

+        PRINT_FIELD_NAMED(allocationCountNotZero, "allocationCount > 0");

+        PRINT_FIELD(poolCount);

+        PRINT_FIELD_NAMED(poolCountNotZero, "poolCount > 0");

+    }

+};

+

+#undef PRINT_FIELD_NAMED

+#undef PRINT_FIELD

+

+} // namespace DetailedStats

 

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

 // and let VMA report asserts about them.

@@ -196,19 +726,24 @@
     Statistics();

     void Init(uint32_t memHeapCount, uint32_t memTypeCount);

     void PrintMemStats() const;

+    void PrintDetailedStats() 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; }

+    size_t GetAllocationCreationCount() const { return (size_t)m_VmaAllocationCreateInfo.totalCount + m_CreateLostAllocationCount; }

+    size_t GetPoolCreationCount() const { return m_VmaPoolCreateInfo.totalCount; }

+    size_t GetBufferCreationCount() const { return (size_t)m_VkBufferCreateInfo.totalCount; }

 

     void RegisterFunctionCall(VMA_FUNCTION func);

-    void RegisterCreateImage(uint32_t usage, uint32_t tiling);

-    void RegisterCreateBuffer(uint32_t usage);

-    void RegisterCreatePool();

-    void RegisterCreateAllocation(size_t allocCount = 1);

+    void RegisterCreateImage(const VkImageCreateInfo& info);

+    void RegisterCreateBuffer(const VkBufferCreateInfo& info);

+    void RegisterCreatePool(const VmaPoolCreateInfo& info);

+    void RegisterCreateAllocation(const VmaAllocationCreateInfo& info, size_t allocCount = 1);

+    void RegisterCreateLostAllocation() { ++m_CreateLostAllocationCount; }

+    void RegisterAllocateMemoryPages(size_t allocCount) { m_VmaAllocateMemoryPages.PostValue(allocCount); }

+    void RegisterDefragmentation(const VmaDefragmentationInfo2& info);

 

     void UpdateMemStats(const VmaStats& currStats);

 

@@ -220,8 +755,6 @@
     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

@@ -240,6 +773,14 @@
         MemStatInfo total;

     } m_PeakMemStats;

 

+    DetailedStats::VmaPoolCreateInfoStats m_VmaPoolCreateInfo;

+    DetailedStats::VkBufferCreateInfoStats m_VkBufferCreateInfo;

+    DetailedStats::VkImageCreateInfoStats m_VkImageCreateInfo;

+    DetailedStats::VmaAllocationCreateInfoStats m_VmaAllocationCreateInfo;

+    size_t m_CreateLostAllocationCount = 0;

+    DetailedStats::VmaAllocateMemoryPagesStats m_VmaAllocateMemoryPages;

+    DetailedStats::VmaDefragmentationInfo2Stats m_VmaDefragmentationInfo2;

+

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

     static void PrintMemStatInfo(const MemStatInfo& info);

 };

@@ -346,40 +887,55 @@
     }

 }

 

+void Statistics::PrintDetailedStats() const

+{

+    m_VmaPoolCreateInfo.Print();

+    m_VmaAllocationCreateInfo.Print();

+    m_VmaAllocateMemoryPages.Print();

+    m_VkBufferCreateInfo.Print();

+    m_VkImageCreateInfo.Print();

+    m_VmaDefragmentationInfo2.Print();

+}

+

 void Statistics::RegisterFunctionCall(VMA_FUNCTION func)

 {

     ++m_FunctionCallCount[(size_t)func];

 }

 

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

+void Statistics::RegisterCreateImage(const VkImageCreateInfo& info)

 {

-    if(tiling == VK_IMAGE_TILING_LINEAR)

+    if(info.tiling == VK_IMAGE_TILING_LINEAR)

         ++m_LinearImageCreationCount;

     else

     {

-        const uint32_t imgClass = ImageUsageToClass(usage);

+        const uint32_t imgClass = ImageUsageToClass(info.usage);

         ++m_ImageCreationCount[imgClass];

     }

 

-    ++m_AllocationCreationCount;

+    m_VkImageCreateInfo.PostValue(info);

 }

 

-void Statistics::RegisterCreateBuffer(uint32_t usage)

+void Statistics::RegisterCreateBuffer(const VkBufferCreateInfo& info)

 {

-    const uint32_t bufClass = BufferUsageToClass(usage);

+    const uint32_t bufClass = BufferUsageToClass(info.usage);

     ++m_BufferCreationCount[bufClass];

 

-    ++m_AllocationCreationCount;

+    m_VkBufferCreateInfo.PostValue(info);

 }

 

-void Statistics::RegisterCreatePool()

+void Statistics::RegisterCreatePool(const VmaPoolCreateInfo& info)

 {

-    ++m_PoolCreationCount;

+    m_VmaPoolCreateInfo.PostValue(info);

 }

 

-void Statistics::RegisterCreateAllocation(size_t allocCount)

+void Statistics::RegisterCreateAllocation(const VmaAllocationCreateInfo& info, size_t allocCount)

 {

-    m_AllocationCreationCount += allocCount;

+    m_VmaAllocationCreateInfo.PostValue(info, allocCount);

+}

+

+void Statistics::RegisterDefragmentation(const VmaDefragmentationInfo2& info)

+{

+    m_VmaDefragmentationInfo2.PostValue(info);

 }

 

 void Statistics::UpdateMemStats(const VmaStats& currStats)

@@ -1885,14 +2441,9 @@
     }

 

     // Buffers

-    const size_t bufferCreationCount =

-        m_Stats.GetBufferCreationCount(0) +

-        m_Stats.GetBufferCreationCount(1) +

-        m_Stats.GetBufferCreationCount(2) +

-        m_Stats.GetBufferCreationCount(3);

-    if(bufferCreationCount > 0)

+    if(m_Stats.GetBufferCreationCount())

     {

-        printf("    Total buffers created: %zu\n", bufferCreationCount);

+        printf("    Total buffers created: %zu\n", m_Stats.GetBufferCreationCount());

         if(g_Verbosity == VERBOSITY::MAXIMUM)

         {

             printf("        Class 0 (indirect/vertex/index): %zu\n", m_Stats.GetBufferCreationCount(0));

@@ -1972,6 +2523,12 @@
         }

     }

 

+    // Detailed stats

+    if(g_Verbosity == VERBOSITY::MAXIMUM)

+    {

+        m_Stats.PrintDetailedStats();

+    }

+

     if(g_MemStatsEnabled)

     {

         m_Stats.PrintMemStats();

@@ -2063,7 +2620,7 @@
             StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), poolCreateInfo.frameInUseCount) &&

             StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), origPtr))

         {

-            m_Stats.RegisterCreatePool();

+            m_Stats.RegisterCreatePool(poolCreateInfo);

 

             Pool poolDesc = {};

             VkResult res = vmaCreatePool(m_Allocator, &poolCreateInfo, &poolDesc.pool);

@@ -2242,9 +2799,6 @@
         {

             FindPool(lineNumber, origPool, allocCreateInfo.pool);

 

-            // Forcing VK_SHARING_MODE_EXCLUSIVE because we use only one queue anyway.

-            bufCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

-

             if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 11)

             {

                 PrepareUserData(

@@ -2255,7 +2809,11 @@
                     allocCreateInfo.pUserData);

             }

 

-            m_Stats.RegisterCreateBuffer(bufCreateInfo.usage);

+            m_Stats.RegisterCreateBuffer(bufCreateInfo);

+            m_Stats.RegisterCreateAllocation(allocCreateInfo);

+

+            // Forcing VK_SHARING_MODE_EXCLUSIVE because we use only one queue anyway.

+            bufCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

 

             Allocation allocDesc = { };

             allocDesc.allocationFlags = allocCreateInfo.flags;

@@ -2379,9 +2937,6 @@
         {

             FindPool(lineNumber, origPool, allocCreateInfo.pool);

 

-            // Forcing VK_SHARING_MODE_EXCLUSIVE because we use only one queue anyway.

-            imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

-

             if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 20)

             {

                 PrepareUserData(

@@ -2392,7 +2947,11 @@
                     allocCreateInfo.pUserData);

             }

 

-            m_Stats.RegisterCreateImage(imageCreateInfo.usage, imageCreateInfo.tiling);

+            m_Stats.RegisterCreateImage(imageCreateInfo);

+            m_Stats.RegisterCreateAllocation(allocCreateInfo);

+

+            // Forcing VK_SHARING_MODE_EXCLUSIVE because we use only one queue anyway.

+            imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

 

             Allocation allocDesc = {};

             allocDesc.allocationFlags = allocCreateInfo.flags;

@@ -2470,7 +3029,7 @@
             Allocation allocDesc = {};

             vmaCreateLostAllocation(m_Allocator, &allocDesc.allocation);

             UpdateMemStats();

-            m_Stats.RegisterCreateAllocation();

+            m_Stats.RegisterCreateLostAllocation();

 

             AddAllocation(lineNumber, origPtr, VK_SUCCESS, "vmaCreateLostAllocation", std::move(allocDesc));

         }

@@ -2519,7 +3078,7 @@
             }

 

             UpdateMemStats();

-            m_Stats.RegisterCreateAllocation();

+            m_Stats.RegisterCreateAllocation(allocCreateInfo);

 

             Allocation allocDesc = {};

             allocDesc.allocationFlags = allocCreateInfo.flags;

@@ -2574,7 +3133,8 @@
                 }

 

                 UpdateMemStats();

-                m_Stats.RegisterCreateAllocation(allocCount);

+                m_Stats.RegisterCreateAllocation(allocCreateInfo, allocCount);

+                m_Stats.RegisterAllocateMemoryPages(allocCount);

 

                 std::vector<VmaAllocation> allocations(allocCount);

 

@@ -2645,6 +3205,9 @@
                     allocCreateInfo.pUserData);

             }

 

+            UpdateMemStats();

+            m_Stats.RegisterCreateAllocation(allocCreateInfo);

+

             if(requiresDedicatedAllocation || prefersDedicatedAllocation)

             {

                 allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;

@@ -2659,9 +3222,6 @@
                 m_AllocateForBufferImageWarningIssued = true;

             }

 

-            UpdateMemStats();

-            m_Stats.RegisterCreateAllocation();

-

             Allocation allocDesc = {};

             allocDesc.allocationFlags = allocCreateInfo.flags;

             VkResult res = vmaAllocateMemory(m_Allocator, &memReq, &allocCreateInfo, &allocDesc.allocation, nullptr);

@@ -3118,6 +3678,8 @@
                 }

             }

 

+            m_Stats.RegisterDefragmentation(defragInfo);

+

             VmaDefragmentationContext defragCtx = nullptr;

             VkResult res = vmaDefragmentationBegin(m_Allocator, &defragInfo, nullptr, &defragCtx);

 

@@ -3251,7 +3813,6 @@
         "    --DefragmentAfterLine <Line> - Defragment memory after specified source file line and print statistics.\n"

         "        It also prints detailed statistics to files VmaReplay_Line####_Defragment*.json\n"

         "    --DefragmentationFlags <Flags> - Flags to be applied when using DefragmentAfterLine.\n"

-        "        E.g. 1 for FAST algorithm, 2 for OPTIMAL algorithm.\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"