vulkaninfo: Replace devsim with Profile json output
authorCharles Giessen <charles@lunarg.com>
Tue, 22 Feb 2022 23:38:43 +0000 (16:38 -0700)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Tue, 22 Mar 2022 23:20:50 +0000 (17:20 -0600)
Make vulkaninfo capable of printing Vulkan Profiles with the json output. This
replaces the current DevSim output and folds the portability schema output into
the regular JSON output.

Changes include:
* Printing to file by default if json output is chosen
* Cleaning up codegen for extension structs
* Fixing up the help message
* Consolidating the portability schema output into just json

scripts/vulkaninfo_generator.py
vulkaninfo/generated/vulkaninfo.hpp
vulkaninfo/outputprinter.h
vulkaninfo/vulkaninfo.cpp
vulkaninfo/vulkaninfo.h
vulkaninfo/vulkaninfo.md

index 1ddcc42..3f0e2be 100644 (file)
@@ -59,20 +59,15 @@ license_header = '''
 '''
 
 custom_formatters = r'''
-void DumpVkConformanceVersion(Printer &p, std::string name, VkConformanceVersion &c) {
-    p.PrintKeyString("conformanceVersion", std::to_string(c.major)+ "." + std::to_string(c.minor) + "." + std::to_string(c.subminor) + "."
-             + std::to_string(c.patch));
-}
-
 template <typename T>
-std::string to_hex_str(T i) {
+std::string to_hex_str(const T i) {
     std::stringstream stream;
     stream << "0x" << std::setfill('0') << std::setw(sizeof(T)) << std::hex << i;
     return stream.str();
 }
 
 template <typename T>
-std::string to_hex_str(Printer &p, T i) {
+std::string to_hex_str(Printer &p, const T i) {
     if (p.Type() == OutputType::json)
         return std::to_string(i);
     else if (p.Type() == OutputType::vkconfig_output)
@@ -89,7 +84,7 @@ structures_to_gen = ['VkExtent3D', 'VkExtent2D', 'VkPhysicalDeviceLimits', 'VkPh
                      'VkSurfaceCapabilitiesKHR', 'VkSurfaceFormatKHR', 'VkLayerProperties', 'VkPhysicalDeviceToolProperties']
 enums_to_gen = ['VkResult', 'VkFormat', 'VkPresentModeKHR',
                 'VkPhysicalDeviceType', 'VkImageTiling']
-flags_to_gen = ['VkSurfaceTransformFlagsKHR', 'VkCompositeAlphaFlagsKHR', 'VkSurfaceCounterFlagsEXT',
+flags_to_gen = ['VkSurfaceTransformFlagsKHR', 'VkCompositeAlphaFlagsKHR', 'VkSurfaceCounterFlagsEXT', 'VkQueueFlags',
                 'VkDeviceGroupPresentModeFlagsKHR', 'VkFormatFeatureFlags', 'VkFormatFeatureFlags2', 'VkMemoryPropertyFlags', 'VkMemoryHeapFlags']
 flags_strings_to_gen = ['VkQueueFlags']
 
@@ -98,12 +93,17 @@ struct_short_versions_to_gen = ['VkExtent3D']
 struct_comparisons_to_gen = ['VkSurfaceFormatKHR', 'VkSurfaceFormat2KHR', 'VkSurfaceCapabilitiesKHR',
                              'VkSurfaceCapabilities2KHR', 'VkSurfaceCapabilities2EXT']
 # don't generate these structures
-struct_blacklist = ['VkConformanceVersion']
+struct_blacklist = ['VkVideoProfilesKHR', 'VkVideoProfileKHR', 'VkDrmFormatModifierPropertiesListEXT', 'VkDrmFormatModifierPropertiesEXT', 'VkDrmFormatModifierPropertiesList2EXT']
+
+# generate these structures such that they only print when not in json mode (as json wants them separate)
+portability_structs = ['VkPhysicalDevicePortabilitySubsetFeaturesKHR', 'VkPhysicalDevicePortabilitySubsetPropertiesKHR']
 
 # iostream or custom outputter handles these types
 predefined_types = ['char', 'VkBool32', 'uint32_t', 'uint8_t', 'int32_t',
                     'float', 'uint64_t', 'size_t', 'VkDeviceSize', 'int64_t']
 
+names_to_ignore = ['sType', 'pNext', 'stdProfileIdc']
+
 EXTENSION_TYPE_INSTANCE = 'instance'
 EXTENSION_TYPE_DEVICE = 'device'
 EXTENSION_TYPE_BOTH = 'both'
@@ -364,24 +364,24 @@ class VulkanInfoGenerator(OutputGenerator):
                         return
 
         for key, value in EXTENSION_CATEGORIES.items():
-            if typeinfo.elem.get('structextends') == value.get('extends'):
+            if str(typeinfo.elem.get('structextends')).find(value.get('extends')) != -1:
                 self.extension_sets[key].add(name)
 
 
 def GatherTypesToGen(structure_list, structures):
     types = set()
+    for s in structures:
+        types.add(s)
     added_stuff = True  # repeat until no new types are added
     while added_stuff == True:
         added_stuff = False
-        for s in (x for x in structure_list if x.name in structures):
-            size = len(types)
-            types.add(s.name)
-            if len(types) != size:
-                added_stuff = True
-            for m in s.members:
-                if m.typeID not in predefined_types and m.name not in ['sType', 'pNext']:
-                    types.add(m.typeID)
-    types = sorted(types)
+        for s in structure_list:
+            if s.name in types:
+                for m in s.members:
+                    if m.typeID not in predefined_types and m.name not in names_to_ignore:
+                        if m.typeID not in types:
+                            types.add(m.typeID)
+                            added_stuff = True
     return types
 
 
@@ -425,10 +425,10 @@ def PrintEnum(enum, gen):
     out = ''
     out += AddGuardHeader(GetExtension(enum.name, gen))
     out += f"""void Dump{enum.name}(Printer &p, std::string name, {enum.name} value) {{
-    if (p.Type() == OutputType::json) {{
-        p.PrintKeyValue(name, value);
-    }} else {{
-        p.PrintKeyString(name, {enum.name}String(value));\n    }}
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + {enum.name}String(value));
+    else
+        p.PrintKeyString(name, {enum.name}String(value));
 }}
 """
     out += AddGuardFooter(GetExtension(enum.name, gen))
@@ -451,17 +451,19 @@ def PrintGetFlagStrings(name, bitmask):
 
 def PrintFlags(bitmask, name):
     out = f"void Dump{name}(Printer &p, std::string name, {name} value) {{\n"
-    out += f"""    if (p.Type() == OutputType::json) {{ p.PrintKeyValue(name, value); return; }}
-    if (static_cast<{bitmask.name}>(value) == 0) {{
+    out += f"""    if (static_cast<{bitmask.name}>(value) == 0) {{
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }}
     auto strings = {bitmask.name}GetStrings(static_cast<{bitmask.name}>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){{
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }}
 }}
 """
@@ -471,7 +473,8 @@ def PrintFlags(bitmask, name):
 def PrintFlagBits(bitmask):
     return f"""void Dump{bitmask.name}(Printer &p, std::string name, {bitmask.name} value) {{
     auto strings = {bitmask.name}GetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }}
 """
 
@@ -517,7 +520,7 @@ def PrintStructure(struct, types_to_gen, structure_names, aliases):
             if len(v.name) > max_key_len:
                 max_key_len = len(v.name)
 
-    out += f"void Dump{struct.name}(Printer &p, std::string name, {struct.name} &obj) {{\n"
+    out += f"void Dump{struct.name}(Printer &p, std::string name, const {struct.name} &obj) {{\n"
     if struct.name == "VkPhysicalDeviceLimits":
         out += f"    if (p.Type() == OutputType::json)\n"
         out += f'        p.ObjectStart("limits");\n'
@@ -539,15 +542,23 @@ def PrintStructure(struct, types_to_gen, structure_names, aliases):
             if v.typeID == "char":
                 out += f'    p.PrintKeyString("{v.name}", obj.{v.name});\n'
             # uuid's
-            elif (v.arrayLength == str(16) and v.typeID == "uint8_t"):  # VK_UUID_SIZE
-                out += f'    p.PrintKeyString("{v.name}", to_string_16(obj.{v.name}));\n'
-            elif (v.arrayLength == str(8) and v.typeID == "uint8_t"):  # VK_LUID_SIZE
-                out += f"    if (obj.deviceLUIDValid)"  # special case
-                out += f' p.PrintKeyString("{v.name}", to_string_8(obj.{v.name}));\n'
-            elif struct.name == "VkQueueFamilyGlobalPriorityPropertiesEXT" and v.name == "priorities":
+            elif v.typeID == "uint8_t" and (v.arrayLength == '8' or v.arrayLength == '16'):  # VK_UUID_SIZE
+                if v.arrayLength == '8':
+                    out += '    if (obj.deviceLUIDValid) { // special case\n'
+                out += f'''    if (p.Type() == OutputType::json) {{
+        ArrayWrapper arr(p, "{v.name}");
+        for (uint32_t i = 0; i < {v.arrayLength}; i++) p.PrintElement(static_cast<uint32_t>(obj.{v.name}[i]));
+    }} else
+        p.PrintKeyString("{v.name}", to_string_{v.arrayLength}(obj.{v.name}));\n'''
+                if v.arrayLength == '8':
+                    out += '    }\n'
+            elif struct.name == "VkQueueFamilyGlobalPriorityPropertiesKHR" and v.name == "priorities":
                 out += f'    ArrayWrapper arr(p,"{v.name}", obj.priorityCount);\n'
                 out += f"    for (uint32_t i = 0; i < obj.priorityCount; i++) {{\n"
-                out += f'        Dump{v.typeID}(p, "{v.name}", obj.{v.name}[i]);\n'
+                out += f'       if (p.Type() == OutputType::json)\n'
+                out += f'           p.PrintString(std::string("VK_") + VkQueueGlobalPriorityKHRString(obj.priorities[i]));\n'
+                out += f'       else\n'
+                out += f'           p.PrintString(VkQueueGlobalPriorityKHRString(obj.priorities[i]));\n'
                 out += f"    }}\n"
             elif v.arrayLength.isdigit():
                 out += f'    {{   ArrayWrapper arr(p,"{v.name}", ' + v.arrayLength + ');\n'
@@ -567,15 +578,16 @@ def PrintStructure(struct, types_to_gen, structure_names, aliases):
                 out += f"    }}\n"
         elif v.typeID == "VkBool32":
             out += f'    p.PrintKeyBool("{v.name}", static_cast<bool>(obj.{v.name}));\n'
-        elif v.typeID == "VkConformanceVersion":
-            out += f'    DumpVkConformanceVersion(p, "conformanceVersion", obj.{v.name});\n'
+        elif v.typeID == 'uint8_t':
+            out += f'    p.PrintKeyValue("{v.name}", static_cast<uint32_t>(obj.{v.name}));\n'
         elif v.typeID == "VkDeviceSize":
             out += f'    p.PrintKeyValue("{v.name}", to_hex_str(p, obj.{v.name}));\n'
         elif v.typeID in predefined_types:
             out += f'    p.PrintKeyValue("{v.name}", obj.{v.name});\n'
-        elif v.name not in ['sType', 'pNext']:
+        elif v.name not in names_to_ignore:
             # if it is an enum/flag/bitmask
             out += f'    Dump{v.typeID}(p, "{v.name}", obj.{v.name});\n'
+
     if struct.name in ["VkPhysicalDeviceLimits", "VkPhysicalDeviceSparseProperties"]:
         out += f"    p.ObjectEnd();\n"
     out += f"}}\n"
@@ -622,6 +634,8 @@ def PrintChainStruct(listName, structures, all_structures, chain_details):
 
     out += f"    void* start_of_chain = nullptr;\n"
     for s in structs_to_print:
+        if s.name in struct_blacklist:
+            continue
         out += AddGuardHeader(s)
         if s.sTypeName is not None:
             out += f"    {s.name} {s.name[2:]}{{}};\n"
@@ -635,6 +649,8 @@ def PrintChainStruct(listName, structures, all_structures, chain_details):
         out += AddGuardFooter(s)
     out += f"    void initialize_chain() noexcept {{\n"
     for s in structs_to_print:
+        if s.name in struct_blacklist:
+            continue
         out += AddGuardHeader(s)
         out += f"        {s.name[2:]}.sType = {s.sTypeName};\n"
         out += AddGuardFooter(s)
@@ -642,6 +658,8 @@ def PrintChainStruct(listName, structures, all_structures, chain_details):
 
     out += f"        std::vector<VkBaseOutStructure*> chain_members;\n"
     for s in structs_to_print:
+        if s.name in struct_blacklist:
+            continue
         out += AddGuardHeader(s)
         out += f"        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&{s.name[2:]}));\n"
         out += AddGuardFooter(s)
@@ -683,7 +701,7 @@ def PrintChainIterator(listName, structures, all_structures, checkExtLoc, extTyp
         version_desc = "inst.instance_version"
 
     for s in sorted_structures:
-        if s.sTypeName is None:
+        if s.sTypeName is None or s.name in struct_blacklist:
             continue
 
         extEnables = {}
@@ -704,6 +722,8 @@ def PrintChainIterator(listName, structures, all_structures, checkExtLoc, extTyp
         if s.name in structures:
             out += AddGuardHeader(s)
             out += f"        if (structure->sType == {s.sTypeName}"
+            if s.name in portability_structs:
+                out += f" && p.Type() != OutputType::json"
             has_version = version is not None
             has_extNameStr = len(extEnables) > 0 or s.name in aliases.keys()
 
@@ -754,7 +774,7 @@ def PrintStructComparison(structure):
     out += f"    return "
     is_first = True
     for m in structure.members:
-        if m.name not in ['sType', 'pNext']:
+        if m.name not in names_to_ignore:
             if not is_first:
                 out += f"\n        && "
             else:
@@ -868,14 +888,13 @@ class VulkanFlags:
 
 
 class VulkanVariable:
-    def __init__(self, rootNode, constants, parentName):
+    def __init__(self, rootNode, constants):
         self.name = rootNode.find('name').text
         # Typename, dereferenced and converted to a useable C++ token
         self.typeID = rootNode.find('type').text
         self.baseType = self.typeID
         self.childType = None
         self.arrayLength = None
-
         self.text = ''
         for node in rootNode.itertext():
             comment = rootNode.find('comment')
@@ -937,8 +956,7 @@ class VulkanStructure:
         for node in rootNode.findall('member'):
             if(node.get('values') is not None):
                 self.sTypeName = node.get('values')
-            self.members.append(VulkanVariable(
-                node, constants, self.name))
+            self.members.append(VulkanVariable(node, constants))
 
         for k, elem in extTypes.items():
             if k == self.name:
index 53c5935..3ac1d21 100644 (file)
 #include "vulkaninfo.h"
 #include "outputprinter.h"
 
-void DumpVkConformanceVersion(Printer &p, std::string name, VkConformanceVersion &c) {
-    p.PrintKeyString("conformanceVersion", std::to_string(c.major)+ "." + std::to_string(c.minor) + "." + std::to_string(c.subminor) + "."
-             + std::to_string(c.patch));
-}
-
 template <typename T>
-std::string to_hex_str(T i) {
+std::string to_hex_str(const T i) {
     std::stringstream stream;
     stream << "0x" << std::setfill('0') << std::setw(sizeof(T)) << std::hex << i;
     return stream.str();
 }
 
 template <typename T>
-std::string to_hex_str(Printer &p, T i) {
+std::string to_hex_str(Printer &p, const T i) {
     if (p.Type() == OutputType::json)
         return std::to_string(i);
     else if (p.Type() == OutputType::vkconfig_output)
@@ -71,11 +66,10 @@ std::string VkColorSpaceKHRString(VkColorSpaceKHR value) {
     }
 }
 void DumpVkColorSpaceKHR(Printer &p, std::string name, VkColorSpaceKHR value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkColorSpaceKHRString(value));
+    else
         p.PrintKeyString(name, VkColorSpaceKHRString(value));
-    }
 }
 std::string VkDriverIdString(VkDriverId value) {
     switch (value) {
@@ -105,11 +99,10 @@ std::string VkDriverIdString(VkDriverId value) {
     }
 }
 void DumpVkDriverId(Printer &p, std::string name, VkDriverId value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkDriverIdString(value));
+    else
         p.PrintKeyString(name, VkDriverIdString(value));
-    }
 }
 std::string VkFormatString(VkFormat value) {
     switch (value) {
@@ -364,11 +357,10 @@ std::string VkFormatString(VkFormat value) {
     }
 }
 void DumpVkFormat(Printer &p, std::string name, VkFormat value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkFormatString(value));
+    else
         p.PrintKeyString(name, VkFormatString(value));
-    }
 }
 std::string VkImageTilingString(VkImageTiling value) {
     switch (value) {
@@ -379,11 +371,10 @@ std::string VkImageTilingString(VkImageTiling value) {
     }
 }
 void DumpVkImageTiling(Printer &p, std::string name, VkImageTiling value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkImageTilingString(value));
+    else
         p.PrintKeyString(name, VkImageTilingString(value));
-    }
 }
 std::string VkPhysicalDeviceTypeString(VkPhysicalDeviceType value) {
     switch (value) {
@@ -396,11 +387,10 @@ std::string VkPhysicalDeviceTypeString(VkPhysicalDeviceType value) {
     }
 }
 void DumpVkPhysicalDeviceType(Printer &p, std::string name, VkPhysicalDeviceType value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkPhysicalDeviceTypeString(value));
+    else
         p.PrintKeyString(name, VkPhysicalDeviceTypeString(value));
-    }
 }
 std::string VkPointClippingBehaviorString(VkPointClippingBehavior value) {
     switch (value) {
@@ -410,11 +400,10 @@ std::string VkPointClippingBehaviorString(VkPointClippingBehavior value) {
     }
 }
 void DumpVkPointClippingBehavior(Printer &p, std::string name, VkPointClippingBehavior value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkPointClippingBehaviorString(value));
+    else
         p.PrintKeyString(name, VkPointClippingBehaviorString(value));
-    }
 }
 std::string VkPresentModeKHRString(VkPresentModeKHR value) {
     switch (value) {
@@ -428,11 +417,10 @@ std::string VkPresentModeKHRString(VkPresentModeKHR value) {
     }
 }
 void DumpVkPresentModeKHR(Printer &p, std::string name, VkPresentModeKHR value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkPresentModeKHRString(value));
+    else
         p.PrintKeyString(name, VkPresentModeKHRString(value));
-    }
 }
 std::string VkQueueGlobalPriorityKHRString(VkQueueGlobalPriorityKHR value) {
     switch (value) {
@@ -444,11 +432,10 @@ std::string VkQueueGlobalPriorityKHRString(VkQueueGlobalPriorityKHR value) {
     }
 }
 void DumpVkQueueGlobalPriorityKHR(Printer &p, std::string name, VkQueueGlobalPriorityKHR value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkQueueGlobalPriorityKHRString(value));
+    else
         p.PrintKeyString(name, VkQueueGlobalPriorityKHRString(value));
-    }
 }
 std::string VkResultString(VkResult value) {
     switch (value) {
@@ -494,11 +481,10 @@ std::string VkResultString(VkResult value) {
     }
 }
 void DumpVkResult(Printer &p, std::string name, VkResult value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkResultString(value));
+    else
         p.PrintKeyString(name, VkResultString(value));
-    }
 }
 std::string VkShaderFloatControlsIndependenceString(VkShaderFloatControlsIndependence value) {
     switch (value) {
@@ -509,11 +495,10 @@ std::string VkShaderFloatControlsIndependenceString(VkShaderFloatControlsIndepen
     }
 }
 void DumpVkShaderFloatControlsIndependence(Printer &p, std::string name, VkShaderFloatControlsIndependence value) {
-    if (p.Type() == OutputType::json) {
-        p.PrintKeyValue(name, value);
-    } else {
+    if (p.Type() == OutputType::json)
+        p.PrintKeyString(name, std::string("VK_") + VkShaderFloatControlsIndependenceString(value));
+    else
         p.PrintKeyString(name, VkShaderFloatControlsIndependenceString(value));
-    }
 }
 std::vector<const char *> VkCompositeAlphaFlagBitsKHRGetStrings(VkCompositeAlphaFlagBitsKHR value) {
     std::vector<const char *> strings;
@@ -525,22 +510,25 @@ std::vector<const char *> VkCompositeAlphaFlagBitsKHRGetStrings(VkCompositeAlpha
     return strings;
 }
 void DumpVkCompositeAlphaFlagsKHR(Printer &p, std::string name, VkCompositeAlphaFlagsKHR value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkCompositeAlphaFlagBitsKHR>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkCompositeAlphaFlagBitsKHRGetStrings(static_cast<VkCompositeAlphaFlagBitsKHR>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkCompositeAlphaFlagBitsKHR(Printer &p, std::string name, VkCompositeAlphaFlagBitsKHR value) {
     auto strings = VkCompositeAlphaFlagBitsKHRGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkDeviceGroupPresentModeFlagBitsKHRGetStrings(VkDeviceGroupPresentModeFlagBitsKHR value) {
@@ -553,22 +541,25 @@ std::vector<const char *> VkDeviceGroupPresentModeFlagBitsKHRGetStrings(VkDevice
     return strings;
 }
 void DumpVkDeviceGroupPresentModeFlagsKHR(Printer &p, std::string name, VkDeviceGroupPresentModeFlagsKHR value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkDeviceGroupPresentModeFlagBitsKHR>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkDeviceGroupPresentModeFlagBitsKHRGetStrings(static_cast<VkDeviceGroupPresentModeFlagBitsKHR>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkDeviceGroupPresentModeFlagBitsKHR(Printer &p, std::string name, VkDeviceGroupPresentModeFlagBitsKHR value) {
     auto strings = VkDeviceGroupPresentModeFlagBitsKHRGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkFormatFeatureFlagBitsGetStrings(VkFormatFeatureFlagBits value) {
@@ -608,22 +599,25 @@ std::vector<const char *> VkFormatFeatureFlagBitsGetStrings(VkFormatFeatureFlagB
     return strings;
 }
 void DumpVkFormatFeatureFlags(Printer &p, std::string name, VkFormatFeatureFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkFormatFeatureFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkFormatFeatureFlagBitsGetStrings(static_cast<VkFormatFeatureFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkFormatFeatureFlagBits(Printer &p, std::string name, VkFormatFeatureFlagBits value) {
     auto strings = VkFormatFeatureFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkFormatFeatureFlagBits2GetStrings(VkFormatFeatureFlagBits2 value) {
@@ -667,22 +661,25 @@ std::vector<const char *> VkFormatFeatureFlagBits2GetStrings(VkFormatFeatureFlag
     return strings;
 }
 void DumpVkFormatFeatureFlags2(Printer &p, std::string name, VkFormatFeatureFlags2 value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkFormatFeatureFlagBits2>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkFormatFeatureFlagBits2GetStrings(static_cast<VkFormatFeatureFlagBits2>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkFormatFeatureFlagBits2(Printer &p, std::string name, VkFormatFeatureFlagBits2 value) {
     auto strings = VkFormatFeatureFlagBits2GetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkImageUsageFlagBitsGetStrings(VkImageUsageFlagBits value) {
@@ -708,22 +705,25 @@ std::vector<const char *> VkImageUsageFlagBitsGetStrings(VkImageUsageFlagBits va
     return strings;
 }
 void DumpVkImageUsageFlags(Printer &p, std::string name, VkImageUsageFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkImageUsageFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkImageUsageFlagBitsGetStrings(static_cast<VkImageUsageFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkImageUsageFlagBits(Printer &p, std::string name, VkImageUsageFlagBits value) {
     auto strings = VkImageUsageFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkMemoryHeapFlagBitsGetStrings(VkMemoryHeapFlagBits value) {
@@ -734,22 +734,25 @@ std::vector<const char *> VkMemoryHeapFlagBitsGetStrings(VkMemoryHeapFlagBits va
     return strings;
 }
 void DumpVkMemoryHeapFlags(Printer &p, std::string name, VkMemoryHeapFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkMemoryHeapFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkMemoryHeapFlagBitsGetStrings(static_cast<VkMemoryHeapFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkMemoryHeapFlagBits(Printer &p, std::string name, VkMemoryHeapFlagBits value) {
     auto strings = VkMemoryHeapFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkMemoryPropertyFlagBitsGetStrings(VkMemoryPropertyFlagBits value) {
@@ -767,22 +770,59 @@ std::vector<const char *> VkMemoryPropertyFlagBitsGetStrings(VkMemoryPropertyFla
     return strings;
 }
 void DumpVkMemoryPropertyFlags(Printer &p, std::string name, VkMemoryPropertyFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkMemoryPropertyFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkMemoryPropertyFlagBitsGetStrings(static_cast<VkMemoryPropertyFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkMemoryPropertyFlagBits(Printer &p, std::string name, VkMemoryPropertyFlagBits value) {
     auto strings = VkMemoryPropertyFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
+}
+
+std::vector<const char *> VkQueueFlagBitsGetStrings(VkQueueFlagBits value) {
+    std::vector<const char *> strings;
+    if (value == 0) { strings.push_back("None"); return strings; }
+    if (VK_QUEUE_GRAPHICS_BIT & value) strings.push_back("QUEUE_GRAPHICS_BIT");
+    if (VK_QUEUE_COMPUTE_BIT & value) strings.push_back("QUEUE_COMPUTE_BIT");
+    if (VK_QUEUE_TRANSFER_BIT & value) strings.push_back("QUEUE_TRANSFER_BIT");
+    if (VK_QUEUE_SPARSE_BINDING_BIT & value) strings.push_back("QUEUE_SPARSE_BINDING_BIT");
+    if (VK_QUEUE_PROTECTED_BIT & value) strings.push_back("QUEUE_PROTECTED_BIT");
+    if (VK_QUEUE_VIDEO_DECODE_BIT_KHR & value) strings.push_back("QUEUE_VIDEO_DECODE_BIT_KHR");
+    if (VK_QUEUE_VIDEO_ENCODE_BIT_KHR & value) strings.push_back("QUEUE_VIDEO_ENCODE_BIT_KHR");
+    return strings;
+}
+void DumpVkQueueFlags(Printer &p, std::string name, VkQueueFlags value) {
+    if (static_cast<VkQueueFlagBits>(value) == 0) {
+        ArrayWrapper arr(p, name, 0);
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
+            p.SetAsType().PrintString("None");
+        return;
+    }
+    auto strings = VkQueueFlagBitsGetStrings(static_cast<VkQueueFlagBits>(value));
+    ArrayWrapper arr(p, name, strings.size());
+    for(auto& str : strings){
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
+    }
+}
+void DumpVkQueueFlagBits(Printer &p, std::string name, VkQueueFlagBits value) {
+    auto strings = VkQueueFlagBitsGetStrings(value);
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::string VkQueueFlagsString(VkQueueFlags value) {
@@ -828,22 +868,25 @@ std::vector<const char *> VkResolveModeFlagBitsGetStrings(VkResolveModeFlagBits
     return strings;
 }
 void DumpVkResolveModeFlags(Printer &p, std::string name, VkResolveModeFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkResolveModeFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkResolveModeFlagBitsGetStrings(static_cast<VkResolveModeFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkResolveModeFlagBits(Printer &p, std::string name, VkResolveModeFlagBits value) {
     auto strings = VkResolveModeFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkSampleCountFlagBitsGetStrings(VkSampleCountFlagBits value) {
@@ -859,22 +902,25 @@ std::vector<const char *> VkSampleCountFlagBitsGetStrings(VkSampleCountFlagBits
     return strings;
 }
 void DumpVkSampleCountFlags(Printer &p, std::string name, VkSampleCountFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkSampleCountFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkSampleCountFlagBitsGetStrings(static_cast<VkSampleCountFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkSampleCountFlagBits(Printer &p, std::string name, VkSampleCountFlagBits value) {
     auto strings = VkSampleCountFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkShaderStageFlagBitsGetStrings(VkShaderStageFlagBits value) {
@@ -900,22 +946,25 @@ std::vector<const char *> VkShaderStageFlagBitsGetStrings(VkShaderStageFlagBits
     return strings;
 }
 void DumpVkShaderStageFlags(Printer &p, std::string name, VkShaderStageFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkShaderStageFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkShaderStageFlagBitsGetStrings(static_cast<VkShaderStageFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkShaderStageFlagBits(Printer &p, std::string name, VkShaderStageFlagBits value) {
     auto strings = VkShaderStageFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkSubgroupFeatureFlagBitsGetStrings(VkSubgroupFeatureFlagBits value) {
@@ -933,22 +982,25 @@ std::vector<const char *> VkSubgroupFeatureFlagBitsGetStrings(VkSubgroupFeatureF
     return strings;
 }
 void DumpVkSubgroupFeatureFlags(Printer &p, std::string name, VkSubgroupFeatureFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkSubgroupFeatureFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkSubgroupFeatureFlagBitsGetStrings(static_cast<VkSubgroupFeatureFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkSubgroupFeatureFlagBits(Printer &p, std::string name, VkSubgroupFeatureFlagBits value) {
     auto strings = VkSubgroupFeatureFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkSurfaceCounterFlagBitsEXTGetStrings(VkSurfaceCounterFlagBitsEXT value) {
@@ -958,22 +1010,25 @@ std::vector<const char *> VkSurfaceCounterFlagBitsEXTGetStrings(VkSurfaceCounter
     return strings;
 }
 void DumpVkSurfaceCounterFlagsEXT(Printer &p, std::string name, VkSurfaceCounterFlagsEXT value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkSurfaceCounterFlagBitsEXT>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkSurfaceCounterFlagBitsEXTGetStrings(static_cast<VkSurfaceCounterFlagBitsEXT>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkSurfaceCounterFlagBitsEXT(Printer &p, std::string name, VkSurfaceCounterFlagBitsEXT value) {
     auto strings = VkSurfaceCounterFlagBitsEXTGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkSurfaceTransformFlagBitsKHRGetStrings(VkSurfaceTransformFlagBitsKHR value) {
@@ -991,22 +1046,25 @@ std::vector<const char *> VkSurfaceTransformFlagBitsKHRGetStrings(VkSurfaceTrans
     return strings;
 }
 void DumpVkSurfaceTransformFlagsKHR(Printer &p, std::string name, VkSurfaceTransformFlagsKHR value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkSurfaceTransformFlagBitsKHR>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkSurfaceTransformFlagBitsKHRGetStrings(static_cast<VkSurfaceTransformFlagBitsKHR>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkSurfaceTransformFlagBitsKHR(Printer &p, std::string name, VkSurfaceTransformFlagBitsKHR value) {
     auto strings = VkSurfaceTransformFlagBitsKHRGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 
 std::vector<const char *> VkToolPurposeFlagBitsGetStrings(VkToolPurposeFlagBits value) {
@@ -1022,23 +1080,59 @@ std::vector<const char *> VkToolPurposeFlagBitsGetStrings(VkToolPurposeFlagBits
     return strings;
 }
 void DumpVkToolPurposeFlags(Printer &p, std::string name, VkToolPurposeFlags value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkToolPurposeFlagBits>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkToolPurposeFlagBitsGetStrings(static_cast<VkToolPurposeFlagBits>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkToolPurposeFlagBits(Printer &p, std::string name, VkToolPurposeFlagBits value) {
     auto strings = VkToolPurposeFlagBitsGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
+}
+
+std::vector<const char *> VkVideoChromaSubsamplingFlagBitsKHRGetStrings(VkVideoChromaSubsamplingFlagBitsKHR value) {
+    std::vector<const char *> strings;
+    if (VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_BIT_KHR & value) strings.push_back("VIDEO_CHROMA_SUBSAMPLING_INVALID_BIT_KHR");
+    if (VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR & value) strings.push_back("VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR");
+    if (VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR & value) strings.push_back("VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR");
+    if (VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR & value) strings.push_back("VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR");
+    if (VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR & value) strings.push_back("VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR");
+    return strings;
+}
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+void DumpVkVideoChromaSubsamplingFlagsKHR(Printer &p, std::string name, VkVideoChromaSubsamplingFlagsKHR value) {
+    if (static_cast<VkVideoChromaSubsamplingFlagBitsKHR>(value) == 0) {
+        ArrayWrapper arr(p, name, 0);
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
+            p.SetAsType().PrintString("None");
+        return;
+    }
+    auto strings = VkVideoChromaSubsamplingFlagBitsKHRGetStrings(static_cast<VkVideoChromaSubsamplingFlagBitsKHR>(value));
+    ArrayWrapper arr(p, name, strings.size());
+    for(auto& str : strings){
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
+    }
+}
+void DumpVkVideoChromaSubsamplingFlagBitsKHR(Printer &p, std::string name, VkVideoChromaSubsamplingFlagBitsKHR value) {
+    auto strings = VkVideoChromaSubsamplingFlagBitsKHRGetStrings(value);
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
+#endif  // VK_ENABLE_BETA_EXTENSIONS
 
 std::vector<const char *> VkVideoCodecOperationFlagBitsKHRGetStrings(VkVideoCodecOperationFlagBitsKHR value) {
     std::vector<const char *> strings;
@@ -1051,83 +1145,126 @@ std::vector<const char *> VkVideoCodecOperationFlagBitsKHRGetStrings(VkVideoCode
 }
 #ifdef VK_ENABLE_BETA_EXTENSIONS
 void DumpVkVideoCodecOperationFlagsKHR(Printer &p, std::string name, VkVideoCodecOperationFlagsKHR value) {
-    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }
     if (static_cast<VkVideoCodecOperationFlagBitsKHR>(value) == 0) {
         ArrayWrapper arr(p, name, 0);
-        if (p.Type() != OutputType::vkconfig_output)
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
             p.SetAsType().PrintString("None");
         return;
     }
     auto strings = VkVideoCodecOperationFlagBitsKHRGetStrings(static_cast<VkVideoCodecOperationFlagBitsKHR>(value));
     ArrayWrapper arr(p, name, strings.size());
     for(auto& str : strings){
-        p.SetAsType().PrintString(str);
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
     }
 }
 void DumpVkVideoCodecOperationFlagBitsKHR(Printer &p, std::string name, VkVideoCodecOperationFlagBitsKHR value) {
     auto strings = VkVideoCodecOperationFlagBitsKHRGetStrings(value);
-    p.PrintKeyString(name, strings.at(0));
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
 }
 #endif  // VK_ENABLE_BETA_EXTENSIONS
 
-void DumpVkDrmFormatModifierProperties2EXT(Printer &p, std::string name, VkDrmFormatModifierProperties2EXT &obj) {
+std::vector<const char *> VkVideoComponentBitDepthFlagBitsKHRGetStrings(VkVideoComponentBitDepthFlagBitsKHR value) {
+    std::vector<const char *> strings;
+    if (VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR & value) strings.push_back("VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR");
+    if (VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR & value) strings.push_back("VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR");
+    if (VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR & value) strings.push_back("VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR");
+    if (VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR & value) strings.push_back("VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR");
+    return strings;
+}
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+void DumpVkVideoComponentBitDepthFlagsKHR(Printer &p, std::string name, VkVideoComponentBitDepthFlagsKHR value) {
+    if (static_cast<VkVideoComponentBitDepthFlagBitsKHR>(value) == 0) {
+        ArrayWrapper arr(p, name, 0);
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
+            p.SetAsType().PrintString("None");
+        return;
+    }
+    auto strings = VkVideoComponentBitDepthFlagBitsKHRGetStrings(static_cast<VkVideoComponentBitDepthFlagBitsKHR>(value));
+    ArrayWrapper arr(p, name, strings.size());
+    for(auto& str : strings){
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
+    }
+}
+void DumpVkVideoComponentBitDepthFlagBitsKHR(Printer &p, std::string name, VkVideoComponentBitDepthFlagBitsKHR value) {
+    auto strings = VkVideoComponentBitDepthFlagBitsKHRGetStrings(value);
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
+}
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+
+std::vector<const char *> VkVideoDecodeH264PictureLayoutFlagBitsEXTGetStrings(VkVideoDecodeH264PictureLayoutFlagBitsEXT value) {
+    std::vector<const char *> strings;
+    if (VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT & value) strings.push_back("VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT");
+    if (VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT & value) strings.push_back("VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT");
+    if (VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT & value) strings.push_back("VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT");
+    return strings;
+}
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+void DumpVkVideoDecodeH264PictureLayoutFlagsEXT(Printer &p, std::string name, VkVideoDecodeH264PictureLayoutFlagsEXT value) {
+    if (static_cast<VkVideoDecodeH264PictureLayoutFlagBitsEXT>(value) == 0) {
+        ArrayWrapper arr(p, name, 0);
+        if (p.Type() != OutputType::json && p.Type() != OutputType::vkconfig_output)
+            p.SetAsType().PrintString("None");
+        return;
+    }
+    auto strings = VkVideoDecodeH264PictureLayoutFlagBitsEXTGetStrings(static_cast<VkVideoDecodeH264PictureLayoutFlagBitsEXT>(value));
+    ArrayWrapper arr(p, name, strings.size());
+    for(auto& str : strings){
+        if (p.Type() == OutputType::json)
+            p.SetAsType().PrintString(std::string("VK_") + str);
+        else
+            p.SetAsType().PrintString(str);
+    }
+}
+void DumpVkVideoDecodeH264PictureLayoutFlagBitsEXT(Printer &p, std::string name, VkVideoDecodeH264PictureLayoutFlagBitsEXT value) {
+    auto strings = VkVideoDecodeH264PictureLayoutFlagBitsEXTGetStrings(value);
+    if (strings.size() > 0)
+        p.PrintKeyString(name, strings.at(0));
+}
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+
+void DumpVkConformanceVersion(Printer &p, std::string name, const VkConformanceVersion &obj) {
     ObjectWrapper object{p, name};
-    p.SetMinKeyWidth(27);
-    p.PrintKeyValue("drmFormatModifier", obj.drmFormatModifier);
-    p.PrintKeyValue("drmFormatModifierPlaneCount", obj.drmFormatModifierPlaneCount);
-    DumpVkFormatFeatureFlags2(p, "drmFormatModifierTilingFeatures", obj.drmFormatModifierTilingFeatures);
+    p.SetMinKeyWidth(8);
+    p.PrintKeyValue("major", static_cast<uint32_t>(obj.major));
+    p.PrintKeyValue("minor", static_cast<uint32_t>(obj.minor));
+    p.PrintKeyValue("subminor", static_cast<uint32_t>(obj.subminor));
+    p.PrintKeyValue("patch", static_cast<uint32_t>(obj.patch));
 }
-void DumpVkDrmFormatModifierPropertiesEXT(Printer &p, std::string name, VkDrmFormatModifierPropertiesEXT &obj) {
+void DumpVkDrmFormatModifierProperties2EXT(Printer &p, std::string name, const VkDrmFormatModifierProperties2EXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(27);
     p.PrintKeyValue("drmFormatModifier", obj.drmFormatModifier);
     p.PrintKeyValue("drmFormatModifierPlaneCount", obj.drmFormatModifierPlaneCount);
-    DumpVkFormatFeatureFlags(p, "drmFormatModifierTilingFeatures", obj.drmFormatModifierTilingFeatures);
-}
-void DumpVkDrmFormatModifierPropertiesList2EXT(Printer &p, std::string name, VkDrmFormatModifierPropertiesList2EXT &obj) {
-    ObjectWrapper object{p, name};
-    p.SetMinKeyWidth(52);
-    p.PrintKeyValue("drmFormatModifierCount", obj.drmFormatModifierCount);
-    ArrayWrapper arr(p,"pDrmFormatModifierProperties", obj.drmFormatModifierCount);
-    for (uint32_t i = 0; i < obj.drmFormatModifierCount; i++) {
-        if (obj.pDrmFormatModifierProperties != nullptr) {
-            p.SetElementIndex(i);
-            DumpVkDrmFormatModifierProperties2EXT(p, "pDrmFormatModifierProperties", obj.pDrmFormatModifierProperties[i]);
-        }
-    }
-}
-void DumpVkDrmFormatModifierPropertiesListEXT(Printer &p, std::string name, VkDrmFormatModifierPropertiesListEXT &obj) {
-    ObjectWrapper object{p, name};
-    p.SetMinKeyWidth(52);
-    p.PrintKeyValue("drmFormatModifierCount", obj.drmFormatModifierCount);
-    ArrayWrapper arr(p,"pDrmFormatModifierProperties", obj.drmFormatModifierCount);
-    for (uint32_t i = 0; i < obj.drmFormatModifierCount; i++) {
-        if (obj.pDrmFormatModifierProperties != nullptr) {
-            p.SetElementIndex(i);
-            DumpVkDrmFormatModifierPropertiesEXT(p, "pDrmFormatModifierProperties", obj.pDrmFormatModifierProperties[i]);
-        }
-    }
+    DumpVkFormatFeatureFlags2(p, "drmFormatModifierTilingFeatures", obj.drmFormatModifierTilingFeatures);
 }
-void DumpVkExtent2D(Printer &p, std::string name, VkExtent2D &obj) {
+void DumpVkExtent2D(Printer &p, std::string name, const VkExtent2D &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(6);
     p.PrintKeyValue("width", obj.width);
     p.PrintKeyValue("height", obj.height);
 }
-void DumpVkExtent3D(Printer &p, std::string name, VkExtent3D &obj) {
+void DumpVkExtent3D(Printer &p, std::string name, const VkExtent3D &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(6);
     p.PrintKeyValue("width", obj.width);
     p.PrintKeyValue("height", obj.height);
     p.PrintKeyValue("depth", obj.depth);
 }
-void DumpVkFormatProperties3(Printer &p, std::string name, VkFormatProperties3 &obj) {
+void DumpVkFormatProperties3(Printer &p, std::string name, const VkFormatProperties3 &obj) {
     ObjectWrapper object{p, name};
     DumpVkFormatFeatureFlags2(p, "linearTilingFeatures", obj.linearTilingFeatures);
     DumpVkFormatFeatureFlags2(p, "optimalTilingFeatures", obj.optimalTilingFeatures);
     DumpVkFormatFeatureFlags2(p, "bufferFeatures", obj.bufferFeatures);
 }
-void DumpVkLayerProperties(Printer &p, std::string name, VkLayerProperties &obj) {
+void DumpVkLayerProperties(Printer &p, std::string name, const VkLayerProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(21);
     p.PrintKeyString("layerName", obj.layerName);
@@ -1135,7 +1272,7 @@ void DumpVkLayerProperties(Printer &p, std::string name, VkLayerProperties &obj)
     p.PrintKeyValue("implementationVersion", obj.implementationVersion);
     p.PrintKeyString("description", obj.description);
 }
-void DumpVkPhysicalDevice16BitStorageFeatures(Printer &p, std::string name, VkPhysicalDevice16BitStorageFeatures &obj) {
+void DumpVkPhysicalDevice16BitStorageFeatures(Printer &p, std::string name, const VkPhysicalDevice16BitStorageFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(34);
     p.PrintKeyBool("storageBuffer16BitAccess", static_cast<bool>(obj.storageBuffer16BitAccess));
@@ -1143,25 +1280,25 @@ void DumpVkPhysicalDevice16BitStorageFeatures(Printer &p, std::string name, VkPh
     p.PrintKeyBool("storagePushConstant16", static_cast<bool>(obj.storagePushConstant16));
     p.PrintKeyBool("storageInputOutput16", static_cast<bool>(obj.storageInputOutput16));
 }
-void DumpVkPhysicalDevice4444FormatsFeaturesEXT(Printer &p, std::string name, VkPhysicalDevice4444FormatsFeaturesEXT &obj) {
+void DumpVkPhysicalDevice4444FormatsFeaturesEXT(Printer &p, std::string name, const VkPhysicalDevice4444FormatsFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(14);
     p.PrintKeyBool("formatA4R4G4B4", static_cast<bool>(obj.formatA4R4G4B4));
     p.PrintKeyBool("formatA4B4G4R4", static_cast<bool>(obj.formatA4B4G4R4));
 }
-void DumpVkPhysicalDevice8BitStorageFeatures(Printer &p, std::string name, VkPhysicalDevice8BitStorageFeatures &obj) {
+void DumpVkPhysicalDevice8BitStorageFeatures(Printer &p, std::string name, const VkPhysicalDevice8BitStorageFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(33);
     p.PrintKeyBool("storageBuffer8BitAccess", static_cast<bool>(obj.storageBuffer8BitAccess));
     p.PrintKeyBool("uniformAndStorageBuffer8BitAccess", static_cast<bool>(obj.uniformAndStorageBuffer8BitAccess));
     p.PrintKeyBool("storagePushConstant8", static_cast<bool>(obj.storagePushConstant8));
 }
-void DumpVkPhysicalDeviceASTCDecodeFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceASTCDecodeFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceASTCDecodeFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceASTCDecodeFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(24);
     p.PrintKeyBool("decodeModeSharedExponent", static_cast<bool>(obj.decodeModeSharedExponent));
 }
-void DumpVkPhysicalDeviceAccelerationStructureFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceAccelerationStructureFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceAccelerationStructureFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceAccelerationStructureFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(53);
     p.PrintKeyBool("accelerationStructure", static_cast<bool>(obj.accelerationStructure));
@@ -1170,7 +1307,7 @@ void DumpVkPhysicalDeviceAccelerationStructureFeaturesKHR(Printer &p, std::strin
     p.PrintKeyBool("accelerationStructureHostCommands", static_cast<bool>(obj.accelerationStructureHostCommands));
     p.PrintKeyBool("descriptorBindingAccelerationStructureUpdateAfterBind", static_cast<bool>(obj.descriptorBindingAccelerationStructureUpdateAfterBind));
 }
-void DumpVkPhysicalDeviceAccelerationStructurePropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceAccelerationStructurePropertiesKHR &obj) {
+void DumpVkPhysicalDeviceAccelerationStructurePropertiesKHR(Printer &p, std::string name, const VkPhysicalDeviceAccelerationStructurePropertiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(58);
     p.PrintKeyValue("maxGeometryCount", obj.maxGeometryCount);
@@ -1182,12 +1319,12 @@ void DumpVkPhysicalDeviceAccelerationStructurePropertiesKHR(Printer &p, std::str
     p.PrintKeyValue("maxDescriptorSetUpdateAfterBindAccelerationStructures", obj.maxDescriptorSetUpdateAfterBindAccelerationStructures);
     p.PrintKeyValue("minAccelerationStructureScratchOffsetAlignment", obj.minAccelerationStructureScratchOffsetAlignment);
 }
-void DumpVkPhysicalDeviceBlendOperationAdvancedFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceBlendOperationAdvancedFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(31);
     p.PrintKeyBool("advancedBlendCoherentOperations", static_cast<bool>(obj.advancedBlendCoherentOperations));
 }
-void DumpVkPhysicalDeviceBlendOperationAdvancedPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceBlendOperationAdvancedPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(37);
     p.PrintKeyValue("advancedBlendMaxColorAttachments", obj.advancedBlendMaxColorAttachments);
@@ -1197,38 +1334,38 @@ void DumpVkPhysicalDeviceBlendOperationAdvancedPropertiesEXT(Printer &p, std::st
     p.PrintKeyBool("advancedBlendCorrelatedOverlap", static_cast<bool>(obj.advancedBlendCorrelatedOverlap));
     p.PrintKeyBool("advancedBlendAllOperations", static_cast<bool>(obj.advancedBlendAllOperations));
 }
-void DumpVkPhysicalDeviceBorderColorSwizzleFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceBorderColorSwizzleFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceBorderColorSwizzleFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceBorderColorSwizzleFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(27);
     p.PrintKeyBool("borderColorSwizzle", static_cast<bool>(obj.borderColorSwizzle));
     p.PrintKeyBool("borderColorSwizzleFromImage", static_cast<bool>(obj.borderColorSwizzleFromImage));
 }
-void DumpVkPhysicalDeviceBufferDeviceAddressFeatures(Printer &p, std::string name, VkPhysicalDeviceBufferDeviceAddressFeatures &obj) {
+void DumpVkPhysicalDeviceBufferDeviceAddressFeatures(Printer &p, std::string name, const VkPhysicalDeviceBufferDeviceAddressFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(32);
     p.PrintKeyBool("bufferDeviceAddress", static_cast<bool>(obj.bufferDeviceAddress));
     p.PrintKeyBool("bufferDeviceAddressCaptureReplay", static_cast<bool>(obj.bufferDeviceAddressCaptureReplay));
     p.PrintKeyBool("bufferDeviceAddressMultiDevice", static_cast<bool>(obj.bufferDeviceAddressMultiDevice));
 }
-void DumpVkPhysicalDeviceBufferDeviceAddressFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceBufferDeviceAddressFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceBufferDeviceAddressFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(32);
     p.PrintKeyBool("bufferDeviceAddress", static_cast<bool>(obj.bufferDeviceAddress));
     p.PrintKeyBool("bufferDeviceAddressCaptureReplay", static_cast<bool>(obj.bufferDeviceAddressCaptureReplay));
     p.PrintKeyBool("bufferDeviceAddressMultiDevice", static_cast<bool>(obj.bufferDeviceAddressMultiDevice));
 }
-void DumpVkPhysicalDeviceColorWriteEnableFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceColorWriteEnableFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceColorWriteEnableFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceColorWriteEnableFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(16);
     p.PrintKeyBool("colorWriteEnable", static_cast<bool>(obj.colorWriteEnable));
 }
-void DumpVkPhysicalDeviceConditionalRenderingFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceConditionalRenderingFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceConditionalRenderingFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceConditionalRenderingFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(29);
     p.PrintKeyBool("conditionalRendering", static_cast<bool>(obj.conditionalRendering));
     p.PrintKeyBool("inheritedConditionalRendering", static_cast<bool>(obj.inheritedConditionalRendering));
 }
-void DumpVkPhysicalDeviceConservativeRasterizationPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceConservativeRasterizationPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceConservativeRasterizationPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceConservativeRasterizationPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(43);
     p.PrintKeyValue("primitiveOverestimationSize", obj.primitiveOverestimationSize);
@@ -1241,28 +1378,28 @@ void DumpVkPhysicalDeviceConservativeRasterizationPropertiesEXT(Printer &p, std:
     p.PrintKeyBool("fullyCoveredFragmentShaderInputVariable", static_cast<bool>(obj.fullyCoveredFragmentShaderInputVariable));
     p.PrintKeyBool("conservativeRasterizationPostDepthCoverage", static_cast<bool>(obj.conservativeRasterizationPostDepthCoverage));
 }
-void DumpVkPhysicalDeviceCustomBorderColorFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceCustomBorderColorFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceCustomBorderColorFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceCustomBorderColorFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(30);
     p.PrintKeyBool("customBorderColors", static_cast<bool>(obj.customBorderColors));
     p.PrintKeyBool("customBorderColorWithoutFormat", static_cast<bool>(obj.customBorderColorWithoutFormat));
 }
-void DumpVkPhysicalDeviceCustomBorderColorPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceCustomBorderColorPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceCustomBorderColorPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceCustomBorderColorPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(28);
     p.PrintKeyValue("maxCustomBorderColorSamplers", obj.maxCustomBorderColorSamplers);
 }
-void DumpVkPhysicalDeviceDepthClipControlFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceDepthClipControlFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceDepthClipControlFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceDepthClipControlFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(16);
     p.PrintKeyBool("depthClipControl", static_cast<bool>(obj.depthClipControl));
 }
-void DumpVkPhysicalDeviceDepthClipEnableFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceDepthClipEnableFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceDepthClipEnableFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceDepthClipEnableFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(15);
     p.PrintKeyBool("depthClipEnable", static_cast<bool>(obj.depthClipEnable));
 }
-void DumpVkPhysicalDeviceDepthStencilResolveProperties(Printer &p, std::string name, VkPhysicalDeviceDepthStencilResolveProperties &obj) {
+void DumpVkPhysicalDeviceDepthStencilResolveProperties(Printer &p, std::string name, const VkPhysicalDeviceDepthStencilResolveProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(22);
     DumpVkResolveModeFlags(p, "supportedDepthResolveModes", obj.supportedDepthResolveModes);
@@ -1270,7 +1407,7 @@ void DumpVkPhysicalDeviceDepthStencilResolveProperties(Printer &p, std::string n
     p.PrintKeyBool("independentResolveNone", static_cast<bool>(obj.independentResolveNone));
     p.PrintKeyBool("independentResolve", static_cast<bool>(obj.independentResolve));
 }
-void DumpVkPhysicalDeviceDescriptorIndexingFeatures(Printer &p, std::string name, VkPhysicalDeviceDescriptorIndexingFeatures &obj) {
+void DumpVkPhysicalDeviceDescriptorIndexingFeatures(Printer &p, std::string name, const VkPhysicalDeviceDescriptorIndexingFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(50);
     p.PrintKeyBool("shaderInputAttachmentArrayDynamicIndexing", static_cast<bool>(obj.shaderInputAttachmentArrayDynamicIndexing));
@@ -1294,7 +1431,7 @@ void DumpVkPhysicalDeviceDescriptorIndexingFeatures(Printer &p, std::string name
     p.PrintKeyBool("descriptorBindingVariableDescriptorCount", static_cast<bool>(obj.descriptorBindingVariableDescriptorCount));
     p.PrintKeyBool("runtimeDescriptorArray", static_cast<bool>(obj.runtimeDescriptorArray));
 }
-void DumpVkPhysicalDeviceDescriptorIndexingProperties(Printer &p, std::string name, VkPhysicalDeviceDescriptorIndexingProperties &obj) {
+void DumpVkPhysicalDeviceDescriptorIndexingProperties(Printer &p, std::string name, const VkPhysicalDeviceDescriptorIndexingProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(52);
     p.PrintKeyValue("maxUpdateAfterBindDescriptorsInAllPools", obj.maxUpdateAfterBindDescriptorsInAllPools);
@@ -1321,25 +1458,25 @@ void DumpVkPhysicalDeviceDescriptorIndexingProperties(Printer &p, std::string na
     p.PrintKeyValue("maxDescriptorSetUpdateAfterBindStorageImages", obj.maxDescriptorSetUpdateAfterBindStorageImages);
     p.PrintKeyValue("maxDescriptorSetUpdateAfterBindInputAttachments", obj.maxDescriptorSetUpdateAfterBindInputAttachments);
 }
-void DumpVkPhysicalDeviceDeviceMemoryReportFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceDeviceMemoryReportFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceDeviceMemoryReportFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceDeviceMemoryReportFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(18);
     p.PrintKeyBool("deviceMemoryReport", static_cast<bool>(obj.deviceMemoryReport));
 }
-void DumpVkPhysicalDeviceDiscardRectanglePropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceDiscardRectanglePropertiesEXT &obj) {
+void DumpVkPhysicalDeviceDiscardRectanglePropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceDiscardRectanglePropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(20);
     p.PrintKeyValue("maxDiscardRectangles", obj.maxDiscardRectangles);
 }
-void DumpVkPhysicalDeviceDriverProperties(Printer &p, std::string name, VkPhysicalDeviceDriverProperties &obj) {
+void DumpVkPhysicalDeviceDriverProperties(Printer &p, std::string name, const VkPhysicalDeviceDriverProperties &obj) {
     ObjectWrapper object{p, name};
-    p.SetMinKeyWidth(18);
+    p.SetMinKeyWidth(15);
     DumpVkDriverId(p, "driverID", obj.driverID);
     p.PrintKeyString("driverName", obj.driverName);
     p.PrintKeyString("driverInfo", obj.driverInfo);
     DumpVkConformanceVersion(p, "conformanceVersion", obj.conformanceVersion);
 }
-void DumpVkPhysicalDeviceDrmPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceDrmPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceDrmPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceDrmPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(12);
     p.PrintKeyBool("hasPrimary", static_cast<bool>(obj.hasPrimary));
@@ -1349,29 +1486,29 @@ void DumpVkPhysicalDeviceDrmPropertiesEXT(Printer &p, std::string name, VkPhysic
     p.PrintKeyValue("renderMajor", obj.renderMajor);
     p.PrintKeyValue("renderMinor", obj.renderMinor);
 }
-void DumpVkPhysicalDeviceDynamicRenderingFeatures(Printer &p, std::string name, VkPhysicalDeviceDynamicRenderingFeatures &obj) {
+void DumpVkPhysicalDeviceDynamicRenderingFeatures(Printer &p, std::string name, const VkPhysicalDeviceDynamicRenderingFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(16);
     p.PrintKeyBool("dynamicRendering", static_cast<bool>(obj.dynamicRendering));
 }
-void DumpVkPhysicalDeviceExtendedDynamicState2FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceExtendedDynamicState2FeaturesEXT &obj) {
+void DumpVkPhysicalDeviceExtendedDynamicState2FeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceExtendedDynamicState2FeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(39);
     p.PrintKeyBool("extendedDynamicState2", static_cast<bool>(obj.extendedDynamicState2));
     p.PrintKeyBool("extendedDynamicState2LogicOp", static_cast<bool>(obj.extendedDynamicState2LogicOp));
     p.PrintKeyBool("extendedDynamicState2PatchControlPoints", static_cast<bool>(obj.extendedDynamicState2PatchControlPoints));
 }
-void DumpVkPhysicalDeviceExtendedDynamicStateFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceExtendedDynamicStateFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceExtendedDynamicStateFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceExtendedDynamicStateFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(20);
     p.PrintKeyBool("extendedDynamicState", static_cast<bool>(obj.extendedDynamicState));
 }
-void DumpVkPhysicalDeviceExternalMemoryHostPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceExternalMemoryHostPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceExternalMemoryHostPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceExternalMemoryHostPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(31);
     p.PrintKeyValue("minImportedHostPointerAlignment", to_hex_str(p, obj.minImportedHostPointerAlignment));
 }
-void DumpVkPhysicalDeviceFeatures(Printer &p, std::string name, VkPhysicalDeviceFeatures &obj) {
+void DumpVkPhysicalDeviceFeatures(Printer &p, std::string name, const VkPhysicalDeviceFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(39);
     p.PrintKeyBool("robustBufferAccess", static_cast<bool>(obj.robustBufferAccess));
@@ -1430,7 +1567,7 @@ void DumpVkPhysicalDeviceFeatures(Printer &p, std::string name, VkPhysicalDevice
     p.PrintKeyBool("variableMultisampleRate", static_cast<bool>(obj.variableMultisampleRate));
     p.PrintKeyBool("inheritedQueries", static_cast<bool>(obj.inheritedQueries));
 }
-void DumpVkPhysicalDeviceFloatControlsProperties(Printer &p, std::string name, VkPhysicalDeviceFloatControlsProperties &obj) {
+void DumpVkPhysicalDeviceFloatControlsProperties(Printer &p, std::string name, const VkPhysicalDeviceFloatControlsProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(37);
     DumpVkShaderFloatControlsIndependence(p, "denormBehaviorIndependence", obj.denormBehaviorIndependence);
@@ -1451,12 +1588,12 @@ void DumpVkPhysicalDeviceFloatControlsProperties(Printer &p, std::string name, V
     p.PrintKeyBool("shaderRoundingModeRTZFloat32", static_cast<bool>(obj.shaderRoundingModeRTZFloat32));
     p.PrintKeyBool("shaderRoundingModeRTZFloat64", static_cast<bool>(obj.shaderRoundingModeRTZFloat64));
 }
-void DumpVkPhysicalDeviceFragmentDensityMap2FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMap2FeaturesEXT &obj) {
+void DumpVkPhysicalDeviceFragmentDensityMap2FeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceFragmentDensityMap2FeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(26);
     p.PrintKeyBool("fragmentDensityMapDeferred", static_cast<bool>(obj.fragmentDensityMapDeferred));
 }
-void DumpVkPhysicalDeviceFragmentDensityMap2PropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMap2PropertiesEXT &obj) {
+void DumpVkPhysicalDeviceFragmentDensityMap2PropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceFragmentDensityMap2PropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(41);
     p.PrintKeyBool("subsampledLoads", static_cast<bool>(obj.subsampledLoads));
@@ -1464,35 +1601,35 @@ void DumpVkPhysicalDeviceFragmentDensityMap2PropertiesEXT(Printer &p, std::strin
     p.PrintKeyValue("maxSubsampledArrayLayers", obj.maxSubsampledArrayLayers);
     p.PrintKeyValue("maxDescriptorSetSubsampledSamplers", obj.maxDescriptorSetSubsampledSamplers);
 }
-void DumpVkPhysicalDeviceFragmentDensityMapFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMapFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceFragmentDensityMapFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceFragmentDensityMapFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(37);
     p.PrintKeyBool("fragmentDensityMap", static_cast<bool>(obj.fragmentDensityMap));
     p.PrintKeyBool("fragmentDensityMapDynamic", static_cast<bool>(obj.fragmentDensityMapDynamic));
     p.PrintKeyBool("fragmentDensityMapNonSubsampledImages", static_cast<bool>(obj.fragmentDensityMapNonSubsampledImages));
 }
-void DumpVkPhysicalDeviceFragmentDensityMapPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMapPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceFragmentDensityMapPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceFragmentDensityMapPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(26);
     DumpVkExtent2D(p, "minFragmentDensityTexelSize", obj.minFragmentDensityTexelSize);
     DumpVkExtent2D(p, "maxFragmentDensityTexelSize", obj.maxFragmentDensityTexelSize);
     p.PrintKeyBool("fragmentDensityInvocations", static_cast<bool>(obj.fragmentDensityInvocations));
 }
-void DumpVkPhysicalDeviceFragmentShaderInterlockFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceFragmentShaderInterlockFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(34);
     p.PrintKeyBool("fragmentShaderSampleInterlock", static_cast<bool>(obj.fragmentShaderSampleInterlock));
     p.PrintKeyBool("fragmentShaderPixelInterlock", static_cast<bool>(obj.fragmentShaderPixelInterlock));
     p.PrintKeyBool("fragmentShaderShadingRateInterlock", static_cast<bool>(obj.fragmentShaderShadingRateInterlock));
 }
-void DumpVkPhysicalDeviceFragmentShadingRateFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceFragmentShadingRateFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceFragmentShadingRateFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceFragmentShadingRateFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(29);
     p.PrintKeyBool("pipelineFragmentShadingRate", static_cast<bool>(obj.pipelineFragmentShadingRate));
     p.PrintKeyBool("primitiveFragmentShadingRate", static_cast<bool>(obj.primitiveFragmentShadingRate));
     p.PrintKeyBool("attachmentFragmentShadingRate", static_cast<bool>(obj.attachmentFragmentShadingRate));
 }
-void DumpVkPhysicalDeviceFragmentShadingRatePropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceFragmentShadingRatePropertiesKHR &obj) {
+void DumpVkPhysicalDeviceFragmentShadingRatePropertiesKHR(Printer &p, std::string name, const VkPhysicalDeviceFragmentShadingRatePropertiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(52);
     DumpVkExtent2D(p, "minFragmentShadingRateAttachmentTexelSize", obj.minFragmentShadingRateAttachmentTexelSize);
@@ -1513,52 +1650,66 @@ void DumpVkPhysicalDeviceFragmentShadingRatePropertiesKHR(Printer &p, std::strin
     p.PrintKeyBool("fragmentShadingRateWithCustomSampleLocations", static_cast<bool>(obj.fragmentShadingRateWithCustomSampleLocations));
     p.PrintKeyBool("fragmentShadingRateStrictMultiplyCombiner", static_cast<bool>(obj.fragmentShadingRateStrictMultiplyCombiner));
 }
-void DumpVkPhysicalDeviceGlobalPriorityQueryFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceGlobalPriorityQueryFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(19);
     p.PrintKeyBool("globalPriorityQuery", static_cast<bool>(obj.globalPriorityQuery));
 }
-void DumpVkPhysicalDeviceHostQueryResetFeatures(Printer &p, std::string name, VkPhysicalDeviceHostQueryResetFeatures &obj) {
+void DumpVkPhysicalDeviceHostQueryResetFeatures(Printer &p, std::string name, const VkPhysicalDeviceHostQueryResetFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(14);
     p.PrintKeyBool("hostQueryReset", static_cast<bool>(obj.hostQueryReset));
 }
-void DumpVkPhysicalDeviceIDProperties(Printer &p, std::string name, VkPhysicalDeviceIDProperties &obj) {
+void DumpVkPhysicalDeviceIDProperties(Printer &p, std::string name, const VkPhysicalDeviceIDProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(15);
-    p.PrintKeyString("deviceUUID", to_string_16(obj.deviceUUID));
-    p.PrintKeyString("driverUUID", to_string_16(obj.driverUUID));
-    if (obj.deviceLUIDValid) p.PrintKeyString("deviceLUID", to_string_8(obj.deviceLUID));
+    if (p.Type() == OutputType::json) {
+        ArrayWrapper arr(p, "deviceUUID");
+        for (uint32_t i = 0; i < 16; i++) p.PrintElement(static_cast<uint32_t>(obj.deviceUUID[i]));
+    } else
+        p.PrintKeyString("deviceUUID", to_string_16(obj.deviceUUID));
+    if (p.Type() == OutputType::json) {
+        ArrayWrapper arr(p, "driverUUID");
+        for (uint32_t i = 0; i < 16; i++) p.PrintElement(static_cast<uint32_t>(obj.driverUUID[i]));
+    } else
+        p.PrintKeyString("driverUUID", to_string_16(obj.driverUUID));
+    if (obj.deviceLUIDValid) { // special case
+    if (p.Type() == OutputType::json) {
+        ArrayWrapper arr(p, "deviceLUID");
+        for (uint32_t i = 0; i < 8; i++) p.PrintElement(static_cast<uint32_t>(obj.deviceLUID[i]));
+    } else
+        p.PrintKeyString("deviceLUID", to_string_8(obj.deviceLUID));
+    }
     p.PrintKeyValue("deviceNodeMask", obj.deviceNodeMask);
     p.PrintKeyBool("deviceLUIDValid", static_cast<bool>(obj.deviceLUIDValid));
 }
-void DumpVkPhysicalDeviceImageRobustnessFeatures(Printer &p, std::string name, VkPhysicalDeviceImageRobustnessFeatures &obj) {
+void DumpVkPhysicalDeviceImageRobustnessFeatures(Printer &p, std::string name, const VkPhysicalDeviceImageRobustnessFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(17);
     p.PrintKeyBool("robustImageAccess", static_cast<bool>(obj.robustImageAccess));
 }
-void DumpVkPhysicalDeviceImageViewMinLodFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceImageViewMinLodFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceImageViewMinLodFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceImageViewMinLodFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(6);
     p.PrintKeyBool("minLod", static_cast<bool>(obj.minLod));
 }
-void DumpVkPhysicalDeviceImagelessFramebufferFeatures(Printer &p, std::string name, VkPhysicalDeviceImagelessFramebufferFeatures &obj) {
+void DumpVkPhysicalDeviceImagelessFramebufferFeatures(Printer &p, std::string name, const VkPhysicalDeviceImagelessFramebufferFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(20);
     p.PrintKeyBool("imagelessFramebuffer", static_cast<bool>(obj.imagelessFramebuffer));
 }
-void DumpVkPhysicalDeviceIndexTypeUint8FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceIndexTypeUint8FeaturesEXT &obj) {
+void DumpVkPhysicalDeviceIndexTypeUint8FeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceIndexTypeUint8FeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(14);
     p.PrintKeyBool("indexTypeUint8", static_cast<bool>(obj.indexTypeUint8));
 }
-void DumpVkPhysicalDeviceInlineUniformBlockFeatures(Printer &p, std::string name, VkPhysicalDeviceInlineUniformBlockFeatures &obj) {
+void DumpVkPhysicalDeviceInlineUniformBlockFeatures(Printer &p, std::string name, const VkPhysicalDeviceInlineUniformBlockFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(50);
     p.PrintKeyBool("inlineUniformBlock", static_cast<bool>(obj.inlineUniformBlock));
     p.PrintKeyBool("descriptorBindingInlineUniformBlockUpdateAfterBind", static_cast<bool>(obj.descriptorBindingInlineUniformBlockUpdateAfterBind));
 }
-void DumpVkPhysicalDeviceInlineUniformBlockProperties(Printer &p, std::string name, VkPhysicalDeviceInlineUniformBlockProperties &obj) {
+void DumpVkPhysicalDeviceInlineUniformBlockProperties(Printer &p, std::string name, const VkPhysicalDeviceInlineUniformBlockProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(55);
     p.PrintKeyValue("maxInlineUniformBlockSize", obj.maxInlineUniformBlockSize);
@@ -1567,7 +1718,7 @@ void DumpVkPhysicalDeviceInlineUniformBlockProperties(Printer &p, std::string na
     p.PrintKeyValue("maxDescriptorSetInlineUniformBlocks", obj.maxDescriptorSetInlineUniformBlocks);
     p.PrintKeyValue("maxDescriptorSetUpdateAfterBindInlineUniformBlocks", obj.maxDescriptorSetUpdateAfterBindInlineUniformBlocks);
 }
-void DumpVkPhysicalDeviceLimits(Printer &p, std::string name, VkPhysicalDeviceLimits &obj) {
+void DumpVkPhysicalDeviceLimits(Printer &p, std::string name, const VkPhysicalDeviceLimits &obj) {
     if (p.Type() == OutputType::json)
         p.ObjectStart("limits");
     else
@@ -1701,7 +1852,7 @@ void DumpVkPhysicalDeviceLimits(Printer &p, std::string name, VkPhysicalDeviceLi
     p.PrintKeyValue("nonCoherentAtomSize", to_hex_str(p, obj.nonCoherentAtomSize));
     p.ObjectEnd();
 }
-void DumpVkPhysicalDeviceLineRasterizationFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceLineRasterizationFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceLineRasterizationFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceLineRasterizationFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(24);
     p.PrintKeyBool("rectangularLines", static_cast<bool>(obj.rectangularLines));
@@ -1711,28 +1862,28 @@ void DumpVkPhysicalDeviceLineRasterizationFeaturesEXT(Printer &p, std::string na
     p.PrintKeyBool("stippledBresenhamLines", static_cast<bool>(obj.stippledBresenhamLines));
     p.PrintKeyBool("stippledSmoothLines", static_cast<bool>(obj.stippledSmoothLines));
 }
-void DumpVkPhysicalDeviceLineRasterizationPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceLineRasterizationPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceLineRasterizationPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceLineRasterizationPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(25);
     p.PrintKeyValue("lineSubPixelPrecisionBits", obj.lineSubPixelPrecisionBits);
 }
-void DumpVkPhysicalDeviceMaintenance3Properties(Printer &p, std::string name, VkPhysicalDeviceMaintenance3Properties &obj) {
+void DumpVkPhysicalDeviceMaintenance3Properties(Printer &p, std::string name, const VkPhysicalDeviceMaintenance3Properties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(23);
     p.PrintKeyValue("maxPerSetDescriptors", obj.maxPerSetDescriptors);
     p.PrintKeyValue("maxMemoryAllocationSize", to_hex_str(p, obj.maxMemoryAllocationSize));
 }
-void DumpVkPhysicalDeviceMaintenance4Features(Printer &p, std::string name, VkPhysicalDeviceMaintenance4Features &obj) {
+void DumpVkPhysicalDeviceMaintenance4Features(Printer &p, std::string name, const VkPhysicalDeviceMaintenance4Features &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(12);
     p.PrintKeyBool("maintenance4", static_cast<bool>(obj.maintenance4));
 }
-void DumpVkPhysicalDeviceMaintenance4Properties(Printer &p, std::string name, VkPhysicalDeviceMaintenance4Properties &obj) {
+void DumpVkPhysicalDeviceMaintenance4Properties(Printer &p, std::string name, const VkPhysicalDeviceMaintenance4Properties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(13);
     p.PrintKeyValue("maxBufferSize", to_hex_str(p, obj.maxBufferSize));
 }
-void DumpVkPhysicalDeviceMemoryBudgetPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceMemoryBudgetPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceMemoryBudgetPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceMemoryBudgetPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(14);
     {   ArrayWrapper arr(p,"heapBudget", 16);
@@ -1772,35 +1923,35 @@ void DumpVkPhysicalDeviceMemoryBudgetPropertiesEXT(Printer &p, std::string name,
         p.PrintElement(obj.heapUsage[15]);
     }
 }
-void DumpVkPhysicalDeviceMemoryPriorityFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceMemoryPriorityFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceMemoryPriorityFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceMemoryPriorityFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(14);
     p.PrintKeyBool("memoryPriority", static_cast<bool>(obj.memoryPriority));
 }
-void DumpVkPhysicalDeviceMultiDrawFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceMultiDrawFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceMultiDrawFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceMultiDrawFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(9);
     p.PrintKeyBool("multiDraw", static_cast<bool>(obj.multiDraw));
 }
-void DumpVkPhysicalDeviceMultiDrawPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceMultiDrawPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceMultiDrawPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceMultiDrawPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(17);
     p.PrintKeyValue("maxMultiDrawCount", obj.maxMultiDrawCount);
 }
-void DumpVkPhysicalDeviceMultiviewFeatures(Printer &p, std::string name, VkPhysicalDeviceMultiviewFeatures &obj) {
+void DumpVkPhysicalDeviceMultiviewFeatures(Printer &p, std::string name, const VkPhysicalDeviceMultiviewFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(27);
     p.PrintKeyBool("multiview", static_cast<bool>(obj.multiview));
     p.PrintKeyBool("multiviewGeometryShader", static_cast<bool>(obj.multiviewGeometryShader));
     p.PrintKeyBool("multiviewTessellationShader", static_cast<bool>(obj.multiviewTessellationShader));
 }
-void DumpVkPhysicalDeviceMultiviewProperties(Printer &p, std::string name, VkPhysicalDeviceMultiviewProperties &obj) {
+void DumpVkPhysicalDeviceMultiviewProperties(Printer &p, std::string name, const VkPhysicalDeviceMultiviewProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(25);
     p.PrintKeyValue("maxMultiviewViewCount", obj.maxMultiviewViewCount);
     p.PrintKeyValue("maxMultiviewInstanceIndex", obj.maxMultiviewInstanceIndex);
 }
-void DumpVkPhysicalDevicePCIBusInfoPropertiesEXT(Printer &p, std::string name, VkPhysicalDevicePCIBusInfoPropertiesEXT &obj) {
+void DumpVkPhysicalDevicePCIBusInfoPropertiesEXT(Printer &p, std::string name, const VkPhysicalDevicePCIBusInfoPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(11);
     p.PrintKeyValue("pciDomain", obj.pciDomain);
@@ -1808,38 +1959,38 @@ void DumpVkPhysicalDevicePCIBusInfoPropertiesEXT(Printer &p, std::string name, V
     p.PrintKeyValue("pciDevice", obj.pciDevice);
     p.PrintKeyValue("pciFunction", obj.pciFunction);
 }
-void DumpVkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT(Printer &p, std::string name, VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT &obj) {
+void DumpVkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT(Printer &p, std::string name, const VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(25);
     p.PrintKeyBool("pageableDeviceLocalMemory", static_cast<bool>(obj.pageableDeviceLocalMemory));
 }
-void DumpVkPhysicalDevicePerformanceQueryFeaturesKHR(Printer &p, std::string name, VkPhysicalDevicePerformanceQueryFeaturesKHR &obj) {
+void DumpVkPhysicalDevicePerformanceQueryFeaturesKHR(Printer &p, std::string name, const VkPhysicalDevicePerformanceQueryFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(36);
     p.PrintKeyBool("performanceCounterQueryPools", static_cast<bool>(obj.performanceCounterQueryPools));
     p.PrintKeyBool("performanceCounterMultipleQueryPools", static_cast<bool>(obj.performanceCounterMultipleQueryPools));
 }
-void DumpVkPhysicalDevicePerformanceQueryPropertiesKHR(Printer &p, std::string name, VkPhysicalDevicePerformanceQueryPropertiesKHR &obj) {
+void DumpVkPhysicalDevicePerformanceQueryPropertiesKHR(Printer &p, std::string name, const VkPhysicalDevicePerformanceQueryPropertiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(29);
     p.PrintKeyBool("allowCommandBufferQueryCopies", static_cast<bool>(obj.allowCommandBufferQueryCopies));
 }
-void DumpVkPhysicalDevicePipelineCreationCacheControlFeatures(Printer &p, std::string name, VkPhysicalDevicePipelineCreationCacheControlFeatures &obj) {
+void DumpVkPhysicalDevicePipelineCreationCacheControlFeatures(Printer &p, std::string name, const VkPhysicalDevicePipelineCreationCacheControlFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(28);
     p.PrintKeyBool("pipelineCreationCacheControl", static_cast<bool>(obj.pipelineCreationCacheControl));
 }
-void DumpVkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR(Printer &p, std::string name, VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR &obj) {
+void DumpVkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR(Printer &p, std::string name, const VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(22);
     p.PrintKeyBool("pipelineExecutableInfo", static_cast<bool>(obj.pipelineExecutableInfo));
 }
-void DumpVkPhysicalDevicePointClippingProperties(Printer &p, std::string name, VkPhysicalDevicePointClippingProperties &obj) {
+void DumpVkPhysicalDevicePointClippingProperties(Printer &p, std::string name, const VkPhysicalDevicePointClippingProperties &obj) {
     ObjectWrapper object{p, name};
     DumpVkPointClippingBehavior(p, "pointClippingBehavior", obj.pointClippingBehavior);
 }
 #ifdef VK_ENABLE_BETA_EXTENSIONS
-void DumpVkPhysicalDevicePortabilitySubsetFeaturesKHR(Printer &p, std::string name, VkPhysicalDevicePortabilitySubsetFeaturesKHR &obj) {
+void DumpVkPhysicalDevicePortabilitySubsetFeaturesKHR(Printer &p, std::string name, const VkPhysicalDevicePortabilitySubsetFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(38);
     p.PrintKeyBool("constantAlphaColorBlendFactors", static_cast<bool>(obj.constantAlphaColorBlendFactors));
@@ -1860,71 +2011,71 @@ void DumpVkPhysicalDevicePortabilitySubsetFeaturesKHR(Printer &p, std::string na
 }
 #endif  // VK_ENABLE_BETA_EXTENSIONS
 #ifdef VK_ENABLE_BETA_EXTENSIONS
-void DumpVkPhysicalDevicePortabilitySubsetPropertiesKHR(Printer &p, std::string name, VkPhysicalDevicePortabilitySubsetPropertiesKHR &obj) {
+void DumpVkPhysicalDevicePortabilitySubsetPropertiesKHR(Printer &p, std::string name, const VkPhysicalDevicePortabilitySubsetPropertiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(36);
     p.PrintKeyValue("minVertexInputBindingStrideAlignment", obj.minVertexInputBindingStrideAlignment);
 }
 #endif  // VK_ENABLE_BETA_EXTENSIONS
-void DumpVkPhysicalDevicePresentIdFeaturesKHR(Printer &p, std::string name, VkPhysicalDevicePresentIdFeaturesKHR &obj) {
+void DumpVkPhysicalDevicePresentIdFeaturesKHR(Printer &p, std::string name, const VkPhysicalDevicePresentIdFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(9);
     p.PrintKeyBool("presentId", static_cast<bool>(obj.presentId));
 }
-void DumpVkPhysicalDevicePresentWaitFeaturesKHR(Printer &p, std::string name, VkPhysicalDevicePresentWaitFeaturesKHR &obj) {
+void DumpVkPhysicalDevicePresentWaitFeaturesKHR(Printer &p, std::string name, const VkPhysicalDevicePresentWaitFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(11);
     p.PrintKeyBool("presentWait", static_cast<bool>(obj.presentWait));
 }
-void DumpVkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT(Printer &p, std::string name, VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT &obj) {
+void DumpVkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT(Printer &p, std::string name, const VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(33);
     p.PrintKeyBool("primitiveTopologyListRestart", static_cast<bool>(obj.primitiveTopologyListRestart));
     p.PrintKeyBool("primitiveTopologyPatchListRestart", static_cast<bool>(obj.primitiveTopologyPatchListRestart));
 }
-void DumpVkPhysicalDevicePrivateDataFeatures(Printer &p, std::string name, VkPhysicalDevicePrivateDataFeatures &obj) {
+void DumpVkPhysicalDevicePrivateDataFeatures(Printer &p, std::string name, const VkPhysicalDevicePrivateDataFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(11);
     p.PrintKeyBool("privateData", static_cast<bool>(obj.privateData));
 }
-void DumpVkPhysicalDeviceProtectedMemoryFeatures(Printer &p, std::string name, VkPhysicalDeviceProtectedMemoryFeatures &obj) {
+void DumpVkPhysicalDeviceProtectedMemoryFeatures(Printer &p, std::string name, const VkPhysicalDeviceProtectedMemoryFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(15);
     p.PrintKeyBool("protectedMemory", static_cast<bool>(obj.protectedMemory));
 }
-void DumpVkPhysicalDeviceProtectedMemoryProperties(Printer &p, std::string name, VkPhysicalDeviceProtectedMemoryProperties &obj) {
+void DumpVkPhysicalDeviceProtectedMemoryProperties(Printer &p, std::string name, const VkPhysicalDeviceProtectedMemoryProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(16);
     p.PrintKeyBool("protectedNoFault", static_cast<bool>(obj.protectedNoFault));
 }
-void DumpVkPhysicalDeviceProvokingVertexFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceProvokingVertexFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceProvokingVertexFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceProvokingVertexFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(41);
     p.PrintKeyBool("provokingVertexLast", static_cast<bool>(obj.provokingVertexLast));
     p.PrintKeyBool("transformFeedbackPreservesProvokingVertex", static_cast<bool>(obj.transformFeedbackPreservesProvokingVertex));
 }
-void DumpVkPhysicalDeviceProvokingVertexPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceProvokingVertexPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceProvokingVertexPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceProvokingVertexPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(52);
     p.PrintKeyBool("provokingVertexModePerPipeline", static_cast<bool>(obj.provokingVertexModePerPipeline));
     p.PrintKeyBool("transformFeedbackPreservesTriangleFanProvokingVertex", static_cast<bool>(obj.transformFeedbackPreservesTriangleFanProvokingVertex));
 }
-void DumpVkPhysicalDevicePushDescriptorPropertiesKHR(Printer &p, std::string name, VkPhysicalDevicePushDescriptorPropertiesKHR &obj) {
+void DumpVkPhysicalDevicePushDescriptorPropertiesKHR(Printer &p, std::string name, const VkPhysicalDevicePushDescriptorPropertiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(18);
     p.PrintKeyValue("maxPushDescriptors", obj.maxPushDescriptors);
 }
-void DumpVkPhysicalDeviceRGBA10X6FormatsFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceRGBA10X6FormatsFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(33);
     p.PrintKeyBool("formatRgba10x6WithoutYCbCrSampler", static_cast<bool>(obj.formatRgba10x6WithoutYCbCrSampler));
 }
-void DumpVkPhysicalDeviceRayQueryFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceRayQueryFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceRayQueryFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceRayQueryFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(8);
     p.PrintKeyBool("rayQuery", static_cast<bool>(obj.rayQuery));
 }
-void DumpVkPhysicalDeviceRayTracingPipelineFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceRayTracingPipelineFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceRayTracingPipelineFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceRayTracingPipelineFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(53);
     p.PrintKeyBool("rayTracingPipeline", static_cast<bool>(obj.rayTracingPipeline));
@@ -1933,7 +2084,7 @@ void DumpVkPhysicalDeviceRayTracingPipelineFeaturesKHR(Printer &p, std::string n
     p.PrintKeyBool("rayTracingPipelineTraceRaysIndirect", static_cast<bool>(obj.rayTracingPipelineTraceRaysIndirect));
     p.PrintKeyBool("rayTraversalPrimitiveCulling", static_cast<bool>(obj.rayTraversalPrimitiveCulling));
 }
-void DumpVkPhysicalDeviceRayTracingPipelinePropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceRayTracingPipelinePropertiesKHR &obj) {
+void DumpVkPhysicalDeviceRayTracingPipelinePropertiesKHR(Printer &p, std::string name, const VkPhysicalDeviceRayTracingPipelinePropertiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(34);
     p.PrintKeyValue("shaderGroupHandleSize", obj.shaderGroupHandleSize);
@@ -1945,20 +2096,20 @@ void DumpVkPhysicalDeviceRayTracingPipelinePropertiesKHR(Printer &p, std::string
     p.PrintKeyValue("shaderGroupHandleAlignment", obj.shaderGroupHandleAlignment);
     p.PrintKeyValue("maxRayHitAttributeSize", obj.maxRayHitAttributeSize);
 }
-void DumpVkPhysicalDeviceRobustness2FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceRobustness2FeaturesEXT &obj) {
+void DumpVkPhysicalDeviceRobustness2FeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceRobustness2FeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(19);
     p.PrintKeyBool("robustBufferAccess2", static_cast<bool>(obj.robustBufferAccess2));
     p.PrintKeyBool("robustImageAccess2", static_cast<bool>(obj.robustImageAccess2));
     p.PrintKeyBool("nullDescriptor", static_cast<bool>(obj.nullDescriptor));
 }
-void DumpVkPhysicalDeviceRobustness2PropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceRobustness2PropertiesEXT &obj) {
+void DumpVkPhysicalDeviceRobustness2PropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceRobustness2PropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(38);
     p.PrintKeyValue("robustStorageBufferAccessSizeAlignment", to_hex_str(p, obj.robustStorageBufferAccessSizeAlignment));
     p.PrintKeyValue("robustUniformBufferAccessSizeAlignment", to_hex_str(p, obj.robustUniformBufferAccessSizeAlignment));
 }
-void DumpVkPhysicalDeviceSampleLocationsPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceSampleLocationsPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceSampleLocationsPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceSampleLocationsPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(32);
     DumpVkSampleCountFlags(p, "sampleLocationSampleCounts", obj.sampleLocationSampleCounts);
@@ -1970,28 +2121,28 @@ void DumpVkPhysicalDeviceSampleLocationsPropertiesEXT(Printer &p, std::string na
     p.PrintKeyValue("sampleLocationSubPixelBits", obj.sampleLocationSubPixelBits);
     p.PrintKeyBool("variableSampleLocations", static_cast<bool>(obj.variableSampleLocations));
 }
-void DumpVkPhysicalDeviceSamplerFilterMinmaxProperties(Printer &p, std::string name, VkPhysicalDeviceSamplerFilterMinmaxProperties &obj) {
+void DumpVkPhysicalDeviceSamplerFilterMinmaxProperties(Printer &p, std::string name, const VkPhysicalDeviceSamplerFilterMinmaxProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(34);
     p.PrintKeyBool("filterMinmaxSingleComponentFormats", static_cast<bool>(obj.filterMinmaxSingleComponentFormats));
     p.PrintKeyBool("filterMinmaxImageComponentMapping", static_cast<bool>(obj.filterMinmaxImageComponentMapping));
 }
-void DumpVkPhysicalDeviceSamplerYcbcrConversionFeatures(Printer &p, std::string name, VkPhysicalDeviceSamplerYcbcrConversionFeatures &obj) {
+void DumpVkPhysicalDeviceSamplerYcbcrConversionFeatures(Printer &p, std::string name, const VkPhysicalDeviceSamplerYcbcrConversionFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(22);
     p.PrintKeyBool("samplerYcbcrConversion", static_cast<bool>(obj.samplerYcbcrConversion));
 }
-void DumpVkPhysicalDeviceScalarBlockLayoutFeatures(Printer &p, std::string name, VkPhysicalDeviceScalarBlockLayoutFeatures &obj) {
+void DumpVkPhysicalDeviceScalarBlockLayoutFeatures(Printer &p, std::string name, const VkPhysicalDeviceScalarBlockLayoutFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(17);
     p.PrintKeyBool("scalarBlockLayout", static_cast<bool>(obj.scalarBlockLayout));
 }
-void DumpVkPhysicalDeviceSeparateDepthStencilLayoutsFeatures(Printer &p, std::string name, VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures &obj) {
+void DumpVkPhysicalDeviceSeparateDepthStencilLayoutsFeatures(Printer &p, std::string name, const VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(27);
     p.PrintKeyBool("separateDepthStencilLayouts", static_cast<bool>(obj.separateDepthStencilLayouts));
 }
-void DumpVkPhysicalDeviceShaderAtomicFloat2FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT &obj) {
+void DumpVkPhysicalDeviceShaderAtomicFloat2FeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(31);
     p.PrintKeyBool("shaderBufferFloat16Atomics", static_cast<bool>(obj.shaderBufferFloat16Atomics));
@@ -2007,7 +2158,7 @@ void DumpVkPhysicalDeviceShaderAtomicFloat2FeaturesEXT(Printer &p, std::string n
     p.PrintKeyBool("shaderImageFloat32AtomicMinMax", static_cast<bool>(obj.shaderImageFloat32AtomicMinMax));
     p.PrintKeyBool("sparseImageFloat32AtomicMinMax", static_cast<bool>(obj.sparseImageFloat32AtomicMinMax));
 }
-void DumpVkPhysicalDeviceShaderAtomicFloatFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceShaderAtomicFloatFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceShaderAtomicFloatFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(28);
     p.PrintKeyBool("shaderBufferFloat32Atomics", static_cast<bool>(obj.shaderBufferFloat32Atomics));
@@ -2023,46 +2174,46 @@ void DumpVkPhysicalDeviceShaderAtomicFloatFeaturesEXT(Printer &p, std::string na
     p.PrintKeyBool("sparseImageFloat32Atomics", static_cast<bool>(obj.sparseImageFloat32Atomics));
     p.PrintKeyBool("sparseImageFloat32AtomicAdd", static_cast<bool>(obj.sparseImageFloat32AtomicAdd));
 }
-void DumpVkPhysicalDeviceShaderAtomicInt64Features(Printer &p, std::string name, VkPhysicalDeviceShaderAtomicInt64Features &obj) {
+void DumpVkPhysicalDeviceShaderAtomicInt64Features(Printer &p, std::string name, const VkPhysicalDeviceShaderAtomicInt64Features &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(24);
     p.PrintKeyBool("shaderBufferInt64Atomics", static_cast<bool>(obj.shaderBufferInt64Atomics));
     p.PrintKeyBool("shaderSharedInt64Atomics", static_cast<bool>(obj.shaderSharedInt64Atomics));
 }
-void DumpVkPhysicalDeviceShaderClockFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceShaderClockFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceShaderClockFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceShaderClockFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(19);
     p.PrintKeyBool("shaderSubgroupClock", static_cast<bool>(obj.shaderSubgroupClock));
     p.PrintKeyBool("shaderDeviceClock", static_cast<bool>(obj.shaderDeviceClock));
 }
-void DumpVkPhysicalDeviceShaderDemoteToHelperInvocationFeatures(Printer &p, std::string name, VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures &obj) {
+void DumpVkPhysicalDeviceShaderDemoteToHelperInvocationFeatures(Printer &p, std::string name, const VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(30);
     p.PrintKeyBool("shaderDemoteToHelperInvocation", static_cast<bool>(obj.shaderDemoteToHelperInvocation));
 }
-void DumpVkPhysicalDeviceShaderDrawParametersFeatures(Printer &p, std::string name, VkPhysicalDeviceShaderDrawParametersFeatures &obj) {
+void DumpVkPhysicalDeviceShaderDrawParametersFeatures(Printer &p, std::string name, const VkPhysicalDeviceShaderDrawParametersFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(20);
     p.PrintKeyBool("shaderDrawParameters", static_cast<bool>(obj.shaderDrawParameters));
 }
-void DumpVkPhysicalDeviceShaderFloat16Int8Features(Printer &p, std::string name, VkPhysicalDeviceShaderFloat16Int8Features &obj) {
+void DumpVkPhysicalDeviceShaderFloat16Int8Features(Printer &p, std::string name, const VkPhysicalDeviceShaderFloat16Int8Features &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(13);
     p.PrintKeyBool("shaderFloat16", static_cast<bool>(obj.shaderFloat16));
     p.PrintKeyBool("shaderInt8", static_cast<bool>(obj.shaderInt8));
 }
-void DumpVkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT &obj) {
+void DumpVkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(23);
     p.PrintKeyBool("shaderImageInt64Atomics", static_cast<bool>(obj.shaderImageInt64Atomics));
     p.PrintKeyBool("sparseImageInt64Atomics", static_cast<bool>(obj.sparseImageInt64Atomics));
 }
-void DumpVkPhysicalDeviceShaderIntegerDotProductFeatures(Printer &p, std::string name, VkPhysicalDeviceShaderIntegerDotProductFeatures &obj) {
+void DumpVkPhysicalDeviceShaderIntegerDotProductFeatures(Printer &p, std::string name, const VkPhysicalDeviceShaderIntegerDotProductFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(23);
     p.PrintKeyBool("shaderIntegerDotProduct", static_cast<bool>(obj.shaderIntegerDotProduct));
 }
-void DumpVkPhysicalDeviceShaderIntegerDotProductProperties(Printer &p, std::string name, VkPhysicalDeviceShaderIntegerDotProductProperties &obj) {
+void DumpVkPhysicalDeviceShaderIntegerDotProductProperties(Printer &p, std::string name, const VkPhysicalDeviceShaderIntegerDotProductProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(77);
     p.PrintKeyBool("integerDotProduct8BitUnsignedAccelerated", static_cast<bool>(obj.integerDotProduct8BitUnsignedAccelerated));
@@ -2096,22 +2247,22 @@ void DumpVkPhysicalDeviceShaderIntegerDotProductProperties(Printer &p, std::stri
     p.PrintKeyBool("integerDotProductAccumulatingSaturating64BitSignedAccelerated", static_cast<bool>(obj.integerDotProductAccumulatingSaturating64BitSignedAccelerated));
     p.PrintKeyBool("integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated", static_cast<bool>(obj.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated));
 }
-void DumpVkPhysicalDeviceShaderSubgroupExtendedTypesFeatures(Printer &p, std::string name, VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures &obj) {
+void DumpVkPhysicalDeviceShaderSubgroupExtendedTypesFeatures(Printer &p, std::string name, const VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(27);
     p.PrintKeyBool("shaderSubgroupExtendedTypes", static_cast<bool>(obj.shaderSubgroupExtendedTypes));
 }
-void DumpVkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(32);
     p.PrintKeyBool("shaderSubgroupUniformControlFlow", static_cast<bool>(obj.shaderSubgroupUniformControlFlow));
 }
-void DumpVkPhysicalDeviceShaderTerminateInvocationFeatures(Printer &p, std::string name, VkPhysicalDeviceShaderTerminateInvocationFeatures &obj) {
+void DumpVkPhysicalDeviceShaderTerminateInvocationFeatures(Printer &p, std::string name, const VkPhysicalDeviceShaderTerminateInvocationFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(25);
     p.PrintKeyBool("shaderTerminateInvocation", static_cast<bool>(obj.shaderTerminateInvocation));
 }
-void DumpVkPhysicalDeviceSparseProperties(Printer &p, std::string name, VkPhysicalDeviceSparseProperties &obj) {
+void DumpVkPhysicalDeviceSparseProperties(Printer &p, std::string name, const VkPhysicalDeviceSparseProperties &obj) {
     if (p.Type() == OutputType::json)
         p.ObjectStart("sparseProperties");
     else
@@ -2124,7 +2275,7 @@ void DumpVkPhysicalDeviceSparseProperties(Printer &p, std::string name, VkPhysic
     p.PrintKeyBool("residencyNonResidentStrict", static_cast<bool>(obj.residencyNonResidentStrict));
     p.ObjectEnd();
 }
-void DumpVkPhysicalDeviceSubgroupProperties(Printer &p, std::string name, VkPhysicalDeviceSubgroupProperties &obj) {
+void DumpVkPhysicalDeviceSubgroupProperties(Printer &p, std::string name, const VkPhysicalDeviceSubgroupProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(25);
     p.PrintKeyValue("subgroupSize", obj.subgroupSize);
@@ -2132,13 +2283,13 @@ void DumpVkPhysicalDeviceSubgroupProperties(Printer &p, std::string name, VkPhys
     DumpVkSubgroupFeatureFlags(p, "supportedOperations", obj.supportedOperations);
     p.PrintKeyBool("quadOperationsInAllStages", static_cast<bool>(obj.quadOperationsInAllStages));
 }
-void DumpVkPhysicalDeviceSubgroupSizeControlFeatures(Printer &p, std::string name, VkPhysicalDeviceSubgroupSizeControlFeatures &obj) {
+void DumpVkPhysicalDeviceSubgroupSizeControlFeatures(Printer &p, std::string name, const VkPhysicalDeviceSubgroupSizeControlFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(20);
     p.PrintKeyBool("subgroupSizeControl", static_cast<bool>(obj.subgroupSizeControl));
     p.PrintKeyBool("computeFullSubgroups", static_cast<bool>(obj.computeFullSubgroups));
 }
-void DumpVkPhysicalDeviceSubgroupSizeControlProperties(Printer &p, std::string name, VkPhysicalDeviceSubgroupSizeControlProperties &obj) {
+void DumpVkPhysicalDeviceSubgroupSizeControlProperties(Printer &p, std::string name, const VkPhysicalDeviceSubgroupSizeControlProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(28);
     p.PrintKeyValue("minSubgroupSize", obj.minSubgroupSize);
@@ -2146,17 +2297,17 @@ void DumpVkPhysicalDeviceSubgroupSizeControlProperties(Printer &p, std::string n
     p.PrintKeyValue("maxComputeWorkgroupSubgroups", obj.maxComputeWorkgroupSubgroups);
     DumpVkShaderStageFlags(p, "requiredSubgroupSizeStages", obj.requiredSubgroupSizeStages);
 }
-void DumpVkPhysicalDeviceSynchronization2Features(Printer &p, std::string name, VkPhysicalDeviceSynchronization2Features &obj) {
+void DumpVkPhysicalDeviceSynchronization2Features(Printer &p, std::string name, const VkPhysicalDeviceSynchronization2Features &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(16);
     p.PrintKeyBool("synchronization2", static_cast<bool>(obj.synchronization2));
 }
-void DumpVkPhysicalDeviceTexelBufferAlignmentFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceTexelBufferAlignmentFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(20);
     p.PrintKeyBool("texelBufferAlignment", static_cast<bool>(obj.texelBufferAlignment));
 }
-void DumpVkPhysicalDeviceTexelBufferAlignmentProperties(Printer &p, std::string name, VkPhysicalDeviceTexelBufferAlignmentProperties &obj) {
+void DumpVkPhysicalDeviceTexelBufferAlignmentProperties(Printer &p, std::string name, const VkPhysicalDeviceTexelBufferAlignmentProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(44);
     p.PrintKeyValue("storageTexelBufferOffsetAlignmentBytes", to_hex_str(p, obj.storageTexelBufferOffsetAlignmentBytes));
@@ -2164,22 +2315,22 @@ void DumpVkPhysicalDeviceTexelBufferAlignmentProperties(Printer &p, std::string
     p.PrintKeyValue("uniformTexelBufferOffsetAlignmentBytes", to_hex_str(p, obj.uniformTexelBufferOffsetAlignmentBytes));
     p.PrintKeyBool("uniformTexelBufferOffsetSingleTexelAlignment", static_cast<bool>(obj.uniformTexelBufferOffsetSingleTexelAlignment));
 }
-void DumpVkPhysicalDeviceTextureCompressionASTCHDRFeatures(Printer &p, std::string name, VkPhysicalDeviceTextureCompressionASTCHDRFeatures &obj) {
+void DumpVkPhysicalDeviceTextureCompressionASTCHDRFeatures(Printer &p, std::string name, const VkPhysicalDeviceTextureCompressionASTCHDRFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(26);
     p.PrintKeyBool("textureCompressionASTC_HDR", static_cast<bool>(obj.textureCompressionASTC_HDR));
 }
-void DumpVkPhysicalDeviceTimelineSemaphoreFeatures(Printer &p, std::string name, VkPhysicalDeviceTimelineSemaphoreFeatures &obj) {
+void DumpVkPhysicalDeviceTimelineSemaphoreFeatures(Printer &p, std::string name, const VkPhysicalDeviceTimelineSemaphoreFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(17);
     p.PrintKeyBool("timelineSemaphore", static_cast<bool>(obj.timelineSemaphore));
 }
-void DumpVkPhysicalDeviceTimelineSemaphoreProperties(Printer &p, std::string name, VkPhysicalDeviceTimelineSemaphoreProperties &obj) {
+void DumpVkPhysicalDeviceTimelineSemaphoreProperties(Printer &p, std::string name, const VkPhysicalDeviceTimelineSemaphoreProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(35);
     p.PrintKeyValue("maxTimelineSemaphoreValueDifference", obj.maxTimelineSemaphoreValueDifference);
 }
-void DumpVkPhysicalDeviceToolProperties(Printer &p, std::string name, VkPhysicalDeviceToolProperties &obj) {
+void DumpVkPhysicalDeviceToolProperties(Printer &p, std::string name, const VkPhysicalDeviceToolProperties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(16);
     p.PrintKeyString("name", obj.name);
@@ -2188,13 +2339,13 @@ void DumpVkPhysicalDeviceToolProperties(Printer &p, std::string name, VkPhysical
     p.PrintKeyString("description", obj.description);
     p.PrintKeyString("layer", obj.layer);
 }
-void DumpVkPhysicalDeviceTransformFeedbackFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTransformFeedbackFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceTransformFeedbackFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceTransformFeedbackFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(17);
     p.PrintKeyBool("transformFeedback", static_cast<bool>(obj.transformFeedback));
     p.PrintKeyBool("geometryStreams", static_cast<bool>(obj.geometryStreams));
 }
-void DumpVkPhysicalDeviceTransformFeedbackPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceTransformFeedbackPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceTransformFeedbackPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceTransformFeedbackPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(42);
     p.PrintKeyValue("maxTransformFeedbackStreams", obj.maxTransformFeedbackStreams);
@@ -2208,34 +2359,34 @@ void DumpVkPhysicalDeviceTransformFeedbackPropertiesEXT(Printer &p, std::string
     p.PrintKeyBool("transformFeedbackRasterizationStreamSelect", static_cast<bool>(obj.transformFeedbackRasterizationStreamSelect));
     p.PrintKeyBool("transformFeedbackDraw", static_cast<bool>(obj.transformFeedbackDraw));
 }
-void DumpVkPhysicalDeviceUniformBufferStandardLayoutFeatures(Printer &p, std::string name, VkPhysicalDeviceUniformBufferStandardLayoutFeatures &obj) {
+void DumpVkPhysicalDeviceUniformBufferStandardLayoutFeatures(Printer &p, std::string name, const VkPhysicalDeviceUniformBufferStandardLayoutFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(27);
     p.PrintKeyBool("uniformBufferStandardLayout", static_cast<bool>(obj.uniformBufferStandardLayout));
 }
-void DumpVkPhysicalDeviceVariablePointersFeatures(Printer &p, std::string name, VkPhysicalDeviceVariablePointersFeatures &obj) {
+void DumpVkPhysicalDeviceVariablePointersFeatures(Printer &p, std::string name, const VkPhysicalDeviceVariablePointersFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(29);
     p.PrintKeyBool("variablePointersStorageBuffer", static_cast<bool>(obj.variablePointersStorageBuffer));
     p.PrintKeyBool("variablePointers", static_cast<bool>(obj.variablePointers));
 }
-void DumpVkPhysicalDeviceVertexAttributeDivisorFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceVertexAttributeDivisorFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(38);
     p.PrintKeyBool("vertexAttributeInstanceRateDivisor", static_cast<bool>(obj.vertexAttributeInstanceRateDivisor));
     p.PrintKeyBool("vertexAttributeInstanceRateZeroDivisor", static_cast<bool>(obj.vertexAttributeInstanceRateZeroDivisor));
 }
-void DumpVkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT &obj) {
+void DumpVkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(Printer &p, std::string name, const VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(22);
     p.PrintKeyValue("maxVertexAttribDivisor", obj.maxVertexAttribDivisor);
 }
-void DumpVkPhysicalDeviceVertexInputDynamicStateFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceVertexInputDynamicStateFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(23);
     p.PrintKeyBool("vertexInputDynamicState", static_cast<bool>(obj.vertexInputDynamicState));
 }
-void DumpVkPhysicalDeviceVulkan11Features(Printer &p, std::string name, VkPhysicalDeviceVulkan11Features &obj) {
+void DumpVkPhysicalDeviceVulkan11Features(Printer &p, std::string name, const VkPhysicalDeviceVulkan11Features &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(34);
     p.PrintKeyBool("storageBuffer16BitAccess", static_cast<bool>(obj.storageBuffer16BitAccess));
@@ -2251,12 +2402,26 @@ void DumpVkPhysicalDeviceVulkan11Features(Printer &p, std::string name, VkPhysic
     p.PrintKeyBool("samplerYcbcrConversion", static_cast<bool>(obj.samplerYcbcrConversion));
     p.PrintKeyBool("shaderDrawParameters", static_cast<bool>(obj.shaderDrawParameters));
 }
-void DumpVkPhysicalDeviceVulkan11Properties(Printer &p, std::string name, VkPhysicalDeviceVulkan11Properties &obj) {
+void DumpVkPhysicalDeviceVulkan11Properties(Printer &p, std::string name, const VkPhysicalDeviceVulkan11Properties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(33);
-    p.PrintKeyString("deviceUUID", to_string_16(obj.deviceUUID));
-    p.PrintKeyString("driverUUID", to_string_16(obj.driverUUID));
-    if (obj.deviceLUIDValid) p.PrintKeyString("deviceLUID", to_string_8(obj.deviceLUID));
+    if (p.Type() == OutputType::json) {
+        ArrayWrapper arr(p, "deviceUUID");
+        for (uint32_t i = 0; i < 16; i++) p.PrintElement(static_cast<uint32_t>(obj.deviceUUID[i]));
+    } else
+        p.PrintKeyString("deviceUUID", to_string_16(obj.deviceUUID));
+    if (p.Type() == OutputType::json) {
+        ArrayWrapper arr(p, "driverUUID");
+        for (uint32_t i = 0; i < 16; i++) p.PrintElement(static_cast<uint32_t>(obj.driverUUID[i]));
+    } else
+        p.PrintKeyString("driverUUID", to_string_16(obj.driverUUID));
+    if (obj.deviceLUIDValid) { // special case
+    if (p.Type() == OutputType::json) {
+        ArrayWrapper arr(p, "deviceLUID");
+        for (uint32_t i = 0; i < 8; i++) p.PrintElement(static_cast<uint32_t>(obj.deviceLUID[i]));
+    } else
+        p.PrintKeyString("deviceLUID", to_string_8(obj.deviceLUID));
+    }
     p.PrintKeyValue("deviceNodeMask", obj.deviceNodeMask);
     p.PrintKeyBool("deviceLUIDValid", static_cast<bool>(obj.deviceLUIDValid));
     p.PrintKeyValue("subgroupSize", obj.subgroupSize);
@@ -2270,7 +2435,7 @@ void DumpVkPhysicalDeviceVulkan11Properties(Printer &p, std::string name, VkPhys
     p.PrintKeyValue("maxPerSetDescriptors", obj.maxPerSetDescriptors);
     p.PrintKeyValue("maxMemoryAllocationSize", to_hex_str(p, obj.maxMemoryAllocationSize));
 }
-void DumpVkPhysicalDeviceVulkan12Features(Printer &p, std::string name, VkPhysicalDeviceVulkan12Features &obj) {
+void DumpVkPhysicalDeviceVulkan12Features(Printer &p, std::string name, const VkPhysicalDeviceVulkan12Features &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(50);
     p.PrintKeyBool("samplerMirrorClampToEdge", static_cast<bool>(obj.samplerMirrorClampToEdge));
@@ -2321,7 +2486,7 @@ void DumpVkPhysicalDeviceVulkan12Features(Printer &p, std::string name, VkPhysic
     p.PrintKeyBool("shaderOutputLayer", static_cast<bool>(obj.shaderOutputLayer));
     p.PrintKeyBool("subgroupBroadcastDynamicId", static_cast<bool>(obj.subgroupBroadcastDynamicId));
 }
-void DumpVkPhysicalDeviceVulkan12Properties(Printer &p, std::string name, VkPhysicalDeviceVulkan12Properties &obj) {
+void DumpVkPhysicalDeviceVulkan12Properties(Printer &p, std::string name, const VkPhysicalDeviceVulkan12Properties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(52);
     DumpVkDriverId(p, "driverID", obj.driverID);
@@ -2377,7 +2542,7 @@ void DumpVkPhysicalDeviceVulkan12Properties(Printer &p, std::string name, VkPhys
     p.PrintKeyValue("maxTimelineSemaphoreValueDifference", obj.maxTimelineSemaphoreValueDifference);
     DumpVkSampleCountFlags(p, "framebufferIntegerColorSampleCounts", obj.framebufferIntegerColorSampleCounts);
 }
-void DumpVkPhysicalDeviceVulkan13Features(Printer &p, std::string name, VkPhysicalDeviceVulkan13Features &obj) {
+void DumpVkPhysicalDeviceVulkan13Features(Printer &p, std::string name, const VkPhysicalDeviceVulkan13Features &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(50);
     p.PrintKeyBool("robustImageAccess", static_cast<bool>(obj.robustImageAccess));
@@ -2396,7 +2561,7 @@ void DumpVkPhysicalDeviceVulkan13Features(Printer &p, std::string name, VkPhysic
     p.PrintKeyBool("shaderIntegerDotProduct", static_cast<bool>(obj.shaderIntegerDotProduct));
     p.PrintKeyBool("maintenance4", static_cast<bool>(obj.maintenance4));
 }
-void DumpVkPhysicalDeviceVulkan13Properties(Printer &p, std::string name, VkPhysicalDeviceVulkan13Properties &obj) {
+void DumpVkPhysicalDeviceVulkan13Properties(Printer &p, std::string name, const VkPhysicalDeviceVulkan13Properties &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(77);
     p.PrintKeyValue("minSubgroupSize", obj.minSubgroupSize);
@@ -2445,14 +2610,14 @@ void DumpVkPhysicalDeviceVulkan13Properties(Printer &p, std::string name, VkPhys
     p.PrintKeyBool("uniformTexelBufferOffsetSingleTexelAlignment", static_cast<bool>(obj.uniformTexelBufferOffsetSingleTexelAlignment));
     p.PrintKeyValue("maxBufferSize", to_hex_str(p, obj.maxBufferSize));
 }
-void DumpVkPhysicalDeviceVulkanMemoryModelFeatures(Printer &p, std::string name, VkPhysicalDeviceVulkanMemoryModelFeatures &obj) {
+void DumpVkPhysicalDeviceVulkanMemoryModelFeatures(Printer &p, std::string name, const VkPhysicalDeviceVulkanMemoryModelFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(45);
     p.PrintKeyBool("vulkanMemoryModel", static_cast<bool>(obj.vulkanMemoryModel));
     p.PrintKeyBool("vulkanMemoryModelDeviceScope", static_cast<bool>(obj.vulkanMemoryModelDeviceScope));
     p.PrintKeyBool("vulkanMemoryModelAvailabilityVisibilityChains", static_cast<bool>(obj.vulkanMemoryModelAvailabilityVisibilityChains));
 }
-void DumpVkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR &obj) {
+void DumpVkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR(Printer &p, std::string name, const VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(46);
     p.PrintKeyBool("workgroupMemoryExplicitLayout", static_cast<bool>(obj.workgroupMemoryExplicitLayout));
@@ -2460,63 +2625,52 @@ void DumpVkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR(Printer &p, st
     p.PrintKeyBool("workgroupMemoryExplicitLayout8BitAccess", static_cast<bool>(obj.workgroupMemoryExplicitLayout8BitAccess));
     p.PrintKeyBool("workgroupMemoryExplicitLayout16BitAccess", static_cast<bool>(obj.workgroupMemoryExplicitLayout16BitAccess));
 }
-void DumpVkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(21);
     p.PrintKeyBool("ycbcr2plane444Formats", static_cast<bool>(obj.ycbcr2plane444Formats));
 }
-void DumpVkPhysicalDeviceYcbcrImageArraysFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceYcbcrImageArraysFeaturesEXT &obj) {
+void DumpVkPhysicalDeviceYcbcrImageArraysFeaturesEXT(Printer &p, std::string name, const VkPhysicalDeviceYcbcrImageArraysFeaturesEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(16);
     p.PrintKeyBool("ycbcrImageArrays", static_cast<bool>(obj.ycbcrImageArrays));
 }
-void DumpVkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures(Printer &p, std::string name, VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures &obj) {
+void DumpVkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures(Printer &p, std::string name, const VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(35);
     p.PrintKeyBool("shaderZeroInitializeWorkgroupMemory", static_cast<bool>(obj.shaderZeroInitializeWorkgroupMemory));
 }
-void DumpVkQueueFamilyGlobalPriorityPropertiesKHR(Printer &p, std::string name, VkQueueFamilyGlobalPriorityPropertiesKHR &obj) {
+void DumpVkQueueFamilyGlobalPriorityPropertiesKHR(Printer &p, std::string name, const VkQueueFamilyGlobalPriorityPropertiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(14);
     p.PrintKeyValue("priorityCount", obj.priorityCount);
-    {   ArrayWrapper arr(p,"priorities", 16);
-        p.PrintElement(obj.priorities[0]);
-        p.PrintElement(obj.priorities[1]);
-        p.PrintElement(obj.priorities[2]);
-        p.PrintElement(obj.priorities[3]);
-        p.PrintElement(obj.priorities[4]);
-        p.PrintElement(obj.priorities[5]);
-        p.PrintElement(obj.priorities[6]);
-        p.PrintElement(obj.priorities[7]);
-        p.PrintElement(obj.priorities[8]);
-        p.PrintElement(obj.priorities[9]);
-        p.PrintElement(obj.priorities[10]);
-        p.PrintElement(obj.priorities[11]);
-        p.PrintElement(obj.priorities[12]);
-        p.PrintElement(obj.priorities[13]);
-        p.PrintElement(obj.priorities[14]);
-        p.PrintElement(obj.priorities[15]);
+    ArrayWrapper arr(p,"priorities", obj.priorityCount);
+    for (uint32_t i = 0; i < obj.priorityCount; i++) {
+       if (p.Type() == OutputType::json)
+           p.PrintString(std::string("VK_") + VkQueueGlobalPriorityKHRString(obj.priorities[i]));
+       else
+           p.PrintString(VkQueueGlobalPriorityKHRString(obj.priorities[i]));
     }
 }
 #ifdef VK_ENABLE_BETA_EXTENSIONS
-void DumpVkQueueFamilyQueryResultStatusProperties2KHR(Printer &p, std::string name, VkQueueFamilyQueryResultStatusProperties2KHR &obj) {
+void DumpVkQueueFamilyQueryResultStatusProperties2KHR(Printer &p, std::string name, const VkQueueFamilyQueryResultStatusProperties2KHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(9);
     p.PrintKeyBool("supported", static_cast<bool>(obj.supported));
 }
 #endif  // VK_ENABLE_BETA_EXTENSIONS
-void DumpVkSharedPresentSurfaceCapabilitiesKHR(Printer &p, std::string name, VkSharedPresentSurfaceCapabilitiesKHR &obj) {
+void DumpVkSharedPresentSurfaceCapabilitiesKHR(Printer &p, std::string name, const VkSharedPresentSurfaceCapabilitiesKHR &obj) {
     ObjectWrapper object{p, name};
     DumpVkImageUsageFlags(p, "sharedPresentSupportedUsageFlags", obj.sharedPresentSupportedUsageFlags);
 }
 #ifdef VK_USE_PLATFORM_WIN32_KHR
-void DumpVkSurfaceCapabilitiesFullScreenExclusiveEXT(Printer &p, std::string name, VkSurfaceCapabilitiesFullScreenExclusiveEXT &obj) {
+void DumpVkSurfaceCapabilitiesFullScreenExclusiveEXT(Printer &p, std::string name, const VkSurfaceCapabilitiesFullScreenExclusiveEXT &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(28);
     p.PrintKeyBool("fullScreenExclusiveSupported", static_cast<bool>(obj.fullScreenExclusiveSupported));
 }
 #endif  // VK_USE_PLATFORM_WIN32_KHR
-void DumpVkSurfaceCapabilitiesKHR(Printer &p, std::string name, VkSurfaceCapabilitiesKHR &obj) {
+void DumpVkSurfaceCapabilitiesKHR(Printer &p, std::string name, const VkSurfaceCapabilitiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(19);
     p.PrintKeyValue("minImageCount", obj.minImageCount);
@@ -2530,18 +2684,39 @@ void DumpVkSurfaceCapabilitiesKHR(Printer &p, std::string name, VkSurfaceCapabil
     DumpVkCompositeAlphaFlagsKHR(p, "supportedCompositeAlpha", obj.supportedCompositeAlpha);
     DumpVkImageUsageFlags(p, "supportedUsageFlags", obj.supportedUsageFlags);
 }
-void DumpVkSurfaceFormatKHR(Printer &p, std::string name, VkSurfaceFormatKHR &obj) {
+void DumpVkSurfaceFormatKHR(Printer &p, std::string name, const VkSurfaceFormatKHR &obj) {
     ObjectWrapper object{p, name};
     DumpVkFormat(p, "format", obj.format);
     DumpVkColorSpaceKHR(p, "colorSpace", obj.colorSpace);
 }
-void DumpVkSurfaceProtectedCapabilitiesKHR(Printer &p, std::string name, VkSurfaceProtectedCapabilitiesKHR &obj) {
+void DumpVkSurfaceProtectedCapabilitiesKHR(Printer &p, std::string name, const VkSurfaceProtectedCapabilitiesKHR &obj) {
     ObjectWrapper object{p, name};
     p.SetMinKeyWidth(17);
     p.PrintKeyBool("supportsProtected", static_cast<bool>(obj.supportsProtected));
 }
 #ifdef VK_ENABLE_BETA_EXTENSIONS
-void DumpVkVideoQueueFamilyProperties2KHR(Printer &p, std::string name, VkVideoQueueFamilyProperties2KHR &obj) {
+void DumpVkVideoDecodeH264ProfileEXT(Printer &p, std::string name, const VkVideoDecodeH264ProfileEXT &obj) {
+    ObjectWrapper object{p, name};
+    DumpVkVideoDecodeH264PictureLayoutFlagsEXT(p, "pictureLayout", obj.pictureLayout);
+}
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+void DumpVkVideoDecodeH265ProfileEXT(Printer &p, std::string name, const VkVideoDecodeH265ProfileEXT &obj) {
+    ObjectWrapper object{p, name};
+}
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+void DumpVkVideoEncodeH264ProfileEXT(Printer &p, std::string name, const VkVideoEncodeH264ProfileEXT &obj) {
+    ObjectWrapper object{p, name};
+}
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+void DumpVkVideoEncodeH265ProfileEXT(Printer &p, std::string name, const VkVideoEncodeH265ProfileEXT &obj) {
+    ObjectWrapper object{p, name};
+}
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+void DumpVkVideoQueueFamilyProperties2KHR(Printer &p, std::string name, const VkVideoQueueFamilyProperties2KHR &obj) {
     ObjectWrapper object{p, name};
     DumpVkVideoCodecOperationFlagsKHR(p, "videoCodecOperations", obj.videoCodecOperations);
 }
@@ -3043,17 +3218,47 @@ struct format_properties2_chain {
     format_properties2_chain(format_properties2_chain &&) = delete;
     format_properties2_chain& operator=(format_properties2_chain &&) = delete;
     void* start_of_chain = nullptr;
-    VkDrmFormatModifierPropertiesList2EXT DrmFormatModifierPropertiesList2EXT{};
-    VkDrmFormatModifierPropertiesListEXT DrmFormatModifierPropertiesListEXT{};
     VkFormatProperties3 FormatProperties3{};
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+    VkVideoDecodeH264ProfileEXT VideoDecodeH264ProfileEXT{};
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+    VkVideoDecodeH265ProfileEXT VideoDecodeH265ProfileEXT{};
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+    VkVideoEncodeH264ProfileEXT VideoEncodeH264ProfileEXT{};
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+    VkVideoEncodeH265ProfileEXT VideoEncodeH265ProfileEXT{};
+#endif  // VK_ENABLE_BETA_EXTENSIONS
     void initialize_chain() noexcept {
-        DrmFormatModifierPropertiesList2EXT.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT;
-        DrmFormatModifierPropertiesListEXT.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT;
         FormatProperties3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        VideoDecodeH264ProfileEXT.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT;
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        VideoDecodeH265ProfileEXT.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT;
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        VideoEncodeH264ProfileEXT.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT;
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        VideoEncodeH265ProfileEXT.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_EXT;
+#endif  // VK_ENABLE_BETA_EXTENSIONS
         std::vector<VkBaseOutStructure*> chain_members;
-        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&DrmFormatModifierPropertiesList2EXT));
-        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&DrmFormatModifierPropertiesListEXT));
         chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&FormatProperties3));
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&VideoDecodeH264ProfileEXT));
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&VideoDecodeH265ProfileEXT));
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&VideoEncodeH264ProfileEXT));
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&VideoEncodeH265ProfileEXT));
+#endif  // VK_ENABLE_BETA_EXTENSIONS
 
         for(size_t i = 0; i < chain_members.size() - 1; i++){
             chain_members[i]->pNext = chain_members[i + 1];
@@ -3267,7 +3472,7 @@ void chain_iterator_phys_device_props2(Printer &p, AppInstance &inst, AppGpu &gp
             p.AddNewline();
         }
 #ifdef VK_ENABLE_BETA_EXTENSIONS
-        if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR &&
+        if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR && p.Type() != OutputType::json &&
            (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME))) {
             VkPhysicalDevicePortabilitySubsetPropertiesKHR* props = (VkPhysicalDevicePortabilitySubsetPropertiesKHR*)structure;
             DumpVkPhysicalDevicePortabilitySubsetPropertiesKHR(p, "VkPhysicalDevicePortabilitySubsetPropertiesKHR", *props);
@@ -3635,7 +3840,7 @@ void chain_iterator_phys_device_features2(Printer &p, AppGpu &gpu, void * place)
             p.AddNewline();
         }
 #ifdef VK_ENABLE_BETA_EXTENSIONS
-        if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR &&
+        if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR && p.Type() != OutputType::json &&
            (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME))) {
             VkPhysicalDevicePortabilitySubsetFeaturesKHR* props = (VkPhysicalDevicePortabilitySubsetFeaturesKHR*)structure;
             DumpVkPhysicalDevicePortabilitySubsetFeaturesKHR(p, "VkPhysicalDevicePortabilitySubsetFeaturesKHR", *props);
@@ -3952,18 +4157,6 @@ void chain_iterator_format_properties2(Printer &p, AppGpu &gpu, void * place) {
     while (place) {
         struct VkBaseOutStructure *structure = (struct VkBaseOutStructure *)place;
         p.SetSubHeader();
-        if (structure->sType == VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT &&
-           (gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME))) {
-            VkDrmFormatModifierPropertiesList2EXT* props = (VkDrmFormatModifierPropertiesList2EXT*)structure;
-            DumpVkDrmFormatModifierPropertiesList2EXT(p, "VkDrmFormatModifierPropertiesList2EXT", *props);
-            p.AddNewline();
-        }
-        if (structure->sType == VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT &&
-           (gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME))) {
-            VkDrmFormatModifierPropertiesListEXT* props = (VkDrmFormatModifierPropertiesListEXT*)structure;
-            DumpVkDrmFormatModifierPropertiesListEXT(p, "VkDrmFormatModifierPropertiesListEXT", *props);
-            p.AddNewline();
-        }
         if (structure->sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 &&
            (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME) ||
             gpu.api_version.minor >= 3)) {
@@ -3971,6 +4164,38 @@ void chain_iterator_format_properties2(Printer &p, AppGpu &gpu, void * place) {
             DumpVkFormatProperties3(p, gpu.api_version.minor >= 3 ?"VkFormatProperties3":"VkFormatProperties3KHR", *props);
             p.AddNewline();
         }
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        if (structure->sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT &&
+           (gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME))) {
+            VkVideoDecodeH264ProfileEXT* props = (VkVideoDecodeH264ProfileEXT*)structure;
+            DumpVkVideoDecodeH264ProfileEXT(p, "VkVideoDecodeH264ProfileEXT", *props);
+            p.AddNewline();
+        }
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        if (structure->sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT &&
+           (gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_VIDEO_DECODE_H265_EXTENSION_NAME))) {
+            VkVideoDecodeH265ProfileEXT* props = (VkVideoDecodeH265ProfileEXT*)structure;
+            DumpVkVideoDecodeH265ProfileEXT(p, "VkVideoDecodeH265ProfileEXT", *props);
+            p.AddNewline();
+        }
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        if (structure->sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT &&
+           (gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME))) {
+            VkVideoEncodeH264ProfileEXT* props = (VkVideoEncodeH264ProfileEXT*)structure;
+            DumpVkVideoEncodeH264ProfileEXT(p, "VkVideoEncodeH264ProfileEXT", *props);
+            p.AddNewline();
+        }
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+        if (structure->sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_EXT &&
+           (gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME))) {
+            VkVideoEncodeH265ProfileEXT* props = (VkVideoEncodeH265ProfileEXT*)structure;
+            DumpVkVideoEncodeH265ProfileEXT(p, "VkVideoEncodeH265ProfileEXT", *props);
+            p.AddNewline();
+        }
+#endif  // VK_ENABLE_BETA_EXTENSIONS
         place = structure->pNext;
     }
 }
index e9245c4..26dd2a2 100644 (file)
@@ -32,7 +32,7 @@
 
 std::string insert_quotes(std::string s) { return "\"" + s + "\""; }
 
-std::string to_string_16(uint8_t uid[16]) {
+std::string to_string_16(const uint8_t uid[16]) {
     std::stringstream ss;
     ss << std::hex << std::setfill('0');
     for (int i = 0; i < 16; ++i) {
@@ -42,7 +42,7 @@ std::string to_string_16(uint8_t uid[16]) {
     return ss.str();
 }
 
-std::string to_string_8(uint8_t uid[8]) {
+std::string to_string_8(const uint8_t uid[8]) {
     std::stringstream ss;
     ss << std::hex << std::setfill('0');
     for (int i = 0; i < 8; ++i) {
@@ -63,6 +63,11 @@ std::string VkVersionString(VulkanVersion v) {
     return std::to_string(v.major) + "." + std::to_string(v.minor) + "." + std::to_string(v.patch);
 }
 
+std::string VkConformanceVersionString(const VkConformanceVersion &c) {
+    return std::to_string(c.major) + "." + std::to_string(c.minor) + "." + std::to_string(c.subminor) + "." +
+           std::to_string(c.patch);
+}
+
 enum class OutputType { text, html, json, vkconfig_output };
 
 struct PrinterCreateDetails {
@@ -74,7 +79,7 @@ struct PrinterCreateDetails {
 
 class Printer {
   public:
-    Printer(const PrinterCreateDetails &details, std::ostream &out, const uint32_t selected_gpu, const VulkanVersion vulkan_version)
+    Printer(const PrinterCreateDetails &details, std::ostream &out, const VulkanVersion vulkan_version)
         : output_type(details.output_type), out(out) {
         StackNode node{};
         node.is_first_item = false;
@@ -181,9 +186,6 @@ class Printer {
                 node.indents = 3;
                 break;
             case (OutputType::json):
-                out << details.start_string;
-                node.indents = 1;
-                break;
             case (OutputType::vkconfig_output):
                 out << details.start_string;
                 node.indents = 1;
@@ -532,18 +534,7 @@ class Printer {
 
     // For printing key - string pairs (necessary because of json)
     void PrintKeyBool(std::string key, bool value, std::string value_description = "") {
-        switch (output_type) {
-            case (OutputType::text):
-            case (OutputType::html):
-            case (OutputType::vkconfig_output):
-                PrintKeyValue(key, value ? "true" : "false", value_description);
-                break;
-            case (OutputType::json):
-                PrintKeyValue(key, value, value_description);
-                break;
-            default:
-                break;
-        }
+        PrintKeyValue(key, value ? "true" : "false", value_description);
     }
 
     // print inside array
@@ -608,10 +599,7 @@ class Printer {
                     << DecorateAsValue(std::to_string(revision)) << "</summary></details>\n";
                 break;
             case (OutputType::json):
-                ObjectStart("");
-                PrintKeyString("extensionName", ext_name);
-                PrintKeyValue("specVersion", revision);
-                ObjectEnd();
+                PrintKeyValue(ext_name, revision);
                 break;
             case (OutputType::vkconfig_output):
                 ObjectStart(ext_name);
index b57b026..7f56657 100644 (file)
@@ -31,7 +31,7 @@
 
 // =========== Dump Functions ========= //
 
-void DumpExtensions(Printer &p, std::string layer_name, std::vector<VkExtensionProperties> extensions, bool do_indent) {
+void DumpExtensions(Printer &p, std::string section_name, std::vector<VkExtensionProperties> extensions, bool do_indent = false) {
     std::sort(extensions.begin(), extensions.end(), [](VkExtensionProperties &a, VkExtensionProperties &b) -> int {
         return std::string(a.extensionName) < std::string(b.extensionName);
     });
@@ -40,17 +40,20 @@ void DumpExtensions(Printer &p, std::string layer_name, std::vector<VkExtensionP
     for (const auto &ext : extensions) {
         max_length = std::max(max_length, std::strlen(ext.extensionName));
     }
-
-    ObjectWrapper obj(p, layer_name + " Extensions", extensions.size());
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    const std::string portability_ext_name = VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME;
+#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
+    ObjectWrapper obj(p, section_name, extensions.size());
     if (do_indent) p.IndentDecrease();
     for (auto &ext : extensions) {
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+        if (p.Type() == OutputType::json && portability_ext_name == ext.extensionName) continue;
+#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
         p.PrintExtension(ext.extensionName, ext.specVersion, max_length);
     }
     if (do_indent) p.IndentIncrease();
 }
-void DumpExtensions(Printer &p, std::string layer_name, std::vector<VkExtensionProperties> extensions) {
-    DumpExtensions(p, layer_name, extensions, false);
-}
+
 void DumpLayers(Printer &p, std::vector<LayerExtensionList> layers, const std::vector<std::unique_ptr<AppGpu>> &gpus) {
     std::sort(layers.begin(), layers.end(), [](LayerExtensionList &left, LayerExtensionList &right) -> int {
         return std::strncmp(left.layer_properties.layerName, right.layer_properties.layerName, VK_MAX_DESCRIPTION_SIZE) < 0;
@@ -70,13 +73,13 @@ void DumpLayers(Printer &p, std::vector<LayerExtensionList> layers, const std::v
                                      p.DecorateAsValue(v_str) + ", layer version " +
                                      p.DecorateAsValue(std::to_string(props.implementationVersion));
                 ObjectWrapper obj(p, header);
-                DumpExtensions(p, "Layer", layer.extension_properties);
+                DumpExtensions(p, "Layer Extensions", layer.extension_properties);
 
                 ArrayWrapper arr_devices(p, "Devices", gpus.size());
                 for (auto &gpu : gpus) {
                     p.PrintKeyValue("GPU id", gpu->id, gpu->props.deviceName);
                     auto exts = gpu->inst.AppGetPhysicalDeviceLayerExtensions(gpu->phys_device, props.layerName);
-                    DumpExtensions(p, "Layer-Device", exts);
+                    DumpExtensions(p, "Layer-Device Extensions", exts);
                     p.AddNewline();
                 }
             }
@@ -84,12 +87,7 @@ void DumpLayers(Printer &p, std::vector<LayerExtensionList> layers, const std::v
         }
 
         case OutputType::json: {
-            ArrayWrapper arr(p, "ArrayOfVkLayerProperties", layers.size());
-            int i = 0;
-            for (auto &layer : layers) {
-                p.SetElementIndex(i++);
-                DumpVkLayerProperties(p, "layerProperty", layer.layer_properties);
-            }
+            assert(false && "unimplemented");
             break;
         }
         case OutputType::vkconfig_output: {
@@ -101,13 +99,13 @@ void DumpLayers(Printer &p, std::vector<LayerExtensionList> layers, const std::v
                 p.PrintKeyString("version", VkVersionString(layer.layer_properties.specVersion));
                 p.PrintKeyValue("implementation version", layer.layer_properties.implementationVersion);
                 p.PrintKeyString("description", layer.layer_properties.description);
-                DumpExtensions(p, "Layer", layer.extension_properties);
+                DumpExtensions(p, "Layer Extensions", layer.extension_properties);
                 ObjectWrapper obj_devices(p, "Devices");
                 for (auto &gpu : gpus) {
                     ObjectWrapper obj_gpu(p, gpu->props.deviceName);
                     p.PrintKeyValue("GPU id", gpu->id, gpu->props.deviceName);
                     auto exts = gpu->inst.AppGetPhysicalDeviceLayerExtensions(gpu->phys_device, layer.layer_properties.layerName);
-                    DumpExtensions(p, "Layer-Device", exts);
+                    DumpExtensions(p, "Layer-Device Extensions", exts);
                 }
             }
             break;
@@ -313,25 +311,6 @@ void GpuDumpProps(Printer &p, AppGpu &gpu) {
         p.AddNewline();
     }
 }
-void GpuDumpPropsJson(Printer &p, AppGpu &gpu) {
-    auto props = gpu.GetDeviceProperties();
-    ObjectWrapper obj(p, "VkPhysicalDeviceProperties");
-    p.PrintKeyValue("apiVersion", props.apiVersion, VkVersionString(props.apiVersion));
-    p.PrintKeyValue("driverVersion", props.driverVersion, to_hex_str(props.driverVersion));
-    p.PrintKeyValue("vendorID", props.vendorID);
-    p.PrintKeyValue("deviceID", props.deviceID);
-    p.PrintKeyValue("deviceType", props.deviceType);
-    p.PrintKeyString("deviceName", props.deviceName);
-    {
-        ArrayWrapper arr(p, "pipelineCacheUUID", VK_UUID_SIZE);
-        for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) {
-            p.PrintElement(static_cast<uint32_t>(props.pipelineCacheUUID[i]));
-        }
-    }
-
-    DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", gpu.props.limits);
-    DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", gpu.props.sparseProperties);
-}
 
 void GpuDumpQueueProps(Printer &p, AppGpu &gpu, const AppQueueFamilyProperties &queue) {
     VkQueueFamilyProperties props = queue.props;
@@ -365,14 +344,6 @@ void GpuDumpQueueProps(Printer &p, AppGpu &gpu, const AppQueueFamilyProperties &
     p.AddNewline();
 }
 
-void GpuDumpQueuePropsJson(Printer &p, std::vector<SurfaceExtension> &surfaces, VkQueueFamilyProperties props) {
-    ObjectWrapper obj(p, "");
-    DumpVkExtent3D(p, "minImageTransferGranularity", props.minImageTransferGranularity);
-    p.PrintKeyValue("queueCount", props.queueCount);
-    p.PrintKeyValue("queueFlags", props.queueFlags);
-    p.PrintKeyValue("timestampValidBits", props.timestampValidBits);
-}
-
 // This prints a number of bytes in a human-readable format according to prefixes of the International System of Quantities (ISQ),
 // defined in ISO/IEC 80000. The prefixes used here are not SI prefixes, but rather the binary prefixes based on powers of 1024
 // (kibi-, mebi-, gibi- etc.).
@@ -482,26 +453,6 @@ void GpuDumpMemoryProps(Printer &p, AppGpu &gpu) {
     p.AddNewline();
 }
 
-void GpuDumpMemoryPropsJson(Printer &p, AppGpu &gpu) {
-    ObjectWrapper obj_mem_props(p, "VkPhysicalDeviceMemoryProperties");
-    {
-        ArrayWrapper arr(p, "memoryHeaps", gpu.memory_props.memoryHeapCount);
-        for (uint32_t i = 0; i < gpu.memory_props.memoryHeapCount; ++i) {
-            ObjectWrapper obj(p, "");
-            p.PrintKeyValue("flags", gpu.memory_props.memoryHeaps[i].flags);
-            p.PrintKeyValue("size", gpu.memory_props.memoryHeaps[i].size);
-        }
-    }
-    {
-        ArrayWrapper arr(p, "memoryTypes", gpu.memory_props.memoryTypeCount);
-        for (uint32_t i = 0; i < gpu.memory_props.memoryTypeCount; ++i) {
-            ObjectWrapper obj(p, "");
-            p.PrintKeyValue("heapIndex", gpu.memory_props.memoryTypes[i].heapIndex);
-            p.PrintKeyValue("propertyFlags", gpu.memory_props.memoryTypes[i].propertyFlags);
-        }
-    }
-}
-
 void GpuDumpFeatures(Printer &p, AppGpu &gpu) {
     p.SetHeader();
     DumpVkPhysicalDeviceFeatures(p, "VkPhysicalDeviceFeatures", gpu.features);
@@ -513,41 +464,33 @@ void GpuDumpFeatures(Printer &p, AppGpu &gpu) {
 }
 
 void GpuDumpFormatProperty(Printer &p, VkFormat fmt, VkFormatProperties prop) {
+    std::string name{};
     switch (p.Type()) {
         case OutputType::text: {
-            ObjectWrapper obj(p, "Properties");
-            DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures);
-            DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures);
-            DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures);
+            name = "Properties";
             break;
         }
         case OutputType::html: {
-            p.SetTitleAsType();
-            ObjectWrapper obj(p, VkFormatString(fmt));
-            p.SetOpenDetails();
-            DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures);
-            p.SetOpenDetails();
-            DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures);
-            p.SetOpenDetails();
-            DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures);
+            name = VkFormatString(fmt);
             break;
         }
         case OutputType::json: {
-            ObjectWrapper obj(p, "");
-            p.PrintKeyValue("formatID", fmt);
-            p.PrintKeyValue("linearTilingFeatures", prop.linearTilingFeatures);
-            p.PrintKeyValue("optimalTilingFeatures", prop.optimalTilingFeatures);
-            p.PrintKeyValue("bufferFeatures", prop.bufferFeatures);
+            name = "VkFormatProperties";
             break;
         }
         case OutputType::vkconfig_output: {
-            ObjectWrapper obj(p, VkFormatString(fmt));
-            DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures);
-            DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures);
-            DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures);
+            name = VkFormatString(fmt);
             break;
         }
     }
+    p.SetTitleAsType();
+    ObjectWrapper obj(p, name);
+    p.SetOpenDetails();
+    DumpVkFormatFeatureFlags(p, "linearTilingFeatures", prop.linearTilingFeatures);
+    p.SetOpenDetails();
+    DumpVkFormatFeatureFlags(p, "optimalTilingFeatures", prop.optimalTilingFeatures);
+    p.SetOpenDetails();
+    DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures);
 }
 
 void GpuDumpToolingInfo(Printer &p, AppGpu &gpu) {
@@ -617,32 +560,14 @@ void GpuDevDump(Printer &p, AppGpu &gpu) {
     p.AddNewline();
 }
 
-void GpuDevDumpJson(Printer &p, AppGpu &gpu) {
-    ArrayWrapper arr(p, "ArrayOfVkFormatProperties");
-    for (auto &format : gpu.supported_format_ranges) {
-        if (gpu.FormatRangeSupported(format)) {
-            for (int32_t fmt_counter = format.first_format; fmt_counter <= format.last_format; ++fmt_counter) {
-                VkFormat fmt = static_cast<VkFormat>(fmt_counter);
-
-                VkFormatProperties props;
-                gpu.inst.dll.fp_vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props);
-
-                // don't print format properties that are unsupported
-                if ((props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures) == 0) continue;
-
-                GpuDumpFormatProperty(p, fmt, props);
-            }
-        }
-    }
-}
 // Print gpu info for text, html, & vkconfig_output
-// Uses a seperate function than schema-json for clarity
+// Uses a separate function than schema-json for clarity
 void DumpGpu(Printer &p, AppGpu &gpu, bool show_tooling_info, bool show_formats) {
     ObjectWrapper obj_gpu(p, "GPU" + std::to_string(gpu.id));
     IndentWrapper indent(p);
 
     GpuDumpProps(p, gpu);
-    DumpExtensions(p, "Device", gpu.device_extensions);
+    DumpExtensions(p, "Device Extensions", gpu.device_extensions);
     p.AddNewline();
     {
         p.SetHeader();
@@ -664,31 +589,178 @@ void DumpGpu(Printer &p, AppGpu &gpu, bool show_tooling_info, bool show_formats)
     p.AddNewline();
 }
 
-// Print gpu info for json
-void DumpGpuJson(Printer &p, AppGpu &gpu) {
-    GpuDumpPropsJson(p, gpu);
+// Print capabilities section of profiles schema
+void DumpGpuProfileCapabilities(Printer &p, AppGpu &gpu) {
+    ObjectWrapper capabilities(p, "capabilities");
     {
-        ArrayWrapper arr(p, "ArrayOfVkQueueFamilyProperties");
-        for (const auto &queue_prop : gpu.queue_props) {
-            GpuDumpQueuePropsJson(p, gpu.inst.surface_extensions, queue_prop);
+        ObjectWrapper temp_name_obj(p, "device");
+        DumpExtensions(p, "extensions", gpu.device_extensions);
+        {
+            ObjectWrapper obj(p, "features");
+            GpuDumpFeatures(p, gpu);
+        }
+        {
+            ObjectWrapper obj(p, "properties");
+            {
+                ObjectWrapper props_obj(p, "VkPhysicalDeviceProperties");
+                auto props = gpu.GetDeviceProperties();
+                p.PrintKeyValue("apiVersion", props.apiVersion, VkVersionString(props.apiVersion));
+                p.PrintKeyValue("deviceID", props.deviceID);
+                p.PrintKeyString("deviceName", props.deviceName);
+                p.PrintKeyString("deviceType", std::string("VK_") + VkPhysicalDeviceTypeString(props.deviceType));
+                p.PrintKeyValue("driverVersion", props.driverVersion);
+                DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", gpu.props.limits);
+                {
+                    ArrayWrapper arr(p, "pipelineCacheUUID");
+                    for (const auto &uuid : props.pipelineCacheUUID) p.PrintElement(static_cast<uint32_t>(uuid));
+                }
+                DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", gpu.props.sparseProperties);
+                p.PrintKeyValue("vendorID", props.vendorID);
+            }
+            if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
+                void *place = gpu.props2.pNext;
+                chain_iterator_phys_device_props2(p, gpu.inst, gpu, place);
+            }
+        }
+        {
+            ObjectWrapper obj(p, "formats");
+            for (auto &format : gpu.supported_format_ranges) {
+                if (gpu.FormatRangeSupported(format)) {
+                    for (int32_t fmt_counter = format.first_format; fmt_counter <= format.last_format; ++fmt_counter) {
+                        VkFormat fmt = static_cast<VkFormat>(fmt_counter);
+
+                        VkFormatProperties props;
+                        gpu.inst.dll.fp_vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props);
+
+                        // don't print format properties that are unsupported
+                        if ((props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures) == 0) continue;
+
+                        ObjectWrapper format_obj(p, std::string("VK_") + VkFormatString(fmt));
+                        {
+                            GpuDumpFormatProperty(p, fmt, props);
+
+                            VkFormatProperties2 format_props2{};
+                            format_props2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
+                            format_props2.formatProperties = props;
+                            std::unique_ptr<format_properties2_chain> chain_for_format_props2;
+                            setup_format_properties2_chain(format_props2, chain_for_format_props2);
+                            gpu.inst.ext_funcs.vkGetPhysicalDeviceFormatProperties2KHR(gpu.phys_device, fmt, &format_props2);
+                            chain_iterator_format_properties2(p, gpu, format_props2.pNext);
+                        }
+                    }
+                }
+            }
+        }
+        {
+            ArrayWrapper arr(p, "queueFamiliesProperties");
+            for (const auto &extended_queue_prop : gpu.extended_queue_props) {
+                ObjectWrapper queue_obj(p, "");
+                {
+                    ObjectWrapper obj_queue_props(p, "VkQueueFamilyProperties");
+                    VkQueueFamilyProperties props = extended_queue_prop.props;
+                    DumpVkExtent3D(p, "minImageTransferGranularity", props.minImageTransferGranularity);
+                    p.PrintKeyValue("queueCount", props.queueCount);
+                    DumpVkQueueFlags(p, "queueFlags", props.queueFlags);
+                    p.PrintKeyValue("timestampValidBits", props.timestampValidBits);
+                }
+                chain_iterator_queue_properties2(p, gpu, extended_queue_prop.pNext);
+            }
         }
     }
-    {
-        ArrayWrapper arr(p, "ArrayOfVkExtensionProperties");
-        for (auto &ext : gpu.device_extensions) {
-            p.PrintExtension(ext.extensionName, ext.specVersion);
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    // Print portability subset extension, features, and properties if available
+    if (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) &&
+        (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) ||
+         gpu.inst.instance_version >= VK_API_VERSION_1_1)) {
+        ObjectWrapper macos_obj(p, "macos-specific");
+        {
+            ObjectWrapper ext_obj(p, "extensions");
+            const std::string portability_ext_name = VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME;
+            for (const auto &ext : gpu.device_extensions) {
+                if (portability_ext_name == ext.extensionName) {
+                    p.PrintExtension(ext.extensionName, ext.specVersion);
+                }
+            }
+        }
+        {
+            ObjectWrapper features_obj(p, "features");
+            void *feats_place = gpu.features2.pNext;
+            while (feats_place) {
+                VkBaseOutStructure *structure = static_cast<VkBaseOutStructure *>(feats_place);
+                if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR) {
+                    auto *features = reinterpret_cast<VkPhysicalDevicePortabilitySubsetFeaturesKHR *>(structure);
+                    DumpVkPhysicalDevicePortabilitySubsetFeaturesKHR(p, "VkPhysicalDevicePortabilitySubsetFeaturesKHR", *features);
+                    break;
+                }
+                feats_place = structure->pNext;
+            }
+        }
+        {
+            ObjectWrapper property_obj(p, "properties");
+            void *props_place = gpu.props2.pNext;
+            while (props_place) {
+                VkBaseOutStructure *structure = static_cast<VkBaseOutStructure *>(props_place);
+                if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR) {
+                    auto *props = reinterpret_cast<VkPhysicalDevicePortabilitySubsetPropertiesKHR *>(structure);
+                    DumpVkPhysicalDevicePortabilitySubsetPropertiesKHR(p, "VkPhysicalDevicePortabilitySubsetPropertiesKHR", *props);
+                    break;
+                }
+                props_place = structure->pNext;
+            }
         }
     }
+#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
+}
+void PrintProfileBaseInfo(Printer &p, const std::string &device_name, uint32_t apiVersion, const std::string &device_label,
+                          const std::vector<std::string> &capabilities) {
+    ObjectWrapper vk_info(p, device_name);
+    p.PrintKeyValue("version", 1);
+    p.PrintKeyString("api-version", VkVersionString(apiVersion));
+    p.PrintKeyString("label", device_label);
+    p.PrintKeyString("description", "Exported from vulkaninfo");
+    { ObjectWrapper contributors(p, "contributors"); }
+    {
+        ArrayWrapper contributors(p, "history");
+        ObjectWrapper element(p, "");
+        p.PrintKeyValue("revision", 1);
+        std::time_t t = std::time(0);  // get time now
+        std::tm *now = std::localtime(&t);
+        std::string date =
+            std::to_string(now->tm_year + 1900) + '-' + std::to_string(now->tm_mon + 1) + '-' + std::to_string(now->tm_mday);
+        p.PrintKeyString("date", date);
+        p.PrintKeyString("author", "Automated export from vulkaninfo");
+        p.PrintKeyString("comment", "");
+    }
+    ArrayWrapper contributors(p, "capabilities");
+    for (const auto &str : capabilities) p.PrintString(str);
+}
 
-    GpuDumpMemoryPropsJson(p, gpu);
-    DumpVkPhysicalDeviceFeatures(p, "VkPhysicalDeviceFeatures", gpu.features);
-    GpuDevDumpJson(p, gpu);
+// Prints profiles section of profiles schema
+void DumpGpuProfileInfo(Printer &p, AppGpu &gpu) {
+    ObjectWrapper profiles(p, "profiles");
+
+    std::string device_label = std::string(gpu.props.deviceName) + " driver " + VkVersionString(gpu.props.driverVersion);
+    std::string device_name =
+        std::string("VP_VULKANINFO_") + std::string(gpu.props.deviceName) + "_" + VkVersionString(gpu.props.driverVersion);
+    ;
+    for (auto &c : device_name) {
+        if (c == ' ' || c == '.') c = '_';
+    }
+    PrintProfileBaseInfo(p, device_name, gpu.props.apiVersion, device_label, {"device"});
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    if (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) &&
+        (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) ||
+         gpu.inst.instance_version >= VK_API_VERSION_1_1)) {
+        PrintProfileBaseInfo(p, device_name + "_portability_subset", gpu.props.apiVersion, device_label + " subset",
+                             {"device", "macos-specific"});
+    }
+#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
 }
 
 // Print summary of system
 void DumpSummaryInstance(Printer &p, AppInstance &inst) {
     p.SetSubHeader();
-    DumpExtensions(p, "Instance", inst.global_extensions, true);
+    DumpExtensions(p, "Instance Extensions", inst.global_extensions, true);
     p.AddNewline();
 
     p.SetSubHeader();
@@ -742,7 +814,7 @@ void DumpSummaryGPU(Printer &p, AppGpu &gpu) {
                 DumpVkDriverId(p, "driverID", driver_props->driverID);
                 p.PrintKeyString("driverName", driver_props->driverName);
                 p.PrintKeyString("driverInfo", driver_props->driverInfo);
-                DumpVkConformanceVersion(p, "conformanceVersion", driver_props->conformanceVersion);
+                p.PrintKeyString("conformanceVersion", VkConformanceVersionString(driver_props->conformanceVersion));
             }
             if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES) {
                 VkPhysicalDeviceIDProperties *device_id_props = reinterpret_cast<VkPhysicalDeviceIDProperties *>(structure);
@@ -754,38 +826,6 @@ void DumpSummaryGPU(Printer &p, AppGpu &gpu) {
     }
 }
 
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-void DumpPortability(Printer &p, AppGpu &gpu) {
-    if (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
-        if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
-            void *props_place = gpu.props2.pNext;
-            while (props_place) {
-                VkBaseOutStructure *structure = static_cast<VkBaseOutStructure *>(props_place);
-                if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR) {
-                    VkPhysicalDevicePortabilitySubsetPropertiesKHR *props =
-                        reinterpret_cast<VkPhysicalDevicePortabilitySubsetPropertiesKHR *>(structure);
-                    DumpVkPhysicalDevicePortabilitySubsetPropertiesKHR(p, "VkPhysicalDevicePortabilitySubsetPropertiesKHR", *props);
-                    break;
-                }
-                props_place = structure->pNext;
-            }
-
-            void *feats_place = gpu.features2.pNext;
-            while (feats_place) {
-                VkBaseOutStructure *structure = static_cast<VkBaseOutStructure *>(feats_place);
-                if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR) {
-                    VkPhysicalDevicePortabilitySubsetFeaturesKHR *features =
-                        reinterpret_cast<VkPhysicalDevicePortabilitySubsetFeaturesKHR *>(structure);
-                    DumpVkPhysicalDevicePortabilitySubsetFeaturesKHR(p, "VkPhysicalDevicePortabilitySubsetFeaturesKHR", *features);
-                    break;
-                }
-                feats_place = structure->pNext;
-            }
-        }
-    }
-}
-#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
-
 // ============ Printing Logic ============= //
 
 #ifdef _WIN32
@@ -814,49 +854,42 @@ static void ConsoleEnlarge() {
 #endif
 
 // Global configuration
-enum class OutputCategory {
-    text,
-    html,
-    devsim_json,
-    vkconfig_output,
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-    portability_json,
-#endif
-    summary
-};
-
-void print_usage(const char *argv0) {
+enum class OutputCategory { text, html, profile_json, vkconfig_output, summary };
+const char *help_message_body =
+    "OPTIONS:\n"
+    "[-h, --help]        Print this help.\n"
+    "[--summary]         Show a summary of the instance and GPU's on a system.\n"
+    "[-o <filename>, --output <filename>]\n"
+    "                    Print output to a new file whose name is specified by filename.\n"
+    "                    File will be written to the current working directory.\n"
+    "[--text]            Produce a text version of vulkaninfo output to stdout. This is\n"
+    "                    the default output.\n"
+    "[--html]            Produce an html version of vulkaninfo output, saved as\n"
+    "                    \"vulkaninfo.html\" in the directory in which the command\n"
+    "                    is run.\n"
+    "[-j, --json]        Produce a json version of vulkaninfo output conforming to the Vulkan\n"
+    "                    Profiles schema, saved as \"vulkaninfo.json\", of the first gpu in the\n"
+    "                    system.\n"
+    "[-j=<gpu-number>, --json=<gpu-number>]\n"
+    "                    For a multi-gpu system, a single gpu can be targetted by\n"
+    "                    specifying the gpu-number associated with the gpu of \n"
+    "                    interest. This number can be determined by running\n"
+    "                    vulkaninfo without any options specified.\n"
+    "[--show-tool-props] Show the active VkPhysicalDeviceToolPropertiesEXT that vulkaninfo finds.\n"
+    "[--show-formats]    Display the format properties of each physical device.\n"
+    "                    Note: This only affects text output.\n";
+
+void print_usage(const std::string &executable_name) {
     std::cout << "\nvulkaninfo - Summarize Vulkan information in relation to the current environment.\n\n";
-    std::cout << "USAGE: " << argv0 << " [options]\n\n";
-    std::cout << "OPTIONS:\n";
-    std::cout << "-h, --help          Print this help.\n";
-    std::cout << "--summary           Show a summary of the instance and GPU's on a system.\n";
-    std::cout << "--text              Produce a text version of vulkaninfo output to stdout. This is\n";
-    std::cout << "                    the default output.\n";
-    std::cout << "--html              Produce an html version of vulkaninfo output, saved as\n";
-    std::cout << "                    \"vulkaninfo.html\" in the directory in which the command\n";
-    std::cout << "                    is run.\n";
-    std::cout << "-j, --json          Produce a json version of vulkaninfo to standard output of the\n";
-    std::cout << "                    first gpu in the system conforming to the DevSim schema.\n";
-    std::cout << "--json=<gpu-number> For a multi-gpu system, a single gpu can be targetted by\n";
-    std::cout << "                    specifying the gpu-number associated with the gpu of \n";
-    std::cout << "                    interest. This number can be determined by running\n";
-    std::cout << "                    vulkaninfo without any options specified.\n";
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-    std::cout << "--portability       Produce a json version of vulkaninfo to standard output of the first\n";
-    std::cout << "                    gpu in the system conforming to the DevSim Portability Subset schema.\n";
-    std::cout << "--portability=<N>   Produce the json output conforming to the DevSim Portability\n";
-    std::cout << "                    Subset Schema for the GPU specified to standard output,\n";
-    std::cout << "                    where N is the GPU desired.\n";
-#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
-    std::cout << "--show-tool-props   Show the active VkPhysicalDeviceToolPropertiesEXT that vulkaninfo finds.\n";
-    std::cout << "--show-formats      Display the format properties of each physical device.\n";
-    std::cout << "                    Note: This option does not affect html or json output;\n";
-    std::cout << "                    they will always print format properties.\n";
-    std::cout << "-o <filename>, --output<filename>\n";
-    std::cout << "                    Print output to a new file whose name is specified by filename.\n";
-    std::cout << "                    File will be written to the current working directory.\n";
-    std::cout << "\n";
+    std::cout << "USAGE: \n";
+    std::cout << "    " << executable_name << " --summary\n";
+    std::cout << "    " << executable_name << " -o <filename> | --output <filename>\n";
+    std::cout << "    " << executable_name << " -j | -j=<gpu-number> | --json | --json=<gpu-number>\n";
+    std::cout << "    " << executable_name << " --text\n";
+    std::cout << "    " << executable_name << " --html\n";
+    std::cout << "    " << executable_name << " --show-formats\n";
+    std::cout << "    " << executable_name << " --show-tool-props\n";
+    std::cout << "\n" << help_message_body << std::endl;
 }
 
 struct ParsedResults {
@@ -870,7 +903,7 @@ struct ParsedResults {
     std::string default_filename;
 };
 
-util::vulkaninfo_optional<ParsedResults> parse_arguments(int argc, char **argv) {
+util::vulkaninfo_optional<ParsedResults> parse_arguments(int argc, char **argv, std::string executable_name) {
     ParsedResults results{};                         // default it to zero init everything
     results.output_category = OutputCategory::text;  // default output category
     results.default_filename = "vulkaninfo.txt";
@@ -895,17 +928,9 @@ util::vulkaninfo_optional<ParsedResults> parse_arguments(int argc, char **argv)
                 results.selected_gpu = static_cast<uint32_t>(strtol(argv[i] + 7, nullptr, 10));
                 results.has_selected_gpu = true;
             }
-            results.output_category = OutputCategory::devsim_json;
+            results.output_category = OutputCategory::profile_json;
             results.default_filename = "vulkaninfo.json";
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-        } else if (strncmp("--portability", argv[i], 13) == 0) {
-            if (strlen(argv[i]) > 14 && strncmp("--portability=", argv[i], 14) == 0) {
-                results.selected_gpu = static_cast<uint32_t>(strtol(argv[i] + 14, nullptr, 10));
-                results.has_selected_gpu = true;
-            }
-            results.output_category = OutputCategory::portability_json;
-            results.default_filename = "portability.json";
-#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
+            results.print_to_file = true;
         } else if (strcmp(argv[i], "--summary") == 0) {
             results.output_category = OutputCategory::summary;
         } else if (strcmp(argv[i], "--text") == 0) {
@@ -928,10 +953,10 @@ util::vulkaninfo_optional<ParsedResults> parse_arguments(int argc, char **argv)
             results.filename = argv[i + 1];
             ++i;
         } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
-            print_usage(argv[0]);
+            print_usage(executable_name);
             return {};
         } else {
-            print_usage(argv[0]);
+            print_usage(executable_name);
             return {};
         }
     }
@@ -951,36 +976,11 @@ PrinterCreateDetails get_printer_create_details(ParsedResults &parse_data, AppIn
         case (OutputCategory::html):
             create.output_type = OutputType::html;
             break;
-        case (OutputCategory::devsim_json):
-            create.output_type = OutputType::json;
-            create.start_string = std::string("{\n\t\"$schema\": \"https://schema.khronos.org/vulkan/devsim_1_0_0.json#\",\n") +
-                                  "\t\"comments\": {\n\t\t\"desc\": \"JSON configuration file describing GPU " +
-                                  std::to_string(parse_data.selected_gpu) + " (" + selected_gpu.props.deviceName +
-                                  "). Generated using the " + executable_name + " program.\",\n\t\t\"vulkanApiVersion\": \"" +
-                                  VkVersionString(inst.vk_version) + "\"\n" + "\t}";
-#ifdef VK_USE_PLATFORM_IOS_MVK
-            create.print_to_file = true;
-#endif
-            break;
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-        case (OutputCategory::portability_json):
+        case (OutputCategory::profile_json):
             create.output_type = OutputType::json;
             create.start_string =
-                std::string(
-                    "{\n\t\"$schema\": "
-                    "\"https://schema.khronos.org/vulkan/devsim_VK_KHR_portability_subset-provisional-1.json#\",\n") +
-                "\t\"comments\": {\n\t\t\"desc\": \"JSON configuration file describing GPU " +
-                std::to_string(parse_data.selected_gpu) + "'s (" + selected_gpu.props.deviceName +
-                ") portability features and properties. Generated using the " + executable_name +
-                " program.\",\n\t\t\"vulkanApiVersion\": "
-                "\"" +
-                VkVersionString(inst.vk_version) + "\"\n" + "\t}";
-#ifdef VK_USE_PLATFORM_IOS_MVK
-            create.print_to_file = true;
-#endif
+                std::string("{\n\t\"$schema\": ") + "\"https://schema.khronos.org/vulkan/profiles-0.8-latest.json\"";
             break;
-#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
-
         case (OutputCategory::vkconfig_output):
             create.output_type = OutputType::vkconfig_output;
             create.start_string = "{\n\t\"Vulkan Instance Version\": \"" + VkVersionString(inst.vk_version) + "\"";
@@ -1002,18 +1002,13 @@ void RunPrinter(Printer &p, ParsedResults parse_data, AppInstance &instance, std
         for (auto &gpu : gpus) {
             DumpSummaryGPU(p, *(gpu.get()));
         }
-    }
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-    else if (parse_data.output_category == OutputCategory::portability_json) {
-        DumpPortability(p, *(gpus.at(parse_data.selected_gpu).get()));
-#endif  // defined(VK_ENABLE_BETA_EXTENSIONS)
-    } else if (parse_data.output_category == OutputCategory::devsim_json) {
-        DumpLayers(p, instance.global_layers, gpus);
-        DumpGpuJson(p, *(gpus.at(parse_data.selected_gpu).get()));
+    } else if (parse_data.output_category == OutputCategory::profile_json) {
+        DumpGpuProfileCapabilities(p, *(gpus.at(parse_data.selected_gpu).get()));
+        DumpGpuProfileInfo(p, *(gpus.at(parse_data.selected_gpu).get()));
     } else {
         // text, html, vkconfig_output
         p.SetHeader();
-        DumpExtensions(p, "Instance", instance.global_extensions);
+        DumpExtensions(p, "Instance Extensions", instance.global_extensions);
         p.AddNewline();
 
         DumpLayers(p, instance.global_layers, gpus);
@@ -1040,7 +1035,23 @@ int vulkanInfoMain(int argc, char **argv) {
 int main(int argc, char **argv) {
 #endif
 
-    auto parsing_return = parse_arguments(argc, argv);
+    // Figure out the name of the executable, pull out the name if given a path
+    // Default is `vulkaninfo`
+    std::string executable_name = "vulkaninfo";
+    if (argc >= 1) {
+        const auto argv_0 = std::string(argv[0]);
+        // don't include path separator
+        // Look for forward slash first, only look for backslash if that found nothing
+        auto last_occurrence = argv_0.rfind('/');
+        if (last_occurrence == std::string::npos) {
+            last_occurrence = argv_0.rfind('\\');
+        }
+        if (last_occurrence != std::string::npos && last_occurrence + 1 < argv_0.size()) {
+            executable_name = argv_0.substr(last_occurrence + 1);
+        }
+    }
+
+    auto parsing_return = parse_arguments(argc, argv, executable_name);
     if (!parsing_return) return 1;
     ParsedResults parse_data = parsing_return.value();
 
@@ -1060,22 +1071,6 @@ int main(int argc, char **argv) {
     }
 #endif
 
-    // Figure out the name of the executable, pull out the name if given a path
-    // Default is `vulkaninfo`
-    std::string executable_name = "vulkaninfo";
-    if (argc >= 1) {
-        const auto argv_0 = std::string(argv[0]);
-        // don't include path separator
-        // Look for forward slash first, only look for backslash if that found nothing
-        auto last_occurrence = argv_0.rfind('/');
-        if (last_occurrence == std::string::npos) {
-            last_occurrence = argv_0.rfind('\\');
-        }
-        if (last_occurrence != std::string::npos && last_occurrence + 1 < argv_0.size()) {
-            executable_name = argv_0.substr(last_occurrence + 1);
-        }
-    }
-
     int return_code = 0;  // set in case of error
     std::unique_ptr<Printer> printer;
     std::ostream std_out(std::cout.rdbuf());
@@ -1121,27 +1116,17 @@ int main(int argc, char **argv) {
                     }
                     return 1;
                 }
-            } else if (parse_data.output_category == OutputCategory::devsim_json ||
-                       parse_data.output_category == OutputCategory::portability_json) {
+            } else if (parse_data.output_category == OutputCategory::profile_json) {
                 std::cout << "vulkaninfo could not find any GPU's.\n";
             }
         }
 
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-        if (parse_data.output_category == OutputCategory::portability_json &&
-            !gpus.at(parse_data.selected_gpu)->CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
-            std::cerr << "Cannot create a json because the current selected GPU (" << parse_data.selected_gpu
-                      << ") does not support the VK_KHR_portability_subset extension.\n";
-            return 1;
-        }
-#endif
-
         auto printer_data = get_printer_create_details(parse_data, instance, *gpus.at(parse_data.selected_gpu), executable_name);
         if (printer_data.print_to_file) {
             file_out = std::ofstream(printer_data.file_name);
             out = &file_out;
         }
-        printer = std::unique_ptr<Printer>(new Printer(printer_data, *out, parse_data.selected_gpu, instance.vk_version));
+        printer = std::unique_ptr<Printer>(new Printer(printer_data, *out, instance.vk_version));
 
         RunPrinter(*(printer.get()), parse_data, instance, gpus, surfaces);
 
index 789e7ad..ad1b998 100644 (file)
@@ -44,6 +44,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <cstring>
 
 #ifdef __GNUC__
index 0f7b929..4e093e5 100644 (file)
@@ -50,31 +50,37 @@ vulkaninfo --json
 ```
 vulkaninfo - Summarize Vulkan information in relation to the current environment.
 
-USAGE: ./vulkaninfo [options]
+USAGE:
+    vulkaninfo --summary
+    vulkaninfo -o <filename> | --output <filename>
+    vulkaninfo -j | -j=<gpu-number> | --json | --json=<gpu-number>
+    vulkaninfo --text
+    vulkaninfo --html
+    vulkaninfo --show-formats
+    vulkaninfo --show-tool-props
 
 OPTIONS:
--h, --help          Print this help.
---html              Produce an html version of vulkaninfo output, saved as
-                    "vulkaninfo.html" in the directory in which the command is
-                    run.
--j, --json          Produce a json version of vulkaninfo output to standard
-                    output.
---json=<gpu-number> For a multi-gpu system, a single gpu can be targetted by
+[-h, --help]        Print this help.
+[--summary]         Show a summary of the instance and GPU's on a system.
+[-o <filename>, --output <filename>]
+                    Print output to a new file whose name is specified by filename.
+                    File will be written to the current working directory.
+[--text]            Produce a text version of vulkaninfo output to stdout. This is
+                    the default output.
+[--html]            Produce an html version of vulkaninfo output, saved as
+                    \"vulkaninfo.html\" in the directory in which the command
+                    is run.
+[-j, --json]        Produce a json version of vulkaninfo output conforming to the Vulkan
+                    Profiles schema, saved as \"vulkaninfo.json\", of the first gpu in the
+                    system.
+[-j=<gpu-number>, --json=<gpu-number>]
+                    For a multi-gpu system, a single gpu can be targetted by
                     specifying the gpu-number associated with the gpu of
                     interest. This number can be determined by running
                     vulkaninfo without any options specified.
---portability       Produce a json version of vulkaninfo to standard output of the first
-                    gpu in the system conforming to the DevSim Portability Subset schema.
---portability=<N>   Produce the json output conforming to the DevSim Portability
-                    Subset Schema for the GPU specified to standard output
-                    where N is the GPU desired.
---show-formats      Display the format properties of each physical device.
-                    Note: This option does not affect html or json output;
-                    they will always print format properties.
--o <filename>, --output<filename>
-                    Print output to a new file whose name is specified by filename.
-                    File will be written to the current working directory.
---summary           Show a summary of the instance and GPU's on a system.
+[--show-tool-props] Show the active VkPhysicalDeviceToolPropertiesEXT that vulkaninfo finds.
+[--show-formats]    Display the format properties of each physical device.
+                    Note: This only affects text output.
 ```
 
 ### Windows