diff options
| -rw-r--r-- | scripts/kvt_genvk.py | 213 | ||||
| -rw-r--r-- | scripts/vulkaninfo_generator.py | 855 | ||||
| -rw-r--r-- | vulkaninfo/CMakeLists.txt | 32 | ||||
| -rw-r--r-- | vulkaninfo/generated/.clang-format | 5 | ||||
| -rw-r--r-- | vulkaninfo/generated/vulkaninfo.hpp | 2064 | ||||
| -rw-r--r-- | vulkaninfo/macOS/vulkaninfo.cmake | 11 | ||||
| -rw-r--r-- | vulkaninfo/macOS/vulkaninfo/metal_view.mm (renamed from vulkaninfo/macOS/vulkaninfo/metal_view.m) | 0 | ||||
| -rw-r--r-- | vulkaninfo/outputprinter.h | 564 | ||||
| -rw-r--r-- | vulkaninfo/vulkaninfo.c | 6514 | ||||
| -rw-r--r-- | vulkaninfo/vulkaninfo.cpp | 751 | ||||
| -rw-r--r-- | vulkaninfo/vulkaninfo.h | 1341 |
11 files changed, 5742 insertions, 6608 deletions
diff --git a/scripts/kvt_genvk.py b/scripts/kvt_genvk.py index 1d2f2550..ce021a7f 100644 --- a/scripts/kvt_genvk.py +++ b/scripts/kvt_genvk.py @@ -14,16 +14,24 @@ # See the License for the specific language governing permissions and # limitations under the License. -import argparse, cProfile, pdb, string, sys, time, os +import argparse +import cProfile +import pdb +import string +import sys +import time +import os # Simple timer functions startTime = None + def startTimer(timeit): global startTime if timeit: startTime = time.process_time() + def endTimer(timeit, msg): global startTime if timeit: @@ -32,7 +40,9 @@ def endTimer(timeit, msg): startTime = None # Turn a list of strings into a regexp string matching exactly those strings -def makeREstring(list, default = None): + + +def makeREstring(list, default=None): if len(list) > 0 or default is None: return '^(' + '|'.join(list) + ')$' else: @@ -43,6 +53,8 @@ def makeREstring(list, default = None): # parameters: # # args is an parsed argument object; see below for the fields that are used. + + def makeGenOpts(args): global genOpts genOpts = {} @@ -70,14 +82,14 @@ def makeGenOpts(args): # Descriptive names for various regexp patterns used to select # versions and extensions - allFeatures = allExtensions = '.*' - noFeatures = noExtensions = None + allFeatures = allExtensions = '.*' + noFeatures = noExtensions = None # Turn lists of names/patterns into matching regular expressions - addExtensionsPat = makeREstring(extensions, None) - removeExtensionsPat = makeREstring(removeExtensions, None) - emitExtensionsPat = makeREstring(emitExtensions, allExtensions) - featuresPat = makeREstring(features, allFeatures) + addExtensionsPat = makeREstring(extensions, None) + removeExtensionsPat = makeREstring(removeExtensions, None) + emitExtensionsPat = makeREstring(emitExtensions, allExtensions) + featuresPat = makeREstring(features, allFeatures) # Copyright text prefixing all headers (list of strings). prefixStrings = [ @@ -116,78 +128,103 @@ def makeGenOpts(args): # Helper file generator options for typemap_helper.h genOpts['vk_typemap_helper.h'] = [ - HelperFileOutputGenerator, - HelperFileOutputGeneratorOptions( - conventions = conventions, - filename = 'vk_typemap_helper.h', - directory = directory, - apiname = 'vulkan', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'vulkan', - addExtensions = addExtensionsPat, - removeExtensions = removeExtensionsPat, - emitExtensions = emitExtensionsPat, - prefixText = prefixStrings + vkPrefixStrings, - protectFeature = False, - apicall = 'VKAPI_ATTR ', - apientry = 'VKAPI_CALL ', - apientryp = 'VKAPI_PTR *', - alignFuncParam = 48, - expandEnumerants = False, - helper_file_type = 'typemap_helper_header') - ] + HelperFileOutputGenerator, + HelperFileOutputGeneratorOptions( + conventions=conventions, + filename='vk_typemap_helper.h', + directory=directory, + apiname='vulkan', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='vulkan', + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False, + helper_file_type='typemap_helper_header') + ] # Options for mock ICD header genOpts['mock_icd.h'] = [ - MockICDOutputGenerator, - MockICDGeneratorOptions( - conventions = conventions, - filename = 'mock_icd.h', - directory = directory, - apiname = 'vulkan', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'vulkan', - addExtensions = addExtensionsPat, - removeExtensions = removeExtensionsPat, - emitExtensions = emitExtensionsPat, - prefixText = prefixStrings + vkPrefixStrings, - protectFeature = False, - apicall = 'VKAPI_ATTR ', - apientry = 'VKAPI_CALL ', - apientryp = 'VKAPI_PTR *', - alignFuncParam = 48, - expandEnumerants = False, - helper_file_type = 'mock_icd_header') - ] + MockICDOutputGenerator, + MockICDGeneratorOptions( + conventions=conventions, + filename='mock_icd.h', + directory=directory, + apiname='vulkan', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='vulkan', + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False, + helper_file_type='mock_icd_header') + ] # Options for mock ICD cpp genOpts['mock_icd.cpp'] = [ - MockICDOutputGenerator, - MockICDGeneratorOptions( - conventions = conventions, - filename = 'mock_icd.cpp', - directory = directory, - apiname = 'vulkan', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'vulkan', - addExtensions = addExtensionsPat, - removeExtensions = removeExtensionsPat, - emitExtensions = emitExtensionsPat, - prefixText = prefixStrings + vkPrefixStrings, - protectFeature = False, - apicall = 'VKAPI_ATTR ', - apientry = 'VKAPI_CALL ', - apientryp = 'VKAPI_PTR *', - alignFuncParam = 48, - expandEnumerants = False, - helper_file_type = 'mock_icd_source') - ] + MockICDOutputGenerator, + MockICDGeneratorOptions( + conventions=conventions, + filename='mock_icd.cpp', + directory=directory, + apiname='vulkan', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='vulkan', + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False, + helper_file_type='mock_icd_source') + ] + + # Options for vulkaninfo.hpp + genOpts['vulkaninfo.hpp'] = [ + VulkanInfoGenerator, + VulkanInfoGeneratorOptions( + conventions=conventions, + filename='vulkaninfo.hpp', + directory=directory, + apiname='vulkan', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='vulkan', + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False) + ] + # Generate a target based on the options in the matching genOpts{} object. # This is encapsulated in a function so it can be profiled and/or timed. @@ -210,12 +247,18 @@ def genTarget(args): if not args.quiet: write('* Building', options.filename, file=sys.stderr) - write('* options.versions =', options.versions, file=sys.stderr) - write('* options.emitversions =', options.emitversions, file=sys.stderr) - write('* options.defaultExtensions =', options.defaultExtensions, file=sys.stderr) - write('* options.addExtensions =', options.addExtensions, file=sys.stderr) - write('* options.removeExtensions =', options.removeExtensions, file=sys.stderr) - write('* options.emitExtensions =', options.emitExtensions, file=sys.stderr) + write('* options.versions =', + options.versions, file=sys.stderr) + write('* options.emitversions =', + options.emitversions, file=sys.stderr) + write('* options.defaultExtensions =', + options.defaultExtensions, file=sys.stderr) + write('* options.addExtensions =', + options.addExtensions, file=sys.stderr) + write('* options.removeExtensions =', + options.removeExtensions, file=sys.stderr) + write('* options.emitExtensions =', + options.emitExtensions, file=sys.stderr) startTimer(args.time) gen = createGenerator(errFile=errWarn, @@ -231,6 +274,7 @@ def genTarget(args): write('No generator options for unknown target:', args.target, file=sys.stderr) + # -feature name # -extension name # For both, "name" may be a single name, or a space-separated list @@ -305,8 +349,10 @@ if __name__ == '__main__': # Generator Modifications from mock_icd_generator import MockICDGeneratorOptions, MockICDOutputGenerator from vulkan_tools_helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions + from vulkaninfo_generator import VulkanInfoGenerator, VulkanInfoGeneratorOptions # Temporary workaround for vkconventions python2 compatibility - import abc; abc.ABC = abc.ABCMeta('ABC', (object,), {}) + import abc + abc.ABC = abc.ABCMeta('ABC', (object,), {}) from vkconventions import VulkanConventions # This splits arguments which are space-separated lists @@ -332,7 +378,7 @@ if __name__ == '__main__': if (args.dump): write('* Dumping registry to regdump.txt', file=sys.stderr) - reg.dumpReg(filehandle = open('regdump.txt', 'w', encoding='utf-8')) + reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8')) # create error/warning & diagnostic files if (args.errfile): @@ -348,7 +394,8 @@ if __name__ == '__main__': if (args.debug): pdb.run('genTarget(args)') elif (args.profile): - import cProfile, pstats + import cProfile + import pstats cProfile.run('genTarget(args)', 'profile.txt') p = pstats.Stats('profile.txt') p.strip_dirs().sort_stats('time').print_stats(50) diff --git a/scripts/vulkaninfo_generator.py b/scripts/vulkaninfo_generator.py new file mode 100644 index 00000000..10d5cac2 --- /dev/null +++ b/scripts/vulkaninfo_generator.py @@ -0,0 +1,855 @@ +#!/usr/bin/python3 +# +# Copyright (c) 2019 Valve Corporation +# Copyright (c) 2019 LunarG, Inc. +# Copyright (c) 2019 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Author: Charles Giessen <charles@lunarg.com> + +import os +import re +import sys +import string +import xml.etree.ElementTree as etree +import generator as gen +import operator +from collections import namedtuple +from collections import OrderedDict +from generator import * +from common_codegen import * + +license_header = ''' +/* + * Copyright (c) 2019 The Khronos Group Inc. + * Copyright (c) 2019 Valve Corporation + * Copyright (c) 2019 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Charles Giessen <charles@lunarg.com> + * + */ + +/* + * This file is generated from the Khronos Vulkan XML API Registry. + */ +''' + +custom_formaters = ''' +std::ostream &operator<<(std::ostream &o, VkConformanceVersionKHR &c) { + return o << std::to_string(c.major) << "." << std::to_string(c.minor) << "." << std::to_string(c.subminor) << "." + << std::to_string(c.patch); +} + +std::string VkExtent3DString(VkExtent3D e) { + return std::string("(") + std::to_string(e.width) + ", " + std::to_string(e.height) + ", " + std::to_string(e.depth) + ")"; +} + +template <typename T> +std::string to_hex_str(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) { + if (p.Type() == OutputType::json) + return std::to_string(i); + else + return to_hex_str(i); +} +''' + +# used in the .cpp code +structures_to_gen = ['VkExtent3D', 'VkExtent2D', 'VkPhysicalDeviceLimits', 'VkPhysicalDeviceFeatures', + 'VkPhysicalDeviceSparseProperties', 'VkSurfaceCapabilitiesKHR', 'VkSurfaceFormatKHR', 'VkLayerProperties'] +enums_to_gen = ['VkResult', 'VkFormat', 'VkPresentModeKHR', + 'VkPhysicalDeviceType', 'VkImageTiling'] +flags_to_gen = ['VkSurfaceTransformFlagsKHR', 'VkCompositeAlphaFlagsKHR', + 'VkDeviceGroupPresentModeFlagsKHR', 'VkFormatFeatureFlags', 'VkMemoryPropertyFlags', 'VkMemoryHeapFlags'] +flags_strings_to_gen = ['VkQueueFlags'] + +# iostream or custom outputter handles these types +predefined_types = ['char', 'VkBool32', 'uint32_t', 'uint8_t', 'int32_t', + 'float', 'uint64_t', 'size_t', 'VkDeviceSize', 'VkConformanceVersionKHR'] +# need list of venders to blacklist vendor extensions +vendor_abbreviations = ['_IMG', '_AMD', '_AMDX', '_ARM', '_FSL', '_BRCM', '_NXP', '_NV', '_NVX', '_VIV', '_VSI', '_KDAB', + '_ANDROID', '_CHROMIUM', '_FUCHSIA', '_GGP', '_GOOGLE', '_QCOM', '_LUNARG', '_SAMSUNG', '_SEC', '_TIZEN', + '_RENDERDOC', '_NN', '_MVK', '_KHX', '_MESA', '_INTEL'] + +# Types that need pNext Chains built. 'extends' is the xml tag used in the structextends member. 'type' can be device, instance, or both +EXTENSION_CATEGORIES = {'phys_device_props2': {'extends': 'VkPhysicalDeviceProperties2', 'type': 'device'}, + 'phys_device_mem_props2': {'extends': 'VkPhysicalDeviceMemoryProperties2', 'type': 'device'}, + 'phys_device_features2': {'extends': 'VkPhysicalDeviceFeatures2,VkDeviceCreateInfo', 'type': 'device'}, + 'surface_capabilities2': {'extends': 'VkSurfaceCapabilities2KHR', 'type': 'both'}, + 'format_properties2': {'extends': 'VkFormatProperties2', 'type': 'device'} + } + + +class VulkanInfoGeneratorOptions(GeneratorOptions): + def __init__(self, + conventions=None, + input=None, + filename=None, + directory='.', + apiname=None, + profile=None, + versions='.*', + emitversions='.*', + defaultExtensions=None, + addExtensions=None, + removeExtensions=None, + emitExtensions=None, + sortProcedure=None, + prefixText="", + genFuncPointers=True, + protectFile=True, + protectFeature=True, + protectProto=None, + protectProtoStr=None, + apicall='', + apientry='', + apientryp='', + indentFuncProto=True, + indentFuncPointer=False, + alignFuncParam=0, + expandEnumerants=True, + ): + GeneratorOptions.__init__(self, conventions, filename, directory, apiname, profile, + versions, emitversions, defaultExtensions, + addExtensions, removeExtensions, emitExtensions, sortProcedure) + self.input = input + self.prefixText = prefixText + self.genFuncPointers = genFuncPointers + self.protectFile = protectFile + self.protectFeature = protectFeature + self.protectProto = protectProto + self.protectProtoStr = protectProtoStr + self.apicall = apicall + self.apientry = apientry + self.apientryp = apientryp + self.indentFuncProto = indentFuncProto + self.indentFuncPointer = indentFuncPointer + self.alignFuncParam = alignFuncParam + +# VulkanInfoGenerator - subclass of OutputGenerator. +# Generates a vulkan info output helper function + + +class VulkanInfoGenerator(OutputGenerator): + + def __init__(self, + errFile=sys.stderr, + warnFile=sys.stderr, + diagFile=sys.stdout): + OutputGenerator.__init__(self, errFile, warnFile, diagFile) + + self.constants = OrderedDict() + + self.extension_sets = OrderedDict() + for ext_cat in EXTENSION_CATEGORIES.keys(): + self.extension_sets[ext_cat] = set() + + self.enums = set() + self.flags = set() + self.bitmasks = set() + self.structures = set() + self.all_structures = set() + + self.types_to_gen = set() + + self.extFuncs = OrderedDict() + self.extTypes = OrderedDict() + self.extensions = set() + + def beginFile(self, genOpts): + gen.OutputGenerator.beginFile(self, genOpts) + + root = self.registry.reg + + for node in self.registry.reg.findall('enums'): + if node.get('name') == 'API Constants': + for item in node.findall('enum'): + self.constants[item.get('name')] = item.get('value') + + for node in root.find('extensions').findall('extension'): + ext = VulkanExtension(node) + self.extensions.add(ext) + for item in ext.vktypes: + self.extTypes[item] = ext + for item in ext.vkfuncs: + self.extFuncs[item] = ext + + def endFile(self): + types_to_gen = set() + for s in enums_to_gen: + types_to_gen.add(s) + + for f in flags_to_gen: + types_to_gen.add(f) + + types_to_gen = types_to_gen.union(GatherTypesToGen(self.structures)) + for key, value in EXTENSION_CATEGORIES.items(): + types_to_gen = types_to_gen.union( + GatherTypesToGen(self.extension_sets[key])) + + self.enums = sorted(self.enums, key=operator.attrgetter('name')) + self.flags = sorted(self.flags, key=operator.attrgetter('name')) + self.bitmasks = sorted(self.bitmasks, key=operator.attrgetter('name')) + self.structures = sorted( + self.structures, key=operator.attrgetter('name')) + self.all_structures = sorted( + self.all_structures, key=operator.attrgetter('name')) + + for key, value in self.extension_sets.items(): + self.extension_sets[key] = sorted( + value, key=operator.attrgetter('name')) + + out = '' + out += license_header + "\n" + out += "#include \"vulkaninfo.h\"\n" + out += "#include \"outputprinter.h\"\n" + out += custom_formaters + + for e in self.enums: + if e.name in types_to_gen: + out += PrintEnumToString(e, self) + out += PrintEnum(e, self) + + for f in self.flags: + if f.name in types_to_gen: + for b in self.bitmasks: + if b.name == f.enum: + out += PrintFlags(f, b, self) + out += PrintBitMask(b, f.name, self) + + if f.name in flags_strings_to_gen: + for b in self.bitmasks: + if b.name == f.enum: + out += PrintBitMaskToString(b, f.name, self) + + # find all structures needed to dump the requested structures + structure_names = set() + for s in self.all_structures: + if s.name in types_to_gen: + structure_names.add(s.name) + + for s in self.all_structures: + if s.name in types_to_gen: + out += PrintForwardDeclaration(s, self) + + for s in self.all_structures: + if s.name in types_to_gen: + out += PrintStructure(s, structure_names, self) + + out += "pNextChainInfos get_chain_infos() {\n" + out += " pNextChainInfos infos;\n" + for key, value in EXTENSION_CATEGORIES.items(): + out += PrintChainBuilders(key, self.extension_sets[key]) + out += " return infos;\n}\n" + + for key, value in EXTENSION_CATEGORIES.items(): + out += PrintChainIterator(key, + self.extension_sets[key], value.get('type')) + + gen.write(out, file=self.outFile) + + gen.OutputGenerator.endFile(self) + + def genCmd(self, cmd, name, alias): + gen.OutputGenerator.genCmd(self, cmd, name, alias) + + # These are actually constants + def genEnum(self, enuminfo, name, alias): + gen.OutputGenerator.genEnum(self, enuminfo, name, alias) + + # These are actually enums + def genGroup(self, groupinfo, groupName, alias): + gen.OutputGenerator.genGroup(self, groupinfo, groupName, alias) + + if alias is not None: + return + + if groupinfo.elem.get('type') == 'bitmask': + self.bitmasks.add(VulkanBitmask(groupinfo.elem, self.extensions)) + elif groupinfo.elem.get('type') == 'enum': + self.enums.add(VulkanEnum(groupinfo.elem, self.extensions)) + + def genType(self, typeinfo, name, alias): + gen.OutputGenerator.genType(self, typeinfo, name, alias) + + if alias is not None: + return + + if typeinfo.elem.get('category') == 'bitmask': + self.flags.add(VulkanFlags(typeinfo.elem)) + + if typeinfo.elem.get('category') == 'struct' and name in structures_to_gen: + self.structures.add(VulkanStructure( + name, typeinfo.elem, self.constants, self.extTypes)) + + if typeinfo.elem.get('category') == 'struct': + self.all_structures.add(VulkanStructure( + name, typeinfo.elem, self.constants, self.extTypes)) + + for vendor in vendor_abbreviations: + for node in typeinfo.elem.findall('member'): + if(node.get('values') is not None): + if(node.get('values').find(vendor)) != -1: + return + + for key, value in EXTENSION_CATEGORIES.items(): + if typeinfo.elem.get('structextends') == value.get('extends'): + self.extension_sets[key].add(VulkanStructure( + name, typeinfo.elem, self.constants, self.extTypes)) + + +def GatherTypesToGen(structures): + types_to_gen = set() + for s in structures: + types_to_gen.add(s.name) + for m in s.members: + if m.typeID not in predefined_types and m.name not in ['sType', 'pNext']: + types_to_gen.add(m.typeID) + return types_to_gen + + +def GetExtension(name, generator): + if name in generator.extFuncs: + return generator.extFuncs[name] + elif name in generator.extTypes: + return generator.extTypes[name] + else: + return None + + +def AddGuardHeader(obj): + if obj is not None and obj.guard is not None: + return "#ifdef {}\n".format(obj.guard) + else: + return "" + + +def AddGuardFooter(obj): + if obj is not None and obj.guard is not None: + return "#endif // {}\n".format(obj.guard) + else: + return "" + + +def PrintEnumToString(e, gen): + out = '' + out += AddGuardHeader(GetExtension(e.name, gen)) + + out += "static const char *" + e.name + "String(" + e.name + " value) {\n" + out += " switch (value) {\n" + for v in e.options: + out += " case (" + str(v.value) + \ + "): return \"" + v.name[3:] + "\";\n" + out += " default: return \"UNKNOWN_" + e.name + "\";\n" + out += " }\n}\n" + out += AddGuardFooter(GetExtension(e.name, gen)) + return out + + +def PrintEnum(e, gen): + out = '' + out += AddGuardHeader(GetExtension(e.name, gen)) + out += "void Dump" + e.name + \ + "(Printer &p, std::string name, " + \ + e.name + " value, int width = 0) {\n" + out += " if (p.Type() == OutputType::json) {\n" + out += " p.PrintKeyValue(name, value, width);\n" + out += " return;\n" + out += " } else {\n" + out += " p.PrintKeyValue(name, " + \ + e.name + "String(value), width);\n }\n" + out += "}\n" + out += AddGuardFooter(GetExtension(e.name, gen)) + return out + + +def PrintFlags(f, b, gen): + out = '' + out += AddGuardHeader(GetExtension(f.name, gen)) + + out += "void Dump" + f.name + \ + "(Printer &p, std::string name, " + \ + f.enum + " value, int width = 0) {\n" + out += " if (value == 0) p.PrintElement(\"None\");\n" + for v in b.options: + out += " if (" + str(v.value) + \ + " & value) p.SetAsType().PrintElement(\"" + \ + str(v.name[3:]) + "\");\n" + out += "}\n" + + out += AddGuardFooter(GetExtension(f.name, gen)) + return out + + +def PrintBitMask(b, name, gen): + out = '' + out += AddGuardHeader(GetExtension(b.name, gen)) + out += "void Dump" + name + \ + "(Printer &p, std::string name, " + name + " value, int width = 0) {\n" + out += " if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }\n" + out += " p.ObjectStart(name);\n" + out += " Dump" + name + \ + "(p, name, static_cast<" + b.name + ">(value), width);\n" + out += " p.ObjectEnd();\n" + out += "}\n" + out += "void Dump" + b.name + \ + "(Printer &p, std::string name, " + \ + b.name + " value, int width = 0) {\n" + out += " if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }\n" + out += " p.ObjectStart(name);\n" + out += " Dump" + name + "(p, name, value, width);\n" + out += " p.ObjectEnd();\n" + out += "}\n" + out += AddGuardFooter(GetExtension(b.name, gen)) + return out + + +def PrintBitMaskToString(b, name, gen): + out = '' + out += AddGuardHeader(GetExtension(b.name, gen)) + out += "std::string " + name + \ + "String(" + name + " value, int width = 0) {\n" + out += " std::string out;\n" + out += " bool is_first = true;\n" + for v in b.options: + out += " if (" + str(v.value) + " & value) {\n" + out += " if (is_first) { is_first = false; } else { out += \" | \"; }\n" + out += " out += \"" + \ + str(v.name).strip("VK_").strip("_BIT") + "\";\n" + out += " }\n" + out += " return out;\n" + out += "}\n" + out += AddGuardFooter(GetExtension(b.name, gen)) + return out + + +def PrintForwardDeclaration(struct, gen): + out = '' + out += AddGuardHeader(struct) + out += "void Dump" + struct.name + \ + "(Printer &p, std::string name, " + struct.name + " &obj);\n" + out += AddGuardFooter(struct) + + return out + + +def PrintStructure(struct, structure_names, gen): + out = '' + out += AddGuardHeader(struct) + max_key_len = len(struct.members[0].name) + for v in struct.members: + if v.arrayLength is not None: + if len(v.name) + len(v.arrayLength) + 2 > max_key_len: + max_key_len = len(v.name) + len(v.arrayLength) + 2 + elif v.typeID in predefined_types: + if len(v.name) > max_key_len: + max_key_len = len(v.name) + + out += "void Dump" + struct.name + \ + "(Printer &p, std::string name, " + struct.name + " &obj) {\n" + if struct.name == "VkPhysicalDeviceLimits": + out += " if (p.Type() == OutputType::json)\n" + out += " p.ObjectStart(\"limits\");\n" + out += " else\n" + out += " p.SetSubHeader().ObjectStart(name);\n" + elif struct.name == "VkPhysicalDeviceSparseProperties": + out += " if (p.Type() == OutputType::json)\n" + out += " p.ObjectStart(\"sparseProperties\");\n" + out += " else\n" + out += " p.SetSubHeader().ObjectStart(name);\n" + else: + out += " p.ObjectStart(name);\n" + + for v in struct.members: + # arrays + if v.arrayLength is not None: + # strings + if v.typeID == "char": + out += " p.PrintKeyString(\"" + v.name + "\", obj." + \ + v.name + ", " + str(max_key_len) + ");\n" + # uuid's + elif (v.arrayLength == str(16) and v.typeID == "uint8_t"): # VK_UUID_SIZE + out += " p.PrintKeyString(\"" + v.name + "\", to_string_16(obj." + \ + v.name + "), " + str(max_key_len) + ");\n" + elif (v.arrayLength == str(8) and v.typeID == "uint8_t"): # VK_LUID_SIZE + out += " if (obj.deviceLUIDValid)" # special case + out += " p.PrintKeyString(\"" + v.name + "\", to_string_8(obj." + \ + v.name + "), " + str(max_key_len) + ");\n" + elif v.arrayLength.isdigit(): + out += " p.ArrayStart(\"" + v.name + \ + "\", "+v.arrayLength+");\n" + for i in range(0, int(v.arrayLength)): + out += " p.PrintElement(obj." + \ + v.name + "[" + str(i) + "]);\n" + out += " p.ArrayEnd();\n" + else: # dynamic array length based on other member + out += " p.ArrayStart(\"" + v.name + \ + "\", obj."+v.arrayLength+");\n" + out += " for (uint32_t i = 0; i < obj." + \ + v.arrayLength+"; i++) {\n" + if v.typeID in structure_names: + out += " if (obj." + v.name + " != nullptr) {\n" + out += " p.SetElementIndex(i);\n" + out += " Dump" + v.typeID + \ + "(p, \"" + v.name + "\", obj." + v.name + "[i]);\n" + out += " }\n" + else: + out += " p.PrintElement(obj." + v.name + "[i]);\n" + out += " }\n p.ArrayEnd();\n" + elif v.typeID == "VkBool32": + out += " p.PrintKeyBool(\"" + v.name + "\", obj." + \ + v.name + ", " + str(max_key_len) + ");\n" + elif v.typeID == "VkDeviceSize": + out += " p.PrintKeyValue(\"" + v.name + "\", to_hex_str(p, obj." + \ + v.name + "), " + str(max_key_len) + ");\n" + elif v.typeID in predefined_types: + out += " p.PrintKeyValue(\"" + v.name + "\", obj." + \ + v.name + ", " + str(max_key_len) + ");\n" + elif v.name not in ['sType', 'pNext']: + if v.typeID in structure_names: + out += " Dump" + v.typeID + \ + "(p, \"" + v.name + "\", obj." + v.name + ");\n" + else: + out += " Dump" + v.typeID + \ + "(p, \"" + v.name + "\", obj." + \ + v.name + ", " + str(max_key_len) + ");\n" + + out += " p.ObjectEnd();\n" + out += "}\n" + + out += AddGuardFooter(struct) + return out + + +def PrintChainBuilders(listName, structures): + out = '' + out += " infos." + listName + " = {\n" + for s in structures: + out += AddGuardHeader(s) + if s.sTypeName is not None: + out += " {" + s.sTypeName + ", sizeof(" + s.name + ")},\n" + out += AddGuardFooter(s) + out += " };\n" + return out + + +def PrintChainIterator(listName, structures, checkExtLoc): + sorted_structures = sorted(structures, key=operator.attrgetter("name")) + + out = '' + out += "void chain_iterator_" + listName + "(Printer &p, " + if checkExtLoc == "device": + out += "AppGpu &gpu" + elif checkExtLoc == "instance": + out += "AppInstance &inst" + elif checkExtLoc == "both": + out += "AppInstance &inst, AppGpu &gpu" + out += ", void * place) {\n" + + out += " while (place) {\n" + out += " struct VkStructureHeader *structure = (struct VkStructureHeader *)place;\n" + out += " p.SetSubHeader();\n" + for s in sorted_structures: + out += AddGuardHeader(s) + if s.sTypeName is not None: + if s.extNameStr is not None: + out += " if (structure->sType == " + \ + s.sTypeName + " &&\n" + if s.extType == "device": + out += " gpu.CheckPhysicalDeviceExtensionIncluded(" + \ + s.extNameStr + ")) {\n" + elif s.extType == "instance": + out += " inst.CheckExtensionEnabled(" + \ + s.extNameStr + ")) {\n" + + else: + out += " if (structure->sType == " + \ + s.sTypeName + ") {\n" + + out += " " + s.name + "* props = " + \ + "("+s.name+"*)structure;\n" + out += " Dump" + s.name + \ + "(p, \"" + s.name + "\", *props);\n" + out += " }\n" + out += AddGuardFooter(s) + out += " p.AddNewline();\n" + out += " place = structure->pNext;\n" + out += " }\n" + out += "}\n" + return out + + +def isPow2(num): + return num != 0 and ((num & (num - 1)) == 0) + + +def StrToInt(s): + try: + return int(s) + except ValueError: + return int(s, 16) + + +class VulkanEnum: + class Option: + + def __init__(self, name, value, bitpos, comment): + self.name = name + self.comment = comment + self.multiValue = None + + if value is not None: + + self.multiValue = not isPow2(StrToInt(value)) + + if value == 0 or value is None: + value = 1 << int(bitpos) + + self.value = value + + def values(self): + return { + 'optName': self.name, + 'optValue': self.value, + 'optComment': self.comment, + 'optMultiValue': self.multiValue, + } + + def __init__(self, rootNode, extensions): + self.name = rootNode.get('name') + self.type = rootNode.get('type') + self.options = [] + self.ext = None + for child in rootNode: + childName = child.get('name') + childValue = child.get('value') + childBitpos = child.get('bitpos') + childComment = child.get('comment') + childExtends = child.get('extends') + childOffset = child.get('offset') + childExtNum = child.get('extnumber') + + if childName is None: + continue + if (childValue is None and childBitpos is None and childOffset is None): + continue + + if childExtends is not None and childExtNum is not None and childOffset is not None: + enumNegative = False + extNum = int(childExtNum) + extOffset = int(childOffset) + extBase = 1000000000 + extBlockSize = 1000 + childValue = extBase + (extNum - 1) * extBlockSize + extOffset + if ('dir' in child.keys()): + childValue = -childValue + duplicate = False + for o in self.options: + if o.values()['optName'] == childName: + duplicate = True + if duplicate: + continue + + self.options.append(VulkanEnum.Option( + childName, childValue, childBitpos, childComment)) + + for ext in extensions: + if self.name in ext.enumValues: + self.ext = ext + childName, childValue = ext.enumValues[self.name] + self.options.append(VulkanEnum.Option( + childName, childValue, None, None)) + + +class VulkanBitmask: + + def __init__(self, rootNode, extensions): + self.name = rootNode.get('name') + self.type = rootNode.get('type') + self.ext = None + + # Read each value that the enum contains + self.options = [] + for child in rootNode: + childName = child.get('name') + childValue = child.get('value') + childBitpos = child.get('bitpos') + childComment = child.get('comment') + if childName is None or (childValue is None and childBitpos is None): + continue + + self.options.append(VulkanEnum.Option( + childName, childValue, childBitpos, childComment)) + + for ext in extensions: + if self.name in ext.enumValues: + self.ext = ext + childName, childValue = ext.enumValues[self.name] + self.options.append(VulkanEnum.Option( + childName, childValue, None, None)) + + +class VulkanFlags: + + def __init__(self, rootNode): + self.name = rootNode.get('name') + self.type = rootNode.get('type') + self.enum = rootNode.get('requires') + + +class VulkanVariable: + def __init__(self, rootNode, constants, parentName): + 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') + if comment is not None and comment.text == node: + continue + self.text += node + + typeMatch = re.search('.+?(?=' + self.name + ')', self.text) + self.type = typeMatch.string[typeMatch.start():typeMatch.end()] + self.type = ' '.join(self.type.split()) + bracketMatch = re.search('(?<=\\[)[a-zA-Z0-9_]+(?=\\])', self.text) + if bracketMatch is not None: + matchText = bracketMatch.string[bracketMatch.start( + ):bracketMatch.end()] + self.childType = self.type + self.type += '[' + matchText + ']' + if matchText in constants: + self.arrayLength = constants[matchText] + else: + self.arrayLength = matchText + + self.lengthMember = False + lengthString = rootNode.get('len') + lengths = [] + if lengthString is not None: + lengths = re.split(',', lengthString) + lengths = list(filter(('null-terminated').__ne__, lengths)) + assert(len(lengths) <= 1) + if self.arrayLength is None and len(lengths) > 0: + self.childType = '*'.join(self.type.split('*')[0:-1]) + self.arrayLength = lengths[0] + self.lengthMember = True + if self.arrayLength is not None and self.arrayLength.startswith('latexmath'): + code = self.arrayLength[10:len(self.arrayLength)] + code = re.sub('\\[', '', code) + code = re.sub('\\]', '', code) + code = re.sub('\\\\(lceil|rceil)', '', code) + code = re.sub('{|}', '', code) + code = re.sub('\\\\mathit', '', code) + code = re.sub('\\\\over', '/', code) + code = re.sub('\\\\textrm', '', code) + self.arrayLength = code + + # Dereference if necessary and handle members of variables + if self.arrayLength is not None: + self.arrayLength = re.sub('::', '->', self.arrayLength) + sections = self.arrayLength.split('->') + if sections[-1][0] == 'p' and sections[0][1].isupper(): + self.arrayLength = '*' + self.arrayLength + + +class VulkanStructure: + def __init__(self, name, rootNode, constants, extTypes): + self.name = name + self.members = [] + self.guard = None + self.sTypeName = None + self.extNameStr = None + self.extType = None + 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)) + + for k, e in extTypes.items(): + if k == self.name: + if e.guard is not None: + self.guard = e.guard + if e.extNameStr is not None: + self.extNameStr = e.extNameStr + if e.type is not None: + self.extType = e.type + + +class VulkanExtension: + def __init__(self, rootNode): + self.name = rootNode.get('name') + self.number = int(rootNode.get('number')) + self.type = rootNode.get('type') + self.dependency = rootNode.get('requires') + self.guard = GetFeatureProtect(rootNode) + self.supported = rootNode.get('supported') + self.extNameStr = None + self.vktypes = [] + self.vkfuncs = [] + self.constants = {} + self.enumValues = {} + + for req in rootNode.findall('require'): + for ty in req.findall('type'): + self.vktypes.append(ty.get('name')) + + for func in req.findall('command'): + self.vkfuncs.append(func.get('name')) + + for enum in req.findall('enum'): + base = enum.get('extends') + name = enum.get('name') + value = enum.get('value') + bitpos = enum.get('bitpos') + offset = enum.get('offset') + # gets the VK_XXX_EXTENSION_NAME string + if value == "\"" + self.name + "\"": + self.extNameStr = name + + if value is None and bitpos is not None: + value = 1 << int(bitpos) + + if offset is not None: + offset = int(offset) + if base is not None and offset is not None: + enumValue = 1000000000 + 1000*(self.number - 1) + offset + if enum.get('dir') == '-': + enumValue = -enumValue + self.enumValues[base] = (name, enumValue) + else: + self.constants[name] = value diff --git a/vulkaninfo/CMakeLists.txt b/vulkaninfo/CMakeLists.txt index 5a822c4f..f17493b9 100644 --- a/vulkaninfo/CMakeLists.txt +++ b/vulkaninfo/CMakeLists.txt @@ -1,6 +1,6 @@ # ~~~ -# Copyright (c) 2018 Valve Corporation -# Copyright (c) 2018 LunarG, Inc. +# Copyright (c) 2018-2019 Valve Corporation +# Copyright (c) 2018-2019 LunarG, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,17 +17,36 @@ # CMakeLists.txt file for building Vulkaninfo +find_package(PythonInterp 3 QUIET) +set (PYTHON_CMD ${PYTHON_EXECUTABLE}) + +set(VKINFO_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(KVULKANTOOLS_SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/scripts) + +if(PYTHONINTERP_FOUND) + add_custom_target(generate_vulkaninfo_hpp + COMMAND ${PYTHON_CMD} ${KVULKANTOOLS_SCRIPTS_DIR}/kvt_genvk.py -registry ${VulkanRegistry_DIR}/vk.xml -scripts ${VulkanRegistry_DIR} vulkaninfo.hpp + DEPENDS ${VulkanRegistry_DIR}/vk.xml ${VulkanRegistry_DIR}/generator.py ${KVULKANTOOLS_SCRIPTS_DIR}/vulkaninfo_generator.py ${KVULKANTOOLS_SCRIPTS_DIR}/kvt_genvk.py ${VulkanRegistry_DIR}/reg.py + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vulkaninfo/generated + ) + else() + message("WARNING: generate_vulkaninfo_hpp target requires python 3") +endif() + if(WIN32) - add_executable(vulkaninfo vulkaninfo.c vulkaninfo.rc) + add_executable(vulkaninfo vulkaninfo.cpp vulkaninfo.rc) elseif(APPLE) add_executable(vulkaninfo - vulkaninfo.c - ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo/metal_view.m + vulkaninfo.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo/metal_view.mm ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo/metal_view.h) else() - add_executable(vulkaninfo vulkaninfo.c) + add_executable(vulkaninfo vulkaninfo.cpp) endif() +target_include_directories(vulkaninfo PRIVATE ${CMAKE_SOURCE_DIR}/vulkaninfo) +target_include_directories(vulkaninfo PRIVATE ${CMAKE_SOURCE_DIR}/vulkaninfo/generated) + if(UNIX AND NOT APPLE) # i.e. Linux include(FindPkgConfig) option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON) @@ -109,3 +128,4 @@ if(APPLE) else() install(TARGETS vulkaninfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() + diff --git a/vulkaninfo/generated/.clang-format b/vulkaninfo/generated/.clang-format new file mode 100644 index 00000000..3bb983a4 --- /dev/null +++ b/vulkaninfo/generated/.clang-format @@ -0,0 +1,5 @@ +--- +# Disable clang-format for generated code +DisableFormat: true +SortIncludes: false +... diff --git a/vulkaninfo/generated/vulkaninfo.hpp b/vulkaninfo/generated/vulkaninfo.hpp new file mode 100644 index 00000000..52f315d8 --- /dev/null +++ b/vulkaninfo/generated/vulkaninfo.hpp @@ -0,0 +1,2064 @@ + +/* + * Copyright (c) 2019 The Khronos Group Inc. + * Copyright (c) 2019 Valve Corporation + * Copyright (c) 2019 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Charles Giessen <charles@lunarg.com> + * + */ + +/* + * This file is generated from the Khronos Vulkan XML API Registry. + */ + +#include "vulkaninfo.h" +#include "outputprinter.h" + +std::ostream &operator<<(std::ostream &o, VkConformanceVersionKHR &c) { + return o << std::to_string(c.major) << "." << std::to_string(c.minor) << "." << std::to_string(c.subminor) << "." + << std::to_string(c.patch); +} + +std::string VkExtent3DString(VkExtent3D e) { + return std::string("(") + std::to_string(e.width) + ", " + std::to_string(e.height) + ", " + std::to_string(e.depth) + ")"; +} + +template <typename T> +std::string to_hex_str(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) { + if (p.Type() == OutputType::json) + return std::to_string(i); + else + return to_hex_str(i); +} +static const char *VkColorSpaceKHRString(VkColorSpaceKHR value) { + switch (value) { + case (0): return "COLOR_SPACE_SRGB_NONLINEAR_KHR"; + case (1000104001): return "COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT"; + case (1000104002): return "COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT"; + case (1000104003): return "COLOR_SPACE_DISPLAY_P3_LINEAR_EXT"; + case (1000104004): return "COLOR_SPACE_DCI_P3_NONLINEAR_EXT"; + case (1000104005): return "COLOR_SPACE_BT709_LINEAR_EXT"; + case (1000104006): return "COLOR_SPACE_BT709_NONLINEAR_EXT"; + case (1000104007): return "COLOR_SPACE_BT2020_LINEAR_EXT"; + case (1000104008): return "COLOR_SPACE_HDR10_ST2084_EXT"; + case (1000104009): return "COLOR_SPACE_DOLBYVISION_EXT"; + case (1000104010): return "COLOR_SPACE_HDR10_HLG_EXT"; + case (1000104011): return "COLOR_SPACE_ADOBERGB_LINEAR_EXT"; + case (1000104012): return "COLOR_SPACE_ADOBERGB_NONLINEAR_EXT"; + case (1000104013): return "COLOR_SPACE_PASS_THROUGH_EXT"; + case (1000104014): return "COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT"; + case (1000213000): return "COLOR_SPACE_DISPLAY_NATIVE_AMD"; + default: return "UNKNOWN_VkColorSpaceKHR"; + } +} +void DumpVkColorSpaceKHR(Printer &p, std::string name, VkColorSpaceKHR value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkColorSpaceKHRString(value), width); + } +} +static const char *VkDriverIdKHRString(VkDriverIdKHR value) { + switch (value) { + case (1): return "DRIVER_ID_AMD_PROPRIETARY_KHR"; + case (2): return "DRIVER_ID_AMD_OPEN_SOURCE_KHR"; + case (3): return "DRIVER_ID_MESA_RADV_KHR"; + case (4): return "DRIVER_ID_NVIDIA_PROPRIETARY_KHR"; + case (5): return "DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR"; + case (6): return "DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR"; + case (7): return "DRIVER_ID_IMAGINATION_PROPRIETARY_KHR"; + case (8): return "DRIVER_ID_QUALCOMM_PROPRIETARY_KHR"; + case (9): return "DRIVER_ID_ARM_PROPRIETARY_KHR"; + case (10): return "DRIVER_ID_GOOGLE_SWIFTSHADER_KHR"; + case (11): return "DRIVER_ID_GGP_PROPRIETARY_KHR"; + case (12): return "DRIVER_ID_BROADCOM_PROPRIETARY_KHR"; + default: return "UNKNOWN_VkDriverIdKHR"; + } +} +void DumpVkDriverIdKHR(Printer &p, std::string name, VkDriverIdKHR value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkDriverIdKHRString(value), width); + } +} +static const char *VkFormatString(VkFormat value) { + switch (value) { + case (0): return "FORMAT_UNDEFINED"; + case (1): return "FORMAT_R4G4_UNORM_PACK8"; + case (2): return "FORMAT_R4G4B4A4_UNORM_PACK16"; + case (3): return "FORMAT_B4G4R4A4_UNORM_PACK16"; + case (4): return "FORMAT_R5G6B5_UNORM_PACK16"; + case (5): return "FORMAT_B5G6R5_UNORM_PACK16"; + case (6): return "FORMAT_R5G5B5A1_UNORM_PACK16"; + case (7): return "FORMAT_B5G5R5A1_UNORM_PACK16"; + case (8): return "FORMAT_A1R5G5B5_UNORM_PACK16"; + case (9): return "FORMAT_R8_UNORM"; + case (10): return "FORMAT_R8_SNORM"; + case (11): return "FORMAT_R8_USCALED"; + case (12): return "FORMAT_R8_SSCALED"; + case (13): return "FORMAT_R8_UINT"; + case (14): return "FORMAT_R8_SINT"; + case (15): return "FORMAT_R8_SRGB"; + case (16): return "FORMAT_R8G8_UNORM"; + case (17): return "FORMAT_R8G8_SNORM"; + case (18): return "FORMAT_R8G8_USCALED"; + case (19): return "FORMAT_R8G8_SSCALED"; + case (20): return "FORMAT_R8G8_UINT"; + case (21): return "FORMAT_R8G8_SINT"; + case (22): return "FORMAT_R8G8_SRGB"; + case (23): return "FORMAT_R8G8B8_UNORM"; + case (24): return "FORMAT_R8G8B8_SNORM"; + case (25): return "FORMAT_R8G8B8_USCALED"; + case (26): return "FORMAT_R8G8B8_SSCALED"; + case (27): return "FORMAT_R8G8B8_UINT"; + case (28): return "FORMAT_R8G8B8_SINT"; + case (29): return "FORMAT_R8G8B8_SRGB"; + case (30): return "FORMAT_B8G8R8_UNORM"; + case (31): return "FORMAT_B8G8R8_SNORM"; + case (32): return "FORMAT_B8G8R8_USCALED"; + case (33): return "FORMAT_B8G8R8_SSCALED"; + case (34): return "FORMAT_B8G8R8_UINT"; + case (35): return "FORMAT_B8G8R8_SINT"; + case (36): return "FORMAT_B8G8R8_SRGB"; + case (37): return "FORMAT_R8G8B8A8_UNORM"; + case (38): return "FORMAT_R8G8B8A8_SNORM"; + case (39): return "FORMAT_R8G8B8A8_USCALED"; + case (40): return "FORMAT_R8G8B8A8_SSCALED"; + case (41): return "FORMAT_R8G8B8A8_UINT"; + case (42): return "FORMAT_R8G8B8A8_SINT"; + case (43): return "FORMAT_R8G8B8A8_SRGB"; + case (44): return "FORMAT_B8G8R8A8_UNORM"; + case (45): return "FORMAT_B8G8R8A8_SNORM"; + case (46): return "FORMAT_B8G8R8A8_USCALED"; + case (47): return "FORMAT_B8G8R8A8_SSCALED"; + case (48): return "FORMAT_B8G8R8A8_UINT"; + case (49): return "FORMAT_B8G8R8A8_SINT"; + case (50): return "FORMAT_B8G8R8A8_SRGB"; + case (51): return "FORMAT_A8B8G8R8_UNORM_PACK32"; + case (52): return "FORMAT_A8B8G8R8_SNORM_PACK32"; + case (53): return "FORMAT_A8B8G8R8_USCALED_PACK32"; + case (54): return "FORMAT_A8B8G8R8_SSCALED_PACK32"; + case (55): return "FORMAT_A8B8G8R8_UINT_PACK32"; + case (56): return "FORMAT_A8B8G8R8_SINT_PACK32"; + case (57): return "FORMAT_A8B8G8R8_SRGB_PACK32"; + case (58): return "FORMAT_A2R10G10B10_UNORM_PACK32"; + case (59): return "FORMAT_A2R10G10B10_SNORM_PACK32"; + case (60): return "FORMAT_A2R10G10B10_USCALED_PACK32"; + case (61): return "FORMAT_A2R10G10B10_SSCALED_PACK32"; + case (62): return "FORMAT_A2R10G10B10_UINT_PACK32"; + case (63): return "FORMAT_A2R10G10B10_SINT_PACK32"; + case (64): return "FORMAT_A2B10G10R10_UNORM_PACK32"; + case (65): return "FORMAT_A2B10G10R10_SNORM_PACK32"; + case (66): return "FORMAT_A2B10G10R10_USCALED_PACK32"; + case (67): return "FORMAT_A2B10G10R10_SSCALED_PACK32"; + case (68): return "FORMAT_A2B10G10R10_UINT_PACK32"; + case (69): return "FORMAT_A2B10G10R10_SINT_PACK32"; + case (70): return "FORMAT_R16_UNORM"; + case (71): return "FORMAT_R16_SNORM"; + case (72): return "FORMAT_R16_USCALED"; + case (73): return "FORMAT_R16_SSCALED"; + case (74): return "FORMAT_R16_UINT"; + case (75): return "FORMAT_R16_SINT"; + case (76): return "FORMAT_R16_SFLOAT"; + case (77): return "FORMAT_R16G16_UNORM"; + case (78): return "FORMAT_R16G16_SNORM"; + case (79): return "FORMAT_R16G16_USCALED"; + case (80): return "FORMAT_R16G16_SSCALED"; + case (81): return "FORMAT_R16G16_UINT"; + case (82): return "FORMAT_R16G16_SINT"; + case (83): return "FORMAT_R16G16_SFLOAT"; + case (84): return "FORMAT_R16G16B16_UNORM"; + case (85): return "FORMAT_R16G16B16_SNORM"; + case (86): return "FORMAT_R16G16B16_USCALED"; + case (87): return "FORMAT_R16G16B16_SSCALED"; + case (88): return "FORMAT_R16G16B16_UINT"; + case (89): return "FORMAT_R16G16B16_SINT"; + case (90): return "FORMAT_R16G16B16_SFLOAT"; + case (91): return "FORMAT_R16G16B16A16_UNORM"; + case (92): return "FORMAT_R16G16B16A16_SNORM"; + case (93): return "FORMAT_R16G16B16A16_USCALED"; + case (94): return "FORMAT_R16G16B16A16_SSCALED"; + case (95): return "FORMAT_R16G16B16A16_UINT"; + case (96): return "FORMAT_R16G16B16A16_SINT"; + case (97): return "FORMAT_R16G16B16A16_SFLOAT"; + case (98): return "FORMAT_R32_UINT"; + case (99): return "FORMAT_R32_SINT"; + case (100): return "FORMAT_R32_SFLOAT"; + case (101): return "FORMAT_R32G32_UINT"; + case (102): return "FORMAT_R32G32_SINT"; + case (103): return "FORMAT_R32G32_SFLOAT"; + case (104): return "FORMAT_R32G32B32_UINT"; + case (105): return "FORMAT_R32G32B32_SINT"; + case (106): return "FORMAT_R32G32B32_SFLOAT"; + case (107): return "FORMAT_R32G32B32A32_UINT"; + case (108): return "FORMAT_R32G32B32A32_SINT"; + case (109): return "FORMAT_R32G32B32A32_SFLOAT"; + case (110): return "FORMAT_R64_UINT"; + case (111): return "FORMAT_R64_SINT"; + case (112): return "FORMAT_R64_SFLOAT"; + case (113): return "FORMAT_R64G64_UINT"; + case (114): return "FORMAT_R64G64_SINT"; + case (115): return "FORMAT_R64G64_SFLOAT"; + case (116): return "FORMAT_R64G64B64_UINT"; + case (117): return "FORMAT_R64G64B64_SINT"; + case (118): return "FORMAT_R64G64B64_SFLOAT"; + case (119): return "FORMAT_R64G64B64A64_UINT"; + case (120): return "FORMAT_R64G64B64A64_SINT"; + case (121): return "FORMAT_R64G64B64A64_SFLOAT"; + case (122): return "FORMAT_B10G11R11_UFLOAT_PACK32"; + case (123): return "FORMAT_E5B9G9R9_UFLOAT_PACK32"; + case (124): return "FORMAT_D16_UNORM"; + case (125): return "FORMAT_X8_D24_UNORM_PACK32"; + case (126): return "FORMAT_D32_SFLOAT"; + case (127): return "FORMAT_S8_UINT"; + case (128): return "FORMAT_D16_UNORM_S8_UINT"; + case (129): return "FORMAT_D24_UNORM_S8_UINT"; + case (130): return "FORMAT_D32_SFLOAT_S8_UINT"; + case (131): return "FORMAT_BC1_RGB_UNORM_BLOCK"; + case (132): return "FORMAT_BC1_RGB_SRGB_BLOCK"; + case (133): return "FORMAT_BC1_RGBA_UNORM_BLOCK"; + case (134): return "FORMAT_BC1_RGBA_SRGB_BLOCK"; + case (135): return "FORMAT_BC2_UNORM_BLOCK"; + case (136): return "FORMAT_BC2_SRGB_BLOCK"; + case (137): return "FORMAT_BC3_UNORM_BLOCK"; + case (138): return "FORMAT_BC3_SRGB_BLOCK"; + case (139): return "FORMAT_BC4_UNORM_BLOCK"; + case (140): return "FORMAT_BC4_SNORM_BLOCK"; + case (141): return "FORMAT_BC5_UNORM_BLOCK"; + case (142): return "FORMAT_BC5_SNORM_BLOCK"; + case (143): return "FORMAT_BC6H_UFLOAT_BLOCK"; + case (144): return "FORMAT_BC6H_SFLOAT_BLOCK"; + case (145): return "FORMAT_BC7_UNORM_BLOCK"; + case (146): return "FORMAT_BC7_SRGB_BLOCK"; + case (147): return "FORMAT_ETC2_R8G8B8_UNORM_BLOCK"; + case (148): return "FORMAT_ETC2_R8G8B8_SRGB_BLOCK"; + case (149): return "FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK"; + case (150): return "FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK"; + case (151): return "FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK"; + case (152): return "FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK"; + case (153): return "FORMAT_EAC_R11_UNORM_BLOCK"; + case (154): return "FORMAT_EAC_R11_SNORM_BLOCK"; + case (155): return "FORMAT_EAC_R11G11_UNORM_BLOCK"; + case (156): return "FORMAT_EAC_R11G11_SNORM_BLOCK"; + case (157): return "FORMAT_ASTC_4x4_UNORM_BLOCK"; + case (158): return "FORMAT_ASTC_4x4_SRGB_BLOCK"; + case (159): return "FORMAT_ASTC_5x4_UNORM_BLOCK"; + case (160): return "FORMAT_ASTC_5x4_SRGB_BLOCK"; + case (161): return "FORMAT_ASTC_5x5_UNORM_BLOCK"; + case (162): return "FORMAT_ASTC_5x5_SRGB_BLOCK"; + case (163): return "FORMAT_ASTC_6x5_UNORM_BLOCK"; + case (164): return "FORMAT_ASTC_6x5_SRGB_BLOCK"; + case (165): return "FORMAT_ASTC_6x6_UNORM_BLOCK"; + case (166): return "FORMAT_ASTC_6x6_SRGB_BLOCK"; + case (167): return "FORMAT_ASTC_8x5_UNORM_BLOCK"; + case (168): return "FORMAT_ASTC_8x5_SRGB_BLOCK"; + case (169): return "FORMAT_ASTC_8x6_UNORM_BLOCK"; + case (170): return "FORMAT_ASTC_8x6_SRGB_BLOCK"; + case (171): return "FORMAT_ASTC_8x8_UNORM_BLOCK"; + case (172): return "FORMAT_ASTC_8x8_SRGB_BLOCK"; + case (173): return "FORMAT_ASTC_10x5_UNORM_BLOCK"; + case (174): return "FORMAT_ASTC_10x5_SRGB_BLOCK"; + case (175): return "FORMAT_ASTC_10x6_UNORM_BLOCK"; + case (176): return "FORMAT_ASTC_10x6_SRGB_BLOCK"; + case (177): return "FORMAT_ASTC_10x8_UNORM_BLOCK"; + case (178): return "FORMAT_ASTC_10x8_SRGB_BLOCK"; + case (179): return "FORMAT_ASTC_10x10_UNORM_BLOCK"; + case (180): return "FORMAT_ASTC_10x10_SRGB_BLOCK"; + case (181): return "FORMAT_ASTC_12x10_UNORM_BLOCK"; + case (182): return "FORMAT_ASTC_12x10_SRGB_BLOCK"; + case (183): return "FORMAT_ASTC_12x12_UNORM_BLOCK"; + case (184): return "FORMAT_ASTC_12x12_SRGB_BLOCK"; + case (1000156000): return "FORMAT_G8B8G8R8_422_UNORM"; + case (1000156001): return "FORMAT_B8G8R8G8_422_UNORM"; + case (1000156002): return "FORMAT_G8_B8_R8_3PLANE_420_UNORM"; + case (1000156003): return "FORMAT_G8_B8R8_2PLANE_420_UNORM"; + case (1000156004): return "FORMAT_G8_B8_R8_3PLANE_422_UNORM"; + case (1000156005): return "FORMAT_G8_B8R8_2PLANE_422_UNORM"; + case (1000156006): return "FORMAT_G8_B8_R8_3PLANE_444_UNORM"; + case (1000156007): return "FORMAT_R10X6_UNORM_PACK16"; + case (1000156008): return "FORMAT_R10X6G10X6_UNORM_2PACK16"; + case (1000156009): return "FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16"; + case (1000156010): return "FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16"; + case (1000156011): return "FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16"; + case (1000156012): return "FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16"; + case (1000156013): return "FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16"; + case (1000156014): return "FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16"; + case (1000156015): return "FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16"; + case (1000156016): return "FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16"; + case (1000156017): return "FORMAT_R12X4_UNORM_PACK16"; + case (1000156018): return "FORMAT_R12X4G12X4_UNORM_2PACK16"; + case (1000156019): return "FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16"; + case (1000156020): return "FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16"; + case (1000156021): return "FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16"; + case (1000156022): return "FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16"; + case (1000156023): return "FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16"; + case (1000156024): return "FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16"; + case (1000156025): return "FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16"; + case (1000156026): return "FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16"; + case (1000156027): return "FORMAT_G16B16G16R16_422_UNORM"; + case (1000156028): return "FORMAT_B16G16R16G16_422_UNORM"; + case (1000156029): return "FORMAT_G16_B16_R16_3PLANE_420_UNORM"; + case (1000156030): return "FORMAT_G16_B16R16_2PLANE_420_UNORM"; + case (1000156031): return "FORMAT_G16_B16_R16_3PLANE_422_UNORM"; + case (1000156032): return "FORMAT_G16_B16R16_2PLANE_422_UNORM"; + case (1000156033): return "FORMAT_G16_B16_R16_3PLANE_444_UNORM"; + case (1000054000): return "FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG"; + case (1000054001): return "FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG"; + case (1000054002): return "FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG"; + case (1000054003): return "FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG"; + case (1000054004): return "FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG"; + case (1000054005): return "FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG"; + case (1000054006): return "FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG"; + case (1000054007): return "FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG"; + case (1000066000): return "FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT"; + case (1000066001): return "FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT"; + case (1000066002): return "FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT"; + case (1000066003): return "FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT"; + case (1000066004): return "FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT"; + case (1000066005): return "FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT"; + case (1000066006): return "FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT"; + case (1000066007): return "FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT"; + case (1000066008): return "FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT"; + case (1000066009): return "FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT"; + case (1000066010): return "FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT"; + case (1000066011): return "FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT"; + case (1000066012): return "FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT"; + case (1000066013): return "FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT"; + default: return "UNKNOWN_VkFormat"; + } +} +void DumpVkFormat(Printer &p, std::string name, VkFormat value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkFormatString(value), width); + } +} +static const char *VkImageTilingString(VkImageTiling value) { + switch (value) { + case (0): return "IMAGE_TILING_OPTIMAL"; + case (1): return "IMAGE_TILING_LINEAR"; + case (1000158000): return "IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT"; + default: return "UNKNOWN_VkImageTiling"; + } +} +void DumpVkImageTiling(Printer &p, std::string name, VkImageTiling value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkImageTilingString(value), width); + } +} +static const char *VkPhysicalDeviceTypeString(VkPhysicalDeviceType value) { + switch (value) { + case (0): return "PHYSICAL_DEVICE_TYPE_OTHER"; + case (1): return "PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU"; + case (2): return "PHYSICAL_DEVICE_TYPE_DISCRETE_GPU"; + case (3): return "PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU"; + case (4): return "PHYSICAL_DEVICE_TYPE_CPU"; + default: return "UNKNOWN_VkPhysicalDeviceType"; + } +} +void DumpVkPhysicalDeviceType(Printer &p, std::string name, VkPhysicalDeviceType value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkPhysicalDeviceTypeString(value), width); + } +} +static const char *VkPointClippingBehaviorString(VkPointClippingBehavior value) { + switch (value) { + case (0): return "POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES"; + case (1): return "POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY"; + default: return "UNKNOWN_VkPointClippingBehavior"; + } +} +void DumpVkPointClippingBehavior(Printer &p, std::string name, VkPointClippingBehavior value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkPointClippingBehaviorString(value), width); + } +} +static const char *VkPresentModeKHRString(VkPresentModeKHR value) { + switch (value) { + case (0): return "PRESENT_MODE_IMMEDIATE_KHR"; + case (1): return "PRESENT_MODE_MAILBOX_KHR"; + case (2): return "PRESENT_MODE_FIFO_KHR"; + case (3): return "PRESENT_MODE_FIFO_RELAXED_KHR"; + case (1000111000): return "PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR"; + case (1000111001): return "PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR"; + default: return "UNKNOWN_VkPresentModeKHR"; + } +} +void DumpVkPresentModeKHR(Printer &p, std::string name, VkPresentModeKHR value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkPresentModeKHRString(value), width); + } +} +static const char *VkResultString(VkResult value) { + switch (value) { + case (0): return "SUCCESS"; + case (1): return "NOT_READY"; + case (2): return "TIMEOUT"; + case (3): return "EVENT_SET"; + case (4): return "EVENT_RESET"; + case (5): return "INCOMPLETE"; + case (-1): return "ERROR_OUT_OF_HOST_MEMORY"; + case (-2): return "ERROR_OUT_OF_DEVICE_MEMORY"; + case (-3): return "ERROR_INITIALIZATION_FAILED"; + case (-4): return "ERROR_DEVICE_LOST"; + case (-5): return "ERROR_MEMORY_MAP_FAILED"; + case (-6): return "ERROR_LAYER_NOT_PRESENT"; + case (-7): return "ERROR_EXTENSION_NOT_PRESENT"; + case (-8): return "ERROR_FEATURE_NOT_PRESENT"; + case (-9): return "ERROR_INCOMPATIBLE_DRIVER"; + case (-10): return "ERROR_TOO_MANY_OBJECTS"; + case (-11): return "ERROR_FORMAT_NOT_SUPPORTED"; + case (-12): return "ERROR_FRAGMENTED_POOL"; + case (-1000069000): return "ERROR_OUT_OF_POOL_MEMORY"; + case (-1000072003): return "ERROR_INVALID_EXTERNAL_HANDLE"; + case (-1000000000): return "ERROR_SURFACE_LOST_KHR"; + case (-1000000001): return "ERROR_NATIVE_WINDOW_IN_USE_KHR"; + case (1000001003): return "SUBOPTIMAL_KHR"; + case (-1000001004): return "ERROR_OUT_OF_DATE_KHR"; + case (-1000003001): return "ERROR_INCOMPATIBLE_DISPLAY_KHR"; + case (-1000011001): return "ERROR_VALIDATION_FAILED_EXT"; + case (-1000012000): return "ERROR_INVALID_SHADER_NV"; + case (-1000158000): return "ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; + case (-1000161000): return "ERROR_FRAGMENTATION_EXT"; + case (-1000174001): return "ERROR_NOT_PERMITTED_EXT"; + case (-1000244000): return "ERROR_INVALID_DEVICE_ADDRESS_EXT"; + case (-1000255000): return "ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; + default: return "UNKNOWN_VkResult"; + } +} +void DumpVkResult(Printer &p, std::string name, VkResult value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkResultString(value), width); + } +} +static const char *VkShaderFloatControlsIndependenceKHRString(VkShaderFloatControlsIndependenceKHR value) { + switch (value) { + case (0): return "SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR"; + case (1): return "SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR"; + case (2): return "SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR"; + default: return "UNKNOWN_VkShaderFloatControlsIndependenceKHR"; + } +} +void DumpVkShaderFloatControlsIndependenceKHR(Printer &p, std::string name, VkShaderFloatControlsIndependenceKHR value, int width = 0) { + if (p.Type() == OutputType::json) { + p.PrintKeyValue(name, value, width); + return; + } else { + p.PrintKeyValue(name, VkShaderFloatControlsIndependenceKHRString(value), width); + } +} +void DumpVkCompositeAlphaFlagsKHR(Printer &p, std::string name, VkCompositeAlphaFlagBitsKHR value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("COMPOSITE_ALPHA_OPAQUE_BIT_KHR"); + if (2 & value) p.SetAsType().PrintElement("COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR"); + if (4 & value) p.SetAsType().PrintElement("COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR"); + if (8 & value) p.SetAsType().PrintElement("COMPOSITE_ALPHA_INHERIT_BIT_KHR"); +} +void DumpVkCompositeAlphaFlagsKHR(Printer &p, std::string name, VkCompositeAlphaFlagsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkCompositeAlphaFlagsKHR(p, name, static_cast<VkCompositeAlphaFlagBitsKHR>(value), width); + p.ObjectEnd(); +} +void DumpVkCompositeAlphaFlagBitsKHR(Printer &p, std::string name, VkCompositeAlphaFlagBitsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkCompositeAlphaFlagsKHR(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkDeviceGroupPresentModeFlagsKHR(Printer &p, std::string name, VkDeviceGroupPresentModeFlagBitsKHR value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR"); + if (2 & value) p.SetAsType().PrintElement("DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR"); + if (4 & value) p.SetAsType().PrintElement("DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR"); + if (8 & value) p.SetAsType().PrintElement("DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR"); +} +void DumpVkDeviceGroupPresentModeFlagsKHR(Printer &p, std::string name, VkDeviceGroupPresentModeFlagsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkDeviceGroupPresentModeFlagsKHR(p, name, static_cast<VkDeviceGroupPresentModeFlagBitsKHR>(value), width); + p.ObjectEnd(); +} +void DumpVkDeviceGroupPresentModeFlagBitsKHR(Printer &p, std::string name, VkDeviceGroupPresentModeFlagBitsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkDeviceGroupPresentModeFlagsKHR(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkFormatFeatureFlags(Printer &p, std::string name, VkFormatFeatureFlagBits value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_BIT"); + if (2 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_STORAGE_IMAGE_BIT"); + if (4 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT"); + if (8 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT"); + if (16 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT"); + if (32 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT"); + if (64 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_VERTEX_BUFFER_BIT"); + if (128 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_COLOR_ATTACHMENT_BIT"); + if (256 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT"); + if (512 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT"); + if (1024 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_BLIT_SRC_BIT"); + if (2048 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_BLIT_DST_BIT"); + if (4096 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT"); + if (16384 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_TRANSFER_SRC_BIT"); + if (32768 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_TRANSFER_DST_BIT"); + if (131072 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT"); + if (262144 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT"); + if (524288 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT"); + if (1048576 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT"); + if (2097152 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT"); + if (4194304 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_DISJOINT_BIT"); + if (8388608 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"); + if (8192 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG"); + if (134217728 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_RESERVED_27_BIT_KHR"); + if (268435456 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_RESERVED_28_BIT_KHR"); + if (33554432 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_RESERVED_25_BIT_KHR"); + if (67108864 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_RESERVED_26_BIT_KHR"); + if (65536 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT"); + if (16777216 & value) p.SetAsType().PrintElement("FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT"); +} +void DumpVkFormatFeatureFlags(Printer &p, std::string name, VkFormatFeatureFlags value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkFormatFeatureFlags(p, name, static_cast<VkFormatFeatureFlagBits>(value), width); + p.ObjectEnd(); +} +void DumpVkFormatFeatureFlagBits(Printer &p, std::string name, VkFormatFeatureFlagBits value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkFormatFeatureFlags(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkImageUsageFlags(Printer &p, std::string name, VkImageUsageFlagBits value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("IMAGE_USAGE_TRANSFER_SRC_BIT"); + if (2 & value) p.SetAsType().PrintElement("IMAGE_USAGE_TRANSFER_DST_BIT"); + if (4 & value) p.SetAsType().PrintElement("IMAGE_USAGE_SAMPLED_BIT"); + if (8 & value) p.SetAsType().PrintElement("IMAGE_USAGE_STORAGE_BIT"); + if (16 & value) p.SetAsType().PrintElement("IMAGE_USAGE_COLOR_ATTACHMENT_BIT"); + if (32 & value) p.SetAsType().PrintElement("IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT"); + if (64 & value) p.SetAsType().PrintElement("IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT"); + if (128 & value) p.SetAsType().PrintElement("IMAGE_USAGE_INPUT_ATTACHMENT_BIT"); + if (8192 & value) p.SetAsType().PrintElement("IMAGE_USAGE_RESERVED_13_BIT_KHR"); + if (16384 & value) p.SetAsType().PrintElement("IMAGE_USAGE_RESERVED_14_BIT_KHR"); + if (32768 & value) p.SetAsType().PrintElement("IMAGE_USAGE_RESERVED_15_BIT_KHR"); + if (1024 & value) p.SetAsType().PrintElement("IMAGE_USAGE_RESERVED_10_BIT_KHR"); + if (2048 & value) p.SetAsType().PrintElement("IMAGE_USAGE_RESERVED_11_BIT_KHR"); + if (4096 & value) p.SetAsType().PrintElement("IMAGE_USAGE_RESERVED_12_BIT_KHR"); + if (256 & value) p.SetAsType().PrintElement("IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV"); + if (512 & value) p.SetAsType().PrintElement("IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT"); +} +void DumpVkImageUsageFlags(Printer &p, std::string name, VkImageUsageFlags value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkImageUsageFlags(p, name, static_cast<VkImageUsageFlagBits>(value), width); + p.ObjectEnd(); +} +void DumpVkImageUsageFlagBits(Printer &p, std::string name, VkImageUsageFlagBits value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkImageUsageFlags(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkMemoryHeapFlags(Printer &p, std::string name, VkMemoryHeapFlagBits value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("MEMORY_HEAP_DEVICE_LOCAL_BIT"); + if (2 & value) p.SetAsType().PrintElement("MEMORY_HEAP_MULTI_INSTANCE_BIT"); +} +void DumpVkMemoryHeapFlags(Printer &p, std::string name, VkMemoryHeapFlags value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkMemoryHeapFlags(p, name, static_cast<VkMemoryHeapFlagBits>(value), width); + p.ObjectEnd(); +} +void DumpVkMemoryHeapFlagBits(Printer &p, std::string name, VkMemoryHeapFlagBits value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkMemoryHeapFlags(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkMemoryPropertyFlags(Printer &p, std::string name, VkMemoryPropertyFlagBits value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_DEVICE_LOCAL_BIT"); + if (2 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_HOST_VISIBLE_BIT"); + if (4 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_HOST_COHERENT_BIT"); + if (8 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_HOST_CACHED_BIT"); + if (16 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT"); + if (32 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_PROTECTED_BIT"); + if (64 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD"); + if (128 & value) p.SetAsType().PrintElement("MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD"); +} +void DumpVkMemoryPropertyFlags(Printer &p, std::string name, VkMemoryPropertyFlags value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkMemoryPropertyFlags(p, name, static_cast<VkMemoryPropertyFlagBits>(value), width); + p.ObjectEnd(); +} +void DumpVkMemoryPropertyFlagBits(Printer &p, std::string name, VkMemoryPropertyFlagBits value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkMemoryPropertyFlags(p, name, value, width); + p.ObjectEnd(); +} +std::string VkQueueFlagsString(VkQueueFlags value, int width = 0) { + std::string out; + bool is_first = true; + if (1 & value) { + if (is_first) { is_first = false; } else { out += " | "; } + out += "QUEUE_GRAPHICS"; + } + if (2 & value) { + if (is_first) { is_first = false; } else { out += " | "; } + out += "QUEUE_COMPUTE"; + } + if (4 & value) { + if (is_first) { is_first = false; } else { out += " | "; } + out += "QUEUE_TRANSFER"; + } + if (8 & value) { + if (is_first) { is_first = false; } else { out += " | "; } + out += "QUEUE_SPARSE_BINDING"; + } + if (16 & value) { + if (is_first) { is_first = false; } else { out += " | "; } + out += "QUEUE_PROTECTED"; + } + if (64 & value) { + if (is_first) { is_first = false; } else { out += " | "; } + out += "QUEUE_RESERVED_6_BIT_KHR"; + } + if (32 & value) { + if (is_first) { is_first = false; } else { out += " | "; } + out += "QUEUE_RESERVED_5_BIT_KHR"; + } + return out; +} +void DumpVkResolveModeFlagsKHR(Printer &p, std::string name, VkResolveModeFlagBitsKHR value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (0 & value) p.SetAsType().PrintElement("RESOLVE_MODE_NONE_KHR"); + if (1 & value) p.SetAsType().PrintElement("RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR"); + if (2 & value) p.SetAsType().PrintElement("RESOLVE_MODE_AVERAGE_BIT_KHR"); + if (4 & value) p.SetAsType().PrintElement("RESOLVE_MODE_MIN_BIT_KHR"); + if (8 & value) p.SetAsType().PrintElement("RESOLVE_MODE_MAX_BIT_KHR"); +} +void DumpVkResolveModeFlagsKHR(Printer &p, std::string name, VkResolveModeFlagsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkResolveModeFlagsKHR(p, name, static_cast<VkResolveModeFlagBitsKHR>(value), width); + p.ObjectEnd(); +} +void DumpVkResolveModeFlagBitsKHR(Printer &p, std::string name, VkResolveModeFlagBitsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkResolveModeFlagsKHR(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkSampleCountFlags(Printer &p, std::string name, VkSampleCountFlagBits value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("SAMPLE_COUNT_1_BIT"); + if (2 & value) p.SetAsType().PrintElement("SAMPLE_COUNT_2_BIT"); + if (4 & value) p.SetAsType().PrintElement("SAMPLE_COUNT_4_BIT"); + if (8 & value) p.SetAsType().PrintElement("SAMPLE_COUNT_8_BIT"); + if (16 & value) p.SetAsType().PrintElement("SAMPLE_COUNT_16_BIT"); + if (32 & value) p.SetAsType().PrintElement("SAMPLE_COUNT_32_BIT"); + if (64 & value) p.SetAsType().PrintElement("SAMPLE_COUNT_64_BIT"); +} +void DumpVkSampleCountFlags(Printer &p, std::string name, VkSampleCountFlags value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkSampleCountFlags(p, name, static_cast<VkSampleCountFlagBits>(value), width); + p.ObjectEnd(); +} +void DumpVkSampleCountFlagBits(Printer &p, std::string name, VkSampleCountFlagBits value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkSampleCountFlags(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkShaderStageFlags(Printer &p, std::string name, VkShaderStageFlagBits value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("SHADER_STAGE_VERTEX_BIT"); + if (2 & value) p.SetAsType().PrintElement("SHADER_STAGE_TESSELLATION_CONTROL_BIT"); + if (4 & value) p.SetAsType().PrintElement("SHADER_STAGE_TESSELLATION_EVALUATION_BIT"); + if (8 & value) p.SetAsType().PrintElement("SHADER_STAGE_GEOMETRY_BIT"); + if (16 & value) p.SetAsType().PrintElement("SHADER_STAGE_FRAGMENT_BIT"); + if (32 & value) p.SetAsType().PrintElement("SHADER_STAGE_COMPUTE_BIT"); + if (0x0000001F & value) p.SetAsType().PrintElement("SHADER_STAGE_ALL_GRAPHICS"); + if (0x7FFFFFFF & value) p.SetAsType().PrintElement("SHADER_STAGE_ALL"); + if (256 & value) p.SetAsType().PrintElement("SHADER_STAGE_RAYGEN_BIT_NV"); + if (512 & value) p.SetAsType().PrintElement("SHADER_STAGE_ANY_HIT_BIT_NV"); + if (1024 & value) p.SetAsType().PrintElement("SHADER_STAGE_CLOSEST_HIT_BIT_NV"); + if (2048 & value) p.SetAsType().PrintElement("SHADER_STAGE_MISS_BIT_NV"); + if (4096 & value) p.SetAsType().PrintElement("SHADER_STAGE_INTERSECTION_BIT_NV"); + if (8192 & value) p.SetAsType().PrintElement("SHADER_STAGE_CALLABLE_BIT_NV"); + if (64 & value) p.SetAsType().PrintElement("SHADER_STAGE_TASK_BIT_NV"); + if (128 & value) p.SetAsType().PrintElement("SHADER_STAGE_MESH_BIT_NV"); +} +void DumpVkShaderStageFlags(Printer &p, std::string name, VkShaderStageFlags value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkShaderStageFlags(p, name, static_cast<VkShaderStageFlagBits>(value), width); + p.ObjectEnd(); +} +void DumpVkShaderStageFlagBits(Printer &p, std::string name, VkShaderStageFlagBits value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkShaderStageFlags(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkSubgroupFeatureFlags(Printer &p, std::string name, VkSubgroupFeatureFlagBits value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_BASIC_BIT"); + if (2 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_VOTE_BIT"); + if (4 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_ARITHMETIC_BIT"); + if (8 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_BALLOT_BIT"); + if (16 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_SHUFFLE_BIT"); + if (32 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT"); + if (64 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_CLUSTERED_BIT"); + if (128 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_QUAD_BIT"); + if (256 & value) p.SetAsType().PrintElement("SUBGROUP_FEATURE_PARTITIONED_BIT_NV"); +} +void DumpVkSubgroupFeatureFlags(Printer &p, std::string name, VkSubgroupFeatureFlags value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkSubgroupFeatureFlags(p, name, static_cast<VkSubgroupFeatureFlagBits>(value), width); + p.ObjectEnd(); +} +void DumpVkSubgroupFeatureFlagBits(Printer &p, std::string name, VkSubgroupFeatureFlagBits value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkSubgroupFeatureFlags(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkSurfaceTransformFlagsKHR(Printer &p, std::string name, VkSurfaceTransformFlagBitsKHR value, int width = 0) { + if (value == 0) p.PrintElement("None"); + if (1 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_IDENTITY_BIT_KHR"); + if (2 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_ROTATE_90_BIT_KHR"); + if (4 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_ROTATE_180_BIT_KHR"); + if (8 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_ROTATE_270_BIT_KHR"); + if (16 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR"); + if (32 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR"); + if (64 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR"); + if (128 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR"); + if (256 & value) p.SetAsType().PrintElement("SURFACE_TRANSFORM_INHERIT_BIT_KHR"); +} +void DumpVkSurfaceTransformFlagsKHR(Printer &p, std::string name, VkSurfaceTransformFlagsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkSurfaceTransformFlagsKHR(p, name, static_cast<VkSurfaceTransformFlagBitsKHR>(value), width); + p.ObjectEnd(); +} +void DumpVkSurfaceTransformFlagBitsKHR(Printer &p, std::string name, VkSurfaceTransformFlagBitsKHR value, int width = 0) { + if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; } + p.ObjectStart(name); + DumpVkSurfaceTransformFlagsKHR(p, name, value, width); + p.ObjectEnd(); +} +void DumpVkDrmFormatModifierPropertiesEXT(Printer &p, std::string name, VkDrmFormatModifierPropertiesEXT &obj); +void DumpVkDrmFormatModifierPropertiesListEXT(Printer &p, std::string name, VkDrmFormatModifierPropertiesListEXT &obj); +void DumpVkExtent2D(Printer &p, std::string name, VkExtent2D &obj); +void DumpVkExtent3D(Printer &p, std::string name, VkExtent3D &obj); +void DumpVkLayerProperties(Printer &p, std::string name, VkLayerProperties &obj); +void DumpVkPhysicalDevice16BitStorageFeatures(Printer &p, std::string name, VkPhysicalDevice16BitStorageFeatures &obj); +void DumpVkPhysicalDevice8BitStorageFeaturesKHR(Printer &p, std::string name, VkPhysicalDevice8BitStorageFeaturesKHR &obj); +void DumpVkPhysicalDeviceASTCDecodeFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceASTCDecodeFeaturesEXT &obj); +void DumpVkPhysicalDeviceBlendOperationAdvancedFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT &obj); +void DumpVkPhysicalDeviceBlendOperationAdvancedPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT &obj); +void DumpVkPhysicalDeviceBufferDeviceAddressFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceBufferDeviceAddressFeaturesEXT &obj); +void DumpVkPhysicalDeviceConditionalRenderingFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceConditionalRenderingFeaturesEXT &obj); +void DumpVkPhysicalDeviceConservativeRasterizationPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceConservativeRasterizationPropertiesEXT &obj); +void DumpVkPhysicalDeviceDepthClipEnableFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceDepthClipEnableFeaturesEXT &obj); +void DumpVkPhysicalDeviceDepthStencilResolvePropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceDepthStencilResolvePropertiesKHR &obj); +void DumpVkPhysicalDeviceDescriptorIndexingFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceDescriptorIndexingFeaturesEXT &obj); +void DumpVkPhysicalDeviceDescriptorIndexingPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceDescriptorIndexingPropertiesEXT &obj); +void DumpVkPhysicalDeviceDiscardRectanglePropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceDiscardRectanglePropertiesEXT &obj); +void DumpVkPhysicalDeviceDriverPropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceDriverPropertiesKHR &obj); +void DumpVkPhysicalDeviceExternalMemoryHostPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceExternalMemoryHostPropertiesEXT &obj); +void DumpVkPhysicalDeviceFeatures(Printer &p, std::string name, VkPhysicalDeviceFeatures &obj); +void DumpVkPhysicalDeviceFloatControlsPropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceFloatControlsPropertiesKHR &obj); +void DumpVkPhysicalDeviceFragmentDensityMapFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMapFeaturesEXT &obj); +void DumpVkPhysicalDeviceFragmentDensityMapPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMapPropertiesEXT &obj); +void DumpVkPhysicalDeviceFragmentShaderInterlockFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT &obj); +void DumpVkPhysicalDeviceHostQueryResetFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceHostQueryResetFeaturesEXT &obj); +void DumpVkPhysicalDeviceIDProperties(Printer &p, std::string name, VkPhysicalDeviceIDProperties &obj); +void DumpVkPhysicalDeviceImagelessFramebufferFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceImagelessFramebufferFeaturesKHR &obj); +void DumpVkPhysicalDeviceIndexTypeUint8FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceIndexTypeUint8FeaturesEXT &obj); +void DumpVkPhysicalDeviceInlineUniformBlockFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceInlineUniformBlockFeaturesEXT &obj); +void DumpVkPhysicalDeviceInlineUniformBlockPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceInlineUniformBlockPropertiesEXT &obj); +void DumpVkPhysicalDeviceLimits(Printer &p, std::string name, VkPhysicalDeviceLimits &obj); +void DumpVkPhysicalDeviceLineRasterizationFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceLineRasterizationFeaturesEXT &obj); +void DumpVkPhysicalDeviceLineRasterizationPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceLineRasterizationPropertiesEXT &obj); +void DumpVkPhysicalDeviceMaintenance3Properties(Printer &p, std::string name, VkPhysicalDeviceMaintenance3Properties &obj); +void DumpVkPhysicalDeviceMemoryBudgetPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceMemoryBudgetPropertiesEXT &obj); +void DumpVkPhysicalDeviceMemoryPriorityFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceMemoryPriorityFeaturesEXT &obj); +void DumpVkPhysicalDeviceMultiviewFeatures(Printer &p, std::string name, VkPhysicalDeviceMultiviewFeatures &obj); +void DumpVkPhysicalDeviceMultiviewProperties(Printer &p, std::string name, VkPhysicalDeviceMultiviewProperties &obj); +void DumpVkPhysicalDevicePCIBusInfoPropertiesEXT(Printer &p, std::string name, VkPhysicalDevicePCIBusInfoPropertiesEXT &obj); +void DumpVkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR(Printer &p, std::string name, VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR &obj); +void DumpVkPhysicalDevicePointClippingProperties(Printer &p, std::string name, VkPhysicalDevicePointClippingProperties &obj); +void DumpVkPhysicalDeviceProtectedMemoryFeatures(Printer &p, std::string name, VkPhysicalDeviceProtectedMemoryFeatures &obj); +void DumpVkPhysicalDeviceProtectedMemoryProperties(Printer &p, std::string name, VkPhysicalDeviceProtectedMemoryProperties &obj); +void DumpVkPhysicalDevicePushDescriptorPropertiesKHR(Printer &p, std::string name, VkPhysicalDevicePushDescriptorPropertiesKHR &obj); +void DumpVkPhysicalDeviceSampleLocationsPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceSampleLocationsPropertiesEXT &obj); +void DumpVkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT &obj); +void DumpVkPhysicalDeviceSamplerYcbcrConversionFeatures(Printer &p, std::string name, VkPhysicalDeviceSamplerYcbcrConversionFeatures &obj); +void DumpVkPhysicalDeviceScalarBlockLayoutFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceScalarBlockLayoutFeaturesEXT &obj); +void DumpVkPhysicalDeviceShaderAtomicInt64FeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceShaderAtomicInt64FeaturesKHR &obj); +void DumpVkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT &obj); +void DumpVkPhysicalDeviceShaderDrawParametersFeatures(Printer &p, std::string name, VkPhysicalDeviceShaderDrawParametersFeatures &obj); +void DumpVkPhysicalDeviceShaderFloat16Int8FeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceShaderFloat16Int8FeaturesKHR &obj); +void DumpVkPhysicalDeviceSparseProperties(Printer &p, std::string name, VkPhysicalDeviceSparseProperties &obj); +void DumpVkPhysicalDeviceSubgroupProperties(Printer &p, std::string name, VkPhysicalDeviceSubgroupProperties &obj); +void DumpVkPhysicalDeviceSubgroupSizeControlFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceSubgroupSizeControlFeaturesEXT &obj); +void DumpVkPhysicalDeviceSubgroupSizeControlPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceSubgroupSizeControlPropertiesEXT &obj); +void DumpVkPhysicalDeviceTexelBufferAlignmentFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT &obj); +void DumpVkPhysicalDeviceTexelBufferAlignmentPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT &obj); +void DumpVkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT &obj); +void DumpVkPhysicalDeviceTransformFeedbackFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTransformFeedbackFeaturesEXT &obj); +void DumpVkPhysicalDeviceTransformFeedbackPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceTransformFeedbackPropertiesEXT &obj); +void DumpVkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR &obj); +void DumpVkPhysicalDeviceVariablePointersFeatures(Printer &p, std::string name, VkPhysicalDeviceVariablePointersFeatures &obj); +void DumpVkPhysicalDeviceVertexAttributeDivisorFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT &obj); +void DumpVkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT &obj); +void DumpVkPhysicalDeviceVulkanMemoryModelFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceVulkanMemoryModelFeaturesKHR &obj); +void DumpVkPhysicalDeviceYcbcrImageArraysFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceYcbcrImageArraysFeaturesEXT &obj); +void DumpVkSharedPresentSurfaceCapabilitiesKHR(Printer &p, std::string name, VkSharedPresentSurfaceCapabilitiesKHR &obj); +#ifdef VK_USE_PLATFORM_WIN32_KHR +void DumpVkSurfaceCapabilitiesFullScreenExclusiveEXT(Printer &p, std::string name, VkSurfaceCapabilitiesFullScreenExclusiveEXT &obj); +#endif // VK_USE_PLATFORM_WIN32_KHR +void DumpVkSurfaceCapabilitiesKHR(Printer &p, std::string name, VkSurfaceCapabilitiesKHR &obj); +void DumpVkSurfaceFormatKHR(Printer &p, std::string name, VkSurfaceFormatKHR &obj); +void DumpVkSurfaceProtectedCapabilitiesKHR(Printer &p, std::string name, VkSurfaceProtectedCapabilitiesKHR &obj); +void DumpVkDrmFormatModifierPropertiesEXT(Printer &p, std::string name, VkDrmFormatModifierPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("drmFormatModifier", obj.drmFormatModifier, 27); + p.PrintKeyValue("drmFormatModifierPlaneCount", obj.drmFormatModifierPlaneCount, 27); + DumpVkFormatFeatureFlags(p, "drmFormatModifierTilingFeatures", obj.drmFormatModifierTilingFeatures, 27); + p.ObjectEnd(); +} +void DumpVkDrmFormatModifierPropertiesListEXT(Printer &p, std::string name, VkDrmFormatModifierPropertiesListEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("drmFormatModifierCount", obj.drmFormatModifierCount, 52); + p.ArrayStart("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]); + } + } + p.ArrayEnd(); + p.ObjectEnd(); +} +void DumpVkExtent2D(Printer &p, std::string name, VkExtent2D &obj) { + p.ObjectStart(name); + p.PrintKeyValue("width", obj.width, 6); + p.PrintKeyValue("height", obj.height, 6); + p.ObjectEnd(); +} +void DumpVkExtent3D(Printer &p, std::string name, VkExtent3D &obj) { + p.ObjectStart(name); + p.PrintKeyValue("width", obj.width, 6); + p.PrintKeyValue("height", obj.height, 6); + p.PrintKeyValue("depth", obj.depth, 6); + p.ObjectEnd(); +} +void DumpVkLayerProperties(Printer &p, std::string name, VkLayerProperties &obj) { + p.ObjectStart(name); + p.PrintKeyString("layerName", obj.layerName, 21); + p.PrintKeyValue("specVersion", obj.specVersion, 21); + p.PrintKeyValue("implementationVersion", obj.implementationVersion, 21); + p.PrintKeyString("description", obj.description, 21); + p.ObjectEnd(); +} +void DumpVkPhysicalDevice16BitStorageFeatures(Printer &p, std::string name, VkPhysicalDevice16BitStorageFeatures &obj) { + p.ObjectStart(name); + p.PrintKeyBool("storageBuffer16BitAccess", obj.storageBuffer16BitAccess, 34); + p.PrintKeyBool("uniformAndStorageBuffer16BitAccess", obj.uniformAndStorageBuffer16BitAccess, 34); + p.PrintKeyBool("storagePushConstant16", obj.storagePushConstant16, 34); + p.PrintKeyBool("storageInputOutput16", obj.storageInputOutput16, 34); + p.ObjectEnd(); +} +void DumpVkPhysicalDevice8BitStorageFeaturesKHR(Printer &p, std::string name, VkPhysicalDevice8BitStorageFeaturesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("storageBuffer8BitAccess", obj.storageBuffer8BitAccess, 33); + p.PrintKeyBool("uniformAndStorageBuffer8BitAccess", obj.uniformAndStorageBuffer8BitAccess, 33); + p.PrintKeyBool("storagePushConstant8", obj.storagePushConstant8, 33); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceASTCDecodeFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceASTCDecodeFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("decodeModeSharedExponent", obj.decodeModeSharedExponent, 24); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceBlendOperationAdvancedFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("advancedBlendCoherentOperations", obj.advancedBlendCoherentOperations, 31); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceBlendOperationAdvancedPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("advancedBlendMaxColorAttachments", obj.advancedBlendMaxColorAttachments, 37); + p.PrintKeyBool("advancedBlendIndependentBlend", obj.advancedBlendIndependentBlend, 37); + p.PrintKeyBool("advancedBlendNonPremultipliedSrcColor", obj.advancedBlendNonPremultipliedSrcColor, 37); + p.PrintKeyBool("advancedBlendNonPremultipliedDstColor", obj.advancedBlendNonPremultipliedDstColor, 37); + p.PrintKeyBool("advancedBlendCorrelatedOverlap", obj.advancedBlendCorrelatedOverlap, 37); + p.PrintKeyBool("advancedBlendAllOperations", obj.advancedBlendAllOperations, 37); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceBufferDeviceAddressFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceBufferDeviceAddressFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("bufferDeviceAddress", obj.bufferDeviceAddress, 32); + p.PrintKeyBool("bufferDeviceAddressCaptureReplay", obj.bufferDeviceAddressCaptureReplay, 32); + p.PrintKeyBool("bufferDeviceAddressMultiDevice", obj.bufferDeviceAddressMultiDevice, 32); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceConditionalRenderingFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceConditionalRenderingFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("conditionalRendering", obj.conditionalRendering, 29); + p.PrintKeyBool("inheritedConditionalRendering", obj.inheritedConditionalRendering, 29); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceConservativeRasterizationPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceConservativeRasterizationPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("primitiveOverestimationSize", obj.primitiveOverestimationSize, 43); + p.PrintKeyValue("maxExtraPrimitiveOverestimationSize", obj.maxExtraPrimitiveOverestimationSize, 43); + p.PrintKeyValue("extraPrimitiveOverestimationSizeGranularity", obj.extraPrimitiveOverestimationSizeGranularity, 43); + p.PrintKeyBool("primitiveUnderestimation", obj.primitiveUnderestimation, 43); + p.PrintKeyBool("conservativePointAndLineRasterization", obj.conservativePointAndLineRasterization, 43); + p.PrintKeyBool("degenerateTrianglesRasterized", obj.degenerateTrianglesRasterized, 43); + p.PrintKeyBool("degenerateLinesRasterized", obj.degenerateLinesRasterized, 43); + p.PrintKeyBool("fullyCoveredFragmentShaderInputVariable", obj.fullyCoveredFragmentShaderInputVariable, 43); + p.PrintKeyBool("conservativeRasterizationPostDepthCoverage", obj.conservativeRasterizationPostDepthCoverage, 43); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceDepthClipEnableFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceDepthClipEnableFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("depthClipEnable", obj.depthClipEnable, 15); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceDepthStencilResolvePropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceDepthStencilResolvePropertiesKHR &obj) { + p.ObjectStart(name); + DumpVkResolveModeFlagsKHR(p, "supportedDepthResolveModes", obj.supportedDepthResolveModes, 22); + DumpVkResolveModeFlagsKHR(p, "supportedStencilResolveModes", obj.supportedStencilResolveModes, 22); + p.PrintKeyBool("independentResolveNone", obj.independentResolveNone, 22); + p.PrintKeyBool("independentResolve", obj.independentResolve, 22); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceDescriptorIndexingFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceDescriptorIndexingFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("shaderInputAttachmentArrayDynamicIndexing", obj.shaderInputAttachmentArrayDynamicIndexing, 50); + p.PrintKeyBool("shaderUniformTexelBufferArrayDynamicIndexing", obj.shaderUniformTexelBufferArrayDynamicIndexing, 50); + p.PrintKeyBool("shaderStorageTexelBufferArrayDynamicIndexing", obj.shaderStorageTexelBufferArrayDynamicIndexing, 50); + p.PrintKeyBool("shaderUniformBufferArrayNonUniformIndexing", obj.shaderUniformBufferArrayNonUniformIndexing, 50); + p.PrintKeyBool("shaderSampledImageArrayNonUniformIndexing", obj.shaderSampledImageArrayNonUniformIndexing, 50); + p.PrintKeyBool("shaderStorageBufferArrayNonUniformIndexing", obj.shaderStorageBufferArrayNonUniformIndexing, 50); + p.PrintKeyBool("shaderStorageImageArrayNonUniformIndexing", obj.shaderStorageImageArrayNonUniformIndexing, 50); + p.PrintKeyBool("shaderInputAttachmentArrayNonUniformIndexing", obj.shaderInputAttachmentArrayNonUniformIndexing, 50); + p.PrintKeyBool("shaderUniformTexelBufferArrayNonUniformIndexing", obj.shaderUniformTexelBufferArrayNonUniformIndexing, 50); + p.PrintKeyBool("shaderStorageTexelBufferArrayNonUniformIndexing", obj.shaderStorageTexelBufferArrayNonUniformIndexing, 50); + p.PrintKeyBool("descriptorBindingUniformBufferUpdateAfterBind", obj.descriptorBindingUniformBufferUpdateAfterBind, 50); + p.PrintKeyBool("descriptorBindingSampledImageUpdateAfterBind", obj.descriptorBindingSampledImageUpdateAfterBind, 50); + p.PrintKeyBool("descriptorBindingStorageImageUpdateAfterBind", obj.descriptorBindingStorageImageUpdateAfterBind, 50); + p.PrintKeyBool("descriptorBindingStorageBufferUpdateAfterBind", obj.descriptorBindingStorageBufferUpdateAfterBind, 50); + p.PrintKeyBool("descriptorBindingUniformTexelBufferUpdateAfterBind", obj.descriptorBindingUniformTexelBufferUpdateAfterBind, 50); + p.PrintKeyBool("descriptorBindingStorageTexelBufferUpdateAfterBind", obj.descriptorBindingStorageTexelBufferUpdateAfterBind, 50); + p.PrintKeyBool("descriptorBindingUpdateUnusedWhilePending", obj.descriptorBindingUpdateUnusedWhilePending, 50); + p.PrintKeyBool("descriptorBindingPartiallyBound", obj.descriptorBindingPartiallyBound, 50); + p.PrintKeyBool("descriptorBindingVariableDescriptorCount", obj.descriptorBindingVariableDescriptorCount, 50); + p.PrintKeyBool("runtimeDescriptorArray", obj.runtimeDescriptorArray, 50); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceDescriptorIndexingPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceDescriptorIndexingPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxUpdateAfterBindDescriptorsInAllPools", obj.maxUpdateAfterBindDescriptorsInAllPools, 52); + p.PrintKeyBool("shaderUniformBufferArrayNonUniformIndexingNative", obj.shaderUniformBufferArrayNonUniformIndexingNative, 52); + p.PrintKeyBool("shaderSampledImageArrayNonUniformIndexingNative", obj.shaderSampledImageArrayNonUniformIndexingNative, 52); + p.PrintKeyBool("shaderStorageBufferArrayNonUniformIndexingNative", obj.shaderStorageBufferArrayNonUniformIndexingNative, 52); + p.PrintKeyBool("shaderStorageImageArrayNonUniformIndexingNative", obj.shaderStorageImageArrayNonUniformIndexingNative, 52); + p.PrintKeyBool("shaderInputAttachmentArrayNonUniformIndexingNative", obj.shaderInputAttachmentArrayNonUniformIndexingNative, 52); + p.PrintKeyBool("robustBufferAccessUpdateAfterBind", obj.robustBufferAccessUpdateAfterBind, 52); + p.PrintKeyBool("quadDivergentImplicitLod", obj.quadDivergentImplicitLod, 52); + p.PrintKeyValue("maxPerStageDescriptorUpdateAfterBindSamplers", obj.maxPerStageDescriptorUpdateAfterBindSamplers, 52); + p.PrintKeyValue("maxPerStageDescriptorUpdateAfterBindUniformBuffers", obj.maxPerStageDescriptorUpdateAfterBindUniformBuffers, 52); + p.PrintKeyValue("maxPerStageDescriptorUpdateAfterBindStorageBuffers", obj.maxPerStageDescriptorUpdateAfterBindStorageBuffers, 52); + p.PrintKeyValue("maxPerStageDescriptorUpdateAfterBindSampledImages", obj.maxPerStageDescriptorUpdateAfterBindSampledImages, 52); + p.PrintKeyValue("maxPerStageDescriptorUpdateAfterBindStorageImages", obj.maxPerStageDescriptorUpdateAfterBindStorageImages, 52); + p.PrintKeyValue("maxPerStageDescriptorUpdateAfterBindInputAttachments", obj.maxPerStageDescriptorUpdateAfterBindInputAttachments, 52); + p.PrintKeyValue("maxPerStageUpdateAfterBindResources", obj.maxPerStageUpdateAfterBindResources, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindSamplers", obj.maxDescriptorSetUpdateAfterBindSamplers, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindUniformBuffers", obj.maxDescriptorSetUpdateAfterBindUniformBuffers, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindUniformBuffersDynamic", obj.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindStorageBuffers", obj.maxDescriptorSetUpdateAfterBindStorageBuffers, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindStorageBuffersDynamic", obj.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindSampledImages", obj.maxDescriptorSetUpdateAfterBindSampledImages, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindStorageImages", obj.maxDescriptorSetUpdateAfterBindStorageImages, 52); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindInputAttachments", obj.maxDescriptorSetUpdateAfterBindInputAttachments, 52); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceDiscardRectanglePropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceDiscardRectanglePropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxDiscardRectangles", obj.maxDiscardRectangles, 20); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceDriverPropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceDriverPropertiesKHR &obj) { + p.ObjectStart(name); + DumpVkDriverIdKHR(p, "driverID", obj.driverID, 18); + p.PrintKeyString("driverName", obj.driverName, 18); + p.PrintKeyString("driverInfo", obj.driverInfo, 18); + p.PrintKeyValue("conformanceVersion", obj.conformanceVersion, 18); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceExternalMemoryHostPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceExternalMemoryHostPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("minImportedHostPointerAlignment", to_hex_str(p, obj.minImportedHostPointerAlignment), 31); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceFeatures(Printer &p, std::string name, VkPhysicalDeviceFeatures &obj) { + p.ObjectStart(name); + p.PrintKeyBool("robustBufferAccess", obj.robustBufferAccess, 39); + p.PrintKeyBool("fullDrawIndexUint32", obj.fullDrawIndexUint32, 39); + p.PrintKeyBool("imageCubeArray", obj.imageCubeArray, 39); + p.PrintKeyBool("independentBlend", obj.independentBlend, 39); + p.PrintKeyBool("geometryShader", obj.geometryShader, 39); + p.PrintKeyBool("tessellationShader", obj.tessellationShader, 39); + p.PrintKeyBool("sampleRateShading", obj.sampleRateShading, 39); + p.PrintKeyBool("dualSrcBlend", obj.dualSrcBlend, 39); + p.PrintKeyBool("logicOp", obj.logicOp, 39); + p.PrintKeyBool("multiDrawIndirect", obj.multiDrawIndirect, 39); + p.PrintKeyBool("drawIndirectFirstInstance", obj.drawIndirectFirstInstance, 39); + p.PrintKeyBool("depthClamp", obj.depthClamp, 39); + p.PrintKeyBool("depthBiasClamp", obj.depthBiasClamp, 39); + p.PrintKeyBool("fillModeNonSolid", obj.fillModeNonSolid, 39); + p.PrintKeyBool("depthBounds", obj.depthBounds, 39); + p.PrintKeyBool("wideLines", obj.wideLines, 39); + p.PrintKeyBool("largePoints", obj.largePoints, 39); + p.PrintKeyBool("alphaToOne", obj.alphaToOne, 39); + p.PrintKeyBool("multiViewport", obj.multiViewport, 39); + p.PrintKeyBool("samplerAnisotropy", obj.samplerAnisotropy, 39); + p.PrintKeyBool("textureCompressionETC2", obj.textureCompressionETC2, 39); + p.PrintKeyBool("textureCompressionASTC_LDR", obj.textureCompressionASTC_LDR, 39); + p.PrintKeyBool("textureCompressionBC", obj.textureCompressionBC, 39); + p.PrintKeyBool("occlusionQueryPrecise", obj.occlusionQueryPrecise, 39); + p.PrintKeyBool("pipelineStatisticsQuery", obj.pipelineStatisticsQuery, 39); + p.PrintKeyBool("vertexPipelineStoresAndAtomics", obj.vertexPipelineStoresAndAtomics, 39); + p.PrintKeyBool("fragmentStoresAndAtomics", obj.fragmentStoresAndAtomics, 39); + p.PrintKeyBool("shaderTessellationAndGeometryPointSize", obj.shaderTessellationAndGeometryPointSize, 39); + p.PrintKeyBool("shaderImageGatherExtended", obj.shaderImageGatherExtended, 39); + p.PrintKeyBool("shaderStorageImageExtendedFormats", obj.shaderStorageImageExtendedFormats, 39); + p.PrintKeyBool("shaderStorageImageMultisample", obj.shaderStorageImageMultisample, 39); + p.PrintKeyBool("shaderStorageImageReadWithoutFormat", obj.shaderStorageImageReadWithoutFormat, 39); + p.PrintKeyBool("shaderStorageImageWriteWithoutFormat", obj.shaderStorageImageWriteWithoutFormat, 39); + p.PrintKeyBool("shaderUniformBufferArrayDynamicIndexing", obj.shaderUniformBufferArrayDynamicIndexing, 39); + p.PrintKeyBool("shaderSampledImageArrayDynamicIndexing", obj.shaderSampledImageArrayDynamicIndexing, 39); + p.PrintKeyBool("shaderStorageBufferArrayDynamicIndexing", obj.shaderStorageBufferArrayDynamicIndexing, 39); + p.PrintKeyBool("shaderStorageImageArrayDynamicIndexing", obj.shaderStorageImageArrayDynamicIndexing, 39); + p.PrintKeyBool("shaderClipDistance", obj.shaderClipDistance, 39); + p.PrintKeyBool("shaderCullDistance", obj.shaderCullDistance, 39); + p.PrintKeyBool("shaderFloat64", obj.shaderFloat64, 39); + p.PrintKeyBool("shaderInt64", obj.shaderInt64, 39); + p.PrintKeyBool("shaderInt16", obj.shaderInt16, 39); + p.PrintKeyBool("shaderResourceResidency", obj.shaderResourceResidency, 39); + p.PrintKeyBool("shaderResourceMinLod", obj.shaderResourceMinLod, 39); + p.PrintKeyBool("sparseBinding", obj.sparseBinding, 39); + p.PrintKeyBool("sparseResidencyBuffer", obj.sparseResidencyBuffer, 39); + p.PrintKeyBool("sparseResidencyImage2D", obj.sparseResidencyImage2D, 39); + p.PrintKeyBool("sparseResidencyImage3D", obj.sparseResidencyImage3D, 39); + p.PrintKeyBool("sparseResidency2Samples", obj.sparseResidency2Samples, 39); + p.PrintKeyBool("sparseResidency4Samples", obj.sparseResidency4Samples, 39); + p.PrintKeyBool("sparseResidency8Samples", obj.sparseResidency8Samples, 39); + p.PrintKeyBool("sparseResidency16Samples", obj.sparseResidency16Samples, 39); + p.PrintKeyBool("sparseResidencyAliased", obj.sparseResidencyAliased, 39); + p.PrintKeyBool("variableMultisampleRate", obj.variableMultisampleRate, 39); + p.PrintKeyBool("inheritedQueries", obj.inheritedQueries, 39); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceFloatControlsPropertiesKHR(Printer &p, std::string name, VkPhysicalDeviceFloatControlsPropertiesKHR &obj) { + p.ObjectStart(name); + DumpVkShaderFloatControlsIndependenceKHR(p, "denormBehaviorIndependence", obj.denormBehaviorIndependence, 37); + DumpVkShaderFloatControlsIndependenceKHR(p, "roundingModeIndependence", obj.roundingModeIndependence, 37); + p.PrintKeyBool("shaderSignedZeroInfNanPreserveFloat16", obj.shaderSignedZeroInfNanPreserveFloat16, 37); + p.PrintKeyBool("shaderSignedZeroInfNanPreserveFloat32", obj.shaderSignedZeroInfNanPreserveFloat32, 37); + p.PrintKeyBool("shaderSignedZeroInfNanPreserveFloat64", obj.shaderSignedZeroInfNanPreserveFloat64, 37); + p.PrintKeyBool("shaderDenormPreserveFloat16", obj.shaderDenormPreserveFloat16, 37); + p.PrintKeyBool("shaderDenormPreserveFloat32", obj.shaderDenormPreserveFloat32, 37); + p.PrintKeyBool("shaderDenormPreserveFloat64", obj.shaderDenormPreserveFloat64, 37); + p.PrintKeyBool("shaderDenormFlushToZeroFloat16", obj.shaderDenormFlushToZeroFloat16, 37); + p.PrintKeyBool("shaderDenormFlushToZeroFloat32", obj.shaderDenormFlushToZeroFloat32, 37); + p.PrintKeyBool("shaderDenormFlushToZeroFloat64", obj.shaderDenormFlushToZeroFloat64, 37); + p.PrintKeyBool("shaderRoundingModeRTEFloat16", obj.shaderRoundingModeRTEFloat16, 37); + p.PrintKeyBool("shaderRoundingModeRTEFloat32", obj.shaderRoundingModeRTEFloat32, 37); + p.PrintKeyBool("shaderRoundingModeRTEFloat64", obj.shaderRoundingModeRTEFloat64, 37); + p.PrintKeyBool("shaderRoundingModeRTZFloat16", obj.shaderRoundingModeRTZFloat16, 37); + p.PrintKeyBool("shaderRoundingModeRTZFloat32", obj.shaderRoundingModeRTZFloat32, 37); + p.PrintKeyBool("shaderRoundingModeRTZFloat64", obj.shaderRoundingModeRTZFloat64, 37); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceFragmentDensityMapFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMapFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("fragmentDensityMap", obj.fragmentDensityMap, 37); + p.PrintKeyBool("fragmentDensityMapDynamic", obj.fragmentDensityMapDynamic, 37); + p.PrintKeyBool("fragmentDensityMapNonSubsampledImages", obj.fragmentDensityMapNonSubsampledImages, 37); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceFragmentDensityMapPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentDensityMapPropertiesEXT &obj) { + p.ObjectStart(name); + DumpVkExtent2D(p, "minFragmentDensityTexelSize", obj.minFragmentDensityTexelSize); + DumpVkExtent2D(p, "maxFragmentDensityTexelSize", obj.maxFragmentDensityTexelSize); + p.PrintKeyBool("fragmentDensityInvocations", obj.fragmentDensityInvocations, 26); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceFragmentShaderInterlockFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("fragmentShaderSampleInterlock", obj.fragmentShaderSampleInterlock, 34); + p.PrintKeyBool("fragmentShaderPixelInterlock", obj.fragmentShaderPixelInterlock, 34); + p.PrintKeyBool("fragmentShaderShadingRateInterlock", obj.fragmentShaderShadingRateInterlock, 34); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceHostQueryResetFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceHostQueryResetFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("hostQueryReset", obj.hostQueryReset, 14); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceIDProperties(Printer &p, std::string name, VkPhysicalDeviceIDProperties &obj) { + p.ObjectStart(name); + p.PrintKeyString("deviceUUID", to_string_16(obj.deviceUUID), 15); + p.PrintKeyString("driverUUID", to_string_16(obj.driverUUID), 15); + if (obj.deviceLUIDValid) p.PrintKeyString("deviceLUID", to_string_8(obj.deviceLUID), 15); + p.PrintKeyValue("deviceNodeMask", obj.deviceNodeMask, 15); + p.PrintKeyBool("deviceLUIDValid", obj.deviceLUIDValid, 15); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceImagelessFramebufferFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceImagelessFramebufferFeaturesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("imagelessFramebuffer", obj.imagelessFramebuffer, 20); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceIndexTypeUint8FeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceIndexTypeUint8FeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("indexTypeUint8", obj.indexTypeUint8, 14); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceInlineUniformBlockFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceInlineUniformBlockFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("inlineUniformBlock", obj.inlineUniformBlock, 50); + p.PrintKeyBool("descriptorBindingInlineUniformBlockUpdateAfterBind", obj.descriptorBindingInlineUniformBlockUpdateAfterBind, 50); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceInlineUniformBlockPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceInlineUniformBlockPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxInlineUniformBlockSize", obj.maxInlineUniformBlockSize, 55); + p.PrintKeyValue("maxPerStageDescriptorInlineUniformBlocks", obj.maxPerStageDescriptorInlineUniformBlocks, 55); + p.PrintKeyValue("maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks", obj.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks, 55); + p.PrintKeyValue("maxDescriptorSetInlineUniformBlocks", obj.maxDescriptorSetInlineUniformBlocks, 55); + p.PrintKeyValue("maxDescriptorSetUpdateAfterBindInlineUniformBlocks", obj.maxDescriptorSetUpdateAfterBindInlineUniformBlocks, 55); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceLimits(Printer &p, std::string name, VkPhysicalDeviceLimits &obj) { + if (p.Type() == OutputType::json) + p.ObjectStart("limits"); + else + p.SetSubHeader().ObjectStart(name); + p.PrintKeyValue("maxImageDimension1D", obj.maxImageDimension1D, 47); + p.PrintKeyValue("maxImageDimension2D", obj.maxImageDimension2D, 47); + p.PrintKeyValue("maxImageDimension3D", obj.maxImageDimension3D, 47); + p.PrintKeyValue("maxImageDimensionCube", obj.maxImageDimensionCube, 47); + p.PrintKeyValue("maxImageArrayLayers", obj.maxImageArrayLayers, 47); + p.PrintKeyValue("maxTexelBufferElements", obj.maxTexelBufferElements, 47); + p.PrintKeyValue("maxUniformBufferRange", obj.maxUniformBufferRange, 47); + p.PrintKeyValue("maxStorageBufferRange", obj.maxStorageBufferRange, 47); + p.PrintKeyValue("maxPushConstantsSize", obj.maxPushConstantsSize, 47); + p.PrintKeyValue("maxMemoryAllocationCount", obj.maxMemoryAllocationCount, 47); + p.PrintKeyValue("maxSamplerAllocationCount", obj.maxSamplerAllocationCount, 47); + p.PrintKeyValue("bufferImageGranularity", to_hex_str(p, obj.bufferImageGranularity), 47); + p.PrintKeyValue("sparseAddressSpaceSize", to_hex_str(p, obj.sparseAddressSpaceSize), 47); + p.PrintKeyValue("maxBoundDescriptorSets", obj.maxBoundDescriptorSets, 47); + p.PrintKeyValue("maxPerStageDescriptorSamplers", obj.maxPerStageDescriptorSamplers, 47); + p.PrintKeyValue("maxPerStageDescriptorUniformBuffers", obj.maxPerStageDescriptorUniformBuffers, 47); + p.PrintKeyValue("maxPerStageDescriptorStorageBuffers", obj.maxPerStageDescriptorStorageBuffers, 47); + p.PrintKeyValue("maxPerStageDescriptorSampledImages", obj.maxPerStageDescriptorSampledImages, 47); + p.PrintKeyValue("maxPerStageDescriptorStorageImages", obj.maxPerStageDescriptorStorageImages, 47); + p.PrintKeyValue("maxPerStageDescriptorInputAttachments", obj.maxPerStageDescriptorInputAttachments, 47); + p.PrintKeyValue("maxPerStageResources", obj.maxPerStageResources, 47); + p.PrintKeyValue("maxDescriptorSetSamplers", obj.maxDescriptorSetSamplers, 47); + p.PrintKeyValue("maxDescriptorSetUniformBuffers", obj.maxDescriptorSetUniformBuffers, 47); + p.PrintKeyValue("maxDescriptorSetUniformBuffersDynamic", obj.maxDescriptorSetUniformBuffersDynamic, 47); + p.PrintKeyValue("maxDescriptorSetStorageBuffers", obj.maxDescriptorSetStorageBuffers, 47); + p.PrintKeyValue("maxDescriptorSetStorageBuffersDynamic", obj.maxDescriptorSetStorageBuffersDynamic, 47); + p.PrintKeyValue("maxDescriptorSetSampledImages", obj.maxDescriptorSetSampledImages, 47); + p.PrintKeyValue("maxDescriptorSetStorageImages", obj.maxDescriptorSetStorageImages, 47); + p.PrintKeyValue("maxDescriptorSetInputAttachments", obj.maxDescriptorSetInputAttachments, 47); + p.PrintKeyValue("maxVertexInputAttributes", obj.maxVertexInputAttributes, 47); + p.PrintKeyValue("maxVertexInputBindings", obj.maxVertexInputBindings, 47); + p.PrintKeyValue("maxVertexInputAttributeOffset", obj.maxVertexInputAttributeOffset, 47); + p.PrintKeyValue("maxVertexInputBindingStride", obj.maxVertexInputBindingStride, 47); + p.PrintKeyValue("maxVertexOutputComponents", obj.maxVertexOutputComponents, 47); + p.PrintKeyValue("maxTessellationGenerationLevel", obj.maxTessellationGenerationLevel, 47); + p.PrintKeyValue("maxTessellationPatchSize", obj.maxTessellationPatchSize, 47); + p.PrintKeyValue("maxTessellationControlPerVertexInputComponents", obj.maxTessellationControlPerVertexInputComponents, 47); + p.PrintKeyValue("maxTessellationControlPerVertexOutputComponents", obj.maxTessellationControlPerVertexOutputComponents, 47); + p.PrintKeyValue("maxTessellationControlPerPatchOutputComponents", obj.maxTessellationControlPerPatchOutputComponents, 47); + p.PrintKeyValue("maxTessellationControlTotalOutputComponents", obj.maxTessellationControlTotalOutputComponents, 47); + p.PrintKeyValue("maxTessellationEvaluationInputComponents", obj.maxTessellationEvaluationInputComponents, 47); + p.PrintKeyValue("maxTessellationEvaluationOutputComponents", obj.maxTessellationEvaluationOutputComponents, 47); + p.PrintKeyValue("maxGeometryShaderInvocations", obj.maxGeometryShaderInvocations, 47); + p.PrintKeyValue("maxGeometryInputComponents", obj.maxGeometryInputComponents, 47); + p.PrintKeyValue("maxGeometryOutputComponents", obj.maxGeometryOutputComponents, 47); + p.PrintKeyValue("maxGeometryOutputVertices", obj.maxGeometryOutputVertices, 47); + p.PrintKeyValue("maxGeometryTotalOutputComponents", obj.maxGeometryTotalOutputComponents, 47); + p.PrintKeyValue("maxFragmentInputComponents", obj.maxFragmentInputComponents, 47); + p.PrintKeyValue("maxFragmentOutputAttachments", obj.maxFragmentOutputAttachments, 47); + p.PrintKeyValue("maxFragmentDualSrcAttachments", obj.maxFragmentDualSrcAttachments, 47); + p.PrintKeyValue("maxFragmentCombinedOutputResources", obj.maxFragmentCombinedOutputResources, 47); + p.PrintKeyValue("maxComputeSharedMemorySize", obj.maxComputeSharedMemorySize, 47); + p.ArrayStart("maxComputeWorkGroupCount", 3); + p.PrintElement(obj.maxComputeWorkGroupCount[0]); + p.PrintElement(obj.maxComputeWorkGroupCount[1]); + p.PrintElement(obj.maxComputeWorkGroupCount[2]); + p.ArrayEnd(); + p.PrintKeyValue("maxComputeWorkGroupInvocations", obj.maxComputeWorkGroupInvocations, 47); + p.ArrayStart("maxComputeWorkGroupSize", 3); + p.PrintElement(obj.maxComputeWorkGroupSize[0]); + p.PrintElement(obj.maxComputeWorkGroupSize[1]); + p.PrintElement(obj.maxComputeWorkGroupSize[2]); + p.ArrayEnd(); + p.PrintKeyValue("subPixelPrecisionBits", obj.subPixelPrecisionBits, 47); + p.PrintKeyValue("subTexelPrecisionBits", obj.subTexelPrecisionBits, 47); + p.PrintKeyValue("mipmapPrecisionBits", obj.mipmapPrecisionBits, 47); + p.PrintKeyValue("maxDrawIndexedIndexValue", obj.maxDrawIndexedIndexValue, 47); + p.PrintKeyValue("maxDrawIndirectCount", obj.maxDrawIndirectCount, 47); + p.PrintKeyValue("maxSamplerLodBias", obj.maxSamplerLodBias, 47); + p.PrintKeyValue("maxSamplerAnisotropy", obj.maxSamplerAnisotropy, 47); + p.PrintKeyValue("maxViewports", obj.maxViewports, 47); + p.ArrayStart("maxViewportDimensions", 2); + p.PrintElement(obj.maxViewportDimensions[0]); + p.PrintElement(obj.maxViewportDimensions[1]); + p.ArrayEnd(); + p.ArrayStart("viewportBoundsRange", 2); + p.PrintElement(obj.viewportBoundsRange[0]); + p.PrintElement(obj.viewportBoundsRange[1]); + p.ArrayEnd(); + p.PrintKeyValue("viewportSubPixelBits", obj.viewportSubPixelBits, 47); + p.PrintKeyValue("minMemoryMapAlignment", obj.minMemoryMapAlignment, 47); + p.PrintKeyValue("minTexelBufferOffsetAlignment", to_hex_str(p, obj.minTexelBufferOffsetAlignment), 47); + p.PrintKeyValue("minUniformBufferOffsetAlignment", to_hex_str(p, obj.minUniformBufferOffsetAlignment), 47); + p.PrintKeyValue("minStorageBufferOffsetAlignment", to_hex_str(p, obj.minStorageBufferOffsetAlignment), 47); + p.PrintKeyValue("minTexelOffset", obj.minTexelOffset, 47); + p.PrintKeyValue("maxTexelOffset", obj.maxTexelOffset, 47); + p.PrintKeyValue("minTexelGatherOffset", obj.minTexelGatherOffset, 47); + p.PrintKeyValue("maxTexelGatherOffset", obj.maxTexelGatherOffset, 47); + p.PrintKeyValue("minInterpolationOffset", obj.minInterpolationOffset, 47); + p.PrintKeyValue("maxInterpolationOffset", obj.maxInterpolationOffset, 47); + p.PrintKeyValue("subPixelInterpolationOffsetBits", obj.subPixelInterpolationOffsetBits, 47); + p.PrintKeyValue("maxFramebufferWidth", obj.maxFramebufferWidth, 47); + p.PrintKeyValue("maxFramebufferHeight", obj.maxFramebufferHeight, 47); + p.PrintKeyValue("maxFramebufferLayers", obj.maxFramebufferLayers, 47); + DumpVkSampleCountFlags(p, "framebufferColorSampleCounts", obj.framebufferColorSampleCounts, 47); + DumpVkSampleCountFlags(p, "framebufferDepthSampleCounts", obj.framebufferDepthSampleCounts, 47); + DumpVkSampleCountFlags(p, "framebufferStencilSampleCounts", obj.framebufferStencilSampleCounts, 47); + DumpVkSampleCountFlags(p, "framebufferNoAttachmentsSampleCounts", obj.framebufferNoAttachmentsSampleCounts, 47); + p.PrintKeyValue("maxColorAttachments", obj.maxColorAttachments, 47); + DumpVkSampleCountFlags(p, "sampledImageColorSampleCounts", obj.sampledImageColorSampleCounts, 47); + DumpVkSampleCountFlags(p, "sampledImageIntegerSampleCounts", obj.sampledImageIntegerSampleCounts, 47); + DumpVkSampleCountFlags(p, "sampledImageDepthSampleCounts", obj.sampledImageDepthSampleCounts, 47); + DumpVkSampleCountFlags(p, "sampledImageStencilSampleCounts", obj.sampledImageStencilSampleCounts, 47); + DumpVkSampleCountFlags(p, "storageImageSampleCounts", obj.storageImageSampleCounts, 47); + p.PrintKeyValue("maxSampleMaskWords", obj.maxSampleMaskWords, 47); + p.PrintKeyBool("timestampComputeAndGraphics", obj.timestampComputeAndGraphics, 47); + p.PrintKeyValue("timestampPeriod", obj.timestampPeriod, 47); + p.PrintKeyValue("maxClipDistances", obj.maxClipDistances, 47); + p.PrintKeyValue("maxCullDistances", obj.maxCullDistances, 47); + p.PrintKeyValue("maxCombinedClipAndCullDistances", obj.maxCombinedClipAndCullDistances, 47); + p.PrintKeyValue("discreteQueuePriorities", obj.discreteQueuePriorities, 47); + p.ArrayStart("pointSizeRange", 2); + p.PrintElement(obj.pointSizeRange[0]); + p.PrintElement(obj.pointSizeRange[1]); + p.ArrayEnd(); + p.ArrayStart("lineWidthRange", 2); + p.PrintElement(obj.lineWidthRange[0]); + p.PrintElement(obj.lineWidthRange[1]); + p.ArrayEnd(); + p.PrintKeyValue("pointSizeGranularity", obj.pointSizeGranularity, 47); + p.PrintKeyValue("lineWidthGranularity", obj.lineWidthGranularity, 47); + p.PrintKeyBool("strictLines", obj.strictLines, 47); + p.PrintKeyBool("standardSampleLocations", obj.standardSampleLocations, 47); + p.PrintKeyValue("optimalBufferCopyOffsetAlignment", to_hex_str(p, obj.optimalBufferCopyOffsetAlignment), 47); + p.PrintKeyValue("optimalBufferCopyRowPitchAlignment", to_hex_str(p, obj.optimalBufferCopyRowPitchAlignment), 47); + p.PrintKeyValue("nonCoherentAtomSize", to_hex_str(p, obj.nonCoherentAtomSize), 47); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceLineRasterizationFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceLineRasterizationFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("rectangularLines", obj.rectangularLines, 24); + p.PrintKeyBool("bresenhamLines", obj.bresenhamLines, 24); + p.PrintKeyBool("smoothLines", obj.smoothLines, 24); + p.PrintKeyBool("stippledRectangularLines", obj.stippledRectangularLines, 24); + p.PrintKeyBool("stippledBresenhamLines", obj.stippledBresenhamLines, 24); + p.PrintKeyBool("stippledSmoothLines", obj.stippledSmoothLines, 24); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceLineRasterizationPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceLineRasterizationPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("lineSubPixelPrecisionBits", obj.lineSubPixelPrecisionBits, 25); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceMaintenance3Properties(Printer &p, std::string name, VkPhysicalDeviceMaintenance3Properties &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxPerSetDescriptors", obj.maxPerSetDescriptors, 23); + p.PrintKeyValue("maxMemoryAllocationSize", to_hex_str(p, obj.maxMemoryAllocationSize), 23); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceMemoryBudgetPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceMemoryBudgetPropertiesEXT &obj) { + p.ObjectStart(name); + p.ArrayStart("heapBudget", 16); + p.PrintElement(obj.heapBudget[0]); + p.PrintElement(obj.heapBudget[1]); + p.PrintElement(obj.heapBudget[2]); + p.PrintElement(obj.heapBudget[3]); + p.PrintElement(obj.heapBudget[4]); + p.PrintElement(obj.heapBudget[5]); + p.PrintElement(obj.heapBudget[6]); + p.PrintElement(obj.heapBudget[7]); + p.PrintElement(obj.heapBudget[8]); + p.PrintElement(obj.heapBudget[9]); + p.PrintElement(obj.heapBudget[10]); + p.PrintElement(obj.heapBudget[11]); + p.PrintElement(obj.heapBudget[12]); + p.PrintElement(obj.heapBudget[13]); + p.PrintElement(obj.heapBudget[14]); + p.PrintElement(obj.heapBudget[15]); + p.ArrayEnd(); + p.ArrayStart("heapUsage", 16); + p.PrintElement(obj.heapUsage[0]); + p.PrintElement(obj.heapUsage[1]); + p.PrintElement(obj.heapUsage[2]); + p.PrintElement(obj.heapUsage[3]); + p.PrintElement(obj.heapUsage[4]); + p.PrintElement(obj.heapUsage[5]); + p.PrintElement(obj.heapUsage[6]); + p.PrintElement(obj.heapUsage[7]); + p.PrintElement(obj.heapUsage[8]); + p.PrintElement(obj.heapUsage[9]); + p.PrintElement(obj.heapUsage[10]); + p.PrintElement(obj.heapUsage[11]); + p.PrintElement(obj.heapUsage[12]); + p.PrintElement(obj.heapUsage[13]); + p.PrintElement(obj.heapUsage[14]); + p.PrintElement(obj.heapUsage[15]); + p.ArrayEnd(); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceMemoryPriorityFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceMemoryPriorityFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("memoryPriority", obj.memoryPriority, 14); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceMultiviewFeatures(Printer &p, std::string name, VkPhysicalDeviceMultiviewFeatures &obj) { + p.ObjectStart(name); + p.PrintKeyBool("multiview", obj.multiview, 27); + p.PrintKeyBool("multiviewGeometryShader", obj.multiviewGeometryShader, 27); + p.PrintKeyBool("multiviewTessellationShader", obj.multiviewTessellationShader, 27); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceMultiviewProperties(Printer &p, std::string name, VkPhysicalDeviceMultiviewProperties &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxMultiviewViewCount", obj.maxMultiviewViewCount, 25); + p.PrintKeyValue("maxMultiviewInstanceIndex", obj.maxMultiviewInstanceIndex, 25); + p.ObjectEnd(); +} +void DumpVkPhysicalDevicePCIBusInfoPropertiesEXT(Printer &p, std::string name, VkPhysicalDevicePCIBusInfoPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("pciDomain", obj.pciDomain, 11); + p.PrintKeyValue("pciBus", obj.pciBus, 11); + p.PrintKeyValue("pciDevice", obj.pciDevice, 11); + p.PrintKeyValue("pciFunction", obj.pciFunction, 11); + p.ObjectEnd(); +} +void DumpVkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR(Printer &p, std::string name, VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("pipelineExecutableInfo", obj.pipelineExecutableInfo, 22); + p.ObjectEnd(); +} +void DumpVkPhysicalDevicePointClippingProperties(Printer &p, std::string name, VkPhysicalDevicePointClippingProperties &obj) { + p.ObjectStart(name); + DumpVkPointClippingBehavior(p, "pointClippingBehavior", obj.pointClippingBehavior, 5); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceProtectedMemoryFeatures(Printer &p, std::string name, VkPhysicalDeviceProtectedMemoryFeatures &obj) { + p.ObjectStart(name); + p.PrintKeyBool("protectedMemory", obj.protectedMemory, 15); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceProtectedMemoryProperties(Printer &p, std::string name, VkPhysicalDeviceProtectedMemoryProperties &obj) { + p.ObjectStart(name); + p.PrintKeyBool("protectedNoFault", obj.protectedNoFault, 16); + p.ObjectEnd(); +} +void DumpVkPhysicalDevicePushDescriptorPropertiesKHR(Printer &p, std::string name, VkPhysicalDevicePushDescriptorPropertiesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxPushDescriptors", obj.maxPushDescriptors, 18); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceSampleLocationsPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceSampleLocationsPropertiesEXT &obj) { + p.ObjectStart(name); + DumpVkSampleCountFlags(p, "sampleLocationSampleCounts", obj.sampleLocationSampleCounts, 32); + DumpVkExtent2D(p, "maxSampleLocationGridSize", obj.maxSampleLocationGridSize); + p.ArrayStart("sampleLocationCoordinateRange", 2); + p.PrintElement(obj.sampleLocationCoordinateRange[0]); + p.PrintElement(obj.sampleLocationCoordinateRange[1]); + p.ArrayEnd(); + p.PrintKeyValue("sampleLocationSubPixelBits", obj.sampleLocationSubPixelBits, 32); + p.PrintKeyBool("variableSampleLocations", obj.variableSampleLocations, 32); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("filterMinmaxSingleComponentFormats", obj.filterMinmaxSingleComponentFormats, 34); + p.PrintKeyBool("filterMinmaxImageComponentMapping", obj.filterMinmaxImageComponentMapping, 34); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceSamplerYcbcrConversionFeatures(Printer &p, std::string name, VkPhysicalDeviceSamplerYcbcrConversionFeatures &obj) { + p.ObjectStart(name); + p.PrintKeyBool("samplerYcbcrConversion", obj.samplerYcbcrConversion, 22); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceScalarBlockLayoutFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceScalarBlockLayoutFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("scalarBlockLayout", obj.scalarBlockLayout, 17); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceShaderAtomicInt64FeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceShaderAtomicInt64FeaturesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("shaderBufferInt64Atomics", obj.shaderBufferInt64Atomics, 24); + p.PrintKeyBool("shaderSharedInt64Atomics", obj.shaderSharedInt64Atomics, 24); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("shaderDemoteToHelperInvocation", obj.shaderDemoteToHelperInvocation, 30); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceShaderDrawParametersFeatures(Printer &p, std::string name, VkPhysicalDeviceShaderDrawParametersFeatures &obj) { + p.ObjectStart(name); + p.PrintKeyBool("shaderDrawParameters", obj.shaderDrawParameters, 20); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceShaderFloat16Int8FeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceShaderFloat16Int8FeaturesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("shaderFloat16", obj.shaderFloat16, 13); + p.PrintKeyBool("shaderInt8", obj.shaderInt8, 13); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceSparseProperties(Printer &p, std::string name, VkPhysicalDeviceSparseProperties &obj) { + if (p.Type() == OutputType::json) + p.ObjectStart("sparseProperties"); + else + p.SetSubHeader().ObjectStart(name); + p.PrintKeyBool("residencyStandard2DBlockShape", obj.residencyStandard2DBlockShape, 40); + p.PrintKeyBool("residencyStandard2DMultisampleBlockShape", obj.residencyStandard2DMultisampleBlockShape, 40); + p.PrintKeyBool("residencyStandard3DBlockShape", obj.residencyStandard3DBlockShape, 40); + p.PrintKeyBool("residencyAlignedMipSize", obj.residencyAlignedMipSize, 40); + p.PrintKeyBool("residencyNonResidentStrict", obj.residencyNonResidentStrict, 40); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceSubgroupProperties(Printer &p, std::string name, VkPhysicalDeviceSubgroupProperties &obj) { + p.ObjectStart(name); + p.PrintKeyValue("subgroupSize", obj.subgroupSize, 25); + DumpVkShaderStageFlags(p, "supportedStages", obj.supportedStages, 25); + DumpVkSubgroupFeatureFlags(p, "supportedOperations", obj.supportedOperations, 25); + p.PrintKeyBool("quadOperationsInAllStages", obj.quadOperationsInAllStages, 25); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceSubgroupSizeControlFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceSubgroupSizeControlFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("subgroupSizeControl", obj.subgroupSizeControl, 20); + p.PrintKeyBool("computeFullSubgroups", obj.computeFullSubgroups, 20); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceSubgroupSizeControlPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceSubgroupSizeControlPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("minSubgroupSize", obj.minSubgroupSize, 28); + p.PrintKeyValue("maxSubgroupSize", obj.maxSubgroupSize, 28); + p.PrintKeyValue("maxComputeWorkgroupSubgroups", obj.maxComputeWorkgroupSubgroups, 28); + DumpVkShaderStageFlags(p, "requiredSubgroupSizeStages", obj.requiredSubgroupSizeStages, 28); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceTexelBufferAlignmentFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("texelBufferAlignment", obj.texelBufferAlignment, 20); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceTexelBufferAlignmentPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("storageTexelBufferOffsetAlignmentBytes", to_hex_str(p, obj.storageTexelBufferOffsetAlignmentBytes), 44); + p.PrintKeyBool("storageTexelBufferOffsetSingleTexelAlignment", obj.storageTexelBufferOffsetSingleTexelAlignment, 44); + p.PrintKeyValue("uniformTexelBufferOffsetAlignmentBytes", to_hex_str(p, obj.uniformTexelBufferOffsetAlignmentBytes), 44); + p.PrintKeyBool("uniformTexelBufferOffsetSingleTexelAlignment", obj.uniformTexelBufferOffsetSingleTexelAlignment, 44); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("textureCompressionASTC_HDR", obj.textureCompressionASTC_HDR, 26); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceTransformFeedbackFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceTransformFeedbackFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("transformFeedback", obj.transformFeedback, 17); + p.PrintKeyBool("geometryStreams", obj.geometryStreams, 17); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceTransformFeedbackPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceTransformFeedbackPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxTransformFeedbackStreams", obj.maxTransformFeedbackStreams, 42); + p.PrintKeyValue("maxTransformFeedbackBuffers", obj.maxTransformFeedbackBuffers, 42); + p.PrintKeyValue("maxTransformFeedbackBufferSize", to_hex_str(p, obj.maxTransformFeedbackBufferSize), 42); + p.PrintKeyValue("maxTransformFeedbackStreamDataSize", obj.maxTransformFeedbackStreamDataSize, 42); + p.PrintKeyValue("maxTransformFeedbackBufferDataSize", obj.maxTransformFeedbackBufferDataSize, 42); + p.PrintKeyValue("maxTransformFeedbackBufferDataStride", obj.maxTransformFeedbackBufferDataStride, 42); + p.PrintKeyBool("transformFeedbackQueries", obj.transformFeedbackQueries, 42); + p.PrintKeyBool("transformFeedbackStreamsLinesTriangles", obj.transformFeedbackStreamsLinesTriangles, 42); + p.PrintKeyBool("transformFeedbackRasterizationStreamSelect", obj.transformFeedbackRasterizationStreamSelect, 42); + p.PrintKeyBool("transformFeedbackDraw", obj.transformFeedbackDraw, 42); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("uniformBufferStandardLayout", obj.uniformBufferStandardLayout, 27); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceVariablePointersFeatures(Printer &p, std::string name, VkPhysicalDeviceVariablePointersFeatures &obj) { + p.ObjectStart(name); + p.PrintKeyBool("variablePointersStorageBuffer", obj.variablePointersStorageBuffer, 29); + p.PrintKeyBool("variablePointers", obj.variablePointers, 29); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceVertexAttributeDivisorFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("vertexAttributeInstanceRateDivisor", obj.vertexAttributeInstanceRateDivisor, 38); + p.PrintKeyBool("vertexAttributeInstanceRateZeroDivisor", obj.vertexAttributeInstanceRateZeroDivisor, 38); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(Printer &p, std::string name, VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyValue("maxVertexAttribDivisor", obj.maxVertexAttribDivisor, 22); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceVulkanMemoryModelFeaturesKHR(Printer &p, std::string name, VkPhysicalDeviceVulkanMemoryModelFeaturesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("vulkanMemoryModel", obj.vulkanMemoryModel, 45); + p.PrintKeyBool("vulkanMemoryModelDeviceScope", obj.vulkanMemoryModelDeviceScope, 45); + p.PrintKeyBool("vulkanMemoryModelAvailabilityVisibilityChains", obj.vulkanMemoryModelAvailabilityVisibilityChains, 45); + p.ObjectEnd(); +} +void DumpVkPhysicalDeviceYcbcrImageArraysFeaturesEXT(Printer &p, std::string name, VkPhysicalDeviceYcbcrImageArraysFeaturesEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("ycbcrImageArrays", obj.ycbcrImageArrays, 16); + p.ObjectEnd(); +} +void DumpVkSharedPresentSurfaceCapabilitiesKHR(Printer &p, std::string name, VkSharedPresentSurfaceCapabilitiesKHR &obj) { + p.ObjectStart(name); + DumpVkImageUsageFlags(p, "sharedPresentSupportedUsageFlags", obj.sharedPresentSupportedUsageFlags, 5); + p.ObjectEnd(); +} +#ifdef VK_USE_PLATFORM_WIN32_KHR +void DumpVkSurfaceCapabilitiesFullScreenExclusiveEXT(Printer &p, std::string name, VkSurfaceCapabilitiesFullScreenExclusiveEXT &obj) { + p.ObjectStart(name); + p.PrintKeyBool("fullScreenExclusiveSupported", obj.fullScreenExclusiveSupported, 28); + p.ObjectEnd(); +} +#endif // VK_USE_PLATFORM_WIN32_KHR +void DumpVkSurfaceCapabilitiesKHR(Printer &p, std::string name, VkSurfaceCapabilitiesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyValue("minImageCount", obj.minImageCount, 19); + p.PrintKeyValue("maxImageCount", obj.maxImageCount, 19); + DumpVkExtent2D(p, "currentExtent", obj.currentExtent); + DumpVkExtent2D(p, "minImageExtent", obj.minImageExtent); + DumpVkExtent2D(p, "maxImageExtent", obj.maxImageExtent); + p.PrintKeyValue("maxImageArrayLayers", obj.maxImageArrayLayers, 19); + DumpVkSurfaceTransformFlagsKHR(p, "supportedTransforms", obj.supportedTransforms, 19); + DumpVkSurfaceTransformFlagBitsKHR(p, "currentTransform", obj.currentTransform, 19); + DumpVkCompositeAlphaFlagsKHR(p, "supportedCompositeAlpha", obj.supportedCompositeAlpha, 19); + DumpVkImageUsageFlags(p, "supportedUsageFlags", obj.supportedUsageFlags, 19); + p.ObjectEnd(); +} +void DumpVkSurfaceFormatKHR(Printer &p, std::string name, VkSurfaceFormatKHR &obj) { + p.ObjectStart(name); + DumpVkFormat(p, "format", obj.format, 6); + DumpVkColorSpaceKHR(p, "colorSpace", obj.colorSpace, 6); + p.ObjectEnd(); +} +void DumpVkSurfaceProtectedCapabilitiesKHR(Printer &p, std::string name, VkSurfaceProtectedCapabilitiesKHR &obj) { + p.ObjectStart(name); + p.PrintKeyBool("supportsProtected", obj.supportsProtected, 17); + p.ObjectEnd(); +} +pNextChainInfos get_chain_infos() { + pNextChainInfos infos; + infos.phys_device_props2 = { + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT, sizeof(VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT, sizeof(VkPhysicalDeviceConservativeRasterizationPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT, sizeof(VkPhysicalDeviceDescriptorIndexingPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT, sizeof(VkPhysicalDeviceDiscardRectanglePropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR, sizeof(VkPhysicalDeviceDriverPropertiesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT, sizeof(VkPhysicalDeviceExternalMemoryHostPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR, sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT, sizeof(VkPhysicalDeviceFragmentDensityMapPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, sizeof(VkPhysicalDeviceIDProperties)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT, sizeof(VkPhysicalDeviceInlineUniformBlockPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT, sizeof(VkPhysicalDeviceLineRasterizationPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, sizeof(VkPhysicalDeviceMaintenance3Properties)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, sizeof(VkPhysicalDeviceMultiviewProperties)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT, sizeof(VkPhysicalDevicePCIBusInfoPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, sizeof(VkPhysicalDevicePointClippingProperties)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES, sizeof(VkPhysicalDeviceProtectedMemoryProperties)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT, sizeof(VkPhysicalDeviceSampleLocationsPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT, sizeof(VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES, sizeof(VkPhysicalDeviceSubgroupProperties)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT, sizeof(VkPhysicalDeviceSubgroupSizeControlPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT, sizeof(VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT, sizeof(VkPhysicalDeviceTransformFeedbackPropertiesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT, sizeof(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT)}, + }; + infos.phys_device_mem_props2 = { + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT, sizeof(VkPhysicalDeviceMemoryBudgetPropertiesEXT)}, + }; + infos.phys_device_features2 = { + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, sizeof(VkPhysicalDevice16BitStorageFeatures)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, sizeof(VkPhysicalDeviceASTCDecodeFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, sizeof(VkPhysicalDeviceBufferDeviceAddressFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, sizeof(VkPhysicalDeviceConditionalRenderingFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, sizeof(VkPhysicalDeviceDepthClipEnableFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, sizeof(VkPhysicalDeviceDescriptorIndexingFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, sizeof(VkPhysicalDeviceFragmentDensityMapFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, sizeof(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, sizeof(VkPhysicalDeviceHostQueryResetFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR, sizeof(VkPhysicalDeviceImagelessFramebufferFeaturesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, sizeof(VkPhysicalDeviceIndexTypeUint8FeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, sizeof(VkPhysicalDeviceInlineUniformBlockFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, sizeof(VkPhysicalDeviceLineRasterizationFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, sizeof(VkPhysicalDeviceMemoryPriorityFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, sizeof(VkPhysicalDeviceMultiviewFeatures)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, sizeof(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, sizeof(VkPhysicalDeviceProtectedMemoryFeatures)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT, sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR, sizeof(VkPhysicalDeviceShaderAtomicInt64FeaturesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT, sizeof(VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, sizeof(VkPhysicalDeviceShaderDrawParametersFeatures)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR, sizeof(VkPhysicalDeviceShaderFloat16Int8FeaturesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT, sizeof(VkPhysicalDeviceSubgroupSizeControlFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, sizeof(VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT, sizeof(VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, sizeof(VkPhysicalDeviceTransformFeedbackFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR, sizeof(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, sizeof(VkPhysicalDeviceVariablePointersFeatures)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT, sizeof(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR, sizeof(VkPhysicalDeviceVulkanMemoryModelFeaturesKHR)}, + {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, sizeof(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT)}, + }; + infos.surface_capabilities2 = { + {VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR, sizeof(VkSharedPresentSurfaceCapabilitiesKHR)}, +#ifdef VK_USE_PLATFORM_WIN32_KHR + {VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT, sizeof(VkSurfaceCapabilitiesFullScreenExclusiveEXT)}, +#endif // VK_USE_PLATFORM_WIN32_KHR + {VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR, sizeof(VkSurfaceProtectedCapabilitiesKHR)}, + }; + infos.format_properties2 = { + {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, sizeof(VkDrmFormatModifierPropertiesListEXT)}, + }; + return infos; +} +void chain_iterator_phys_device_props2(Printer &p, AppGpu &gpu, void * place) { + while (place) { + struct VkStructureHeader *structure = (struct VkStructureHeader *)place; + p.SetSubHeader(); + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME)) { + VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT* props = (VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT*)structure; + DumpVkPhysicalDeviceBlendOperationAdvancedPropertiesEXT(p, "VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) { + VkPhysicalDeviceConservativeRasterizationPropertiesEXT* props = (VkPhysicalDeviceConservativeRasterizationPropertiesEXT*)structure; + DumpVkPhysicalDeviceConservativeRasterizationPropertiesEXT(p, "VkPhysicalDeviceConservativeRasterizationPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME)) { + VkPhysicalDeviceDepthStencilResolvePropertiesKHR* props = (VkPhysicalDeviceDepthStencilResolvePropertiesKHR*)structure; + DumpVkPhysicalDeviceDepthStencilResolvePropertiesKHR(p, "VkPhysicalDeviceDepthStencilResolvePropertiesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) { + VkPhysicalDeviceDescriptorIndexingPropertiesEXT* props = (VkPhysicalDeviceDescriptorIndexingPropertiesEXT*)structure; + DumpVkPhysicalDeviceDescriptorIndexingPropertiesEXT(p, "VkPhysicalDeviceDescriptorIndexingPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME)) { + VkPhysicalDeviceDiscardRectanglePropertiesEXT* props = (VkPhysicalDeviceDiscardRectanglePropertiesEXT*)structure; + DumpVkPhysicalDeviceDiscardRectanglePropertiesEXT(p, "VkPhysicalDeviceDiscardRectanglePropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) { + VkPhysicalDeviceDriverPropertiesKHR* props = (VkPhysicalDeviceDriverPropertiesKHR*)structure; + DumpVkPhysicalDeviceDriverPropertiesKHR(p, "VkPhysicalDeviceDriverPropertiesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME)) { + VkPhysicalDeviceExternalMemoryHostPropertiesEXT* props = (VkPhysicalDeviceExternalMemoryHostPropertiesEXT*)structure; + DumpVkPhysicalDeviceExternalMemoryHostPropertiesEXT(p, "VkPhysicalDeviceExternalMemoryHostPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME)) { + VkPhysicalDeviceFloatControlsPropertiesKHR* props = (VkPhysicalDeviceFloatControlsPropertiesKHR*)structure; + DumpVkPhysicalDeviceFloatControlsPropertiesKHR(p, "VkPhysicalDeviceFloatControlsPropertiesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME)) { + VkPhysicalDeviceFragmentDensityMapPropertiesEXT* props = (VkPhysicalDeviceFragmentDensityMapPropertiesEXT*)structure; + DumpVkPhysicalDeviceFragmentDensityMapPropertiesEXT(p, "VkPhysicalDeviceFragmentDensityMapPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES) { + VkPhysicalDeviceIDProperties* props = (VkPhysicalDeviceIDProperties*)structure; + DumpVkPhysicalDeviceIDProperties(p, "VkPhysicalDeviceIDProperties", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) { + VkPhysicalDeviceInlineUniformBlockPropertiesEXT* props = (VkPhysicalDeviceInlineUniformBlockPropertiesEXT*)structure; + DumpVkPhysicalDeviceInlineUniformBlockPropertiesEXT(p, "VkPhysicalDeviceInlineUniformBlockPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME)) { + VkPhysicalDeviceLineRasterizationPropertiesEXT* props = (VkPhysicalDeviceLineRasterizationPropertiesEXT*)structure; + DumpVkPhysicalDeviceLineRasterizationPropertiesEXT(p, "VkPhysicalDeviceLineRasterizationPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES) { + VkPhysicalDeviceMaintenance3Properties* props = (VkPhysicalDeviceMaintenance3Properties*)structure; + DumpVkPhysicalDeviceMaintenance3Properties(p, "VkPhysicalDeviceMaintenance3Properties", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES) { + VkPhysicalDeviceMultiviewProperties* props = (VkPhysicalDeviceMultiviewProperties*)structure; + DumpVkPhysicalDeviceMultiviewProperties(p, "VkPhysicalDeviceMultiviewProperties", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_PCI_BUS_INFO_EXTENSION_NAME)) { + VkPhysicalDevicePCIBusInfoPropertiesEXT* props = (VkPhysicalDevicePCIBusInfoPropertiesEXT*)structure; + DumpVkPhysicalDevicePCIBusInfoPropertiesEXT(p, "VkPhysicalDevicePCIBusInfoPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES) { + VkPhysicalDevicePointClippingProperties* props = (VkPhysicalDevicePointClippingProperties*)structure; + DumpVkPhysicalDevicePointClippingProperties(p, "VkPhysicalDevicePointClippingProperties", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES) { + VkPhysicalDeviceProtectedMemoryProperties* props = (VkPhysicalDeviceProtectedMemoryProperties*)structure; + DumpVkPhysicalDeviceProtectedMemoryProperties(p, "VkPhysicalDeviceProtectedMemoryProperties", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { + VkPhysicalDevicePushDescriptorPropertiesKHR* props = (VkPhysicalDevicePushDescriptorPropertiesKHR*)structure; + DumpVkPhysicalDevicePushDescriptorPropertiesKHR(p, "VkPhysicalDevicePushDescriptorPropertiesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME)) { + VkPhysicalDeviceSampleLocationsPropertiesEXT* props = (VkPhysicalDeviceSampleLocationsPropertiesEXT*)structure; + DumpVkPhysicalDeviceSampleLocationsPropertiesEXT(p, "VkPhysicalDeviceSampleLocationsPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME)) { + VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT* props = (VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT*)structure; + DumpVkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT(p, "VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES) { + VkPhysicalDeviceSubgroupProperties* props = (VkPhysicalDeviceSubgroupProperties*)structure; + DumpVkPhysicalDeviceSubgroupProperties(p, "VkPhysicalDeviceSubgroupProperties", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) { + VkPhysicalDeviceSubgroupSizeControlPropertiesEXT* props = (VkPhysicalDeviceSubgroupSizeControlPropertiesEXT*)structure; + DumpVkPhysicalDeviceSubgroupSizeControlPropertiesEXT(p, "VkPhysicalDeviceSubgroupSizeControlPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME)) { + VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT* props = (VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT*)structure; + DumpVkPhysicalDeviceTexelBufferAlignmentPropertiesEXT(p, "VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) { + VkPhysicalDeviceTransformFeedbackPropertiesEXT* props = (VkPhysicalDeviceTransformFeedbackPropertiesEXT*)structure; + DumpVkPhysicalDeviceTransformFeedbackPropertiesEXT(p, "VkPhysicalDeviceTransformFeedbackPropertiesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) { + VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT* props = (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT*)structure; + DumpVkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(p, "VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT", *props); + } + p.AddNewline(); + place = structure->pNext; + } +} +void chain_iterator_phys_device_mem_props2(Printer &p, AppGpu &gpu, void * place) { + while (place) { + struct VkStructureHeader *structure = (struct VkStructureHeader *)place; + p.SetSubHeader(); + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) { + VkPhysicalDeviceMemoryBudgetPropertiesEXT* props = (VkPhysicalDeviceMemoryBudgetPropertiesEXT*)structure; + DumpVkPhysicalDeviceMemoryBudgetPropertiesEXT(p, "VkPhysicalDeviceMemoryBudgetPropertiesEXT", *props); + } + p.AddNewline(); + place = structure->pNext; + } +} +void chain_iterator_phys_device_features2(Printer &p, AppGpu &gpu, void * place) { + while (place) { + struct VkStructureHeader *structure = (struct VkStructureHeader *)place; + p.SetSubHeader(); + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES) { + VkPhysicalDevice16BitStorageFeatures* props = (VkPhysicalDevice16BitStorageFeatures*)structure; + DumpVkPhysicalDevice16BitStorageFeatures(p, "VkPhysicalDevice16BitStorageFeatures", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_8BIT_STORAGE_EXTENSION_NAME)) { + VkPhysicalDevice8BitStorageFeaturesKHR* props = (VkPhysicalDevice8BitStorageFeaturesKHR*)structure; + DumpVkPhysicalDevice8BitStorageFeaturesKHR(p, "VkPhysicalDevice8BitStorageFeaturesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME)) { + VkPhysicalDeviceASTCDecodeFeaturesEXT* props = (VkPhysicalDeviceASTCDecodeFeaturesEXT*)structure; + DumpVkPhysicalDeviceASTCDecodeFeaturesEXT(p, "VkPhysicalDeviceASTCDecodeFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME)) { + VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* props = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)structure; + DumpVkPhysicalDeviceBlendOperationAdvancedFeaturesEXT(p, "VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) { + VkPhysicalDeviceBufferDeviceAddressFeaturesEXT* props = (VkPhysicalDeviceBufferDeviceAddressFeaturesEXT*)structure; + DumpVkPhysicalDeviceBufferDeviceAddressFeaturesEXT(p, "VkPhysicalDeviceBufferDeviceAddressFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME)) { + VkPhysicalDeviceConditionalRenderingFeaturesEXT* props = (VkPhysicalDeviceConditionalRenderingFeaturesEXT*)structure; + DumpVkPhysicalDeviceConditionalRenderingFeaturesEXT(p, "VkPhysicalDeviceConditionalRenderingFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME)) { + VkPhysicalDeviceDepthClipEnableFeaturesEXT* props = (VkPhysicalDeviceDepthClipEnableFeaturesEXT*)structure; + DumpVkPhysicalDeviceDepthClipEnableFeaturesEXT(p, "VkPhysicalDeviceDepthClipEnableFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) { + VkPhysicalDeviceDescriptorIndexingFeaturesEXT* props = (VkPhysicalDeviceDescriptorIndexingFeaturesEXT*)structure; + DumpVkPhysicalDeviceDescriptorIndexingFeaturesEXT(p, "VkPhysicalDeviceDescriptorIndexingFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME)) { + VkPhysicalDeviceFragmentDensityMapFeaturesEXT* props = (VkPhysicalDeviceFragmentDensityMapFeaturesEXT*)structure; + DumpVkPhysicalDeviceFragmentDensityMapFeaturesEXT(p, "VkPhysicalDeviceFragmentDensityMapFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME)) { + VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT* props = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)structure; + DumpVkPhysicalDeviceFragmentShaderInterlockFeaturesEXT(p, "VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) { + VkPhysicalDeviceHostQueryResetFeaturesEXT* props = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)structure; + DumpVkPhysicalDeviceHostQueryResetFeaturesEXT(p, "VkPhysicalDeviceHostQueryResetFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME)) { + VkPhysicalDeviceImagelessFramebufferFeaturesKHR* props = (VkPhysicalDeviceImagelessFramebufferFeaturesKHR*)structure; + DumpVkPhysicalDeviceImagelessFramebufferFeaturesKHR(p, "VkPhysicalDeviceImagelessFramebufferFeaturesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME)) { + VkPhysicalDeviceIndexTypeUint8FeaturesEXT* props = (VkPhysicalDeviceIndexTypeUint8FeaturesEXT*)structure; + DumpVkPhysicalDeviceIndexTypeUint8FeaturesEXT(p, "VkPhysicalDeviceIndexTypeUint8FeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) { + VkPhysicalDeviceInlineUniformBlockFeaturesEXT* props = (VkPhysicalDeviceInlineUniformBlockFeaturesEXT*)structure; + DumpVkPhysicalDeviceInlineUniformBlockFeaturesEXT(p, "VkPhysicalDeviceInlineUniformBlockFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME)) { + VkPhysicalDeviceLineRasterizationFeaturesEXT* props = (VkPhysicalDeviceLineRasterizationFeaturesEXT*)structure; + DumpVkPhysicalDeviceLineRasterizationFeaturesEXT(p, "VkPhysicalDeviceLineRasterizationFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME)) { + VkPhysicalDeviceMemoryPriorityFeaturesEXT* props = (VkPhysicalDeviceMemoryPriorityFeaturesEXT*)structure; + DumpVkPhysicalDeviceMemoryPriorityFeaturesEXT(p, "VkPhysicalDeviceMemoryPriorityFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES) { + VkPhysicalDeviceMultiviewFeatures* props = (VkPhysicalDeviceMultiviewFeatures*)structure; + DumpVkPhysicalDeviceMultiviewFeatures(p, "VkPhysicalDeviceMultiviewFeatures", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME)) { + VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR* props = (VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR*)structure; + DumpVkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR(p, "VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES) { + VkPhysicalDeviceProtectedMemoryFeatures* props = (VkPhysicalDeviceProtectedMemoryFeatures*)structure; + DumpVkPhysicalDeviceProtectedMemoryFeatures(p, "VkPhysicalDeviceProtectedMemoryFeatures", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES) { + VkPhysicalDeviceSamplerYcbcrConversionFeatures* props = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)structure; + DumpVkPhysicalDeviceSamplerYcbcrConversionFeatures(p, "VkPhysicalDeviceSamplerYcbcrConversionFeatures", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)) { + VkPhysicalDeviceScalarBlockLayoutFeaturesEXT* props = (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT*)structure; + DumpVkPhysicalDeviceScalarBlockLayoutFeaturesEXT(p, "VkPhysicalDeviceScalarBlockLayoutFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME)) { + VkPhysicalDeviceShaderAtomicInt64FeaturesKHR* props = (VkPhysicalDeviceShaderAtomicInt64FeaturesKHR*)structure; + DumpVkPhysicalDeviceShaderAtomicInt64FeaturesKHR(p, "VkPhysicalDeviceShaderAtomicInt64FeaturesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME)) { + VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT* props = (VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT*)structure; + DumpVkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT(p, "VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES) { + VkPhysicalDeviceShaderDrawParametersFeatures* props = (VkPhysicalDeviceShaderDrawParametersFeatures*)structure; + DumpVkPhysicalDeviceShaderDrawParametersFeatures(p, "VkPhysicalDeviceShaderDrawParametersFeatures", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) { + VkPhysicalDeviceShaderFloat16Int8FeaturesKHR* props = (VkPhysicalDeviceShaderFloat16Int8FeaturesKHR*)structure; + DumpVkPhysicalDeviceShaderFloat16Int8FeaturesKHR(p, "VkPhysicalDeviceShaderFloat16Int8FeaturesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) { + VkPhysicalDeviceSubgroupSizeControlFeaturesEXT* props = (VkPhysicalDeviceSubgroupSizeControlFeaturesEXT*)structure; + DumpVkPhysicalDeviceSubgroupSizeControlFeaturesEXT(p, "VkPhysicalDeviceSubgroupSizeControlFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME)) { + VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT* props = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)structure; + DumpVkPhysicalDeviceTexelBufferAlignmentFeaturesEXT(p, "VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME)) { + VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT* props = (VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT*)structure; + DumpVkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT(p, "VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) { + VkPhysicalDeviceTransformFeedbackFeaturesEXT* props = (VkPhysicalDeviceTransformFeedbackFeaturesEXT*)structure; + DumpVkPhysicalDeviceTransformFeedbackFeaturesEXT(p, "VkPhysicalDeviceTransformFeedbackFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME)) { + VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR* props = (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR*)structure; + DumpVkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR(p, "VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES) { + VkPhysicalDeviceVariablePointersFeatures* props = (VkPhysicalDeviceVariablePointersFeatures*)structure; + DumpVkPhysicalDeviceVariablePointersFeatures(p, "VkPhysicalDeviceVariablePointersFeatures", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) { + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT* props = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)structure; + DumpVkPhysicalDeviceVertexAttributeDivisorFeaturesEXT(p, "VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) { + VkPhysicalDeviceVulkanMemoryModelFeaturesKHR* props = (VkPhysicalDeviceVulkanMemoryModelFeaturesKHR*)structure; + DumpVkPhysicalDeviceVulkanMemoryModelFeaturesKHR(p, "VkPhysicalDeviceVulkanMemoryModelFeaturesKHR", *props); + } + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME)) { + VkPhysicalDeviceYcbcrImageArraysFeaturesEXT* props = (VkPhysicalDeviceYcbcrImageArraysFeaturesEXT*)structure; + DumpVkPhysicalDeviceYcbcrImageArraysFeaturesEXT(p, "VkPhysicalDeviceYcbcrImageArraysFeaturesEXT", *props); + } + p.AddNewline(); + place = structure->pNext; + } +} +void chain_iterator_surface_capabilities2(Printer &p, AppInstance &inst, AppGpu &gpu, void * place) { + while (place) { + struct VkStructureHeader *structure = (struct VkStructureHeader *)place; + p.SetSubHeader(); + if (structure->sType == VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) { + VkSharedPresentSurfaceCapabilitiesKHR* props = (VkSharedPresentSurfaceCapabilitiesKHR*)structure; + DumpVkSharedPresentSurfaceCapabilitiesKHR(p, "VkSharedPresentSurfaceCapabilitiesKHR", *props); + } +#ifdef VK_USE_PLATFORM_WIN32_KHR + if (structure->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT && + gpu.CheckPhysicalDeviceExtensionIncluded(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) { + VkSurfaceCapabilitiesFullScreenExclusiveEXT* props = (VkSurfaceCapabilitiesFullScreenExclusiveEXT*)structure; + DumpVkSurfaceCapabilitiesFullScreenExclusiveEXT(p, "VkSurfaceCapabilitiesFullScreenExclusiveEXT", *props); + } +#endif // VK_USE_PLATFORM_WIN32_KHR + if (structure->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR && + inst.CheckExtensionEnabled(VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME)) { + VkSurfaceProtectedCapabilitiesKHR* props = (VkSurfaceProtectedCapabilitiesKHR*)structure; + DumpVkSurfaceProtectedCapabilitiesKHR(p, "VkSurfaceProtectedCapabilitiesKHR", *props); + } + p.AddNewline(); + place = structure->pNext; + } +} +void chain_iterator_format_properties2(Printer &p, AppGpu &gpu, void * place) { + while (place) { + struct VkStructureHeader *structure = (struct VkStructureHeader *)place; + p.SetSubHeader(); + 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(); + place = structure->pNext; + } +} + diff --git a/vulkaninfo/macOS/vulkaninfo.cmake b/vulkaninfo/macOS/vulkaninfo.cmake index bf4d6698..7ce19612 100644 --- a/vulkaninfo/macOS/vulkaninfo.cmake +++ b/vulkaninfo/macOS/vulkaninfo.cmake @@ -1,6 +1,6 @@ # ~~~ -# Copyright (c) 2018 Valve Corporation -# Copyright (c) 2018 LunarG, Inc. +# Copyright (c) 2018-2019 Valve Corporation +# Copyright (c) 2018-2019 LunarG, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,11 +22,11 @@ # executable is a script that launches Terminal to see the output. add_executable(vulkaninfo-bundle MACOSX_BUNDLE - vulkaninfo.c + vulkaninfo.cpp ${CMAKE_BINARY_DIR}/staging-json/MoltenVK_icd.json ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo.sh ${CMAKE_CURRENT_SOURCE_DIR}/macOS/Resources/VulkanIcon.icns - ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo/metal_view.m + ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo/metal_view.mm ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo/metal_view.h) set_target_properties(vulkaninfo-bundle PROPERTIES OUTPUT_NAME @@ -35,8 +35,9 @@ set_target_properties(vulkaninfo-bundle ${CMAKE_CURRENT_SOURCE_DIR}/macOS/Info.plist) # We do this so vulkaninfo is linked to an individual library and NOT a framework. target_link_libraries(vulkaninfo-bundle ${Vulkan_LIBRARY} "-framework AppKit -framework QuartzCore") -target_include_directories(vulkaninfo-bundle PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo ${VulkanHeaders_INCLUDE_DIR}) +target_include_directories(vulkaninfo-bundle PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo ${CMAKE_BINARY_DIR}/vulkaninfo ${VulkanHeaders_INCLUDE_DIR}) add_dependencies(vulkaninfo-bundle MoltenVK_icd-staging-json) + set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/macOS/vulkaninfo.sh PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS") set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/macOS/Resources/VulkanIcon.icns PROPERTIES diff --git a/vulkaninfo/macOS/vulkaninfo/metal_view.m b/vulkaninfo/macOS/vulkaninfo/metal_view.mm index 0e086537..0e086537 100644 --- a/vulkaninfo/macOS/vulkaninfo/metal_view.m +++ b/vulkaninfo/macOS/vulkaninfo/metal_view.mm diff --git a/vulkaninfo/outputprinter.h b/vulkaninfo/outputprinter.h new file mode 100644 index 00000000..272b38fe --- /dev/null +++ b/vulkaninfo/outputprinter.h @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2019 The Khronos Group Inc. + * Copyright (c) 2019 Valve Corporation + * Copyright (c) 2019 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Charles Giessen <charles@lunarg.com> + * + */ + +#pragma once + +#include <iomanip> +#include <iostream> +#include <ostream> +#include <stack> +#include <sstream> +#include <string> + +#include <assert.h> + +std::string insert_quotes(std::string s) { return "\"" + s + "\""; } + +std::string to_string_16(uint8_t uid[16]) { + std::stringstream stream; + stream << std::setw(2) << std::hex; + stream << (int)uid[0] << (int)uid[1] << (int)uid[2] << (int)uid[3] << "-"; + stream << (int)uid[4] << (int)uid[5] << "-"; + stream << (int)uid[6] << (int)uid[7] << "-"; + stream << (int)uid[8] << (int)uid[9] << "-"; + stream << (int)uid[10] << (int)uid[11] << (int)uid[12] << (int)uid[13] << (int)uid[14] << (int)uid[15]; + + return stream.str(); +} + +std::string to_string_8(uint8_t uid[8]) { + std::stringstream stream; + stream << std::setw(2) << std::hex; + stream << (int)uid[0] << (int)uid[1] << (int)uid[2] << (int)uid[3] << "-"; + stream << (int)uid[4] << (int)uid[5] << (int)uid[6] << (int)uid[7]; + + return stream.str(); +} + +std::string VkVersionString(uint32_t version) { + uint32_t major = version >> 22; + uint32_t minor = (version >> 12) & 0x3ff; + uint32_t patch = version & 0xfff; + return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch); +} + +std::string VkVersionString(VulkanVersion v) { + return std::to_string(v.major) + "." + std::to_string(v.minor) + "." + std::to_string(v.patch); +} + +enum class OutputType { text, html, json }; + +class Printer { + public: + Printer(OutputType output_type, std::ostream &out, const uint32_t selected_gpu, const VulkanVersion vulkan_version) + : output_type(output_type), out(out) { + switch (output_type) { + case (OutputType::text): + out << "==========\n"; + out << "VULKANINFO\n"; + out << "==========\n\n"; + out << "Vulkan Instance Version: " << VkVersionString(vulkan_version) << "\n\n\n"; + + break; + case (OutputType::html): + out << "<!doctype html>\n"; + out << "<html lang='en'>\n"; + out << "\t<head>\n"; + out << "\t\t<title>vulkaninfo</title>\n"; + out << "\t\t<style>\n"; + out << "\t\thtml {\n"; + out << "\t\t\tbackground-color: #0b1e48;\n"; + out << "\t\t\tbackground-image: url(\"https://vulkan.lunarg.com/img/bg-starfield.jpg\");\n"; + out << "\t\t\tbackground-position: center;\n"; + out << "\t\t\t-webkit-background-size: cover;\n"; + out << "\t\t\t-moz-background-size: cover;\n"; + out << "\t\t\t-o-background-size: cover;\n"; + out << "\t\t\tbackground-size: cover;\n"; + out << "\t\t\tbackground-attachment: fixed;\n"; + out << "\t\t\tbackground-repeat: no-repeat;\n"; + out << "\t\t\theight: 100%;\n"; + out << "\t\t}\n"; + out << "\t\t#header {\n"; + out << "\t\t\tz-index: -1;\n"; + out << "\t\t}\n"; + out << "\t\t#header>img {\n"; + out << "\t\t\tposition: absolute;\n"; + out << "\t\t\twidth: 160px;\n"; + out << "\t\t\tmargin-left: -280px;\n"; + out << "\t\t\ttop: -10px;\n"; + out << "\t\t\tleft: 50%;\n"; + out << "\t\t}\n"; + out << "\t\t#header>h1 {\n"; + out << "\t\t\tfont-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;\n"; + out << "\t\t\tfont-size: 44px;\n"; + out << "\t\t\tfont-weight: 200;\n"; + out << "\t\t\ttext-shadow: 4px 4px 5px #000;\n"; + out << "\t\t\tcolor: #eee;\n"; + out << "\t\t\tposition: absolute;\n"; + out << "\t\t\twidth: 400px;\n"; + out << "\t\t\tmargin-left: -80px;\n"; + out << "\t\t\ttop: 8px;\n"; + out << "\t\t\tleft: 50%;\n"; + out << "\t\t}\n"; + out << "\t\tbody {\n"; + out << "\t\t\tfont-family: Consolas, monaco, monospace;\n"; + out << "\t\t\tfont-size: 14px;\n"; + out << "\t\t\tline-height: 20px;\n"; + out << "\t\t\tcolor: #eee;\n"; + out << "\t\t\theight: 100%;\n"; + out << "\t\t\tmargin: 0;\n"; + out << "\t\t\toverflow: hidden;\n"; + out << "\t\t}\n"; + out << "\t\t#wrapper {\n"; + out << "\t\t\tbackground-color: rgba(0, 0, 0, 0.7);\n"; + out << "\t\t\tborder: 1px solid #446;\n"; + out << "\t\t\tbox-shadow: 0px 0px 10px #000;\n"; + out << "\t\t\tpadding: 8px 12px;\n\n"; + out << "\t\t\tdisplay: inline-block;\n"; + out << "\t\t\tposition: absolute;\n"; + out << "\t\t\ttop: 80px;\n"; + out << "\t\t\tbottom: 25px;\n"; + out << "\t\t\tleft: 50px;\n"; + out << "\t\t\tright: 50px;\n"; + out << "\t\t\toverflow: auto;\n"; + out << "\t\t}\n"; + out << "\t\tdetails>details {\n"; + out << "\t\t\tmargin-left: 22px;\n"; + out << "\t\t}\n"; + out << "\t\tdetails>summary:only-child::-webkit-details-marker {\n"; + out << "\t\t\tdisplay: none;\n"; + out << "\t\t}\n"; + out << "\t\t.var, .type, .val {\n"; + out << "\t\t\tdisplay: inline;\n"; + out << "\t\t}\n"; + out << "\t\t.var {\n"; + out << "\t\t}\n"; + out << "\t\t.type {\n"; + out << "\t\t\tcolor: #acf;\n"; + out << "\t\t\tmargin: 0 12px;\n"; + out << "\t\t}\n"; + out << "\t\t.val {\n"; + out << "\t\t\tcolor: #afa;\n"; + out << "\t\t\tbackground: #222;\n"; + out << "\t\t\ttext-align: right;\n"; + out << "\t\t}\n"; + out << "\t\t</style>\n"; + out << "\t</head>\n"; + out << "\t<body>\n"; + out << "\t\t<div id='header'>\n"; + out << "\t\t\t<h1>vulkaninfo</h1>\n"; + out << "\t\t</div>\n"; + out << "\t\t<div id='wrapper'>\n"; + + out << "\t\t\t<details><summary>Vulkan Instance Version: <span class='val'>" << VkVersionString(vulkan_version) + << "</span></summary></details>\n\t\t\t<br />\n"; + indents += 3; + break; + case (OutputType::json): + out << "{\n"; + out << "\t\"$schema\": \"https://schema.khronos.org/vulkan/devsim_1_0_0.json#\",\n"; + out << "\t\"comments\": {\n"; + out << "\t\t\"desc\": \"JSON configuration file describing GPU " << selected_gpu + << ". Generated using the vulkaninfo program.\",\n"; + out << "\t\t\"vulkanApiVersion\": \"" << VkVersionString(vulkan_version) << "\"\n"; + out << "\t}"; + indents++; + is_first_item.push(false); + break; + default: + break; + } + } + ~Printer() { + switch (output_type) { + case (OutputType::text): + + break; + case (OutputType::html): + out << "\t\t</div>\n"; + out << "\t</body>\n"; + out << "</html>\n"; + break; + case (OutputType::json): + out << "\n}\n"; + indents--; + is_first_item.pop(); + assert(indents == 0); + assert(is_first_item.empty()); + break; + } + }; + + OutputType Type() { return output_type; } + + // Custom Formatting + // use by prepending with p.SetXXX().ObjectStart/ArrayStart + + Printer &SetHeader() { + set_next_header = true; + return *this; + } + + Printer &SetSubHeader() { + set_next_subheader = true; + return *this; + } + + Printer &SetOpenDetails() { + set_details_open = true; + return *this; + } + + Printer &SetTitleAsType() { + set_object_name_as_type = true; + return *this; + } + + Printer &SetAsType() { + set_as_type = true; + return *this; + } + + Printer &SetElementIndex(int index) { + element_index = index; + return *this; + } + + void ObjectStart(std::string object_name) { + switch (output_type) { + case (OutputType::text): { + out << std::string(indents, '\t') << object_name; + if (element_index != -1) { + out << "[" << element_index << "]"; + element_index = -1; + } + out << ":\n"; + int headersize = object_name.size() + 1; + if (element_index != -1) { + headersize += 1 + std::to_string(element_index).size(); + element_index = -1; + } + PrintHeaderUnderlines(headersize); + break; + } + case (OutputType::html): + out << std::string(indents, '\t'); + if (set_details_open) { + out << "<details open>"; + set_details_open = false; + } else { + out << "<details>"; + } + out << "<summary>"; + if (set_object_name_as_type) { + out << "<span class='type'>" << object_name << "</span>"; + set_object_name_as_type = false; + } else { + out << object_name; + } + if (element_index != -1) { + out << "[<span class='val'>" << element_index << "</span>]"; + element_index = -1; + } + out << "</summary>\n"; + break; + case (OutputType::json): + if (!is_first_item.top()) { + out << ",\n"; + } else { + is_first_item.top() = false; + } + out << std::string(indents, '\t'); + // Objects with no name are elements in an array of objects + if (object_name == "" || element_index != -1) { + out << "{\n"; + element_index = -1; + } else { + out << "\"" << object_name << "\": {\n"; + } + + is_first_item.push(true); + break; + default: + break; + } + indents++; + } + void ObjectEnd() { + indents--; + switch (output_type) { + case (OutputType::text): + + break; + case (OutputType::html): + out << std::string(indents, '\t') << "</details>\n"; + break; + case (OutputType::json): + out << "\n" << std::string(indents, '\t') << "}"; + is_first_item.pop(); + break; + default: + break; + } + } + void ArrayStart(std::string array_name, int element_count = 0) { + switch (output_type) { + case (OutputType::text): + out << std::string(indents, '\t') << array_name << ": " + << "count = " << element_count << "\n"; + PrintHeaderUnderlines(array_name.size() + 1); + break; + case (OutputType::html): + out << std::string(indents, '\t'); + if (set_details_open) { + out << "<details open>"; + set_details_open = false; + } else { + out << "<details>"; + } + out << "<summary>" << array_name << ": count = <span class='val'>" << element_count << "</span></summary>\n"; + break; + case (OutputType::json): + if (!is_first_item.top()) { + out << ",\n"; + } else { + is_first_item.top() = false; + } + out << std::string(indents, '\t') << "\"" << array_name << "\": " + << "[\n"; + is_first_item.push(true); + break; + default: + break; + } + indents++; + } + void ArrayEnd() { + indents--; + switch (output_type) { + case (OutputType::text): + + break; + case (OutputType::html): + out << std::string(indents, '\t') << "</details>\n"; + break; + case (OutputType::json): + out << "\n" << std::string(indents, '\t') << "]"; + is_first_item.pop(); + break; + default: + break; + } + } + + // For printing key-value pairs. + // min_key_width lines up the values listed + // value_description is for reference information and is displayed inside parenthesis after the value + template <typename T> + void PrintKeyValue(std::string key, T value, size_t min_key_width = 0, std::string value_description = "") { + switch (output_type) { + case (OutputType::text): + if (min_key_width > key.size()) { + out << std::string(indents, '\t') << key << std::string(min_key_width - key.size(), ' '); + } else { + out << std::string(indents, '\t') << key; + } + out << " = " << value; + if (value_description != "") { + out << " (" << value_description << ")"; + } + out << "\n"; + break; + case (OutputType::html): + out << std::string(indents, '\t') << "<details><summary>" << key; + if (min_key_width > key.size()) { + out << std::string(min_key_width - key.size(), ' '); + } + if (set_as_type) { + set_as_type = false; + out << " = <span class='type'>" << value << "</span>"; + } else { + out << " = <span class='val'>" << value << "</span>"; + } + if (value_description != "") { + out << " (<span class='val'>" << value_description << "</span>)"; + } + out << "</summary></details>\n"; + break; + case (OutputType::json): + if (!is_first_item.top()) { + out << ",\n"; + } else { + is_first_item.top() = false; + } + out << std::string(indents, '\t') << "\"" << key << "\": " << value; + default: + break; + } + } + + // For printing key - string pairs (necessary because of json) + void PrintKeyString(std::string key, std::string value, size_t min_key_width = 0, std::string value_description = "") { + switch (output_type) { + case (OutputType::text): + case (OutputType::html): + PrintKeyValue(key, value, min_key_width, value_description); + break; + case (OutputType::json): + PrintKeyValue(key, std::string("\"") + value + "\"", min_key_width, value_description); + break; + default: + break; + } + } + + // For printing key - string pairs (necessary because of json) + void PrintKeyBool(std::string key, bool value, size_t min_key_width = 0, std::string value_description = "") { + switch (output_type) { + case (OutputType::text): + case (OutputType::html): + PrintKeyValue(key, value ? "true" : "false", min_key_width, value_description); + break; + case (OutputType::json): + PrintKeyValue(key, value, min_key_width, value_description); + break; + default: + break; + } + } + + // print inside array + template <typename T> + void PrintElement(T element, std::string value_description = "") { + switch (output_type) { + case (OutputType::text): + out << std::string(indents, '\t') << element; + if (value_description != "") { + out << " (" << value_description << ")"; + } + out << "\n"; + break; + case (OutputType::html): + out << std::string(indents, '\t') << "<details><summary>"; + if (set_as_type) { + set_as_type = false; + out << "<span class='type'>" << element << "</span>"; + } else { + out << "<span class='val'>" << element << "</span>"; + } + if (value_description != "") { + out << " (<span class='val'>" << value_description << "</span>)"; + } + out << "</summary></details>\n"; + break; + case (OutputType::json): + if (!is_first_item.top()) { + out << ",\n"; + } else { + is_first_item.top() = false; + } + out << std::string(indents, '\t') << element; + break; + default: + break; + } + } + void PrintExtension(std::string ext_name, int revision, size_t min_width = 0) { + switch (output_type) { + case (OutputType::text): + out << std::string(indents, '\t') << ext_name << std::string(min_width - ext_name.size(), ' ') + << " : extension revision " << revision << "\n"; + break; + case (OutputType::html): + out << std::string(indents, '\t') << "<details><summary><span class='type'>" << ext_name << "</span>" + << std::string(min_width - ext_name.size(), ' ') << " : extension revision <span class='val'>" << revision + << "</span></summary></details>\n"; + break; + case (OutputType::json): + + break; + default: + break; + } + } + void AddNewline() { + switch (output_type) { + case (OutputType::text): + out << "\n"; + break; + default: + break; + } + } + void IndentIncrease() { + switch (output_type) { + case (OutputType::text): + indents++; + break; + default: + break; + } + } + void IndentDecrease() { + switch (output_type) { + case (OutputType::text): + indents--; + break; + default: + break; + } + } + + protected: + OutputType output_type; + std::ostream &out; + int indents = 0; + + // header, subheader + bool set_next_header = false; + bool set_next_subheader = false; + + // html coloring + bool set_as_type = false; + + // open <details> + bool set_details_open = false; + + // make object titles the color of types + bool set_object_name_as_type = false; + + // objects which are in an array + int element_index = -1; + + // json + std::stack<bool> is_first_item; + + // utility + void PrintHeaderUnderlines(int length) { + if (set_next_header) { + out << std::string(indents, '\t') << std::string(length, '=') << "\n"; + set_next_header = false; + } else if (set_next_subheader) { + out << std::string(indents, '\t') << std::string(length, '-') << "\n"; + set_next_subheader = false; + } + } +}; diff --git a/vulkaninfo/vulkaninfo.c b/vulkaninfo/vulkaninfo.c deleted file mode 100644 index 1ff64255..00000000 --- a/vulkaninfo/vulkaninfo.c +++ /dev/null @@ -1,6514 +0,0 @@ -/* - * Copyright (c) 2015-2019 The Khronos Group Inc. - * Copyright (c) 2015-2019 Valve Corporation - * Copyright (c) 2015-2019 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> - * Author: David Pinedo <david@lunarg.com> - * Author: Mark Lobodzinski <mark@lunarg.com> - * Author: Rene Lindsay <rene@lunarg.com> - * Author: Jeremy Kniager <jeremyk@lunarg.com> - * Author: Shannon McPherson <shannon@lunarg.com> - * Author: Bob Ellison <bob@lunarg.com> - */ - -#ifdef __GNUC__ -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200809L -#endif -#else -#define strndup(p, n) strdup(p) -#endif - -#include <assert.h> -#include <inttypes.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef _WIN32 -#include <fcntl.h> -#include <io.h> -#endif // _WIN32 - -#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) -#include <X11/Xutil.h> -#endif - -#if defined(VK_USE_PLATFORM_MACOS_MVK) -#include "metal_view.h" -#endif - -#include <vulkan/vulkan.h> - -#define ERR(err) fprintf(stderr, "%s:%d: failed with %s\n", __FILE__, __LINE__, VkResultString(err)); - -#ifdef _WIN32 - -#define strdup _strdup - -// Returns nonzero if the console is used only for this process. Will return -// zero if another process (such as cmd.exe) is also attached. -static int ConsoleIsExclusive(void) { - DWORD pids[2]; - DWORD num_pids = GetConsoleProcessList(pids, ARRAYSIZE(pids)); - return num_pids <= 1; -} - -#define WAIT_FOR_CONSOLE_DESTROY \ - do { \ - if (ConsoleIsExclusive()) Sleep(INFINITE); \ - } while (0) -#else -#define WAIT_FOR_CONSOLE_DESTROY -#endif - -#define ERR_EXIT(err) \ - do { \ - ERR(err); \ - fflush(stdout); \ - fflush(stderr); \ - WAIT_FOR_CONSOLE_DESTROY; \ - exit(-1); \ - } while (0) - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -#define MAX_QUEUE_TYPES 5 -#define APP_SHORT_NAME "vulkaninfo" - -static bool html_output = false; -static bool human_readable_output = true; -static bool json_output = false; -static uint32_t selected_gpu = 0; - -struct VkStructureHeader { - VkStructureType sType; - void *pNext; -}; - -struct pNextChainBuildingBlockInfo { - VkStructureType sType; - uint32_t mem_size; -}; - -struct LayerExtensionList { - VkLayerProperties layer_properties; - uint32_t extension_count; - VkExtensionProperties *extension_properties; -}; - -struct AppInstance; - -struct SurfaceExtensionNode { - struct SurfaceExtensionNode *next; - - const char *name; - void (*create_window)(struct AppInstance *); - VkSurfaceKHR (*create_surface)(struct AppInstance *); - void (*destroy_window)(struct AppInstance *); - VkSurfaceKHR surface; - VkBool32 supports_present; -}; - -struct AppInstance { - VkInstance instance; - uint32_t instance_version; - uint32_t vulkan_major; - uint32_t vulkan_minor; - uint32_t vulkan_patch; - - uint32_t global_layer_count; - struct LayerExtensionList *global_layers; - uint32_t global_extension_count; - VkExtensionProperties *global_extensions; // Instance Extensions - - const char **inst_extensions; - uint32_t inst_extensions_count; - - // Functions from vkGetInstanceProcAddress - PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; - PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; - PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR; - PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR; - PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; - PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT; - - struct SurfaceExtensionNode *surface_ext_infos_root; - - int width, height; - -#ifdef VK_USE_PLATFORM_WIN32_KHR - HINSTANCE h_instance; // Windows Instance - HWND h_wnd; // window handle -#endif -#ifdef VK_USE_PLATFORM_XCB_KHR - xcb_connection_t *xcb_connection; - xcb_screen_t *xcb_screen; - xcb_window_t xcb_window; -#endif -#ifdef VK_USE_PLATFORM_XLIB_KHR - Display *xlib_display; - Window xlib_window; -#endif -#ifdef VK_USE_PLATFORM_ANDROID_KHR // TODO - struct ANativeWindow *window; -#endif -#ifdef VK_USE_PLATFORM_MACOS_MVK - void *window; -#endif -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - struct wl_display *wayland_display; - struct wl_surface *wayland_surface; -#endif -}; - -struct MemResSupport { - struct MemImageSupport { - bool regular_supported, sparse_supported, transient_supported; - VkFormat format; - uint32_t regular_memtypes, sparse_memtypes, transient_memtypes; - } image[2][1 + 7]; - // TODO: buffers -}; - -struct AppGpu { - uint32_t id; - VkPhysicalDevice obj; - - VkPhysicalDeviceProperties props; - VkPhysicalDeviceProperties2KHR props2; - - uint32_t queue_count; - VkQueueFamilyProperties *queue_props; - VkQueueFamilyProperties2KHR *queue_props2; - VkDeviceQueueCreateInfo *queue_reqs; - - struct AppInstance *inst; - - VkPhysicalDeviceMemoryProperties memory_props; - VkPhysicalDeviceMemoryProperties2KHR memory_props2; - - struct MemResSupport mem_type_res_support; - - VkPhysicalDeviceFeatures features; - VkPhysicalDeviceFeatures2KHR features2; - VkPhysicalDevice limits; - - uint32_t device_extension_count; - VkExtensionProperties *device_extensions; - - VkDevice dev; - VkPhysicalDeviceFeatures enabled_features; -}; - -// return most severe flag only -static const char *DebugReportFlagString(const VkDebugReportFlagsEXT flags) { - switch (flags) { - case VK_DEBUG_REPORT_ERROR_BIT_EXT: - return "ERROR"; - case VK_DEBUG_REPORT_WARNING_BIT_EXT: - return "WARNING"; - case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT: - return "PERF"; - case VK_DEBUG_REPORT_INFORMATION_BIT_EXT: - return "INFO"; - case VK_DEBUG_REPORT_DEBUG_BIT_EXT: - return "DEBUG"; - default: - return "UNKNOWN"; - } -} - -static VKAPI_ATTR VkBool32 VKAPI_CALL DbgCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, - uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, - const char *pMsg, void *pUserData) { - fprintf(stderr, "%s: [%s] Code %d : %s\n", DebugReportFlagString(msgFlags), pLayerPrefix, msgCode, pMsg); - fflush(stderr); - - // True is reserved for layer developers, and MAY mean calls are not distributed down the layer chain after validation error. - // False SHOULD always be returned by apps: - return VK_FALSE; -} - -static const char *VkResultString(VkResult err) { - switch (err) { -#define STR(r) \ - case r: \ - return #r - STR(VK_SUCCESS); - STR(VK_NOT_READY); - STR(VK_TIMEOUT); - STR(VK_EVENT_SET); - STR(VK_EVENT_RESET); - STR(VK_INCOMPLETE); - STR(VK_ERROR_OUT_OF_HOST_MEMORY); - STR(VK_ERROR_OUT_OF_DEVICE_MEMORY); - STR(VK_ERROR_INITIALIZATION_FAILED); - STR(VK_ERROR_DEVICE_LOST); - STR(VK_ERROR_MEMORY_MAP_FAILED); - STR(VK_ERROR_LAYER_NOT_PRESENT); - STR(VK_ERROR_EXTENSION_NOT_PRESENT); - STR(VK_ERROR_FEATURE_NOT_PRESENT); - STR(VK_ERROR_INCOMPATIBLE_DRIVER); - STR(VK_ERROR_TOO_MANY_OBJECTS); - STR(VK_ERROR_FORMAT_NOT_SUPPORTED); - STR(VK_ERROR_FRAGMENTED_POOL); - STR(VK_ERROR_OUT_OF_POOL_MEMORY); - STR(VK_ERROR_INVALID_EXTERNAL_HANDLE); - STR(VK_ERROR_SURFACE_LOST_KHR); - STR(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); - STR(VK_SUBOPTIMAL_KHR); - STR(VK_ERROR_OUT_OF_DATE_KHR); - STR(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR); - STR(VK_ERROR_VALIDATION_FAILED_EXT); - STR(VK_ERROR_INVALID_SHADER_NV); - STR(VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT); - STR(VK_ERROR_FRAGMENTATION_EXT); - STR(VK_ERROR_NOT_PERMITTED_EXT); -#undef STR - default: - return "UNKNOWN_RESULT"; - } -} - -static const char *VkPhysicalDeviceTypeString(VkPhysicalDeviceType type) { - switch (type) { -#define STR(r) \ - case VK_PHYSICAL_DEVICE_TYPE_##r: \ - return #r - STR(OTHER); - STR(INTEGRATED_GPU); - STR(DISCRETE_GPU); - STR(VIRTUAL_GPU); - STR(CPU); -#undef STR - default: - return "UNKNOWN_DEVICE"; - } -} - -static const char *VkTilingString(const VkImageTiling tiling) { - switch (tiling) { -#define STR(r) \ - case VK_IMAGE_TILING_##r: \ - return #r - STR(OPTIMAL); - STR(LINEAR); - STR(DRM_FORMAT_MODIFIER_EXT); -#undef STR - default: - return "UNKNOWN_TILING"; - } -} - -static const char *VkColorSpaceString(VkColorSpaceKHR cs) { - switch (cs) { -#define STR(r) \ - case VK_COLOR_SPACE_##r: \ - return #r - STR(SRGB_NONLINEAR_KHR); - STR(DISPLAY_P3_NONLINEAR_EXT); - STR(EXTENDED_SRGB_LINEAR_EXT); - STR(DISPLAY_P3_LINEAR_EXT); - STR(DCI_P3_NONLINEAR_EXT); - STR(BT709_LINEAR_EXT); - STR(BT709_NONLINEAR_EXT); - STR(BT2020_LINEAR_EXT); - STR(HDR10_ST2084_EXT); - STR(DOLBYVISION_EXT); - STR(HDR10_HLG_EXT); - STR(ADOBERGB_LINEAR_EXT); - STR(ADOBERGB_NONLINEAR_EXT); - STR(PASS_THROUGH_EXT); - STR(EXTENDED_SRGB_NONLINEAR_EXT); - STR(DISPLAY_NATIVE_AMD); -#undef STR - default: - return "UNKNOWN_COLOR_SPACE"; - } -} - -static const char *VkFormatString(VkFormat fmt) { - switch (fmt) { -#define STR(r) \ - case VK_FORMAT_##r: \ - return #r - STR(UNDEFINED); - STR(R4G4_UNORM_PACK8); - STR(R4G4B4A4_UNORM_PACK16); - STR(B4G4R4A4_UNORM_PACK16); - STR(R5G6B5_UNORM_PACK16); - STR(B5G6R5_UNORM_PACK16); - STR(R5G5B5A1_UNORM_PACK16); - STR(B5G5R5A1_UNORM_PACK16); - STR(A1R5G5B5_UNORM_PACK16); - STR(R8_UNORM); - STR(R8_SNORM); - STR(R8_USCALED); - STR(R8_SSCALED); - STR(R8_UINT); - STR(R8_SINT); - STR(R8_SRGB); - STR(R8G8_UNORM); - STR(R8G8_SNORM); - STR(R8G8_USCALED); - STR(R8G8_SSCALED); - STR(R8G8_UINT); - STR(R8G8_SINT); - STR(R8G8_SRGB); - STR(R8G8B8_UNORM); - STR(R8G8B8_SNORM); - STR(R8G8B8_USCALED); - STR(R8G8B8_SSCALED); - STR(R8G8B8_UINT); - STR(R8G8B8_SINT); - STR(R8G8B8_SRGB); - STR(B8G8R8_UNORM); - STR(B8G8R8_SNORM); - STR(B8G8R8_USCALED); - STR(B8G8R8_SSCALED); - STR(B8G8R8_UINT); - STR(B8G8R8_SINT); - STR(B8G8R8_SRGB); - STR(R8G8B8A8_UNORM); - STR(R8G8B8A8_SNORM); - STR(R8G8B8A8_USCALED); - STR(R8G8B8A8_SSCALED); - STR(R8G8B8A8_UINT); - STR(R8G8B8A8_SINT); - STR(R8G8B8A8_SRGB); - STR(B8G8R8A8_UNORM); - STR(B8G8R8A8_SNORM); - STR(B8G8R8A8_USCALED); - STR(B8G8R8A8_SSCALED); - STR(B8G8R8A8_UINT); - STR(B8G8R8A8_SINT); - STR(B8G8R8A8_SRGB); - STR(A8B8G8R8_UNORM_PACK32); - STR(A8B8G8R8_SNORM_PACK32); - STR(A8B8G8R8_USCALED_PACK32); - STR(A8B8G8R8_SSCALED_PACK32); - STR(A8B8G8R8_UINT_PACK32); - STR(A8B8G8R8_SINT_PACK32); - STR(A8B8G8R8_SRGB_PACK32); - STR(A2R10G10B10_UNORM_PACK32); - STR(A2R10G10B10_SNORM_PACK32); - STR(A2R10G10B10_USCALED_PACK32); - STR(A2R10G10B10_SSCALED_PACK32); - STR(A2R10G10B10_UINT_PACK32); - STR(A2R10G10B10_SINT_PACK32); - STR(A2B10G10R10_UNORM_PACK32); - STR(A2B10G10R10_SNORM_PACK32); - STR(A2B10G10R10_USCALED_PACK32); - STR(A2B10G10R10_SSCALED_PACK32); - STR(A2B10G10R10_UINT_PACK32); - STR(A2B10G10R10_SINT_PACK32); - STR(R16_UNORM); - STR(R16_SNORM); - STR(R16_USCALED); - STR(R16_SSCALED); - STR(R16_UINT); - STR(R16_SINT); - STR(R16_SFLOAT); - STR(R16G16_UNORM); - STR(R16G16_SNORM); - STR(R16G16_USCALED); - STR(R16G16_SSCALED); - STR(R16G16_UINT); - STR(R16G16_SINT); - STR(R16G16_SFLOAT); - STR(R16G16B16_UNORM); - STR(R16G16B16_SNORM); - STR(R16G16B16_USCALED); - STR(R16G16B16_SSCALED); - STR(R16G16B16_UINT); - STR(R16G16B16_SINT); - STR(R16G16B16_SFLOAT); - STR(R16G16B16A16_UNORM); - STR(R16G16B16A16_SNORM); - STR(R16G16B16A16_USCALED); - STR(R16G16B16A16_SSCALED); - STR(R16G16B16A16_UINT); - STR(R16G16B16A16_SINT); - STR(R16G16B16A16_SFLOAT); - STR(R32_UINT); - STR(R32_SINT); - STR(R32_SFLOAT); - STR(R32G32_UINT); - STR(R32G32_SINT); - STR(R32G32_SFLOAT); - STR(R32G32B32_UINT); - STR(R32G32B32_SINT); - STR(R32G32B32_SFLOAT); - STR(R32G32B32A32_UINT); - STR(R32G32B32A32_SINT); - STR(R32G32B32A32_SFLOAT); - STR(R64_UINT); - STR(R64_SINT); - STR(R64_SFLOAT); - STR(R64G64_UINT); - STR(R64G64_SINT); - STR(R64G64_SFLOAT); - STR(R64G64B64_UINT); - STR(R64G64B64_SINT); - STR(R64G64B64_SFLOAT); - STR(R64G64B64A64_UINT); - STR(R64G64B64A64_SINT); - STR(R64G64B64A64_SFLOAT); - STR(B10G11R11_UFLOAT_PACK32); - STR(E5B9G9R9_UFLOAT_PACK32); - STR(D16_UNORM); - STR(X8_D24_UNORM_PACK32); - STR(D32_SFLOAT); - STR(S8_UINT); - STR(D16_UNORM_S8_UINT); - STR(D24_UNORM_S8_UINT); - STR(D32_SFLOAT_S8_UINT); - STR(BC1_RGB_UNORM_BLOCK); - STR(BC1_RGB_SRGB_BLOCK); - STR(BC1_RGBA_UNORM_BLOCK); - STR(BC1_RGBA_SRGB_BLOCK); - STR(BC2_UNORM_BLOCK); - STR(BC2_SRGB_BLOCK); - STR(BC3_UNORM_BLOCK); - STR(BC3_SRGB_BLOCK); - STR(BC4_UNORM_BLOCK); - STR(BC4_SNORM_BLOCK); - STR(BC5_UNORM_BLOCK); - STR(BC5_SNORM_BLOCK); - STR(BC6H_UFLOAT_BLOCK); - STR(BC6H_SFLOAT_BLOCK); - STR(BC7_UNORM_BLOCK); - STR(BC7_SRGB_BLOCK); - STR(ETC2_R8G8B8_UNORM_BLOCK); - STR(ETC2_R8G8B8_SRGB_BLOCK); - STR(ETC2_R8G8B8A1_UNORM_BLOCK); - STR(ETC2_R8G8B8A1_SRGB_BLOCK); - STR(ETC2_R8G8B8A8_UNORM_BLOCK); - STR(ETC2_R8G8B8A8_SRGB_BLOCK); - STR(EAC_R11_UNORM_BLOCK); - STR(EAC_R11_SNORM_BLOCK); - STR(EAC_R11G11_UNORM_BLOCK); - STR(EAC_R11G11_SNORM_BLOCK); - STR(ASTC_4x4_UNORM_BLOCK); - STR(ASTC_4x4_SRGB_BLOCK); - STR(ASTC_5x4_UNORM_BLOCK); - STR(ASTC_5x4_SRGB_BLOCK); - STR(ASTC_5x5_UNORM_BLOCK); - STR(ASTC_5x5_SRGB_BLOCK); - STR(ASTC_6x5_UNORM_BLOCK); - STR(ASTC_6x5_SRGB_BLOCK); - STR(ASTC_6x6_UNORM_BLOCK); - STR(ASTC_6x6_SRGB_BLOCK); - STR(ASTC_8x5_UNORM_BLOCK); - STR(ASTC_8x5_SRGB_BLOCK); - STR(ASTC_8x6_UNORM_BLOCK); - STR(ASTC_8x6_SRGB_BLOCK); - STR(ASTC_8x8_UNORM_BLOCK); - STR(ASTC_8x8_SRGB_BLOCK); - STR(ASTC_10x5_UNORM_BLOCK); - STR(ASTC_10x5_SRGB_BLOCK); - STR(ASTC_10x6_UNORM_BLOCK); - STR(ASTC_10x6_SRGB_BLOCK); - STR(ASTC_10x8_UNORM_BLOCK); - STR(ASTC_10x8_SRGB_BLOCK); - STR(ASTC_10x10_UNORM_BLOCK); - STR(ASTC_10x10_SRGB_BLOCK); - STR(ASTC_12x10_UNORM_BLOCK); - STR(ASTC_12x10_SRGB_BLOCK); - STR(ASTC_12x12_UNORM_BLOCK); - STR(ASTC_12x12_SRGB_BLOCK); - STR(G8B8G8R8_422_UNORM); - STR(B8G8R8G8_422_UNORM); - STR(G8_B8_R8_3PLANE_420_UNORM); - STR(G8_B8R8_2PLANE_420_UNORM); - STR(G8_B8_R8_3PLANE_422_UNORM); - STR(G8_B8R8_2PLANE_422_UNORM); - STR(G8_B8_R8_3PLANE_444_UNORM); - STR(R10X6_UNORM_PACK16); - STR(R10X6G10X6_UNORM_2PACK16); - STR(R10X6G10X6B10X6A10X6_UNORM_4PACK16); - STR(G10X6B10X6G10X6R10X6_422_UNORM_4PACK16); - STR(B10X6G10X6R10X6G10X6_422_UNORM_4PACK16); - STR(G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16); - STR(G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16); - STR(G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16); - STR(G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16); - STR(G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16); - STR(R12X4_UNORM_PACK16); - STR(R12X4G12X4_UNORM_2PACK16); - STR(R12X4G12X4B12X4A12X4_UNORM_4PACK16); - STR(G12X4B12X4G12X4R12X4_422_UNORM_4PACK16); - STR(B12X4G12X4R12X4G12X4_422_UNORM_4PACK16); - STR(G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16); - STR(G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16); - STR(G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16); - STR(G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16); - STR(G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16); - STR(G16B16G16R16_422_UNORM); - STR(B16G16R16G16_422_UNORM); - STR(G16_B16_R16_3PLANE_420_UNORM); - STR(G16_B16R16_2PLANE_420_UNORM); - STR(G16_B16_R16_3PLANE_422_UNORM); - STR(G16_B16R16_2PLANE_422_UNORM); - STR(G16_B16_R16_3PLANE_444_UNORM); - STR(PVRTC1_2BPP_UNORM_BLOCK_IMG); - STR(PVRTC1_4BPP_UNORM_BLOCK_IMG); - STR(PVRTC2_2BPP_UNORM_BLOCK_IMG); - STR(PVRTC2_4BPP_UNORM_BLOCK_IMG); - STR(PVRTC1_2BPP_SRGB_BLOCK_IMG); - STR(PVRTC1_4BPP_SRGB_BLOCK_IMG); - STR(PVRTC2_2BPP_SRGB_BLOCK_IMG); - STR(PVRTC2_4BPP_SRGB_BLOCK_IMG); -#undef STR - default: - return "UNKNOWN_FORMAT"; - } -} - -#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ - defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) -static const char *VkPresentModeString(VkPresentModeKHR mode) { - switch (mode) { -#define STR(r) \ - case VK_PRESENT_MODE_##r: \ - return #r - STR(IMMEDIATE_KHR); - STR(MAILBOX_KHR); - STR(FIFO_KHR); - STR(FIFO_RELAXED_KHR); - STR(SHARED_DEMAND_REFRESH_KHR); - STR(SHARED_CONTINUOUS_REFRESH_KHR); -#undef STR - default: - return "UNKNOWN_FORMAT"; - } -} -#endif - -static const char *VkShaderFloatControlsIndependenceString(const VkShaderFloatControlsIndependenceKHR indep) { - switch (indep) { -#define STR(r) \ - case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_##r: \ - return #r - STR(32_BIT_ONLY_KHR); - STR(ALL_KHR); - STR(NONE_KHR); -#undef STR - default: - return "UNKNOWN_INDEPENDENCE"; - } -} - -static bool CheckExtensionEnabled(const char *extension_to_check, const char **extension_list, uint32_t extension_count) { - for (uint32_t i = 0; i < extension_count; ++i) { - if (!strncmp(extension_to_check, extension_list[i], VK_MAX_EXTENSION_NAME_SIZE)) { - return true; - } - } - return false; -} - -static bool CheckPhysicalDeviceExtensionIncluded(const char *extension_to_check, VkExtensionProperties *extension_list, - uint32_t extension_count) { - for (uint32_t i = 0; i < extension_count; ++i) { - if (!strncmp(extension_to_check, extension_list[i].extensionName, VK_MAX_EXTENSION_NAME_SIZE)) { - return true; - } - } - return false; -} - -static void buildpNextChain(struct VkStructureHeader *first, const struct pNextChainBuildingBlockInfo *chain_info, - uint32_t chain_info_len) { - struct VkStructureHeader *place = first; - - for (uint32_t i = 0; i < chain_info_len; i++) { - place->pNext = malloc(chain_info[i].mem_size); - if (!place->pNext) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - memset(place->pNext, 0, chain_info[i].mem_size); - place = place->pNext; - place->sType = chain_info[i].sType; - } - - place->pNext = NULL; -} - -static void freepNextChain(struct VkStructureHeader *first) { - struct VkStructureHeader *place = first; - struct VkStructureHeader *next = NULL; - - while (place) { - next = place->pNext; - free(place); - place = next; - } -} - -static void ExtractVersion(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) { - *major = version >> 22; - *minor = (version >> 12) & 0x3ff; - *patch = version & 0xfff; -} - -static void AppGetPhysicalDeviceLayerExtensions(struct AppGpu *gpu, char *layer_name, uint32_t *extension_count, - VkExtensionProperties **extension_properties) { - VkResult err; - uint32_t ext_count = 0; - VkExtensionProperties *ext_ptr = NULL; - - /* repeat get until VK_INCOMPLETE goes away */ - do { - err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, NULL); - if (err) ERR_EXIT(err); - - if (ext_ptr) { - free(ext_ptr); - } - ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); - err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, ext_ptr); - } while (err == VK_INCOMPLETE); - if (err) ERR_EXIT(err); - - *extension_count = ext_count; - *extension_properties = ext_ptr; -} - -static void AppGetGlobalLayerExtensions(char *layer_name, uint32_t *extension_count, VkExtensionProperties **extension_properties) { - VkResult err; - uint32_t ext_count = 0; - VkExtensionProperties *ext_ptr = NULL; - - /* repeat get until VK_INCOMPLETE goes away */ - do { - // gets the extension count if the last parameter is NULL - err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, NULL); - if (err) ERR_EXIT(err); - - if (ext_ptr) { - free(ext_ptr); - } - ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); - // gets the extension properties if the last parameter is not NULL - err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_ptr); - } while (err == VK_INCOMPLETE); - if (err) ERR_EXIT(err); - *extension_count = ext_count; - *extension_properties = ext_ptr; -} - -/* Gets a list of layer and instance extensions */ -static void AppGetInstanceExtensions(struct AppInstance *inst) { - VkResult err; - - uint32_t count = 0; - - /* Scan layers */ - VkLayerProperties *global_layer_properties = NULL; - struct LayerExtensionList *global_layers = NULL; - - do { - err = vkEnumerateInstanceLayerProperties(&count, NULL); - if (err) ERR_EXIT(err); - - if (global_layer_properties) { - free(global_layer_properties); - } - global_layer_properties = malloc(sizeof(VkLayerProperties) * count); - assert(global_layer_properties); - - if (global_layers) { - free(global_layers); - } - global_layers = malloc(sizeof(struct LayerExtensionList) * count); - assert(global_layers); - - err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties); - } while (err == VK_INCOMPLETE); - if (err) ERR_EXIT(err); - - inst->global_layer_count = count; - inst->global_layers = global_layers; - - for (uint32_t i = 0; i < inst->global_layer_count; ++i) { - VkLayerProperties *src_info = &global_layer_properties[i]; - struct LayerExtensionList *dst_info = &inst->global_layers[i]; - memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); - - // Save away layer extension info for report - // Gets layer extensions, if first parameter is not NULL - AppGetGlobalLayerExtensions(src_info->layerName, &dst_info->extension_count, &dst_info->extension_properties); - } - free(global_layer_properties); - - // Collect global extensions - inst->global_extension_count = 0; - // Gets instance extensions, if no layer was specified in the first - // paramteter - AppGetGlobalLayerExtensions(NULL, &inst->global_extension_count, &inst->global_extensions); -} - -// Prints opening code for html output file -void PrintHtmlHeader(FILE *out) { - fprintf(out, "<!doctype html>\n"); - fprintf(out, "<html lang='en'>\n"); - fprintf(out, "\t<head>\n"); - fprintf(out, "\t\t<title>vulkaninfo</title>\n"); - fprintf(out, "\t\t<style>\n"); - fprintf(out, "\t\thtml {\n"); - fprintf(out, "\t\t\tbackground-color: #0b1e48;\n"); - fprintf(out, "\t\t\tbackground-image: url(\"https://vulkan.lunarg.com/img/bg-starfield.jpg\");\n"); - fprintf(out, "\t\t\tbackground-position: center;\n"); - fprintf(out, "\t\t\t-webkit-background-size: cover;\n"); - fprintf(out, "\t\t\t-moz-background-size: cover;\n"); - fprintf(out, "\t\t\t-o-background-size: cover;\n"); - fprintf(out, "\t\t\tbackground-size: cover;\n"); - fprintf(out, "\t\t\tbackground-attachment: fixed;\n"); - fprintf(out, "\t\t\tbackground-repeat: no-repeat;\n"); - fprintf(out, "\t\t\theight: 100%%;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t#header {\n"); - fprintf(out, "\t\t\tz-index: -1;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t#header>img {\n"); - fprintf(out, "\t\t\tposition: absolute;\n"); - fprintf(out, "\t\t\twidth: 160px;\n"); - fprintf(out, "\t\t\tmargin-left: -280px;\n"); - fprintf(out, "\t\t\ttop: -10px;\n"); - fprintf(out, "\t\t\tleft: 50%%;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t#header>h1 {\n"); - fprintf(out, "\t\t\tfont-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;\n"); - fprintf(out, "\t\t\tfont-size: 44px;\n"); - fprintf(out, "\t\t\tfont-weight: 200;\n"); - fprintf(out, "\t\t\ttext-shadow: 4px 4px 5px #000;\n"); - fprintf(out, "\t\t\tcolor: #eee;\n"); - fprintf(out, "\t\t\tposition: absolute;\n"); - fprintf(out, "\t\t\twidth: 400px;\n"); - fprintf(out, "\t\t\tmargin-left: -80px;\n"); - fprintf(out, "\t\t\ttop: 8px;\n"); - fprintf(out, "\t\t\tleft: 50%%;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\tbody {\n"); - fprintf(out, "\t\t\tfont-family: Consolas, monaco, monospace;\n"); - fprintf(out, "\t\t\tfont-size: 14px;\n"); - fprintf(out, "\t\t\tline-height: 20px;\n"); - fprintf(out, "\t\t\tcolor: #eee;\n"); - fprintf(out, "\t\t\theight: 100%%;\n"); - fprintf(out, "\t\t\tmargin: 0;\n"); - fprintf(out, "\t\t\toverflow: hidden;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t#wrapper {\n"); - fprintf(out, "\t\t\tbackground-color: rgba(0, 0, 0, 0.7);\n"); - fprintf(out, "\t\t\tborder: 1px solid #446;\n"); - fprintf(out, "\t\t\tbox-shadow: 0px 0px 10px #000;\n"); - fprintf(out, "\t\t\tpadding: 8px 12px;\n\n"); - fprintf(out, "\t\t\tdisplay: inline-block;\n"); - fprintf(out, "\t\t\tposition: absolute;\n"); - fprintf(out, "\t\t\ttop: 80px;\n"); - fprintf(out, "\t\t\tbottom: 25px;\n"); - fprintf(out, "\t\t\tleft: 50px;\n"); - fprintf(out, "\t\t\tright: 50px;\n"); - fprintf(out, "\t\t\toverflow: auto;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\tdetails>details {\n"); - fprintf(out, "\t\t\tmargin-left: 22px;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\tdetails>summary:only-child::-webkit-details-marker {\n"); - fprintf(out, "\t\t\tdisplay: none;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t.var, .type, .val {\n"); - fprintf(out, "\t\t\tdisplay: inline;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t.var {\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t.type {\n"); - fprintf(out, "\t\t\tcolor: #acf;\n"); - fprintf(out, "\t\t\tmargin: 0 12px;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t.val {\n"); - fprintf(out, "\t\t\tcolor: #afa;\n"); - fprintf(out, "\t\t\tbackground: #222;\n"); - fprintf(out, "\t\t\ttext-align: right;\n"); - fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t</style>\n"); - fprintf(out, "\t</head>\n"); - fprintf(out, "\t<body>\n"); - fprintf(out, "\t\t<div id='header'>\n"); - fprintf(out, "\t\t\t<h1>vulkaninfo</h1>\n"); - fprintf(out, "\t\t</div>\n"); - fprintf(out, "\t\t<div id='wrapper'>\n"); -} - -// Prints closing code for html output file -void PrintHtmlFooter(FILE *out) { - fprintf(out, "\t\t</div>\n"); - fprintf(out, "\t</body>\n"); - fprintf(out, "</html>"); -} - -// Prints opening code for json output file -void PrintJsonHeader(const int vulkan_major, const int vulkan_minor, const int vulkan_patch) { - printf("{\n"); - printf("\t\"$schema\": \"https://schema.khronos.org/vulkan/devsim_1_0_0.json#\",\n"); - printf("\t\"comments\": {\n"); - printf("\t\t\"desc\": \"JSON configuration file describing GPU %u. Generated using the vulkaninfo program.\",\n", selected_gpu); - printf("\t\t\"vulkanApiVersion\": \"%d.%d.%d\"\n", vulkan_major, vulkan_minor, vulkan_patch); - printf("\t}"); -} - -// Checks if current argument specifies json output, interprets/updates gpu selection -bool CheckForJsonOption(const char *arg) { - if (strncmp("--json", arg, 6) == 0 || strcmp(arg, "-j") == 0) { - if (strlen(arg) > 7 && strncmp("--json=", arg, 7) == 0) { - selected_gpu = strtol(arg + 7, NULL, 10); - } - human_readable_output = false; - json_output = true; - return true; - } else { - return false; - } -} - -static void AppCompileInstanceExtensionsToEnable(struct AppInstance *inst) { - // Get all supported Instance extensions (excl. layer-provided ones) - inst->inst_extensions_count = inst->global_extension_count; - inst->inst_extensions = malloc(sizeof(char *) * inst->inst_extensions_count); - if (!inst->inst_extensions) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - - for (uint32_t i = 0; i < inst->global_extension_count; ++i) { - inst->inst_extensions[i] = inst->global_extensions[i].extensionName; - } -} - -static void AppLoadInstanceCommands(struct AppInstance *inst) { -#define LOAD_INSTANCE_VK_CMD(cmd) inst->cmd = (PFN_##cmd)vkGetInstanceProcAddr(inst->instance, #cmd) - - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceSupportKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormatsKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormats2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfacePresentModesKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFormatProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceQueueFamilyProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFeatures2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceMemoryProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2EXT); - -#undef LOAD_INSTANCE_VK_CMD -} - -static void AppCreateInstance(struct AppInstance *inst) { - PFN_vkEnumerateInstanceVersion enumerate_instance_version = - (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion"); - - if (!enumerate_instance_version) { - inst->instance_version = VK_API_VERSION_1_0; - } else { - const VkResult err = enumerate_instance_version(&inst->instance_version); - if (err) ERR_EXIT(err); - } - - inst->vulkan_major = VK_VERSION_MAJOR(inst->instance_version); - inst->vulkan_minor = VK_VERSION_MINOR(inst->instance_version); - inst->vulkan_patch = VK_VERSION_PATCH(VK_HEADER_VERSION); - - AppGetInstanceExtensions(inst); - - const VkDebugReportCallbackCreateInfoEXT dbg_info = {.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, - .flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, - .pfnCallback = DbgCallback}; - - const VkApplicationInfo app_info = {.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pApplicationName = APP_SHORT_NAME, - .applicationVersion = 1, - .apiVersion = VK_API_VERSION_1_0}; - - AppCompileInstanceExtensionsToEnable(inst); - const VkInstanceCreateInfo inst_info = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .pNext = &dbg_info, - .pApplicationInfo = &app_info, - .enabledExtensionCount = inst->inst_extensions_count, - .ppEnabledExtensionNames = inst->inst_extensions}; - - VkResult err = vkCreateInstance(&inst_info, NULL, &inst->instance); - if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { - fprintf(stderr, "Cannot create Vulkan instance.\n"); - fprintf(stderr, - "This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU that does " - "not support Vulkan.\n"); - ERR_EXIT(err); - } else if (err) { - ERR_EXIT(err); - } - - AppLoadInstanceCommands(inst); - - inst->surface_ext_infos_root = NULL; -} - -static void AppDestroyInstance(struct AppInstance *inst) { - free(inst->global_extensions); - for (uint32_t i = 0; i < inst->global_layer_count; ++i) { - free(inst->global_layers[i].extension_properties); - } - free(inst->global_layers); - free((char **)inst->inst_extensions); - vkDestroyInstance(inst->instance, NULL); -} - -static void AppGpuInit(struct AppGpu *gpu, struct AppInstance *inst, uint32_t id, VkPhysicalDevice obj) { - uint32_t i; - - memset(gpu, 0, sizeof(*gpu)); - - gpu->id = id; - gpu->obj = obj; - gpu->inst = inst; - - vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props); - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - struct pNextChainBuildingBlockInfo chain_info[] = { - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR, - .mem_size = sizeof(VkPhysicalDevicePointClippingPropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR, - .mem_size = sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceDiscardRectanglePropertiesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR, - .mem_size = sizeof(VkPhysicalDeviceMultiviewPropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR, - .mem_size = sizeof(VkPhysicalDeviceMaintenance3PropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR, .mem_size = sizeof(VkPhysicalDeviceIDPropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR, - .mem_size = sizeof(VkPhysicalDeviceDriverPropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR, - .mem_size = sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDevicePCIBusInfoPropertiesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceTransformFeedbackPropertiesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceFragmentDensityMapPropertiesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceDescriptorIndexingPropertiesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR, - .mem_size = sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceSubgroupSizeControlPropertiesEXT)}}; - - uint32_t chain_info_len = ARRAY_SIZE(chain_info); - - gpu->props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; - buildpNextChain((struct VkStructureHeader *)&gpu->props2, chain_info, chain_info_len); - - inst->vkGetPhysicalDeviceProperties2KHR(gpu->obj, &gpu->props2); - } - - /* get queue count */ - vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL); - - gpu->queue_props = malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count); - - if (!gpu->queue_props) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props); - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - gpu->queue_props2 = malloc(sizeof(gpu->queue_props2[0]) * gpu->queue_count); - - if (!gpu->queue_props2) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - - for (i = 0; i < gpu->queue_count; ++i) { - gpu->queue_props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR; - gpu->queue_props2[i].pNext = NULL; - } - - inst->vkGetPhysicalDeviceQueueFamilyProperties2KHR(gpu->obj, &gpu->queue_count, gpu->queue_props2); - } - - /* set up queue requests */ - gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count); - if (!gpu->queue_reqs) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - for (i = 0; i < gpu->queue_count; ++i) { - float *queue_priorities = NULL; - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - queue_priorities = malloc(gpu->queue_props2[i].queueFamilyProperties.queueCount * sizeof(float)); - } else { - queue_priorities = malloc(gpu->queue_props[i].queueCount * sizeof(float)); - } - if (!queue_priorities) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - memset(queue_priorities, 0, gpu->queue_props2[i].queueFamilyProperties.queueCount * sizeof(float)); - } else { - memset(queue_priorities, 0, gpu->queue_props[i].queueCount * sizeof(float)); - } - - gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - gpu->queue_reqs[i].pNext = NULL; - gpu->queue_reqs[i].flags = 0; - gpu->queue_reqs[i].queueFamilyIndex = i; - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - gpu->queue_reqs[i].queueCount = gpu->queue_props2[i].queueFamilyProperties.queueCount; - } else { - gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount; - } - - gpu->queue_reqs[i].pQueuePriorities = queue_priorities; - } - - vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props); - - vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features); - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - struct pNextChainBuildingBlockInfo mem_prop_chain_info[] = { - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT, - .mem_size = sizeof(VkPhysicalDeviceMemoryBudgetPropertiesEXT)}}; - - uint32_t mem_prop_chain_info_len = ARRAY_SIZE(mem_prop_chain_info); - - gpu->memory_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR; - buildpNextChain((struct VkStructureHeader *)&gpu->memory_props2, mem_prop_chain_info, mem_prop_chain_info_len); - - inst->vkGetPhysicalDeviceMemoryProperties2KHR(gpu->obj, &gpu->memory_props2); - - struct pNextChainBuildingBlockInfo chain_info[] = { - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDevice8BitStorageFeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDevice16BitStorageFeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDeviceVariablePointerFeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDeviceMultiviewFeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDeviceFloat16Int8FeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDeviceShaderAtomicInt64FeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceTransformFeedbackFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceFragmentDensityMapFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceMemoryPriorityFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceBufferAddressFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceDescriptorIndexingFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceHostQueryResetFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR, - .mem_size = sizeof(VkPhysicalDeviceImagelessFramebufferFeaturesKHR)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT)}, - {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, - .mem_size = sizeof(VkPhysicalDeviceIndexTypeUint8FeaturesEXT)}}; - - uint32_t chain_info_len = ARRAY_SIZE(chain_info); - - gpu->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; - buildpNextChain((struct VkStructureHeader *)&gpu->features2, chain_info, chain_info_len); - - inst->vkGetPhysicalDeviceFeatures2KHR(gpu->obj, &gpu->features2); - } - - AppGetPhysicalDeviceLayerExtensions(gpu, NULL, &gpu->device_extension_count, &gpu->device_extensions); - - const float queue_priority = 1.0f; - const VkDeviceQueueCreateInfo q_ci = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueFamilyIndex = 0, // just pick the first one and hope for the best - .queueCount = 1, - .pQueuePriorities = &queue_priority}; - VkPhysicalDeviceFeatures features = {0}; - // if (gpu->features.sparseBinding ) features.sparseBinding = VK_TRUE; - gpu->enabled_features = features; - const VkDeviceCreateInfo device_ci = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .queueCreateInfoCount = 1, - .pQueueCreateInfos = &q_ci, - // TODO: relevant extensions - .pEnabledFeatures = &gpu->enabled_features}; - - VkResult err = vkCreateDevice(gpu->obj, &device_ci, NULL, &gpu->dev); - if (err) ERR_EXIT(err); - - const VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; - const VkFormat formats[] = { - color_format, VK_FORMAT_D16_UNORM, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT, - VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT}; - assert(ARRAY_SIZE(gpu->mem_type_res_support.image[0]) == ARRAY_SIZE(formats)); - const VkImageUsageFlags usages[] = {0, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT}; - const VkImageCreateFlags flagss[] = {0, VK_IMAGE_CREATE_SPARSE_BINDING_BIT}; - - for (size_t fmt_i = 0; fmt_i < ARRAY_SIZE(formats); ++fmt_i) { - for (VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; tiling <= VK_IMAGE_TILING_LINEAR; ++tiling) { - gpu->mem_type_res_support.image[tiling][fmt_i].format = formats[fmt_i]; - gpu->mem_type_res_support.image[tiling][fmt_i].regular_supported = true; - gpu->mem_type_res_support.image[tiling][fmt_i].sparse_supported = true; - gpu->mem_type_res_support.image[tiling][fmt_i].transient_supported = true; - - VkFormatProperties fmt_props; - vkGetPhysicalDeviceFormatProperties(gpu->obj, formats[fmt_i], &fmt_props); - if ((tiling == VK_IMAGE_TILING_OPTIMAL && fmt_props.optimalTilingFeatures == 0) || - (tiling == VK_IMAGE_TILING_LINEAR && fmt_props.linearTilingFeatures == 0)) { - gpu->mem_type_res_support.image[tiling][fmt_i].regular_supported = false; - gpu->mem_type_res_support.image[tiling][fmt_i].sparse_supported = false; - gpu->mem_type_res_support.image[tiling][fmt_i].transient_supported = false; - continue; - } - - for (size_t u_i = 0; u_i < ARRAY_SIZE(usages); ++u_i) { - for (size_t flg_i = 0; flg_i < ARRAY_SIZE(flagss); ++flg_i) { - VkImageCreateInfo image_ci = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .flags = flagss[flg_i], - .imageType = VK_IMAGE_TYPE_2D, - .format = formats[fmt_i], - .extent = {8, 8, 1}, - .mipLevels = 1, - .arrayLayers = 1, - .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = tiling, - .usage = usages[u_i], - }; - - if ((image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && - (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { - continue; - } - - if (image_ci.usage == 0 || (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { - if (image_ci.format == color_format) - image_ci.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - else - image_ci.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - } - - if (!gpu->enabled_features.sparseBinding && (image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { - gpu->mem_type_res_support.image[tiling][fmt_i].sparse_supported = false; - continue; - } - - VkImageFormatProperties img_props; - err = vkGetPhysicalDeviceImageFormatProperties(gpu->obj, image_ci.format, image_ci.imageType, image_ci.tiling, - image_ci.usage, image_ci.flags, &img_props); - - uint32_t *memtypes; - bool *support; - - if (image_ci.flags == 0 && !(image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { - memtypes = &gpu->mem_type_res_support.image[tiling][fmt_i].regular_memtypes; - support = &gpu->mem_type_res_support.image[tiling][fmt_i].regular_supported; - } else if ((image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && - !(image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { - memtypes = &gpu->mem_type_res_support.image[tiling][fmt_i].sparse_memtypes; - support = &gpu->mem_type_res_support.image[tiling][fmt_i].sparse_supported; - } else if (image_ci.flags == 0 && (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { - memtypes = &gpu->mem_type_res_support.image[tiling][fmt_i].transient_memtypes; - support = &gpu->mem_type_res_support.image[tiling][fmt_i].transient_supported; - } else { - assert(false); - } - - if (err == VK_ERROR_FORMAT_NOT_SUPPORTED) { - *support = false; - } else { - if (err) ERR_EXIT(err); - - VkImage dummy_img; - err = vkCreateImage(gpu->dev, &image_ci, NULL, &dummy_img); - if (err) ERR_EXIT(err); - - VkMemoryRequirements mem_req; - vkGetImageMemoryRequirements(gpu->dev, dummy_img, &mem_req); - *memtypes = mem_req.memoryTypeBits; - - vkDestroyImage(gpu->dev, dummy_img, NULL); - } - } - } - } - } - // TODO buffer - memory type compatibility -} - -static void AppGpuDestroy(struct AppGpu *gpu) { - vkDestroyDevice(gpu->dev, NULL); - - free(gpu->device_extensions); - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - freepNextChain(gpu->features2.pNext); - } - - for (uint32_t i = 0; i < gpu->queue_count; ++i) { - free((void *)gpu->queue_reqs[i].pQueuePriorities); - } - free(gpu->queue_reqs); - - free(gpu->queue_props); - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - free(gpu->queue_props2); - - freepNextChain(gpu->props2.pNext); - freepNextChain(gpu->memory_props2.pNext); - } -} - -//----------------------------------------------------------- - -//---------------------------Win32--------------------------- -#ifdef VK_USE_PLATFORM_WIN32_KHR - -// MS-Windows event handling function: -LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } - -static void AppCreateWin32Window(struct AppInstance *inst) { - inst->h_instance = GetModuleHandle(NULL); - - WNDCLASSEX win_class; - - // Initialize the window class structure: - win_class.cbSize = sizeof(WNDCLASSEX); - win_class.style = CS_HREDRAW | CS_VREDRAW; - win_class.lpfnWndProc = WndProc; - win_class.cbClsExtra = 0; - win_class.cbWndExtra = 0; - win_class.hInstance = inst->h_instance; - win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); - win_class.hCursor = LoadCursor(NULL, IDC_ARROW); - win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - win_class.lpszMenuName = NULL; - win_class.lpszClassName = APP_SHORT_NAME; - win_class.hInstance = inst->h_instance; - win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO); - // Register window class: - if (!RegisterClassEx(&win_class)) { - // It didn't work, so try to give a useful error: - fprintf(stderr, "Failed to register the window class!\n"); - exit(1); - } - // Create window with the registered class: - RECT wr = {0, 0, inst->width, inst->height}; - AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); - inst->h_wnd = CreateWindowEx(0, - APP_SHORT_NAME, // class name - APP_SHORT_NAME, // app name - // WS_VISIBLE | WS_SYSMENU | - WS_OVERLAPPEDWINDOW, // window style - 100, 100, // x/y coords - wr.right - wr.left, // width - wr.bottom - wr.top, // height - NULL, // handle to parent - NULL, // handle to menu - inst->h_instance, // hInstance - NULL); // no extra parameters - if (!inst->h_wnd) { - // It didn't work, so try to give a useful error: - fprintf(stderr, "Failed to create a window!\n"); - exit(1); - } -} - -static VkSurfaceKHR AppCreateWin32Surface(struct AppInstance *inst) { - VkWin32SurfaceCreateInfoKHR createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.hinstance = inst->h_instance; - createInfo.hwnd = inst->h_wnd; - - VkSurfaceKHR surface; - VkResult err = vkCreateWin32SurfaceKHR(inst->instance, &createInfo, NULL, &surface); - if (err) ERR_EXIT(err); - return surface; -} - -static void AppDestroyWin32Window(struct AppInstance *inst) { DestroyWindow(inst->h_wnd); } -#endif // VK_USE_PLATFORM_WIN32_KHR -//----------------------------------------------------------- - -#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ - defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || defined(VK_USE_PLATFORM_ANDROID_KHR) -static void AppDestroySurface(struct AppInstance *inst, VkSurfaceKHR surface) { // same for all platforms - vkDestroySurfaceKHR(inst->instance, surface, NULL); -} -#endif - -//----------------------------XCB---------------------------- - -#ifdef VK_USE_PLATFORM_XCB_KHR -static void AppCreateXcbWindow(struct AppInstance *inst) { - //--Init Connection-- - const xcb_setup_t *setup; - xcb_screen_iterator_t iter; - int scr; - - // API guarantees non-null xcb_connection - inst->xcb_connection = xcb_connect(NULL, &scr); - int conn_error = xcb_connection_has_error(inst->xcb_connection); - if (conn_error) { - fprintf(stderr, "XCB failed to connect to the X server due to error:%d.\n", conn_error); - fflush(stderr); - inst->xcb_connection = NULL; - } - - setup = xcb_get_setup(inst->xcb_connection); - iter = xcb_setup_roots_iterator(setup); - while (scr-- > 0) { - xcb_screen_next(&iter); - } - - inst->xcb_screen = iter.data; - //------------------- - - inst->xcb_window = xcb_generate_id(inst->xcb_connection); - xcb_create_window(inst->xcb_connection, XCB_COPY_FROM_PARENT, inst->xcb_window, inst->xcb_screen->root, 0, 0, inst->width, - inst->height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, inst->xcb_screen->root_visual, 0, NULL); - - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst->xcb_connection, 1, 12, "WM_PROTOCOLS"); - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(inst->xcb_connection, cookie, 0); - free(reply); -} - -static VkSurfaceKHR AppCreateXcbSurface(struct AppInstance *inst) { - if (!inst->xcb_connection) { - ERR_EXIT(VK_ERROR_INITIALIZATION_FAILED); - } - - VkXcbSurfaceCreateInfoKHR xcb_createInfo; - xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; - xcb_createInfo.pNext = NULL; - xcb_createInfo.flags = 0; - xcb_createInfo.connection = inst->xcb_connection; - xcb_createInfo.window = inst->xcb_window; - - VkSurfaceKHR surface; - VkResult err = vkCreateXcbSurfaceKHR(inst->instance, &xcb_createInfo, NULL, &surface); - if (err) ERR_EXIT(err); - return surface; -} - -static void AppDestroyXcbWindow(struct AppInstance *inst) { - if (!inst->xcb_connection) { - return; // Nothing to destroy - } - - xcb_destroy_window(inst->xcb_connection, inst->xcb_window); - xcb_disconnect(inst->xcb_connection); -} -#endif // VK_USE_PLATFORM_XCB_KHR -//----------------------------------------------------------- - -//----------------------------XLib--------------------------- -#ifdef VK_USE_PLATFORM_XLIB_KHR -static void AppCreateXlibWindow(struct AppInstance *inst) { - long visualMask = VisualScreenMask; - int numberOfVisuals; - - inst->xlib_display = XOpenDisplay(NULL); - if (inst->xlib_display == NULL) { - fprintf(stderr, "XLib failed to connect to the X server.\nExiting ...\n"); - exit(1); - } - - XVisualInfo vInfoTemplate = {}; - vInfoTemplate.screen = DefaultScreen(inst->xlib_display); - XVisualInfo *visualInfo = XGetVisualInfo(inst->xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); - inst->xlib_window = XCreateWindow(inst->xlib_display, RootWindow(inst->xlib_display, vInfoTemplate.screen), 0, 0, inst->width, - inst->height, 0, visualInfo->depth, InputOutput, visualInfo->visual, 0, NULL); - - XSync(inst->xlib_display, false); - XFree(visualInfo); -} - -static VkSurfaceKHR AppCreateXlibSurface(struct AppInstance *inst) { - VkXlibSurfaceCreateInfoKHR createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.dpy = inst->xlib_display; - createInfo.window = inst->xlib_window; - - VkSurfaceKHR surface; - VkResult err = vkCreateXlibSurfaceKHR(inst->instance, &createInfo, NULL, &surface); - if (err) ERR_EXIT(err); - return surface; -} - -static void AppDestroyXlibWindow(struct AppInstance *inst) { - XDestroyWindow(inst->xlib_display, inst->xlib_window); - XCloseDisplay(inst->xlib_display); -} -#endif // VK_USE_PLATFORM_XLIB_KHR -//----------------------------------------------------------- - -#ifdef VK_USE_PLATFORM_MACOS_MVK - -static void AppCreateMacOSWindow(struct AppInstance *inst) { - inst->window = CreateMetalView(inst->width, inst->height); - if (inst->window == NULL) { - fprintf(stderr, "Could not create a native Metal view.\nExiting...\n"); - exit(1); - } -} - -static VkSurfaceKHR AppCreateMacOSSurface(struct AppInstance *inst) { - VkMacOSSurfaceCreateInfoMVK createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pView = inst->window; - - VkSurfaceKHR surface; - VkResult err = vkCreateMacOSSurfaceMVK(inst->instance, &createInfo, NULL, &surface); - if (err) ERR_EXIT(err); - return surface; -} - -static void AppDestroyMacOSWindow(struct AppInstance *inst) { DestroyMetalView(inst->window); } -#endif // VK_USE_PLATFORM_MACOS_MVK -//----------------------------------------------------------- - -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - -static void wayland_registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, - uint32_t version) { - struct AppInstance *inst = (struct AppInstance *)data; - if (strcmp(interface, "wl_compositor") == 0) { - struct wl_compositor *compositor = (struct wl_compositor *)wl_registry_bind(registry, id, &wl_compositor_interface, 1); - inst->wayland_surface = wl_compositor_create_surface(compositor); - } -} -static void wayland_registry_global_remove(void *data, struct wl_registry *registry, uint32_t id) {} -static const struct wl_registry_listener wayland_registry_listener = {wayland_registry_global, wayland_registry_global_remove}; - -static void AppCreateWaylandWindow(struct AppInstance *inst) { - inst->wayland_display = wl_display_connect(NULL); - struct wl_registry *registry = wl_display_get_registry(inst->wayland_display); - wl_registry_add_listener(wl_display_get_registry(inst->wayland_display), &wayland_registry_listener, inst); - wl_display_roundtrip(inst->wayland_display); - wl_registry_destroy(registry); -} - -static VkSurfaceKHR AppCreateWaylandSurface(struct AppInstance *inst) { - VkWaylandSurfaceCreateInfoKHR createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.display = inst->wayland_display; - createInfo.surface = inst->wayland_surface; - - VkSurfaceKHR surface; - VkResult err = vkCreateWaylandSurfaceKHR(inst->instance, &createInfo, NULL, &surface); - if (err) ERR_EXIT(err); - return surface; -} - -static void AppDestroyWaylandWindow(struct AppInstance *inst) { wl_display_disconnect(inst->wayland_display); } -#endif // VK_USE_PLATFORM_WAYLAND_KHR - -#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ - defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) -static int AppDumpSurfaceFormats(struct AppInstance *inst, struct AppGpu *gpu, VkSurfaceKHR surface, FILE *out) { - // Get the list of VkFormat's that are supported - VkResult err; - uint32_t format_count = 0; - VkSurfaceFormatKHR *surf_formats = NULL; - VkSurfaceFormat2KHR *surf_formats2 = NULL; - - const VkPhysicalDeviceSurfaceInfo2KHR surface_info2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, - .surface = surface}; - - if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - err = inst->vkGetPhysicalDeviceSurfaceFormats2KHR(gpu->obj, &surface_info2, &format_count, NULL); - if (err) ERR_EXIT(err); - surf_formats2 = (VkSurfaceFormat2KHR *)malloc(format_count * sizeof(VkSurfaceFormat2KHR)); - if (!surf_formats2) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - for (uint32_t i = 0; i < format_count; ++i) { - surf_formats2[i].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR; - surf_formats2[i].pNext = NULL; - } - err = inst->vkGetPhysicalDeviceSurfaceFormats2KHR(gpu->obj, &surface_info2, &format_count, surf_formats2); - if (err) ERR_EXIT(err); - } else { - err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, surface, &format_count, NULL); - if (err) ERR_EXIT(err); - surf_formats = (VkSurfaceFormatKHR *)malloc(format_count * sizeof(VkSurfaceFormatKHR)); - if (!surf_formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, surface, &format_count, surf_formats); - if (err) ERR_EXIT(err); - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>Formats: count = <span class='val'>%d</span></summary>", format_count); - if (format_count > 0) { - fprintf(out, "\n"); - } else { - fprintf(out, "</details>\n"); - } - } else if (human_readable_output) { - printf("Formats:\t\tcount = %d\n", format_count); - } - for (uint32_t i = 0; i < format_count; ++i) { - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>SurfaceFormat[%d]:</summary>\n", i); - if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>format = <span class='type'>%s</span></summary></details>\n", - VkFormatString(surf_formats2[i].surfaceFormat.format)); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>colorSpace = <span class='type'>%s</span></summary></details>\n", - VkColorSpaceString(surf_formats2[i].surfaceFormat.colorSpace)); - } else { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>format = <span class='type'>%s</span></summary></details>\n", - VkFormatString(surf_formats[i].format)); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>colorSpace = <span class='type'>%s</span></summary></details>\n", - VkColorSpaceString(surf_formats[i].colorSpace)); - } - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\tSurfaceFormats[%d]\n", i); - if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - printf("\t\tformat = %s\n", VkFormatString(surf_formats2[i].surfaceFormat.format)); - printf("\t\tcolorSpace = %s\n", VkColorSpaceString(surf_formats2[i].surfaceFormat.colorSpace)); - } else { - printf("\t\tformat = %s\n", VkFormatString(surf_formats[i].format)); - printf("\t\tcolorSpace = %s\n", VkColorSpaceString(surf_formats[i].colorSpace)); - } - } - } - if (format_count > 0 && html_output) { - fprintf(out, "\t\t\t\t\t</details>\n"); - } - - fflush(out); - fflush(stdout); - if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - free(surf_formats2); - } else { - free(surf_formats); - } - - return format_count; -} - -static int AppDumpSurfacePresentModes(struct AppInstance *inst, struct AppGpu *gpu, VkSurfaceKHR surface, FILE *out) { - // Get the list of VkPresentMode's that are supported: - VkResult err; - uint32_t present_mode_count = 0; - err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, surface, &present_mode_count, NULL); - if (err) ERR_EXIT(err); - - VkPresentModeKHR *surf_present_modes = (VkPresentModeKHR *)malloc(present_mode_count * sizeof(VkPresentModeKHR)); - if (!surf_present_modes) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, surface, &present_mode_count, surf_present_modes); - if (err) ERR_EXIT(err); - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>Present Modes: count = <span class='val'>%d</span></summary>", - present_mode_count); - if (present_mode_count > 0) { - fprintf(out, "\n"); - } else { - fprintf(out, "</details>"); - } - } else if (human_readable_output) { - printf("Present Modes:\t\tcount = %d\n", present_mode_count); - } - for (uint32_t i = 0; i < present_mode_count; ++i) { - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary><span class='type'>%s</span></summary></details>\n", - VkPresentModeString(surf_present_modes[i])); - } else if (human_readable_output) { - printf("\t%s\n", VkPresentModeString(surf_present_modes[i])); - } - } - if (present_mode_count > 0 && html_output) { - fprintf(out, "\t\t\t\t\t</details>\n"); - } - - fflush(out); - fflush(stdout); - free(surf_present_modes); - - return present_mode_count; -} - -static void AppDumpSurfaceCapabilities(struct AppInstance *inst, struct AppGpu *gpu, VkSurfaceKHR surface, FILE *out) { - if (CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) { - VkSurfaceCapabilitiesKHR surface_capabilities; - VkResult err; - err = inst->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu->obj, surface, &surface_capabilities); - if (err) ERR_EXIT(err); - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkSurfaceCapabilitiesKHR</summary>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>minImageCount = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.minImageCount); - fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageCount = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.maxImageCount); - fprintf(out, "\t\t\t\t\t\t<details><summary>currentExtent</summary>\n"); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>width = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.currentExtent.width); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>height = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.currentExtent.height); - fprintf(out, "\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>minImageExtent</summary>\n"); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>width = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.minImageExtent.width); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>height = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.minImageExtent.height); - fprintf(out, "\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageExtent</summary>\n"); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>width = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.maxImageExtent.width); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>height = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.maxImageExtent.height); - fprintf(out, "\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageArrayLayers = <span class='val'>%u</span></summary></details>\n", - surface_capabilities.maxImageArrayLayers); - fprintf(out, "\t\t\t\t\t\t<details><summary>supportedTransform</summary>\n"); - if (surface_capabilities.supportedTransforms == 0) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR</span></summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>currentTransform</summary>\n"); - if (surface_capabilities.currentTransform == 0) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } - if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR</span></summary></details>\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR</span></summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>supportedCompositeAlpha</summary>\n"); - if (surface_capabilities.supportedCompositeAlpha == 0) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR</span></summary></details>\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR</span></summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>supportedUsageFlags</summary>\n"); - if (surface_capabilities.supportedUsageFlags == 0) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_TRANSFER_SRC_BIT</span></summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_TRANSFER_DST_BIT</span></summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { - fprintf( - out, - "\t\t\t\t\t\t\t<details><summary><span class='type'>VK_IMAGE_USAGE_SAMPLED_BIT</span></summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { - fprintf( - out, - "\t\t\t\t\t\t\t<details><summary><span class='type'>VK_IMAGE_USAGE_STORAGE_BIT</span></summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</span></summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</span></summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT</span></summary></details>\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT</span></summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("VkSurfaceCapabilitiesKHR:\n"); - printf("\tminImageCount = %u\n", surface_capabilities.minImageCount); - printf("\tmaxImageCount = %u\n", surface_capabilities.maxImageCount); - printf("\tcurrentExtent:\n"); - printf("\t\twidth = %u\n", surface_capabilities.currentExtent.width); - printf("\t\theight = %u\n", surface_capabilities.currentExtent.height); - printf("\tminImageExtent:\n"); - printf("\t\twidth = %u\n", surface_capabilities.minImageExtent.width); - printf("\t\theight = %u\n", surface_capabilities.minImageExtent.height); - printf("\tmaxImageExtent:\n"); - printf("\t\twidth = %u\n", surface_capabilities.maxImageExtent.width); - printf("\t\theight = %u\n", surface_capabilities.maxImageExtent.height); - printf("\tmaxImageArrayLayers = %u\n", surface_capabilities.maxImageArrayLayers); - printf("\tsupportedTransform:\n"); - if (surface_capabilities.supportedTransforms == 0) { - printf("\t\tNone\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n"); - } - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n"); - } - printf("\tcurrentTransform:\n"); - if (surface_capabilities.currentTransform == 0) { - printf("\t\tNone\n"); - } - if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n"); - } else if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { - printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n"); - } - printf("\tsupportedCompositeAlpha:\n"); - if (surface_capabilities.supportedCompositeAlpha == 0) { - printf("\t\tNone\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) { - printf("\t\tVK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) { - printf("\t\tVK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) { - printf("\t\tVK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR\n"); - } - if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) { - printf("\t\tVK_COMPOSITE_ALPHA_INHERIT_BIT_KHR\n"); - } - printf("\tsupportedUsageFlags:\n"); - if (surface_capabilities.supportedUsageFlags == 0) { - printf("\t\tNone\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { - printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { - printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { - printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { - printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n"); - } - if (surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n"); - } - } - - // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2EXT - if (CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - VkSurfaceCapabilities2EXT surface_capabilities2_ext = {VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT}; - - err = inst->vkGetPhysicalDeviceSurfaceCapabilities2EXT(gpu->obj, surface, &surface_capabilities2_ext); - if (err) ERR_EXIT(err); - - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>VkSurfaceCapabilities2EXT</summary>\n"); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>supportedSurfaceCounters</summary>\n"); - if (surface_capabilities2_ext.supportedSurfaceCounters == 0) { - fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } - if (surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_SURFACE_COUNTER_VBLANK_EXT</span></summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("VkSurfaceCapabilities2EXT:\n"); - printf("\tsupportedSurfaceCounters:\n"); - if (surface_capabilities2_ext.supportedSurfaceCounters == 0) { - printf("\t\tNone\n"); - } - if (surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) { - printf("\t\tVK_SURFACE_COUNTER_VBLANK_EXT\n"); - } - } - } - - // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2KHR - if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - VkSurfaceCapabilities2KHR surface_capabilities2; - - struct pNextChainBuildingBlockInfo sur_cap2_chain_info[] = { - {.sType = VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR, - .mem_size = sizeof(VkSharedPresentSurfaceCapabilitiesKHR)}, - {.sType = VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR, - .mem_size = sizeof(VkSurfaceProtectedCapabilitiesKHR)} -#ifdef VK_USE_PLATFORM_WIN32_KHR - , - {.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT, - .mem_size = sizeof(VkSurfaceCapabilitiesFullScreenExclusiveEXT)} -#endif - }; - - uint32_t sur_cap2_chain_info_len = ARRAY_SIZE(sur_cap2_chain_info); - - surface_capabilities2.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR; - buildpNextChain((struct VkStructureHeader *)&surface_capabilities2, sur_cap2_chain_info, sur_cap2_chain_info_len); - - VkPhysicalDeviceSurfaceInfo2KHR surface_info; - surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR; - surface_info.pNext = NULL; - surface_info.surface = surface; - - err = inst->vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu->obj, &surface_info, &surface_capabilities2); - if (err) ERR_EXIT(err); - - void *place = surface_capabilities2.pNext; - while (place) { - struct VkStructureHeader *work = (struct VkStructureHeader *)place; - if (work->sType == VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR && - CheckExtensionEnabled(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - VkSharedPresentSurfaceCapabilitiesKHR *shared_surface_capabilities = - (VkSharedPresentSurfaceCapabilitiesKHR *)place; - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>VkSharedPresentSurfaceCapabilitiesKHR</summary>\n"); - fprintf(out, "\t\t\t\t\t\t\t<details><summary>sharedPresentSupportedUsageFlags</summary>\n"); - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags == 0) { - fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_TRANSFER_SRC_BIT</span></summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_TRANSFER_DST_BIT</span></summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_SAMPLED_BIT</span></summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_STORAGE_BIT</span></summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</span></summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</span></summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT</span></summary></details>\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT</span></summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("VkSharedPresentSurfaceCapabilitiesKHR:\n"); - printf("\tsharedPresentSupportedUsageFlags:\n"); - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags == 0) { - printf("\t\tNone\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { - printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { - printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { - printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { - printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n"); - } - if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { - printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n"); - } - } - } else if (work->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR && - CheckExtensionEnabled(VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - VkSurfaceProtectedCapabilitiesKHR *protected_surface_capabilities = (VkSurfaceProtectedCapabilitiesKHR *)place; - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>VkSurfaceProtectedCapabilities</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>supportsProtected = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - protected_surface_capabilities->supportsProtected); - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("VkSurfaceProtectedCapabilities\n"); - printf("\tsupportsProtected = %" PRIuLEAST32 "\n", protected_surface_capabilities->supportsProtected); - } - } -#ifdef VK_USE_PLATFORM_WIN32_KHR - else if (work->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkSurfaceCapabilitiesFullScreenExclusiveEXT *full_screen_exclusive = - (VkSurfaceCapabilitiesFullScreenExclusiveEXT *)place; - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>VkSurfaceCapabilitiesFullScreenExclusiveEXT</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>fullScreenExclusive = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - full_screen_exclusive->fullScreenExclusiveSupported); - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("VkSurfaceCapabilitiesFullScreenExclusiveEXT\n"); - printf("\tfullScreenExclusive = %" PRIuLEAST32 "\n", full_screen_exclusive->fullScreenExclusiveSupported); - } - } -#endif - place = work->pNext; - } - freepNextChain(surface_capabilities2.pNext); - } - if (html_output) { - fprintf(out, "\t\t\t\t\t</details>\n"); - } - } -} - -static void AppDumpSurfaceExtension(struct AppInstance *inst, struct AppGpu *gpus, uint32_t gpu_count, - struct SurfaceExtensionNode *surface_extension, int *format_count, int *present_mode_count, - FILE *out) { - if (!CheckExtensionEnabled(surface_extension->name, inst->inst_extensions, inst->inst_extensions_count)) { - return; - } - - for (uint32_t i = 0; i < gpu_count; ++i) { - if (html_output) { - fprintf(out, "\t\t\t\t<details><summary>GPU id : <span class='val'>%u</span> (%s)</summary>\n", i, - gpus[i].props.deviceName); - fprintf(out, "\t\t\t\t\t<details><summary>Surface type : <span class='type'>%s</span></summary></details>\n", - surface_extension->name); - } else if (human_readable_output) { - printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName); - printf("Surface type : %s\n", surface_extension->name); - } - *format_count += AppDumpSurfaceFormats(inst, &gpus[i], surface_extension->surface, out); - *present_mode_count += AppDumpSurfacePresentModes(inst, &gpus[i], surface_extension->surface, out); - AppDumpSurfaceCapabilities(inst, &gpus[i], surface_extension->surface, out); - - if (html_output) { - fprintf(out, "\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\n"); - } - } -} - -#endif - -static void AppDevDumpFormatProps(const struct AppGpu *gpu, VkFormat fmt, bool *first_in_list, FILE *out) { - VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(gpu->obj, fmt, &props); - struct { - const char *name; - VkFlags flags; - } features[3]; - - features[0].name = "linearTiling FormatFeatureFlags"; - features[0].flags = props.linearTilingFeatures; - features[1].name = "optimalTiling FormatFeatureFlags"; - features[1].flags = props.optimalTilingFeatures; - features[2].name = "bufferFeatures FormatFeatureFlags"; - features[2].flags = props.bufferFeatures; - - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary><span class='type'>FORMAT_%s</span></summary>\n", VkFormatString(fmt)); - } else if (human_readable_output) { - printf("\nFORMAT_%s:", VkFormatString(fmt)); - } - for (uint32_t i = 0; i < ARRAY_SIZE(features); ++i) { - if (html_output) { - fprintf(out, "\t\t\t\t\t\t\t<details open><summary>%s</summary>\n", features[i].name); - if (features[i].flags == 0) { - fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } else { - fprintf( - out, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_" - "BIT</span></summary></details>\n" - : ""), // 0x0001 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_STORAGE_IMAGE_" - "BIT</span></summary></details>\n" - : ""), // 0x0002 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT</span></summary></details>\n" - : ""), // 0x0004 - ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT</span></summary></details>\n" - : ""), // 0x0008 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT</span></summary></details>\n" - : ""), // 0x0010 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT</span></summary></details>\n" - : ""), // 0x0020 - ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_VERTEX_BUFFER_" - "BIT</span></summary></details>\n" - : ""), // 0x0040 - ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_COLOR_" - "ATTACHMENT_BIT</span></summary></details>\n" - : ""), // 0x0080 - ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT</span></summary></details>\n" - : ""), // 0x0100 - ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT</span></summary></details>\n" - : ""), // 0x0200 - ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_BLIT_SRC_BIT</" - "span></summary></details>\n" - : ""), // 0x0400 - ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_BLIT_DST_BIT</" - "span></summary></details>\n" - : ""), // 0x0800 - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT</span></summary></details>\n" - : ""), // 0x1000 - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG) - ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG</span></summary></details>\n" - : ""), // 0x2000 - ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_TRANSFER_" - "SRC_BIT_KHR</span></summary></details>\n" - : ""), // 0x4000 - ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_FORMAT_FEATURE_TRANSFER_" - "DST_BIT_KHR</span></summary></details>\n" - : "")); // 0x8000 - } - fprintf(out, "\t\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\n\t%s:", features[i].name); - if (features[i].flags == 0) { - printf("\n\t\tNone"); - } else { - printf( - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" - : ""), // 0x0001 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" - : ""), // 0x0002 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" - : ""), // 0x0004 - ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" - : ""), // 0x0008 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" - : ""), // 0x0010 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" - : ""), // 0x0020 - ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" - : ""), // 0x0040 - ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" - : ""), // 0x0080 - ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" - : ""), // 0x0100 - ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" - : ""), // 0x0200 - ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), // 0x0400 - ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), // 0x0800 - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT" - : ""), // 0x1000 - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG) - ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG" - : ""), // 0x2000 - ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR" - : ""), // 0x4000 - ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR" - : "")); // 0x8000 - } - } - } - if (html_output) { - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\n"); - } - if (json_output && (props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures)) { - if (!(*first_in_list)) { - printf(","); - } else { - *first_in_list = false; - } - printf("\n"); - printf("\t\t{\n"); - printf("\t\t\t\"formatID\": %d,\n", fmt); - printf("\t\t\t\"linearTilingFeatures\": %u,\n", props.linearTilingFeatures); - printf("\t\t\t\"optimalTilingFeatures\": %u,\n", props.optimalTilingFeatures); - printf("\t\t\t\"bufferFeatures\": %u\n", props.bufferFeatures); - printf("\t\t}"); - } -} - -/* This structure encodes all the format ranges to be queried. - * It ensures that a format is not queried if the instance - * doesn't support it (either through the instance version or - * through extensions). - */ -static struct FormatRange { - // the Vulkan standard version that supports this format range, or 0 if non-standard - uint32_t minimum_instance_version; - - // The name of the extension that supports this format range, or NULL if the range - // is only part of the standard - char *extension_name; - - // The first and last supported formats within this range. - VkFormat first_format; - VkFormat last_format; -} supported_format_ranges[] = { - { - // Standard formats in Vulkan 1.0 - VK_MAKE_VERSION(1, 0, 0), - NULL, - VK_FORMAT_BEGIN_RANGE, - VK_FORMAT_END_RANGE, - }, - { - // YCBCR extension, standard in Vulkan 1.1 - VK_MAKE_VERSION(1, 1, 0), - VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, - VK_FORMAT_G8B8G8R8_422_UNORM, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, - }, - { - // PVRTC extension, not standardized - 0, - VK_IMG_FORMAT_PVRTC_EXTENSION_NAME, - VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, - VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG, - }, -}; - -// Helper function to determine whether a format range is currently supported. -bool FormatRangeSupported(const struct FormatRange *format_range, const struct AppGpu *gpu) { - // True if standard and supported by both this instance and this GPU - if (format_range->minimum_instance_version > 0 && gpu->inst->instance_version >= format_range->minimum_instance_version && - gpu->props.apiVersion >= format_range->minimum_instance_version) { - return true; - } - - // True if this extension is present - if (format_range->extension_name != NULL) { - return CheckExtensionEnabled(format_range->extension_name, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count); - } - - // Otherwise, not supported. - return false; -} - -bool FormatPropsEq(const VkFormatProperties *props1, const VkFormatProperties *props2) { - if (props1->bufferFeatures == props2->bufferFeatures && props1->linearTilingFeatures == props2->linearTilingFeatures && - props1->optimalTilingFeatures == props2->optimalTilingFeatures) { - return true; - } else { - return false; - } -} - -struct PropFormats { - VkFormatProperties props; - - uint32_t format_count; - uint32_t format_reserve; - VkFormat *formats; -}; - -void FormatPropsShortenedDump(const struct AppGpu *gpu) { - const VkFormatProperties unsupported_prop = {0}; - uint32_t unique_props_count = 1; - uint32_t unique_props_reserve = 50; - struct PropFormats *prop_map = malloc(sizeof(struct PropFormats) * unique_props_reserve); - if (!prop_map) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - prop_map[0].props = unsupported_prop; - prop_map[0].format_count = 0; - prop_map[0].format_reserve = 20; - prop_map[0].formats = malloc(sizeof(VkFormat) * prop_map[0].format_reserve); - if (!prop_map[0].formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - - for (uint32_t ri = 0; ri < ARRAY_SIZE(supported_format_ranges); ++ri) { - struct FormatRange format_range = supported_format_ranges[ri]; - if (FormatRangeSupported(&format_range, gpu)) { - for (VkFormat fmt = format_range.first_format; fmt <= format_range.last_format; ++fmt) { - VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(gpu->obj, fmt, &props); - - uint32_t formats_prop_i = 0; - for (; formats_prop_i < unique_props_count; ++formats_prop_i) { - if (FormatPropsEq(&prop_map[formats_prop_i].props, &props)) break; - } - - if (formats_prop_i < unique_props_count) { - struct PropFormats *propFormats = &prop_map[formats_prop_i]; - ++propFormats->format_count; - - if (propFormats->format_count > propFormats->format_reserve) { - propFormats->format_reserve *= 2; - propFormats->formats = realloc(propFormats->formats, sizeof(VkFormat) * propFormats->format_reserve); - if (!propFormats->formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - - propFormats->formats[propFormats->format_count - 1] = fmt; - } else { - assert(formats_prop_i == unique_props_count); - ++unique_props_count; - - if (unique_props_count > unique_props_reserve) { - unique_props_reserve *= 2; - prop_map = realloc(prop_map, sizeof(struct PropFormats) * unique_props_reserve); - if (!prop_map) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - - struct PropFormats *propFormats = &prop_map[formats_prop_i]; - propFormats->props = props; - propFormats->format_count = 1; - propFormats->format_reserve = 20; - propFormats->formats = malloc(sizeof(VkFormat) * propFormats->format_reserve); - if (!propFormats->formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - propFormats->formats[0] = fmt; - } - } - } - } - - for (uint32_t pi = 1; pi < unique_props_count; ++pi) { - struct PropFormats *propFormats = &prop_map[pi]; - - for (uint32_t fi = 0; fi < propFormats->format_count; ++fi) { - const VkFormat fmt = propFormats->formats[fi]; - - printf("\nFORMAT_%s", VkFormatString(fmt)); - - if (fi < propFormats->format_count - 1) - printf(","); - else - printf(":"); - } - - struct { - const char *name; - VkFlags flags; - } features[3]; - - features[0].name = "linearTiling FormatFeatureFlags"; - features[0].flags = propFormats->props.linearTilingFeatures; - features[1].name = "optimalTiling FormatFeatureFlags"; - features[1].flags = propFormats->props.optimalTilingFeatures; - features[2].name = "bufferFeatures FormatFeatureFlags"; - features[2].flags = propFormats->props.bufferFeatures; - - for (uint32_t i = 0; i < ARRAY_SIZE(features); ++i) { - printf("\n\t%s:", features[i].name); - if (features[i].flags == 0) { - printf("\n\t\tNone"); - } else { - printf( - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" - : ""), // 0x0001 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" - : ""), // 0x0002 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" - : ""), // 0x0004 - ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" - : ""), // 0x0008 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" - : ""), // 0x0010 - ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" - : ""), // 0x0020 - ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" - : ""), // 0x0040 - ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" - : ""), // 0x0080 - ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" - : ""), // 0x0100 - ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" - : ""), // 0x0200 - ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), // 0x0400 - ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), // 0x0800 - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) - ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT" - : ""), // 0x1000 - ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG) - ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG" - : ""), // 0x2000 - ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR" - : ""), // 0x4000 - ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR" - : "")); // 0x8000 - } - - printf("\n"); - } - } - - printf("\nUnsupported formats:"); - if (prop_map[0].format_count == 0) printf("\nNone"); - for (uint32_t fi = 0; fi < prop_map[0].format_count; ++fi) { - const VkFormat fmt = prop_map[0].formats[fi]; - - printf("\nFORMAT_%s", VkFormatString(fmt)); - } - - // cleanup - for (uint32_t pi = 0; pi < unique_props_count; ++pi) free(prop_map[pi].formats); - free(prop_map); -} - -static void AppDevDump(const struct AppGpu *gpu, FILE *out) { - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>Format Properties</summary>\n"); - } else if (human_readable_output) { - printf("Format Properties:\n"); - printf("==================\n"); - } - if (json_output) { - printf(",\n"); - printf("\t\"ArrayOfVkFormatProperties\": ["); - } - - if (human_readable_output) { - FormatPropsShortenedDump(gpu); - } else { - bool first_in_list = true; // Used for commas in json output - for (uint32_t i = 0; i < ARRAY_SIZE(supported_format_ranges); ++i) { - struct FormatRange format_range = supported_format_ranges[i]; - if (FormatRangeSupported(&format_range, gpu)) { - for (VkFormat fmt = format_range.first_format; fmt <= format_range.last_format; ++fmt) { - AppDevDumpFormatProps(gpu, fmt, &first_in_list, out); - } - } - } - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t</details>\n"); - } - if (json_output) { - printf("\n\t]"); - } -} - -#ifdef _WIN32 -#define PRINTF_SIZE_T_SPECIFIER "%Iu" -#else -#define PRINTF_SIZE_T_SPECIFIER "%zu" -#endif - -static void AppGpuDumpFeatures(const struct AppGpu *gpu, FILE *out) { - VkPhysicalDeviceFeatures features; - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - const VkPhysicalDeviceFeatures *features2_const = &gpu->features2.features; - features = *features2_const; - } else { - const VkPhysicalDeviceFeatures *features_const = &gpu->features; - features = *features_const; - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>robustBufferAccess = <span " - "class='val'>%u</span></summary></details>\n", - features.robustBufferAccess); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fullDrawIndexUint32 = <span " - "class='val'>%u</span></summary></details>\n", - features.fullDrawIndexUint32); - fprintf(out, - "\t\t\t\t\t\t<details><summary>imageCubeArray = <span " - "class='val'>%u</span></summary></details>\n", - features.imageCubeArray); - fprintf(out, - "\t\t\t\t\t\t<details><summary>independentBlend = <span " - "class='val'>%u</span></summary></details>\n", - features.independentBlend); - fprintf(out, - "\t\t\t\t\t\t<details><summary>geometryShader = <span " - "class='val'>%u</span></summary></details>\n", - features.geometryShader); - fprintf(out, - "\t\t\t\t\t\t<details><summary>tessellationShader = <span " - "class='val'>%u</span></summary></details>\n", - features.tessellationShader); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sampleRateShading = <span " - "class='val'>%u</span></summary></details>\n", - features.sampleRateShading); - fprintf(out, - "\t\t\t\t\t\t<details><summary>dualSrcBlend = <span " - "class='val'>%u</span></summary></details>\n", - features.dualSrcBlend); - fprintf(out, - "\t\t\t\t\t\t<details><summary>logicOp = <span " - "class='val'>%u</span></summary></details>\n", - features.logicOp); - fprintf(out, - "\t\t\t\t\t\t<details><summary>multiDrawIndirect = <span " - "class='val'>%u</span></summary></details>\n", - features.multiDrawIndirect); - fprintf(out, - "\t\t\t\t\t\t<details><summary>drawIndirectFirstInstance = <span " - "class='val'>%u</span></summary></details>\n", - features.drawIndirectFirstInstance); - fprintf(out, - "\t\t\t\t\t\t<details><summary>depthClamp = <span " - "class='val'>%u</span></summary></details>\n", - features.depthClamp); - fprintf(out, - "\t\t\t\t\t\t<details><summary>depthBiasClamp = <span " - "class='val'>%u</span></summary></details>\n", - features.depthBiasClamp); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fillModeNonSolid = <span " - "class='val'>%u</span></summary></details>\n", - features.fillModeNonSolid); - fprintf(out, - "\t\t\t\t\t\t<details><summary>depthBounds = <span " - "class='val'>%u</span></summary></details>\n", - features.depthBounds); - fprintf(out, - "\t\t\t\t\t\t<details><summary>wideLines = <span " - "class='val'>%u</span></summary></details>\n", - features.wideLines); - fprintf(out, - "\t\t\t\t\t\t<details><summary>largePoints = <span " - "class='val'>%u</span></summary></details>\n", - features.largePoints); - fprintf(out, - "\t\t\t\t\t\t<details><summary>alphaToOne = <span " - "class='val'>%u</span></summary></details>\n", - features.alphaToOne); - fprintf(out, - "\t\t\t\t\t\t<details><summary>multiViewport = <span " - "class='val'>%u</span></summary></details>\n", - features.multiViewport); - fprintf(out, - "\t\t\t\t\t\t<details><summary>samplerAnisotropy = <span " - "class='val'>%u</span></summary></details>\n", - features.samplerAnisotropy); - fprintf(out, - "\t\t\t\t\t\t<details><summary>textureCompressionETC2 = <span " - "class='val'>%u</span></summary></details>\n", - features.textureCompressionETC2); - fprintf(out, - "\t\t\t\t\t\t<details><summary>textureCompressionASTC_LDR = <span " - "class='val'>%u</span></summary></details>\n", - features.textureCompressionASTC_LDR); - fprintf(out, - "\t\t\t\t\t\t<details><summary>textureCompressionBC = <span " - "class='val'>%u</span></summary></details>\n", - features.textureCompressionBC); - fprintf(out, - "\t\t\t\t\t\t<details><summary>occlusionQueryPrecise = <span " - "class='val'>%u</span></summary></details>\n", - features.occlusionQueryPrecise); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pipelineStatisticsQuery = <span " - "class='val'>%u</span></summary></details>\n", - features.pipelineStatisticsQuery); - fprintf(out, - "\t\t\t\t\t\t<details><summary>vertexPipelineStoresAndAtomics = <span " - "class='val'>%u</span></summary></details>\n", - features.vertexPipelineStoresAndAtomics); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentStoresAndAtomics = <span " - "class='val'>%u</span></summary></details>\n", - features.fragmentStoresAndAtomics); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderTessellationAndGeometryPointSize = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderTessellationAndGeometryPointSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderImageGatherExtended = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderImageGatherExtended); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageImageExtendedFormats = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderStorageImageExtendedFormats); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageImageMultisample = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderStorageImageMultisample); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageImageReadWithoutFormat = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderStorageImageReadWithoutFormat); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageImageWriteWithoutFormat = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderStorageImageWriteWithoutFormat); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderUniformBufferArrayDynamicIndexing = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderUniformBufferArrayDynamicIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderSampledImageArrayDynamicIndexing = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderSampledImageArrayDynamicIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageBufferArrayDynamicIndexing = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderStorageBufferArrayDynamicIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageImageArrayDynamicIndexing = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderStorageImageArrayDynamicIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderClipDistance = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderClipDistance); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderCullDistance = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderCullDistance); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderFloat64 = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderFloat64); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderInt64 = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderInt64); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderInt16 = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderInt16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderResourceResidency = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderResourceResidency); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderResourceMinLod = <span " - "class='val'>%u</span></summary></details>\n", - features.shaderResourceMinLod); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseBinding = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseBinding); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidencyBuffer = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidencyBuffer); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidencyImage2D = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidencyImage2D); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidencyImage3D = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidencyImage3D); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidency2Samples = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidency2Samples); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidency4Samples = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidency4Samples); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidency8Samples = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidency8Samples); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidency16Samples = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidency16Samples); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseResidencyAliased = <span " - "class='val'>%u</span></summary></details>\n", - features.sparseResidencyAliased); - fprintf(out, - "\t\t\t\t\t\t<details><summary>variableMultisampleRate = <span " - "class='val'>%u</span></summary></details>\n", - features.variableMultisampleRate); - fprintf(out, - "\t\t\t\t\t\t<details><summary>inheritedQueries = <span " - "class='val'>%u</span></summary></details>\n", - features.inheritedQueries); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("VkPhysicalDeviceFeatures:\n"); - printf("=========================\n"); - printf("\trobustBufferAccess = %u\n", features.robustBufferAccess); - printf("\tfullDrawIndexUint32 = %u\n", features.fullDrawIndexUint32); - printf("\timageCubeArray = %u\n", features.imageCubeArray); - printf("\tindependentBlend = %u\n", features.independentBlend); - printf("\tgeometryShader = %u\n", features.geometryShader); - printf("\ttessellationShader = %u\n", features.tessellationShader); - printf("\tsampleRateShading = %u\n", features.sampleRateShading); - printf("\tdualSrcBlend = %u\n", features.dualSrcBlend); - printf("\tlogicOp = %u\n", features.logicOp); - printf("\tmultiDrawIndirect = %u\n", features.multiDrawIndirect); - printf("\tdrawIndirectFirstInstance = %u\n", features.drawIndirectFirstInstance); - printf("\tdepthClamp = %u\n", features.depthClamp); - printf("\tdepthBiasClamp = %u\n", features.depthBiasClamp); - printf("\tfillModeNonSolid = %u\n", features.fillModeNonSolid); - printf("\tdepthBounds = %u\n", features.depthBounds); - printf("\twideLines = %u\n", features.wideLines); - printf("\tlargePoints = %u\n", features.largePoints); - printf("\talphaToOne = %u\n", features.alphaToOne); - printf("\tmultiViewport = %u\n", features.multiViewport); - printf("\tsamplerAnisotropy = %u\n", features.samplerAnisotropy); - printf("\ttextureCompressionETC2 = %u\n", features.textureCompressionETC2); - printf("\ttextureCompressionASTC_LDR = %u\n", features.textureCompressionASTC_LDR); - printf("\ttextureCompressionBC = %u\n", features.textureCompressionBC); - printf("\tocclusionQueryPrecise = %u\n", features.occlusionQueryPrecise); - printf("\tpipelineStatisticsQuery = %u\n", features.pipelineStatisticsQuery); - printf("\tvertexPipelineStoresAndAtomics = %u\n", features.vertexPipelineStoresAndAtomics); - printf("\tfragmentStoresAndAtomics = %u\n", features.fragmentStoresAndAtomics); - printf("\tshaderTessellationAndGeometryPointSize = %u\n", features.shaderTessellationAndGeometryPointSize); - printf("\tshaderImageGatherExtended = %u\n", features.shaderImageGatherExtended); - printf("\tshaderStorageImageExtendedFormats = %u\n", features.shaderStorageImageExtendedFormats); - printf("\tshaderStorageImageMultisample = %u\n", features.shaderStorageImageMultisample); - printf("\tshaderStorageImageReadWithoutFormat = %u\n", features.shaderStorageImageReadWithoutFormat); - printf("\tshaderStorageImageWriteWithoutFormat = %u\n", features.shaderStorageImageWriteWithoutFormat); - printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features.shaderUniformBufferArrayDynamicIndexing); - printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features.shaderSampledImageArrayDynamicIndexing); - printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features.shaderStorageBufferArrayDynamicIndexing); - printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features.shaderStorageImageArrayDynamicIndexing); - printf("\tshaderClipDistance = %u\n", features.shaderClipDistance); - printf("\tshaderCullDistance = %u\n", features.shaderCullDistance); - printf("\tshaderFloat64 = %u\n", features.shaderFloat64); - printf("\tshaderInt64 = %u\n", features.shaderInt64); - printf("\tshaderInt16 = %u\n", features.shaderInt16); - printf("\tshaderResourceResidency = %u\n", features.shaderResourceResidency); - printf("\tshaderResourceMinLod = %u\n", features.shaderResourceMinLod); - printf("\tsparseBinding = %u\n", features.sparseBinding); - printf("\tsparseResidencyBuffer = %u\n", features.sparseResidencyBuffer); - printf("\tsparseResidencyImage2D = %u\n", features.sparseResidencyImage2D); - printf("\tsparseResidencyImage3D = %u\n", features.sparseResidencyImage3D); - printf("\tsparseResidency2Samples = %u\n", features.sparseResidency2Samples); - printf("\tsparseResidency4Samples = %u\n", features.sparseResidency4Samples); - printf("\tsparseResidency8Samples = %u\n", features.sparseResidency8Samples); - printf("\tsparseResidency16Samples = %u\n", features.sparseResidency16Samples); - printf("\tsparseResidencyAliased = %u\n", features.sparseResidencyAliased); - printf("\tvariableMultisampleRate = %u\n", features.variableMultisampleRate); - printf("\tinheritedQueries = %u\n", features.inheritedQueries); - } - if (json_output) { - printf(",\n"); - printf("\t\"VkPhysicalDeviceFeatures\": {\n"); - printf("\t\t\"robustBufferAccess\": %u,\n", features.robustBufferAccess); - printf("\t\t\"fullDrawIndexUint32\": %u,\n", features.fullDrawIndexUint32); - printf("\t\t\"imageCubeArray\": %u,\n", features.imageCubeArray); - printf("\t\t\"independentBlend\": %u,\n", features.independentBlend); - printf("\t\t\"geometryShader\": %u,\n", features.geometryShader); - printf("\t\t\"tessellationShader\": %u,\n", features.tessellationShader); - printf("\t\t\"sampleRateShading\": %u,\n", features.sampleRateShading); - printf("\t\t\"dualSrcBlend\": %u,\n", features.dualSrcBlend); - printf("\t\t\"logicOp\": %u,\n", features.logicOp); - printf("\t\t\"multiDrawIndirect\": %u,\n", features.multiDrawIndirect); - printf("\t\t\"drawIndirectFirstInstance\": %u,\n", features.drawIndirectFirstInstance); - printf("\t\t\"depthClamp\": %u,\n", features.depthClamp); - printf("\t\t\"depthBiasClamp\": %u,\n", features.depthBiasClamp); - printf("\t\t\"fillModeNonSolid\": %u,\n", features.fillModeNonSolid); - printf("\t\t\"depthBounds\": %u,\n", features.depthBounds); - printf("\t\t\"wideLines\": %u,\n", features.wideLines); - printf("\t\t\"largePoints\": %u,\n", features.largePoints); - printf("\t\t\"alphaToOne\": %u,\n", features.alphaToOne); - printf("\t\t\"multiViewport\": %u,\n", features.multiViewport); - printf("\t\t\"samplerAnisotropy\": %u,\n", features.samplerAnisotropy); - printf("\t\t\"textureCompressionETC2\": %u,\n", features.textureCompressionETC2); - printf("\t\t\"textureCompressionASTC_LDR\": %u,\n", features.textureCompressionASTC_LDR); - printf("\t\t\"textureCompressionBC\": %u,\n", features.textureCompressionBC); - printf("\t\t\"occlusionQueryPrecise\": %u,\n", features.occlusionQueryPrecise); - printf("\t\t\"pipelineStatisticsQuery\": %u,\n", features.pipelineStatisticsQuery); - printf("\t\t\"vertexPipelineStoresAndAtomics\": %u,\n", features.vertexPipelineStoresAndAtomics); - printf("\t\t\"fragmentStoresAndAtomics\": %u,\n", features.fragmentStoresAndAtomics); - printf("\t\t\"shaderTessellationAndGeometryPointSize\": %u,\n", features.shaderTessellationAndGeometryPointSize); - printf("\t\t\"shaderImageGatherExtended\": %u,\n", features.shaderImageGatherExtended); - printf("\t\t\"shaderStorageImageExtendedFormats\": %u,\n", features.shaderStorageImageExtendedFormats); - printf("\t\t\"shaderStorageImageMultisample\": %u,\n", features.shaderStorageImageMultisample); - printf("\t\t\"shaderStorageImageReadWithoutFormat\": %u,\n", features.shaderStorageImageReadWithoutFormat); - printf("\t\t\"shaderStorageImageWriteWithoutFormat\": %u,\n", features.shaderStorageImageWriteWithoutFormat); - printf("\t\t\"shaderUniformBufferArrayDynamicIndexing\": %u,\n", features.shaderUniformBufferArrayDynamicIndexing); - printf("\t\t\"shaderSampledImageArrayDynamicIndexing\": %u,\n", features.shaderSampledImageArrayDynamicIndexing); - printf("\t\t\"shaderStorageBufferArrayDynamicIndexing\": %u,\n", features.shaderStorageBufferArrayDynamicIndexing); - printf("\t\t\"shaderStorageImageArrayDynamicIndexing\": %u,\n", features.shaderStorageImageArrayDynamicIndexing); - printf("\t\t\"shaderClipDistance\": %u,\n", features.shaderClipDistance); - printf("\t\t\"shaderCullDistance\": %u,\n", features.shaderCullDistance); - printf("\t\t\"shaderFloat64\": %u,\n", features.shaderFloat64); - printf("\t\t\"shaderInt64\": %u,\n", features.shaderInt64); - printf("\t\t\"shaderInt16\": %u,\n", features.shaderInt16); - printf("\t\t\"shaderResourceResidency\": %u,\n", features.shaderResourceResidency); - printf("\t\t\"shaderResourceMinLod\": %u,\n", features.shaderResourceMinLod); - printf("\t\t\"sparseBinding\": %u,\n", features.sparseBinding); - printf("\t\t\"sparseResidencyBuffer\": %u,\n", features.sparseResidencyBuffer); - printf("\t\t\"sparseResidencyImage2D\": %u,\n", features.sparseResidencyImage2D); - printf("\t\t\"sparseResidencyImage3D\": %u,\n", features.sparseResidencyImage3D); - printf("\t\t\"sparseResidency2Samples\": %u,\n", features.sparseResidency2Samples); - printf("\t\t\"sparseResidency4Samples\": %u,\n", features.sparseResidency4Samples); - printf("\t\t\"sparseResidency8Samples\": %u,\n", features.sparseResidency8Samples); - printf("\t\t\"sparseResidency16Samples\": %u,\n", features.sparseResidency16Samples); - printf("\t\t\"sparseResidencyAliased\": %u,\n", features.sparseResidencyAliased); - printf("\t\t\"variableMultisampleRate\": %u,\n", features.variableMultisampleRate); - printf("\t\t\"inheritedQueries\": %u\n", features.inheritedQueries); - printf("\t}"); - } - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - void *place = gpu->features2.pNext; - while (place) { - struct VkStructureHeader *structure = (struct VkStructureHeader *)place; - if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_8BIT_STORAGE_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDevice8BitStorageFeaturesKHR *b8_store_features = (VkPhysicalDevice8BitStorageFeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevice8BitStorageFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>storageBuffer8BitAccess = <span " - "class='val'>%u</span></summary></details>\n", - b8_store_features->storageBuffer8BitAccess); - fprintf(out, - "\t\t\t\t\t\t<details><summary>uniformAndStorageBuffer8BitAccess = <span " - "class='val'>%u</span></summary></details>\n", - b8_store_features->uniformAndStorageBuffer8BitAccess); - fprintf(out, - "\t\t\t\t\t\t<details><summary>storagePushConstant8 = <span " - "class='val'>%u</span></summary></details>\n", - b8_store_features->storagePushConstant8); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDevice8BitStorageFeatures:\n"); - printf("=====================================\n"); - printf("\tstorageBuffer8BitAccess = %u\n", b8_store_features->storageBuffer8BitAccess); - printf("\tuniformAndStorageBuffer8BitAccess = %u\n", b8_store_features->uniformAndStorageBuffer8BitAccess); - printf("\tstoragePushConstant8 = %u\n", b8_store_features->storagePushConstant8); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_16BIT_STORAGE_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDevice16BitStorageFeaturesKHR *b16_store_features = (VkPhysicalDevice16BitStorageFeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevice16BitStorageFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>storageBuffer16BitAccess = <span " - "class='val'>%u</span></summary></details>\n", - b16_store_features->storageBuffer16BitAccess); - fprintf(out, - "\t\t\t\t\t\t<details><summary>uniformAndStorageBuffer16BitAccess = <span " - "class='val'>%u</span></summary></details>\n", - b16_store_features->uniformAndStorageBuffer16BitAccess); - fprintf(out, - "\t\t\t\t\t\t<details><summary>storagePushConstant16 = <span " - "class='val'>%u</span></summary></details>\n", - b16_store_features->storagePushConstant16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>storageInputOutput16 = <span " - "class='val'>%u</span></summary></details>\n", - b16_store_features->storageInputOutput16); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDevice16BitStorageFeatures:\n"); - printf("=====================================\n"); - printf("\tstorageBuffer16BitAccess = %u\n", b16_store_features->storageBuffer16BitAccess); - printf("\tuniformAndStorageBuffer16BitAccess = %u\n", b16_store_features->uniformAndStorageBuffer16BitAccess); - printf("\tstoragePushConstant16 = %u\n", b16_store_features->storagePushConstant16); - printf("\tstorageInputOutput16 = %u\n", b16_store_features->storageInputOutput16); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR *sampler_ycbcr_features = - (VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceSamplerYcbcrConversionFeatures</summary>\n"); - fprintf( - out, - "\t\t\t\t\t\t<details><summary>samplerYcbcrConversion = <span class='val'>%u</span></summary></details>\n", - sampler_ycbcr_features->samplerYcbcrConversion); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceSamplerYcbcrConversionFeatures:\n"); - printf("===============================================\n"); - printf("\tsamplerYcbcrConversion = %u\n", sampler_ycbcr_features->samplerYcbcrConversion); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceVariablePointerFeaturesKHR *var_pointer_features = - (VkPhysicalDeviceVariablePointerFeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceVariablePointerFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>variablePointersStorageBuffer = <span " - "class='val'>%u</span></summary></details>\n", - var_pointer_features->variablePointersStorageBuffer); - fprintf(out, - "\t\t\t\t\t\t<details><summary>variablePointers = <span " - "class='val'>%u</span></summary></details>\n", - var_pointer_features->variablePointers); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceVariablePointerFeatures:\n"); - printf("========================================\n"); - printf("\tvariablePointersStorageBuffer = %u\n", var_pointer_features->variablePointersStorageBuffer); - printf("\tvariablePointers = %u\n", var_pointer_features->variablePointers); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *blend_op_adv_features = - (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceBlendOperationAdvancedFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>advancedBlendCoherentOperations = <span " - "class='val'>%u</span></summary></details>\n", - blend_op_adv_features->advancedBlendCoherentOperations); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceBlendOperationAdvancedFeatures:\n"); - printf("===============================================\n"); - printf("\tadvancedBlendCoherentOperations = %u\n", blend_op_adv_features->advancedBlendCoherentOperations); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_MULTIVIEW_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceMultiviewFeaturesKHR *multiview_features = (VkPhysicalDeviceMultiviewFeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMultiviewFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>multiview = <span " - "class='val'>%u</span></summary></details>\n", - multiview_features->multiview); - fprintf(out, - "\t\t\t\t\t\t<details><summary>multiviewGeometryShader = <span " - "class='val'>%u</span></summary></details>\n", - multiview_features->multiviewGeometryShader); - fprintf(out, - "\t\t\t\t\t\t<details><summary>multiviewTessellationShader = <span " - "class='val'>%u</span></summary></details>\n", - multiview_features->multiviewTessellationShader); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceMultiviewFeatures:\n"); - printf("==================================\n"); - printf("\tmultiview = %u\n", multiview_features->multiview); - printf("\tmultiviewGeometryShader = %u\n", multiview_features->multiviewGeometryShader); - printf("\tmultiviewTessellationShader = %u\n", multiview_features->multiviewTessellationShader); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceFloat16Int8FeaturesKHR *float_int_features = (VkPhysicalDeviceFloat16Int8FeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFloat16Int8Features</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderFloat16 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_int_features->shaderFloat16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderInt8 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_int_features->shaderInt8); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceFloat16Int8Features:\n"); - printf("====================================\n"); - printf("\tshaderFloat16 = %" PRIuLEAST32 "\n", float_int_features->shaderFloat16); - printf("\tshaderInt8 = %" PRIuLEAST32 "\n", float_int_features->shaderInt8); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *shader_atomic_int64_features = - (VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceShaderAtomicInt64Features</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderBufferInt64Atomics = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - shader_atomic_int64_features->shaderBufferInt64Atomics); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderSharedInt64Atomics = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - shader_atomic_int64_features->shaderSharedInt64Atomics); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceShaderAtomicInt64Features:\n"); - printf("==========================================\n"); - printf("\tshaderBufferInt64Atomics = %" PRIuLEAST32 "\n", - shader_atomic_int64_features->shaderBufferInt64Atomics); - printf("\tshaderSharedInt64Atomics = %" PRIuLEAST32 "\n", - shader_atomic_int64_features->shaderSharedInt64Atomics); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceTransformFeedbackFeaturesEXT *transform_feedback_features = - (VkPhysicalDeviceTransformFeedbackFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceTransformFeedbackFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>transformFeedback = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - transform_feedback_features->transformFeedback); - fprintf(out, - "\t\t\t\t\t\t<details><summary>geometryStreams = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - transform_feedback_features->geometryStreams); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceTransformFeedbackFeatures:\n"); - printf("==========================================\n"); - printf("\ttransformFeedback = %" PRIuLEAST32 "\n", transform_feedback_features->transformFeedback); - printf("\tgeometryStreams = %" PRIuLEAST32 "\n", transform_feedback_features->geometryStreams); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *scalar_block_layout_features = - (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceScalarBlockLayoutFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>scalarBlockLayout = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - scalar_block_layout_features->scalarBlockLayout); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceScalarBlockLayoutFeatures:\n"); - printf("==========================================\n"); - printf("\tscalarBlockLayout = %" PRIuLEAST32 "\n", scalar_block_layout_features->scalarBlockLayout); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceFragmentDensityMapFeaturesEXT *fragment_density_map_features = - (VkPhysicalDeviceFragmentDensityMapFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFragmentDensityMapFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentDensityMap = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_features->fragmentDensityMap); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentDensityMapDynamic = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_features->fragmentDensityMapDynamic); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentDensityMapNonSubsampledImages = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_features->fragmentDensityMapNonSubsampledImages); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceFragmentDensityMapFeatures:\n"); - printf("==========================================\n"); - printf("\tfragmentDensityMap = %" PRIuLEAST32 "\n", - fragment_density_map_features->fragmentDensityMap); - printf("\tfragmentDensityMapDynamic = %" PRIuLEAST32 "\n", - fragment_density_map_features->fragmentDensityMapDynamic); - printf("\tfragmentDensityMapNonSubsampledImages = %" PRIuLEAST32 "\n", - fragment_density_map_features->fragmentDensityMapNonSubsampledImages); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceMemoryPriorityFeaturesEXT *memory_priority_features = - (VkPhysicalDeviceMemoryPriorityFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceMemoryPriorityFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>memoryPriority = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - memory_priority_features->memoryPriority); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceMemoryPriorityFeatures:\n"); - printf("======================================\n"); - printf("\tmemoryPriority = %" PRIuLEAST32 "\n", memory_priority_features->memoryPriority); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceBufferAddressFeaturesEXT *buffer_address_features = - (VkPhysicalDeviceBufferAddressFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceBufferAddressFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>bufferDeviceAddress = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - buffer_address_features->bufferDeviceAddress); - fprintf(out, - "\t\t\t\t\t\t<details><summary>bufferDeviceAddressCaptureReplay = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - buffer_address_features->bufferDeviceAddressCaptureReplay); - fprintf(out, - "\t\t\t\t\t\t<details><summary>bufferDeviceAddressMultiDevice = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - buffer_address_features->bufferDeviceAddressMultiDevice); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceBufferAddressFeatures:\n"); - printf("======================================\n"); - printf("\tbufferDeviceAddress = %" PRIuLEAST32 "\n", buffer_address_features->bufferDeviceAddress); - printf("\tbufferDeviceAddressCaptureReplay = %" PRIuLEAST32 "\n", - buffer_address_features->bufferDeviceAddressCaptureReplay); - printf("\tbufferDeviceAddressMultiDevice = %" PRIuLEAST32 "\n", - buffer_address_features->bufferDeviceAddressMultiDevice); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *ycbcr_image_arrays_features = - (VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceYcbcrImageArraysFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>ycbcrImageArrays = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - ycbcr_image_arrays_features->ycbcrImageArrays); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceYcbcrImageArraysFeatures:\n"); - printf("=========================================\n"); - printf("\tycbcrImageArrays = %" PRIuLEAST32 "\n", ycbcr_image_arrays_features->ycbcrImageArrays); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceHostQueryResetFeaturesEXT *host_query_reset_features = - (VkPhysicalDeviceHostQueryResetFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceHostQueryResetFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>hostQueryReset = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - host_query_reset_features->hostQueryReset); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceHostQueryResetFeatures:\n"); - printf("=======================================\n"); - printf("\thostQueryReset = %" PRIuLEAST32 "\n", host_query_reset_features->hostQueryReset); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceDescriptorIndexingFeaturesEXT *indexing_features = - (VkPhysicalDeviceDescriptorIndexingFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceDescriptorIndexingFeatures</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderInputAttachmentArrayDynamicIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderInputAttachmentArrayDynamicIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderUniformTexelBufferArrayDynamicIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderUniformTexelBufferArrayDynamicIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageTexelBufferArrayDynamicIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderStorageTexelBufferArrayDynamicIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderUniformBufferArrayNonUniformIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderUniformBufferArrayNonUniformIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderSampledImageArrayNonUniformIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderSampledImageArrayNonUniformIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageBufferArrayNonUniformIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderStorageBufferArrayNonUniformIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageImageArrayNonUniformIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderStorageImageArrayNonUniformIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderInputAttachmentArrayNonUniformIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderInputAttachmentArrayNonUniformIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderUniformTexelBufferArrayNonUniformIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderUniformTexelBufferArrayNonUniformIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderStorageTexelBufferArrayNonUniformIndexing = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->shaderStorageTexelBufferArrayNonUniformIndexing); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingUniformBufferUpdateAfterBind = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingUniformBufferUpdateAfterBind); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingSampledImageUpdateAfterBind = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingSampledImageUpdateAfterBind); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingStorageImageUpdateAfterBind = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingStorageImageUpdateAfterBind); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingStorageBufferUpdateAfterBind = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingStorageBufferUpdateAfterBind); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingUniformTexelBufferUpdateAfterBind = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingUniformTexelBufferUpdateAfterBind); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingStorageTexelBufferUpdateAfterBind = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingStorageTexelBufferUpdateAfterBind); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingUpdateUnusedWhilePending = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingUpdateUnusedWhilePending); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingPartiallyBound = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - indexing_features->descriptorBindingPartiallyBound); - fprintf(out, - "\t\t\t\t\t\t<details><summary>descriptorBindingVariableDescriptorCount = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_features->descriptorBindingVariableDescriptorCount); - fprintf(out, - "\t\t\t\t\t\t<details><summary>runtimeDescriptorArray = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - indexing_features->runtimeDescriptorArray); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceDescriptorIndexingFeatures:\n"); - printf("=======================================\n"); - printf("\tshaderInputAttachmentArrayDynamicIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderInputAttachmentArrayDynamicIndexing); - printf("\tshaderUniformTexelBufferArrayDynamicIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderUniformTexelBufferArrayDynamicIndexing); - printf("\tshaderStorageTexelBufferArrayDynamicIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderStorageTexelBufferArrayDynamicIndexing); - printf("\tshaderUniformBufferArrayNonUniformIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderUniformBufferArrayNonUniformIndexing); - printf("\tshaderSampledImageArrayNonUniformIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderSampledImageArrayNonUniformIndexing); - printf("\tshaderStorageBufferArrayNonUniformIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderStorageBufferArrayNonUniformIndexing); - printf("\tshaderStorageImageArrayNonUniformIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderStorageImageArrayNonUniformIndexing); - printf("\tshaderInputAttachmentArrayNonUniformIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderInputAttachmentArrayNonUniformIndexing); - printf("\tshaderUniformTexelBufferArrayNonUniformIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderUniformTexelBufferArrayNonUniformIndexing); - printf("\tshaderStorageTexelBufferArrayNonUniformIndexing = %" PRIuLEAST32 "\n", - indexing_features->shaderStorageTexelBufferArrayNonUniformIndexing); - printf("\tdescriptorBindingUniformBufferUpdateAfterBind = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingUniformBufferUpdateAfterBind); - printf("\tdescriptorBindingSampledImageUpdateAfterBind = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingSampledImageUpdateAfterBind); - printf("\tdescriptorBindingStorageImageUpdateAfterBind = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingStorageImageUpdateAfterBind); - printf("\tdescriptorBindingStorageBufferUpdateAfterBind = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingStorageBufferUpdateAfterBind); - printf("\tdescriptorBindingUniformTexelBufferUpdateAfterBind = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingUniformTexelBufferUpdateAfterBind); - printf("\tdescriptorBindingStorageTexelBufferUpdateAfterBind = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingStorageTexelBufferUpdateAfterBind); - printf("\tdescriptorBindingUpdateUnusedWhilePending = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingUpdateUnusedWhilePending); - printf("\tdescriptorBindingPartiallyBound = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingPartiallyBound); - printf("\tdescriptorBindingVariableDescriptorCount = %" PRIuLEAST32 "\n", - indexing_features->descriptorBindingVariableDescriptorCount); - printf("\truntimeDescriptorArray = %" PRIuLEAST32 "\n", indexing_features->runtimeDescriptorArray); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, - gpu->device_extensions, gpu->device_extension_count)) { - VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *standard_features = - (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)structure; - if (html_output) { - fprintf(out, - "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>uniformBufferStandardLayout = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - standard_features->uniformBufferStandardLayout); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR:\n"); - printf("=======================================================\n"); - printf("\tuniformBufferStandardLayout = %" PRIuLEAST32 "\n", standard_features->uniformBufferStandardLayout); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *fragment_shader_features = - (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentShaderPixelInterlock = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - fragment_shader_features->fragmentShaderPixelInterlock); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentShaderSampleInterlock = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - fragment_shader_features->fragmentShaderSampleInterlock); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentShaderShadingRateInterlock = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - fragment_shader_features->fragmentShaderShadingRateInterlock); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceFragmentShaderInterlockFeaturesEXT:\n"); - printf("===================================================\n"); - printf("\tfragmentShaderPixelInterlock = %" PRIuLEAST32 "\n", - fragment_shader_features->fragmentShaderPixelInterlock); - printf("\tfragmentShaderSampleInterlock = %" PRIuLEAST32 "\n", - fragment_shader_features->fragmentShaderSampleInterlock); - printf("\tfragmentShaderShadingRateInterlock = %" PRIuLEAST32 "\n", - fragment_shader_features->fragmentShaderShadingRateInterlock); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceImagelessFramebufferFeaturesKHR *imageless_framebuffer = - (VkPhysicalDeviceImagelessFramebufferFeaturesKHR *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceImagelessFramebufferFeaturesKHR</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>imagelessFramebuffer = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - imageless_framebuffer->imagelessFramebuffer); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceImagelessFramebufferFeaturesKHR:\n"); - printf("================================================\n"); - printf("\timagelessFramebuffer = %" PRIuLEAST32 "\n", imageless_framebuffer->imagelessFramebuffer); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *texel_buffer_alignment = - (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>texelBufferAlignment = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - texel_buffer_alignment->texelBufferAlignment); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceTexelBufferAlignmentFeaturesEXT:\n"); - printf("================================================\n"); - printf("\ttexelBufferAlignment = %" PRIuLEAST32 "\n", texel_buffer_alignment->texelBufferAlignment); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, - gpu->device_extensions, gpu->device_extension_count)) { - VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *shader_helper = - (VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *)structure; - if (html_output) { - fprintf(out, - "\t\t\t\t\t<details><summary>VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderDemoteToHelperInvocation = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - shader_helper->shaderDemoteToHelperInvocation); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT:\n"); - printf("===================================================\n"); - printf("\tshaderDemoteToHelperInvocation = %" PRIuLEAST32 "\n", shader_helper->shaderDemoteToHelperInvocation); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceIndexTypeUint8FeaturesEXT *index_type_uint8_features = - (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceIndexTypeUint8FeaturesEXT</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>indexTypeUint8 = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - index_type_uint8_features->indexTypeUint8); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceIndexTypeUint8FeaturesEXT:\n"); - printf("===================================================\n"); - printf("\tindexTypeUint8 = %" PRIuLEAST32 "\n", index_type_uint8_features->indexTypeUint8); - } - } - place = structure->pNext; - } - } -} - -static void AppDumpSparseProps(const VkPhysicalDeviceSparseProperties *sparse_props, FILE *out) { - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceSparseProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>residencyStandard2DBlockShape = <span " - "class='val'>%u</span></summary></details>\n", - sparse_props->residencyStandard2DBlockShape); - fprintf(out, - "\t\t\t\t\t\t<details><summary>residencyStandard2DMultisampleBlockShape = <span " - "class='val'>%u</span></summary></details>\n", - sparse_props->residencyStandard2DMultisampleBlockShape); - fprintf(out, - "\t\t\t\t\t\t<details><summary>residencyStandard3DBlockShape = <span " - "class='val'>%u</span></summary></details>\n", - sparse_props->residencyStandard3DBlockShape); - fprintf(out, - "\t\t\t\t\t\t<details><summary>residencyAlignedMipSize = <span " - "class='val'>%u</span></summary></details>\n", - sparse_props->residencyAlignedMipSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>residencyNonResidentStrict = <span " - "class='val'>%u</span></summary></details>\n", - sparse_props->residencyNonResidentStrict); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\tVkPhysicalDeviceSparseProperties:\n"); - printf("\t---------------------------------\n"); - printf("\t\tresidencyStandard2DBlockShape = %u\n", sparse_props->residencyStandard2DBlockShape); - printf("\t\tresidencyStandard2DMultisampleBlockShape = %u\n", sparse_props->residencyStandard2DMultisampleBlockShape); - printf("\t\tresidencyStandard3DBlockShape = %u\n", sparse_props->residencyStandard3DBlockShape); - printf("\t\tresidencyAlignedMipSize = %u\n", sparse_props->residencyAlignedMipSize); - printf("\t\tresidencyNonResidentStrict = %u\n", sparse_props->residencyNonResidentStrict); - } - if (json_output) { - printf(",\n"); - printf("\t\t\"sparseProperties\": {\n"); - printf("\t\t\t\"residencyStandard2DBlockShape\": %u,\n", sparse_props->residencyStandard2DBlockShape); - printf("\t\t\t\"residencyStandard2DMultisampleBlockShape\": %u,\n", sparse_props->residencyStandard2DMultisampleBlockShape); - printf("\t\t\t\"residencyStandard3DBlockShape\": %u,\n", sparse_props->residencyStandard3DBlockShape); - printf("\t\t\t\"residencyAlignedMipSize\": %u,\n", sparse_props->residencyAlignedMipSize); - printf("\t\t\t\"residencyNonResidentStrict\": %u\n", sparse_props->residencyNonResidentStrict); - printf("\t\t}"); - } -} - -static void AppDumpLimits(const VkPhysicalDeviceLimits *limits, FILE *out) { - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceLimits</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxImageDimension1D = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxImageDimension1D); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxImageDimension2D = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxImageDimension2D); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxImageDimension3D = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxImageDimension3D); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxImageDimensionCube = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxImageDimensionCube); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxImageArrayLayers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxImageArrayLayers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTexelBufferElements = <span class='val'>0x%" PRIxLEAST32 - "</span></summary></details>\n", - limits->maxTexelBufferElements); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxUniformBufferRange = <span class='val'>0x%" PRIxLEAST32 - "</span></summary></details>\n", - limits->maxUniformBufferRange); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxStorageBufferRange = <span class='val'>0x%" PRIxLEAST32 - "</span></summary></details>\n", - limits->maxStorageBufferRange); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPushConstantsSize = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPushConstantsSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxMemoryAllocationCount = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxMemoryAllocationCount); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxSamplerAllocationCount = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxSamplerAllocationCount); - fprintf(out, - "\t\t\t\t\t\t<details><summary>bufferImageGranularity = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->bufferImageGranularity); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sparseAddressSpaceSize = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->sparseAddressSpaceSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxBoundDescriptorSets = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxBoundDescriptorSets); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorSamplers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPerStageDescriptorSamplers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUniformBuffers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPerStageDescriptorUniformBuffers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorStorageBuffers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPerStageDescriptorStorageBuffers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorSampledImages = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPerStageDescriptorSampledImages); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorStorageImages = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPerStageDescriptorStorageImages); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorInputAttachments = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPerStageDescriptorInputAttachments); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerStageResources = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxPerStageResources); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetSamplers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetSamplers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetUniformBuffers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetUniformBuffers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetUniformBuffersDynamic = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetUniformBuffersDynamic); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageBuffers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetStorageBuffers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageBuffersDynamic = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetStorageBuffersDynamic); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetSampledImages = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetSampledImages); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageImages = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetStorageImages); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDescriptorSetInputAttachments = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDescriptorSetInputAttachments); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxVertexInputAttributes = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxVertexInputAttributes); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxVertexInputBindings = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxVertexInputBindings); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxVertexInputAttributeOffset = <span class='val'>0x%" PRIxLEAST32 - "</span></summary></details>\n", - limits->maxVertexInputAttributeOffset); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxVertexInputBindingStride = <span class='val'>0x%" PRIxLEAST32 - "</span></summary></details>\n", - limits->maxVertexInputBindingStride); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxVertexOutputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxVertexOutputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationGenerationLevel = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationGenerationLevel); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationPatchSize = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationPatchSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationControlPerVertexInputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationControlPerVertexInputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationControlPerVertexOutputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationControlPerVertexOutputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationControlPerPatchOutputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationControlPerPatchOutputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationControlTotalOutputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationControlTotalOutputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationEvaluationInputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationEvaluationInputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTessellationEvaluationOutputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxTessellationEvaluationOutputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxGeometryShaderInvocations = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxGeometryShaderInvocations); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxGeometryInputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxGeometryInputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxGeometryOutputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxGeometryOutputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxGeometryOutputVertices = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxGeometryOutputVertices); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxGeometryTotalOutputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxGeometryTotalOutputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxFragmentInputComponents = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxFragmentInputComponents); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxFragmentOutputAttachments = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxFragmentOutputAttachments); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxFragmentDualSrcAttachments = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxFragmentDualSrcAttachments); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxFragmentCombinedOutputResources = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxFragmentCombinedOutputResources); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeSharedMemorySize = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - limits->maxComputeSharedMemorySize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[0] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxComputeWorkGroupCount[0]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[1] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxComputeWorkGroupCount[1]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[2] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxComputeWorkGroupCount[2]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupInvocations = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxComputeWorkGroupInvocations); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[0] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxComputeWorkGroupSize[0]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[1] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxComputeWorkGroupSize[1]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[2] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxComputeWorkGroupSize[2]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>subPixelPrecisionBits = <span " - "class='val'>%u</span></summary></details>\n", - limits->subPixelPrecisionBits); - fprintf(out, - "\t\t\t\t\t\t<details><summary>subTexelPrecisionBits = <span " - "class='val'>%u</span></summary></details>\n", - limits->subTexelPrecisionBits); - fprintf(out, - "\t\t\t\t\t\t<details><summary>mipmapPrecisionBits = <span " - "class='val'>%u</span></summary></details>\n", - limits->mipmapPrecisionBits); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDrawIndexedIndexValue = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDrawIndexedIndexValue); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDrawIndirectCount = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxDrawIndirectCount); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxSamplerLodBias = <span " - "class='val'>%f</span></summary></details>\n", - limits->maxSamplerLodBias); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxSamplerAnisotropy = <span " - "class='val'>%f</span></summary></details>\n", - limits->maxSamplerAnisotropy); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxViewports = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxViewports); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxViewportDimensions[0] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxViewportDimensions[0]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxViewportDimensions[1] = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxViewportDimensions[1]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>viewportBoundsRange[0] = <span " - "class='val'>%13f</span></summary></details>\n", - limits->viewportBoundsRange[0]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>viewportBoundsRange[1] = <span " - "class='val'>%13f</span></summary></details>\n", - limits->viewportBoundsRange[1]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>viewportSubPixelBits = <span " - "class='val'>%u</span></summary></details>\n", - limits->viewportSubPixelBits); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minMemoryMapAlignment = <span class='val'>" PRINTF_SIZE_T_SPECIFIER - "</span></summary></details>\n", - limits->minMemoryMapAlignment); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minTexelBufferOffsetAlignment = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->minTexelBufferOffsetAlignment); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minUniformBufferOffsetAlignment = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->minUniformBufferOffsetAlignment); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minStorageBufferOffsetAlignment = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->minStorageBufferOffsetAlignment); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minTexelOffset = <span " - "class='val'>%3d</span></summary></details>\n", - limits->minTexelOffset); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTexelOffset = <span " - "class='val'>%3d</span></summary></details>\n", - limits->maxTexelOffset); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minTexelGatherOffset = <span " - "class='val'>%3d</span></summary></details>\n", - limits->minTexelGatherOffset); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTexelGatherOffset = <span " - "class='val'>%3d</span></summary></details>\n", - limits->maxTexelGatherOffset); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minInterpolationOffset = <span " - "class='val'>%9f</span></summary></details>\n", - limits->minInterpolationOffset); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxInterpolationOffset = <span " - "class='val'>%9f</span></summary></details>\n", - limits->maxInterpolationOffset); - fprintf(out, - "\t\t\t\t\t\t<details><summary>subPixelInterpolationOffsetBits = <span " - "class='val'>%u</span></summary></details>\n", - limits->subPixelInterpolationOffsetBits); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxFramebufferWidth = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxFramebufferWidth); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxFramebufferHeight = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxFramebufferHeight); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxFramebufferLayers = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxFramebufferLayers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>framebufferColorSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->framebufferColorSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>framebufferDepthSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->framebufferDepthSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>framebufferStencilSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->framebufferStencilSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>framebufferNoAttachmentsSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->framebufferNoAttachmentsSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxColorAttachments = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxColorAttachments); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sampledImageColorSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->sampledImageColorSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sampledImageDepthSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->sampledImageDepthSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sampledImageStencilSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->sampledImageStencilSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>sampledImageIntegerSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->sampledImageIntegerSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>storageImageSampleCounts = <span " - "class='val'>%u</span></summary></details>\n", - limits->storageImageSampleCounts); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxSampleMaskWords = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxSampleMaskWords); - fprintf(out, - "\t\t\t\t\t\t<details><summary>timestampComputeAndGraphics = <span " - "class='val'>%u</span></summary></details>\n", - limits->timestampComputeAndGraphics); - fprintf(out, - "\t\t\t\t\t\t<details><summary>timestampPeriod = <span " - "class='val'>%f</span></summary></details>\n", - limits->timestampPeriod); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxClipDistances = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxClipDistances); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxCullDistances = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxCullDistances); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxCombinedClipAndCullDistances = <span " - "class='val'>%u</span></summary></details>\n", - limits->maxCombinedClipAndCullDistances); - fprintf(out, - "\t\t\t\t\t\t<details><summary>discreteQueuePriorities = <span " - "class='val'>%u</span></summary></details>\n", - limits->discreteQueuePriorities); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pointSizeRange[0] = <span " - "class='val'>%f</span></summary></details>\n", - limits->pointSizeRange[0]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pointSizeRange[1] = <span " - "class='val'>%f</span></summary></details>\n", - limits->pointSizeRange[1]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>lineWidthRange[0] = <span " - "class='val'>%f</span></summary></details>\n", - limits->lineWidthRange[0]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>lineWidthRange[1] = <span " - "class='val'>%f</span></summary></details>\n", - limits->lineWidthRange[1]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pointSizeGranularity = <span " - "class='val'>%f</span></summary></details>\n", - limits->pointSizeGranularity); - fprintf(out, - "\t\t\t\t\t\t<details><summary>lineWidthGranularity = <span " - "class='val'>%f</span></summary></details>\n", - limits->lineWidthGranularity); - fprintf(out, - "\t\t\t\t\t\t<details><summary>strictLines = <span " - "class='val'>%u</span></summary></details>\n", - limits->strictLines); - fprintf(out, - "\t\t\t\t\t\t<details><summary>standardSampleLocations = <span " - "class='val'>%u</span></summary></details>\n", - limits->standardSampleLocations); - fprintf(out, - "\t\t\t\t\t\t<details><summary>optimalBufferCopyOffsetAlignment = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->optimalBufferCopyOffsetAlignment); - fprintf(out, - "\t\t\t\t\t\t<details><summary>optimalBufferCopyRowPitchAlignment = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->optimalBufferCopyRowPitchAlignment); - fprintf(out, - "\t\t\t\t\t\t<details><summary>nonCoherentAtomSize = <span class='val'>0x%" PRIxLEAST64 - "</span></summary></details>\n", - limits->nonCoherentAtomSize); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\tVkPhysicalDeviceLimits:\n"); - printf("\t-----------------------\n"); - printf("\t\tmaxImageDimension1D = %u\n", limits->maxImageDimension1D); - printf("\t\tmaxImageDimension2D = %u\n", limits->maxImageDimension2D); - printf("\t\tmaxImageDimension3D = %u\n", limits->maxImageDimension3D); - printf("\t\tmaxImageDimensionCube = %u\n", limits->maxImageDimensionCube); - printf("\t\tmaxImageArrayLayers = %u\n", limits->maxImageArrayLayers); - printf("\t\tmaxTexelBufferElements = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferElements); - printf("\t\tmaxUniformBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferRange); - printf("\t\tmaxStorageBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferRange); - printf("\t\tmaxPushConstantsSize = %u\n", limits->maxPushConstantsSize); - printf("\t\tmaxMemoryAllocationCount = %u\n", limits->maxMemoryAllocationCount); - printf("\t\tmaxSamplerAllocationCount = %u\n", limits->maxSamplerAllocationCount); - printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity); - printf("\t\tsparseAddressSpaceSize = 0x%" PRIxLEAST64 "\n", limits->sparseAddressSpaceSize); - printf("\t\tmaxBoundDescriptorSets = %u\n", limits->maxBoundDescriptorSets); - printf("\t\tmaxPerStageDescriptorSamplers = %u\n", limits->maxPerStageDescriptorSamplers); - printf("\t\tmaxPerStageDescriptorUniformBuffers = %u\n", limits->maxPerStageDescriptorUniformBuffers); - printf("\t\tmaxPerStageDescriptorStorageBuffers = %u\n", limits->maxPerStageDescriptorStorageBuffers); - printf("\t\tmaxPerStageDescriptorSampledImages = %u\n", limits->maxPerStageDescriptorSampledImages); - printf("\t\tmaxPerStageDescriptorStorageImages = %u\n", limits->maxPerStageDescriptorStorageImages); - printf("\t\tmaxPerStageDescriptorInputAttachments = %u\n", limits->maxPerStageDescriptorInputAttachments); - printf("\t\tmaxPerStageResources = %u\n", limits->maxPerStageResources); - printf("\t\tmaxDescriptorSetSamplers = %u\n", limits->maxDescriptorSetSamplers); - printf("\t\tmaxDescriptorSetUniformBuffers = %u\n", limits->maxDescriptorSetUniformBuffers); - printf("\t\tmaxDescriptorSetUniformBuffersDynamic = %u\n", limits->maxDescriptorSetUniformBuffersDynamic); - printf("\t\tmaxDescriptorSetStorageBuffers = %u\n", limits->maxDescriptorSetStorageBuffers); - printf("\t\tmaxDescriptorSetStorageBuffersDynamic = %u\n", limits->maxDescriptorSetStorageBuffersDynamic); - printf("\t\tmaxDescriptorSetSampledImages = %u\n", limits->maxDescriptorSetSampledImages); - printf("\t\tmaxDescriptorSetStorageImages = %u\n", limits->maxDescriptorSetStorageImages); - printf("\t\tmaxDescriptorSetInputAttachments = %u\n", limits->maxDescriptorSetInputAttachments); - printf("\t\tmaxVertexInputAttributes = %u\n", limits->maxVertexInputAttributes); - printf("\t\tmaxVertexInputBindings = %u\n", limits->maxVertexInputBindings); - printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset); - printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride); - printf("\t\tmaxVertexOutputComponents = %u\n", limits->maxVertexOutputComponents); - printf("\t\tmaxTessellationGenerationLevel = %u\n", limits->maxTessellationGenerationLevel); - printf("\t\tmaxTessellationPatchSize = %u\n", limits->maxTessellationPatchSize); - printf("\t\tmaxTessellationControlPerVertexInputComponents = %u\n", - limits->maxTessellationControlPerVertexInputComponents); - printf("\t\tmaxTessellationControlPerVertexOutputComponents = %u\n", - limits->maxTessellationControlPerVertexOutputComponents); - printf("\t\tmaxTessellationControlPerPatchOutputComponents = %u\n", - limits->maxTessellationControlPerPatchOutputComponents); - printf("\t\tmaxTessellationControlTotalOutputComponents = %u\n", limits->maxTessellationControlTotalOutputComponents); - printf("\t\tmaxTessellationEvaluationInputComponents = %u\n", limits->maxTessellationEvaluationInputComponents); - printf("\t\tmaxTessellationEvaluationOutputComponents = %u\n", limits->maxTessellationEvaluationOutputComponents); - printf("\t\tmaxGeometryShaderInvocations = %u\n", limits->maxGeometryShaderInvocations); - printf("\t\tmaxGeometryInputComponents = %u\n", limits->maxGeometryInputComponents); - printf("\t\tmaxGeometryOutputComponents = %u\n", limits->maxGeometryOutputComponents); - printf("\t\tmaxGeometryOutputVertices = %u\n", limits->maxGeometryOutputVertices); - printf("\t\tmaxGeometryTotalOutputComponents = %u\n", limits->maxGeometryTotalOutputComponents); - printf("\t\tmaxFragmentInputComponents = %u\n", limits->maxFragmentInputComponents); - printf("\t\tmaxFragmentOutputAttachments = %u\n", limits->maxFragmentOutputAttachments); - printf("\t\tmaxFragmentDualSrcAttachments = %u\n", limits->maxFragmentDualSrcAttachments); - printf("\t\tmaxFragmentCombinedOutputResources = %u\n", limits->maxFragmentCombinedOutputResources); - printf("\t\tmaxComputeSharedMemorySize = %" PRIuLEAST32 "\n", limits->maxComputeSharedMemorySize); - printf("\t\tmaxComputeWorkGroupCount[0] = %u\n", limits->maxComputeWorkGroupCount[0]); - printf("\t\tmaxComputeWorkGroupCount[1] = %u\n", limits->maxComputeWorkGroupCount[1]); - printf("\t\tmaxComputeWorkGroupCount[2] = %u\n", limits->maxComputeWorkGroupCount[2]); - printf("\t\tmaxComputeWorkGroupInvocations = %u\n", limits->maxComputeWorkGroupInvocations); - printf("\t\tmaxComputeWorkGroupSize[0] = %u\n", limits->maxComputeWorkGroupSize[0]); - printf("\t\tmaxComputeWorkGroupSize[1] = %u\n", limits->maxComputeWorkGroupSize[1]); - printf("\t\tmaxComputeWorkGroupSize[2] = %u\n", limits->maxComputeWorkGroupSize[2]); - printf("\t\tsubPixelPrecisionBits = %u\n", limits->subPixelPrecisionBits); - printf("\t\tsubTexelPrecisionBits = %u\n", limits->subTexelPrecisionBits); - printf("\t\tmipmapPrecisionBits = %u\n", limits->mipmapPrecisionBits); - printf("\t\tmaxDrawIndexedIndexValue = %u\n", limits->maxDrawIndexedIndexValue); - printf("\t\tmaxDrawIndirectCount = %u\n", limits->maxDrawIndirectCount); - printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias); - printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy); - printf("\t\tmaxViewports = %u\n", limits->maxViewports); - printf("\t\tmaxViewportDimensions[0] = %u\n", limits->maxViewportDimensions[0]); - printf("\t\tmaxViewportDimensions[1] = %u\n", limits->maxViewportDimensions[1]); - printf("\t\tviewportBoundsRange[0] = %13f\n", limits->viewportBoundsRange[0]); - printf("\t\tviewportBoundsRange[1] = %13f\n", limits->viewportBoundsRange[1]); - printf("\t\tviewportSubPixelBits = %u\n", limits->viewportSubPixelBits); - printf("\t\tminMemoryMapAlignment = " PRINTF_SIZE_T_SPECIFIER "\n", limits->minMemoryMapAlignment); - printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minTexelBufferOffsetAlignment); - printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minUniformBufferOffsetAlignment); - printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minStorageBufferOffsetAlignment); - printf("\t\tminTexelOffset = %3d\n", limits->minTexelOffset); - printf("\t\tmaxTexelOffset = %3d\n", limits->maxTexelOffset); - printf("\t\tminTexelGatherOffset = %3d\n", limits->minTexelGatherOffset); - printf("\t\tmaxTexelGatherOffset = %3d\n", limits->maxTexelGatherOffset); - printf("\t\tminInterpolationOffset = %9f\n", limits->minInterpolationOffset); - printf("\t\tmaxInterpolationOffset = %9f\n", limits->maxInterpolationOffset); - printf("\t\tsubPixelInterpolationOffsetBits = %u\n", limits->subPixelInterpolationOffsetBits); - printf("\t\tmaxFramebufferWidth = %u\n", limits->maxFramebufferWidth); - printf("\t\tmaxFramebufferHeight = %u\n", limits->maxFramebufferHeight); - printf("\t\tmaxFramebufferLayers = %u\n", limits->maxFramebufferLayers); - printf("\t\tframebufferColorSampleCounts = %u\n", limits->framebufferColorSampleCounts); - printf("\t\tframebufferDepthSampleCounts = %u\n", limits->framebufferDepthSampleCounts); - printf("\t\tframebufferStencilSampleCounts = %u\n", limits->framebufferStencilSampleCounts); - printf("\t\tframebufferNoAttachmentsSampleCounts = %u\n", limits->framebufferNoAttachmentsSampleCounts); - printf("\t\tmaxColorAttachments = %u\n", limits->maxColorAttachments); - printf("\t\tsampledImageColorSampleCounts = %u\n", limits->sampledImageColorSampleCounts); - printf("\t\tsampledImageDepthSampleCounts = %u\n", limits->sampledImageDepthSampleCounts); - printf("\t\tsampledImageStencilSampleCounts = %u\n", limits->sampledImageStencilSampleCounts); - printf("\t\tsampledImageIntegerSampleCounts = %u\n", limits->sampledImageIntegerSampleCounts); - printf("\t\tstorageImageSampleCounts = %u\n", limits->storageImageSampleCounts); - printf("\t\tmaxSampleMaskWords = %u\n", limits->maxSampleMaskWords); - printf("\t\ttimestampComputeAndGraphics = %u\n", limits->timestampComputeAndGraphics); - printf("\t\ttimestampPeriod = %f\n", limits->timestampPeriod); - printf("\t\tmaxClipDistances = %u\n", limits->maxClipDistances); - printf("\t\tmaxCullDistances = %u\n", limits->maxCullDistances); - printf("\t\tmaxCombinedClipAndCullDistances = %u\n", limits->maxCombinedClipAndCullDistances); - printf("\t\tdiscreteQueuePriorities = %u\n", limits->discreteQueuePriorities); - printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0]); - printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1]); - printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0]); - printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1]); - printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity); - printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity); - printf("\t\tstrictLines = %u\n", limits->strictLines); - printf("\t\tstandardSampleLocations = %u\n", limits->standardSampleLocations); - printf("\t\toptimalBufferCopyOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyOffsetAlignment); - printf("\t\toptimalBufferCopyRowPitchAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyRowPitchAlignment); - printf("\t\tnonCoherentAtomSize = 0x%" PRIxLEAST64 "\n", limits->nonCoherentAtomSize); - } - if (json_output) { - printf(",\n"); - printf("\t\t\"limits\": {\n"); - printf("\t\t\t\"maxImageDimension1D\": %u,\n", limits->maxImageDimension1D); - printf("\t\t\t\"maxImageDimension2D\": %u,\n", limits->maxImageDimension2D); - printf("\t\t\t\"maxImageDimension3D\": %u,\n", limits->maxImageDimension3D); - printf("\t\t\t\"maxImageDimensionCube\": %u,\n", limits->maxImageDimensionCube); - printf("\t\t\t\"maxImageArrayLayers\": %u,\n", limits->maxImageArrayLayers); - printf("\t\t\t\"maxTexelBufferElements\": %u,\n", limits->maxTexelBufferElements); - printf("\t\t\t\"maxUniformBufferRange\": %u,\n", limits->maxUniformBufferRange); - printf("\t\t\t\"maxStorageBufferRange\": %u,\n", limits->maxStorageBufferRange); - printf("\t\t\t\"maxPushConstantsSize\": %u,\n", limits->maxPushConstantsSize); - printf("\t\t\t\"maxMemoryAllocationCount\": %u,\n", limits->maxMemoryAllocationCount); - printf("\t\t\t\"maxSamplerAllocationCount\": %u,\n", limits->maxSamplerAllocationCount); - printf("\t\t\t\"bufferImageGranularity\": %llu,\n", (unsigned long long)limits->bufferImageGranularity); - printf("\t\t\t\"sparseAddressSpaceSize\": %llu,\n", (unsigned long long)limits->sparseAddressSpaceSize); - printf("\t\t\t\"maxBoundDescriptorSets\": %u,\n", limits->maxBoundDescriptorSets); - printf("\t\t\t\"maxPerStageDescriptorSamplers\": %u,\n", limits->maxPerStageDescriptorSamplers); - printf("\t\t\t\"maxPerStageDescriptorUniformBuffers\": %u,\n", limits->maxPerStageDescriptorUniformBuffers); - printf("\t\t\t\"maxPerStageDescriptorStorageBuffers\": %u,\n", limits->maxPerStageDescriptorStorageBuffers); - printf("\t\t\t\"maxPerStageDescriptorSampledImages\": %u,\n", limits->maxPerStageDescriptorSampledImages); - printf("\t\t\t\"maxPerStageDescriptorStorageImages\": %u,\n", limits->maxPerStageDescriptorStorageImages); - printf("\t\t\t\"maxPerStageDescriptorInputAttachments\": %u,\n", limits->maxPerStageDescriptorInputAttachments); - printf("\t\t\t\"maxPerStageResources\": %u,\n", limits->maxPerStageResources); - printf("\t\t\t\"maxDescriptorSetSamplers\": %u,\n", limits->maxDescriptorSetSamplers); - printf("\t\t\t\"maxDescriptorSetUniformBuffers\": %u,\n", limits->maxDescriptorSetUniformBuffers); - printf("\t\t\t\"maxDescriptorSetUniformBuffersDynamic\": %u,\n", limits->maxDescriptorSetUniformBuffersDynamic); - printf("\t\t\t\"maxDescriptorSetStorageBuffers\": %u,\n", limits->maxDescriptorSetStorageBuffers); - printf("\t\t\t\"maxDescriptorSetStorageBuffersDynamic\": %u,\n", limits->maxDescriptorSetStorageBuffersDynamic); - printf("\t\t\t\"maxDescriptorSetSampledImages\": %u,\n", limits->maxDescriptorSetSampledImages); - printf("\t\t\t\"maxDescriptorSetStorageImages\": %u,\n", limits->maxDescriptorSetStorageImages); - printf("\t\t\t\"maxDescriptorSetInputAttachments\": %u,\n", limits->maxDescriptorSetInputAttachments); - printf("\t\t\t\"maxVertexInputAttributes\": %u,\n", limits->maxVertexInputAttributes); - printf("\t\t\t\"maxVertexInputBindings\": %u,\n", limits->maxVertexInputBindings); - printf("\t\t\t\"maxVertexInputAttributeOffset\": %u,\n", limits->maxVertexInputAttributeOffset); - printf("\t\t\t\"maxVertexInputBindingStride\": %u,\n", limits->maxVertexInputBindingStride); - printf("\t\t\t\"maxVertexOutputComponents\": %u,\n", limits->maxVertexOutputComponents); - printf("\t\t\t\"maxTessellationGenerationLevel\": %u,\n", limits->maxTessellationGenerationLevel); - printf("\t\t\t\"maxTessellationPatchSize\": %u,\n", limits->maxTessellationPatchSize); - printf("\t\t\t\"maxTessellationControlPerVertexInputComponents\": %u,\n", - limits->maxTessellationControlPerVertexInputComponents); - printf("\t\t\t\"maxTessellationControlPerVertexOutputComponents\": %u,\n", - limits->maxTessellationControlPerVertexOutputComponents); - printf("\t\t\t\"maxTessellationControlPerPatchOutputComponents\": %u,\n", - limits->maxTessellationControlPerPatchOutputComponents); - printf("\t\t\t\"maxTessellationControlTotalOutputComponents\": %u,\n", limits->maxTessellationControlTotalOutputComponents); - printf("\t\t\t\"maxTessellationEvaluationInputComponents\": %u,\n", limits->maxTessellationEvaluationInputComponents); - printf("\t\t\t\"maxTessellationEvaluationOutputComponents\": %u,\n", limits->maxTessellationEvaluationOutputComponents); - printf("\t\t\t\"maxGeometryShaderInvocations\": %u,\n", limits->maxGeometryShaderInvocations); - printf("\t\t\t\"maxGeometryInputComponents\": %u,\n", limits->maxGeometryInputComponents); - printf("\t\t\t\"maxGeometryOutputComponents\": %u,\n", limits->maxGeometryOutputComponents); - printf("\t\t\t\"maxGeometryOutputVertices\": %u,\n", limits->maxGeometryOutputVertices); - printf("\t\t\t\"maxGeometryTotalOutputComponents\": %u,\n", limits->maxGeometryTotalOutputComponents); - printf("\t\t\t\"maxFragmentInputComponents\": %u,\n", limits->maxFragmentInputComponents); - printf("\t\t\t\"maxFragmentOutputAttachments\": %u,\n", limits->maxFragmentOutputAttachments); - printf("\t\t\t\"maxFragmentDualSrcAttachments\": %u,\n", limits->maxFragmentDualSrcAttachments); - printf("\t\t\t\"maxFragmentCombinedOutputResources\": %u,\n", limits->maxFragmentCombinedOutputResources); - printf("\t\t\t\"maxComputeSharedMemorySize\": %u,\n", limits->maxComputeSharedMemorySize); - printf("\t\t\t\"maxComputeWorkGroupCount\": [\n"); - printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupCount[0]); - printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupCount[1]); - printf("\t\t\t\t%u\n", limits->maxComputeWorkGroupCount[2]); - printf("\t\t\t],\n"); - printf("\t\t\t\"maxComputeWorkGroupInvocations\": %u,\n", limits->maxComputeWorkGroupInvocations); - printf("\t\t\t\"maxComputeWorkGroupSize\": [\n"); - printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupSize[0]); - printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupSize[1]); - printf("\t\t\t\t%u\n", limits->maxComputeWorkGroupSize[2]); - printf("\t\t\t],\n"); - printf("\t\t\t\"subPixelPrecisionBits\": %u,\n", limits->subPixelPrecisionBits); - printf("\t\t\t\"subTexelPrecisionBits\": %u,\n", limits->subTexelPrecisionBits); - printf("\t\t\t\"mipmapPrecisionBits\": %u,\n", limits->mipmapPrecisionBits); - printf("\t\t\t\"maxDrawIndexedIndexValue\": %u,\n", limits->maxDrawIndexedIndexValue); - printf("\t\t\t\"maxDrawIndirectCount\": %u,\n", limits->maxDrawIndirectCount); - printf("\t\t\t\"maxSamplerLodBias\": %g,\n", limits->maxSamplerLodBias); - printf("\t\t\t\"maxSamplerAnisotropy\": %g,\n", limits->maxSamplerAnisotropy); - printf("\t\t\t\"maxViewports\": %u,\n", limits->maxViewports); - printf("\t\t\t\"maxViewportDimensions\": [\n"); - printf("\t\t\t\t%u,\n", limits->maxViewportDimensions[0]); - printf("\t\t\t\t%u\n", limits->maxViewportDimensions[1]); - printf("\t\t\t],\n"); - printf("\t\t\t\"viewportBoundsRange\": [\n"); - printf("\t\t\t\t%g,\n", limits->viewportBoundsRange[0]); - printf("\t\t\t\t%g\n", limits->viewportBoundsRange[1]); - printf("\t\t\t],\n"); - printf("\t\t\t\"viewportSubPixelBits\": %u,\n", limits->viewportSubPixelBits); - printf("\t\t\t\"minMemoryMapAlignment\": " PRINTF_SIZE_T_SPECIFIER ",\n", limits->minMemoryMapAlignment); - printf("\t\t\t\"minTexelBufferOffsetAlignment\": %llu,\n", (unsigned long long)limits->minTexelBufferOffsetAlignment); - printf("\t\t\t\"minUniformBufferOffsetAlignment\": %llu,\n", (unsigned long long)limits->minUniformBufferOffsetAlignment); - printf("\t\t\t\"minStorageBufferOffsetAlignment\": %llu,\n", (unsigned long long)limits->minStorageBufferOffsetAlignment); - printf("\t\t\t\"minTexelOffset\": %d,\n", limits->minTexelOffset); - printf("\t\t\t\"maxTexelOffset\": %u,\n", limits->maxTexelOffset); - printf("\t\t\t\"minTexelGatherOffset\": %d,\n", limits->minTexelGatherOffset); - printf("\t\t\t\"maxTexelGatherOffset\": %u,\n", limits->maxTexelGatherOffset); - printf("\t\t\t\"minInterpolationOffset\": %g,\n", limits->minInterpolationOffset); - printf("\t\t\t\"maxInterpolationOffset\": %g,\n", limits->maxInterpolationOffset); - printf("\t\t\t\"subPixelInterpolationOffsetBits\": %u,\n", limits->subPixelInterpolationOffsetBits); - printf("\t\t\t\"maxFramebufferWidth\": %u,\n", limits->maxFramebufferWidth); - printf("\t\t\t\"maxFramebufferHeight\": %u,\n", limits->maxFramebufferHeight); - printf("\t\t\t\"maxFramebufferLayers\": %u,\n", limits->maxFramebufferLayers); - printf("\t\t\t\"framebufferColorSampleCounts\": %u,\n", limits->framebufferColorSampleCounts); - printf("\t\t\t\"framebufferDepthSampleCounts\": %u,\n", limits->framebufferDepthSampleCounts); - printf("\t\t\t\"framebufferStencilSampleCounts\": %u,\n", limits->framebufferStencilSampleCounts); - printf("\t\t\t\"framebufferNoAttachmentsSampleCounts\": %u,\n", limits->framebufferNoAttachmentsSampleCounts); - printf("\t\t\t\"maxColorAttachments\": %u,\n", limits->maxColorAttachments); - printf("\t\t\t\"sampledImageColorSampleCounts\": %u,\n", limits->sampledImageColorSampleCounts); - printf("\t\t\t\"sampledImageIntegerSampleCounts\": %u,\n", limits->sampledImageIntegerSampleCounts); - printf("\t\t\t\"sampledImageDepthSampleCounts\": %u,\n", limits->sampledImageDepthSampleCounts); - printf("\t\t\t\"sampledImageStencilSampleCounts\": %u,\n", limits->sampledImageStencilSampleCounts); - printf("\t\t\t\"storageImageSampleCounts\": %u,\n", limits->storageImageSampleCounts); - printf("\t\t\t\"maxSampleMaskWords\": %u,\n", limits->maxSampleMaskWords); - printf("\t\t\t\"timestampComputeAndGraphics\": %u,\n", limits->timestampComputeAndGraphics); - printf("\t\t\t\"timestampPeriod\": %g,\n", limits->timestampPeriod); - printf("\t\t\t\"maxClipDistances\": %u,\n", limits->maxClipDistances); - printf("\t\t\t\"maxCullDistances\": %u,\n", limits->maxCullDistances); - printf("\t\t\t\"maxCombinedClipAndCullDistances\": %u,\n", limits->maxCombinedClipAndCullDistances); - printf("\t\t\t\"discreteQueuePriorities\": %u,\n", limits->discreteQueuePriorities); - printf("\t\t\t\"pointSizeRange\": [\n"); - printf("\t\t\t\t%g,\n", limits->pointSizeRange[0]); - printf("\t\t\t\t%g\n", limits->pointSizeRange[1]); - printf("\t\t\t],\n"); - printf("\t\t\t\"lineWidthRange\": [\n"); - printf("\t\t\t\t%g,\n", limits->lineWidthRange[0]); - printf("\t\t\t\t%g\n", limits->lineWidthRange[1]); - printf("\t\t\t],\n"); - printf("\t\t\t\"pointSizeGranularity\": %g,\n", limits->pointSizeGranularity); - printf("\t\t\t\"lineWidthGranularity\": %g,\n", limits->lineWidthGranularity); - printf("\t\t\t\"strictLines\": %u,\n", limits->strictLines); - printf("\t\t\t\"standardSampleLocations\": %u,\n", limits->standardSampleLocations); - printf("\t\t\t\"optimalBufferCopyOffsetAlignment\": %llu,\n", (unsigned long long)limits->optimalBufferCopyOffsetAlignment); - printf("\t\t\t\"optimalBufferCopyRowPitchAlignment\": %llu,\n", - (unsigned long long)limits->optimalBufferCopyRowPitchAlignment); - printf("\t\t\t\"nonCoherentAtomSize\": %llu\n", (unsigned long long)limits->nonCoherentAtomSize); - printf("\t\t}"); - } -} - -static void AppGpuDumpProps(const struct AppGpu *gpu, FILE *out) { - VkPhysicalDeviceProperties props; - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - const VkPhysicalDeviceProperties *props2_const = &gpu->props2.properties; - props = *props2_const; - } else { - const VkPhysicalDeviceProperties *props_const = &gpu->props; - props = *props_const; - } - const uint32_t apiVersion = props.apiVersion; - const uint32_t major = VK_VERSION_MAJOR(apiVersion); - const uint32_t minor = VK_VERSION_MINOR(apiVersion); - const uint32_t patch = VK_VERSION_PATCH(apiVersion); - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>apiVersion = <span class='val'>0x%" PRIxLEAST32 - "</span> (<span class='val'>%d.%d.%d</span>)</summary></details>\n", - apiVersion, major, minor, patch); - fprintf(out, - "\t\t\t\t\t\t<details><summary>driverVersion = <span class='val'>%u</span> (<span class='val'>0x%" PRIxLEAST32 - "</span>)</summary></details>\n", - props.driverVersion, props.driverVersion); - fprintf(out, "\t\t\t\t\t\t<details><summary>vendorID = <span class='val'>0x%04x</span></summary></details>\n", - props.vendorID); - fprintf(out, "\t\t\t\t\t\t<details><summary>deviceID = <span class='val'>0x%04x</span></summary></details>\n", - props.deviceID); - fprintf(out, "\t\t\t\t\t\t<details><summary>deviceType = %s</summary></details>\n", - VkPhysicalDeviceTypeString(props.deviceType)); - fprintf(out, "\t\t\t\t\t\t<details><summary>deviceName = %s</summary></details>\n", props.deviceName); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("VkPhysicalDeviceProperties:\n"); - printf("===========================\n"); - printf("\tapiVersion = 0x%" PRIxLEAST32 " (%d.%d.%d)\n", apiVersion, major, minor, patch); - printf("\tdriverVersion = %u (0x%" PRIxLEAST32 ")\n", props.driverVersion, props.driverVersion); - printf("\tvendorID = 0x%04x\n", props.vendorID); - printf("\tdeviceID = 0x%04x\n", props.deviceID); - printf("\tdeviceType = %s\n", VkPhysicalDeviceTypeString(props.deviceType)); - printf("\tdeviceName = %s\n", props.deviceName); - } - if (json_output) { - printf(",\n"); - printf("\t\"VkPhysicalDeviceProperties\": {\n"); - printf("\t\t\"apiVersion\": %u,\n", apiVersion); - printf("\t\t\"driverVersion\": %u,\n", props.driverVersion); - printf("\t\t\"vendorID\": %u,\n", props.vendorID); - printf("\t\t\"deviceID\": %u,\n", props.deviceID); - printf("\t\t\"deviceType\": %u,\n", props.deviceType); - printf("\t\t\"deviceName\": \"%s\",\n", props.deviceName); - printf("\t\t\"pipelineCacheUUID\": ["); - for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) { - if (i > 0) { - printf(","); - } - printf("\n"); - printf("\t\t\t%u", props.pipelineCacheUUID[i]); - } - printf("\n"); - printf("\t\t]"); - } - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - AppDumpLimits(&gpu->props2.properties.limits, out); - } else { - AppDumpLimits(&gpu->props.limits, out); - } - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - AppDumpSparseProps(&gpu->props2.properties.sparseProperties, out); - } else { - AppDumpSparseProps(&gpu->props.sparseProperties, out); - } - - if (json_output) { - printf("\n\t}"); - } - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - void *place = gpu->props2.pNext; - while (place) { - struct VkStructureHeader *structure = (struct VkStructureHeader *)place; - if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT *blend_op_adv_props = - (VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceBlendOperationAdvancedProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>advancedBlendMaxColorAttachments = <span " - "class='val'>%u</span></summary></details>\n", - blend_op_adv_props->advancedBlendMaxColorAttachments); - fprintf(out, - "\t\t\t\t\t\t<details><summary>advancedBlendIndependentBlend = <span " - "class='val'>%u</span></summary></details>\n", - blend_op_adv_props->advancedBlendIndependentBlend); - fprintf(out, - "\t\t\t\t\t\t<details><summary>advancedBlendNonPremultipliedSrcColor = <span " - "class='val'>%u</span></summary></details>\n", - blend_op_adv_props->advancedBlendNonPremultipliedSrcColor); - fprintf(out, - "\t\t\t\t\t\t<details><summary>advancedBlendNonPremultipliedDstColor = <span " - "class='val'>%u</span></summary></details>\n", - blend_op_adv_props->advancedBlendNonPremultipliedDstColor); - fprintf(out, - "\t\t\t\t\t\t<details><summary>advancedBlendCorrelatedOverlap = <span " - "class='val'>%u</span></summary></details>\n", - blend_op_adv_props->advancedBlendCorrelatedOverlap); - fprintf(out, - "\t\t\t\t\t\t<details><summary>advancedBlendAllOperations = <span " - "class='val'>%u</span></summary></details>\n", - blend_op_adv_props->advancedBlendAllOperations); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceBlendOperationAdvancedProperties:\n"); - printf("=================================================\n"); - printf("\tadvancedBlendMaxColorAttachments = %u\n", - blend_op_adv_props->advancedBlendMaxColorAttachments); - printf("\tadvancedBlendIndependentBlend = %u\n", - blend_op_adv_props->advancedBlendIndependentBlend); - printf("\tadvancedBlendNonPremultipliedSrcColor = %u\n", - blend_op_adv_props->advancedBlendNonPremultipliedSrcColor); - printf("\tadvancedBlendNonPremultipliedDstColor = %u\n", - blend_op_adv_props->advancedBlendNonPremultipliedDstColor); - printf("\tadvancedBlendCorrelatedOverlap = %u\n", - blend_op_adv_props->advancedBlendCorrelatedOverlap); - printf("\tadvancedBlendAllOperations = %u\n", - blend_op_adv_props->advancedBlendAllOperations); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_MAINTENANCE2_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDevicePointClippingPropertiesKHR *pt_clip_props = (VkPhysicalDevicePointClippingPropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevicePointClippingProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pointClippingBehavior = <span " - "class='val'>%u</span></summary></details>\n", - pt_clip_props->pointClippingBehavior); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDevicePointClippingProperties:\n"); - printf("========================================\n"); - printf("\tpointClippingBehavior = %u\n", pt_clip_props->pointClippingBehavior); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDevicePushDescriptorPropertiesKHR *push_desc_props = - (VkPhysicalDevicePushDescriptorPropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevicePushDescriptorProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPushDescriptors = <span " - "class='val'>%u</span></summary></details>\n", - push_desc_props->maxPushDescriptors); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDevicePushDescriptorProperties:\n"); - printf("=========================================\n"); - printf("\tmaxPushDescriptors = %u\n", push_desc_props->maxPushDescriptors); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceDiscardRectanglePropertiesEXT *discard_rect_props = - (VkPhysicalDeviceDiscardRectanglePropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceDiscardRectangleProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxDiscardRectangles = <span " - "class='val'>%u</span></summary></details>\n", - discard_rect_props->maxDiscardRectangles); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceDiscardRectangleProperties:\n"); - printf("===========================================\n"); - printf("\tmaxDiscardRectangles = %u\n", discard_rect_props->maxDiscardRectangles); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_MULTIVIEW_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceMultiviewPropertiesKHR *multiview_props = (VkPhysicalDeviceMultiviewPropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMultiviewProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxMultiviewViewCount = <span " - "class='val'>%u</span></summary></details>\n", - multiview_props->maxMultiviewViewCount); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxMultiviewInstanceIndex = <span " - "class='val'>%u</span></summary></details>\n", - multiview_props->maxMultiviewInstanceIndex); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceMultiviewProperties:\n"); - printf("====================================\n"); - printf("\tmaxMultiviewViewCount = %u\n", multiview_props->maxMultiviewViewCount); - printf("\tmaxMultiviewInstanceIndex = %u\n", multiview_props->maxMultiviewInstanceIndex); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR) { - VkPhysicalDeviceMaintenance3PropertiesKHR *maintenance3_props = - (VkPhysicalDeviceMaintenance3PropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMaintenance3Properties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxPerSetDescriptors = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - maintenance3_props->maxPerSetDescriptors); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxMemoryAllocationSize = <span class='val'>%" PRIuLEAST64 - "</span></summary></details>\n", - maintenance3_props->maxMemoryAllocationSize); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceMaintenance3Properties:\n"); - printf("=======================================\n"); - printf("\tmaxPerSetDescriptors = %" PRIuLEAST32 "\n", maintenance3_props->maxPerSetDescriptors); - printf("\tmaxMemoryAllocationSize = %" PRIuLEAST64 "\n", maintenance3_props->maxMemoryAllocationSize); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR) { - const VkPhysicalDeviceIDPropertiesKHR *id_props = (VkPhysicalDeviceIDPropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceIDProperties</summary>\n"); - // Visual Studio 2013's printf does not support the "hh" - // length modifier so cast the operands and use field width - // "2" to fake it. - fprintf(out, - "\t\t\t\t\t\t<details><summary>deviceUUID = <span " - "class='val'>%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x</span></summary></" - "details>\n", - (uint32_t)id_props->deviceUUID[0], (uint32_t)id_props->deviceUUID[1], (uint32_t)id_props->deviceUUID[2], - (uint32_t)id_props->deviceUUID[3], (uint32_t)id_props->deviceUUID[4], (uint32_t)id_props->deviceUUID[5], - (uint32_t)id_props->deviceUUID[6], (uint32_t)id_props->deviceUUID[7], (uint32_t)id_props->deviceUUID[8], - (uint32_t)id_props->deviceUUID[9], (uint32_t)id_props->deviceUUID[10], - (uint32_t)id_props->deviceUUID[11], (uint32_t)id_props->deviceUUID[12], - (uint32_t)id_props->deviceUUID[13], (uint32_t)id_props->deviceUUID[14], - (uint32_t)id_props->deviceUUID[15]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>driverUUID = <span " - "class='val'>%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x</span></summary></" - "details>\n", - (uint32_t)id_props->driverUUID[0], (uint32_t)id_props->driverUUID[1], (uint32_t)id_props->driverUUID[2], - (uint32_t)id_props->driverUUID[3], (uint32_t)id_props->driverUUID[4], (uint32_t)id_props->driverUUID[5], - (uint32_t)id_props->driverUUID[6], (uint32_t)id_props->driverUUID[7], (uint32_t)id_props->driverUUID[8], - (uint32_t)id_props->driverUUID[9], (uint32_t)id_props->driverUUID[10], - (uint32_t)id_props->driverUUID[11], (uint32_t)id_props->driverUUID[12], - (uint32_t)id_props->driverUUID[13], (uint32_t)id_props->driverUUID[14], - (uint32_t)id_props->driverUUID[15]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>deviceLUIDValid = <span class='val'>%s</span></summary></details>\n", - id_props->deviceLUIDValid ? "true" : "false"); - if (id_props->deviceLUIDValid) { - fprintf(out, - "\t\t\t\t\t\t<details><summary>deviceLUID = <span " - "class='val'>%02x%02x%02x%02x-%02x%02x%02x%02x</span></summary></details>\n", - (uint32_t)id_props->deviceLUID[0], (uint32_t)id_props->deviceLUID[1], - (uint32_t)id_props->deviceLUID[2], (uint32_t)id_props->deviceLUID[3], - (uint32_t)id_props->deviceLUID[4], (uint32_t)id_props->deviceLUID[5], - (uint32_t)id_props->deviceLUID[6], (uint32_t)id_props->deviceLUID[7]); - fprintf(out, - "\t\t\t\t\t\t<details><summary>deviceNodeMask = <span " - "class='val'>0x%08x</span></summary></details>\n", - id_props->deviceNodeMask); - } - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceIDProperties:\n"); - printf("=========================================\n"); - printf("\tdeviceUUID = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", - (uint32_t)id_props->deviceUUID[0], (uint32_t)id_props->deviceUUID[1], (uint32_t)id_props->deviceUUID[2], - (uint32_t)id_props->deviceUUID[3], (uint32_t)id_props->deviceUUID[4], (uint32_t)id_props->deviceUUID[5], - (uint32_t)id_props->deviceUUID[6], (uint32_t)id_props->deviceUUID[7], (uint32_t)id_props->deviceUUID[8], - (uint32_t)id_props->deviceUUID[9], (uint32_t)id_props->deviceUUID[10], - (uint32_t)id_props->deviceUUID[11], (uint32_t)id_props->deviceUUID[12], - (uint32_t)id_props->deviceUUID[13], (uint32_t)id_props->deviceUUID[14], - (uint32_t)id_props->deviceUUID[15]); - printf("\tdriverUUID = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", - (uint32_t)id_props->driverUUID[0], (uint32_t)id_props->driverUUID[1], (uint32_t)id_props->driverUUID[2], - (uint32_t)id_props->driverUUID[3], (uint32_t)id_props->driverUUID[4], (uint32_t)id_props->driverUUID[5], - (uint32_t)id_props->driverUUID[6], (uint32_t)id_props->driverUUID[7], (uint32_t)id_props->driverUUID[8], - (uint32_t)id_props->driverUUID[9], (uint32_t)id_props->driverUUID[10], - (uint32_t)id_props->driverUUID[11], (uint32_t)id_props->driverUUID[12], - (uint32_t)id_props->driverUUID[13], (uint32_t)id_props->driverUUID[14], - (uint32_t)id_props->driverUUID[15]); - printf("\tdeviceLUIDValid = %s\n", id_props->deviceLUIDValid ? "true" : "false"); - if (id_props->deviceLUIDValid) { - printf("\tdeviceLUID = %02x%02x%02x%02x-%02x%02x%02x%02x\n", (uint32_t)id_props->deviceLUID[0], - (uint32_t)id_props->deviceLUID[1], (uint32_t)id_props->deviceLUID[2], - (uint32_t)id_props->deviceLUID[3], (uint32_t)id_props->deviceLUID[4], - (uint32_t)id_props->deviceLUID[5], (uint32_t)id_props->deviceLUID[6], - (uint32_t)id_props->deviceLUID[7]); - printf("\tdeviceNodeMask = 0x%08x\n", id_props->deviceNodeMask); - } - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceDriverPropertiesKHR *driver_props = (VkPhysicalDeviceDriverPropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceDriverProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>driverID = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - driver_props->driverID); - fprintf(out, "\t\t\t\t\t\t<details><summary>driverName = %s</summary></details>\n", driver_props->driverName); - fprintf(out, "\t\t\t\t\t\t<details><summary>driverInfo = %s</summary></details>\n", driver_props->driverInfo); - fprintf(out, "\t\t\t\t\t\t<details><summary>conformanceVersion:</summary></details>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>major = <span class='val'>%" PRIuLEAST8 - "</span></summary></details>\n", - driver_props->conformanceVersion.major); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>minor = <span class='val'>%" PRIuLEAST8 - "</span></summary></details>\n", - driver_props->conformanceVersion.minor); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>subminor = <span class='val'>%" PRIuLEAST8 - "</span></summary></details>\n", - driver_props->conformanceVersion.subminor); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>patch = <span class='val'>%" PRIuLEAST8 - "</span></summary></details>\n", - driver_props->conformanceVersion.patch); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceDriverProperties:\n"); - printf("=================================\n"); - printf("\tdriverID = %" PRIuLEAST32 "\n", driver_props->driverID); - printf("\tdriverName = %s\n", driver_props->driverName); - printf("\tdriverInfo = %s\n", driver_props->driverInfo); - printf("\tconformanceVersion:\n"); - printf("\t\tmajor = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.major); - printf("\t\tminor = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.minor); - printf("\t\tsubminor = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.subminor); - printf("\t\tpatch = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.patch); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceFloatControlsPropertiesKHR *float_control_props = - (VkPhysicalDeviceFloatControlsPropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFloatControlsProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>denormBehaviorIndependence = <span " - "class='val'>%s</span></summary></details>\n", - VkShaderFloatControlsIndependenceString(float_control_props->denormBehaviorIndependence)); - fprintf(out, - "\t\t\t\t\t\t<details><summary>roundingModeIndependence = <span " - "class='val'>%s</span></summary></details>\n", - VkShaderFloatControlsIndependenceString(float_control_props->roundingModeIndependence)); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderSignedZeroInfNanPreserveFloat16 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderSignedZeroInfNanPreserveFloat16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderSignedZeroInfNanPreserveFloat32 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderSignedZeroInfNanPreserveFloat32); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderSignedZeroInfNanPreserveFloat64 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderSignedZeroInfNanPreserveFloat64); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderDenormPreserveFloat16 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderDenormPreserveFloat16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderDenormPreserveFloat32 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderDenormPreserveFloat32); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderDenormPreserveFloat64 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderDenormPreserveFloat64); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderDenormFlushToZeroFloat16 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderDenormFlushToZeroFloat16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderDenormFlushToZeroFloat32 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderDenormFlushToZeroFloat32); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderDenormFlushToZeroFloat64 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderDenormFlushToZeroFloat64); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTEFloat16 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderRoundingModeRTEFloat16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTEFloat32 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderRoundingModeRTEFloat32); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTEFloat64 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderRoundingModeRTEFloat64); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTZFloat16 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderRoundingModeRTZFloat16); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTZFloat32 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderRoundingModeRTZFloat32); - fprintf(out, - "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTZFloat64 = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - float_control_props->shaderRoundingModeRTZFloat64); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceFloatControlsProperties:\n"); - printf("========================================\n"); - printf("\tdenormBehaviorIndependence = %s\n", - VkShaderFloatControlsIndependenceString(float_control_props->denormBehaviorIndependence)); - printf("\troundingModeIndependence = %s\n", - VkShaderFloatControlsIndependenceString(float_control_props->roundingModeIndependence)); - printf("\tshaderSignedZeroInfNanPreserveFloat16 = %" PRIuLEAST32 "\n", - float_control_props->shaderSignedZeroInfNanPreserveFloat16); - printf("\tshaderSignedZeroInfNanPreserveFloat32 = %" PRIuLEAST32 "\n", - float_control_props->shaderSignedZeroInfNanPreserveFloat32); - printf("\tshaderSignedZeroInfNanPreserveFloat64 = %" PRIuLEAST32 "\n", - float_control_props->shaderSignedZeroInfNanPreserveFloat64); - printf("\tshaderDenormPreserveFloat16 = %" PRIuLEAST32 "\n", - float_control_props->shaderDenormPreserveFloat16); - printf("\tshaderDenormPreserveFloat32 = %" PRIuLEAST32 "\n", - float_control_props->shaderDenormPreserveFloat32); - printf("\tshaderDenormPreserveFloat64 = %" PRIuLEAST32 "\n", - float_control_props->shaderDenormPreserveFloat64); - printf("\tshaderDenormFlushToZeroFloat16 = %" PRIuLEAST32 "\n", - float_control_props->shaderDenormFlushToZeroFloat16); - printf("\tshaderDenormFlushToZeroFloat32 = %" PRIuLEAST32 "\n", - float_control_props->shaderDenormFlushToZeroFloat32); - printf("\tshaderDenormFlushToZeroFloat64 = %" PRIuLEAST32 "\n", - float_control_props->shaderDenormFlushToZeroFloat64); - printf("\tshaderRoundingModeRTEFloat16 = %" PRIuLEAST32 "\n", - float_control_props->shaderRoundingModeRTEFloat16); - printf("\tshaderRoundingModeRTEFloat32 = %" PRIuLEAST32 "\n", - float_control_props->shaderRoundingModeRTEFloat32); - printf("\tshaderRoundingModeRTEFloat64 = %" PRIuLEAST32 "\n", - float_control_props->shaderRoundingModeRTEFloat64); - printf("\tshaderRoundingModeRTZFloat16 = %" PRIuLEAST32 "\n", - float_control_props->shaderRoundingModeRTZFloat16); - printf("\tshaderRoundingModeRTZFloat32 = %" PRIuLEAST32 "\n", - float_control_props->shaderRoundingModeRTZFloat32); - printf("\tshaderRoundingModeRTZFloat64 = %" PRIuLEAST32 "\n", - float_control_props->shaderRoundingModeRTZFloat64); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_bus_properties = (VkPhysicalDevicePCIBusInfoPropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDevicePCIBusInfoProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pciDomain = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - pci_bus_properties->pciDomain); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pciBus = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - pci_bus_properties->pciBus); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pciDevice = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - pci_bus_properties->pciDevice); - fprintf(out, - "\t\t\t\t\t\t<details><summary>pciFunction = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - pci_bus_properties->pciFunction); - fprintf(out, "\t\t\t\t\t</details>\n"); - - } else if (human_readable_output) { - printf("\nVkPhysicalDevicePCIBusInfoProperties\n"); - printf("====================================\n"); - printf("\tpciDomain = %" PRIuLEAST32 "\n", pci_bus_properties->pciDomain); - printf("\tpciBus = %" PRIuLEAST32 "\n", pci_bus_properties->pciBus); - printf("\tpciDevice = %" PRIuLEAST32 "\n", pci_bus_properties->pciDevice); - printf("\tpciFunction = %" PRIuLEAST32 "\n", pci_bus_properties->pciFunction); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceTransformFeedbackPropertiesEXT *transform_feedback_properties = - (VkPhysicalDeviceTransformFeedbackPropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceTransformFeedbackProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTransformFeedbackStreams = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->maxTransformFeedbackStreams); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBuffers = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->maxTransformFeedbackBuffers); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBufferSize = <span " - "class='val'>%" PRIuLEAST64 "</span></summary></details>\n", - transform_feedback_properties->maxTransformFeedbackBufferSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTransformFeedbackStreamDataSize = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->maxTransformFeedbackStreamDataSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBufferDataSize = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->maxTransformFeedbackBufferDataSize); - fprintf(out, - "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBufferDataStride = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->maxTransformFeedbackBufferDataStride); - fprintf(out, - "\t\t\t\t\t\t<details><summary>transformFeedbackQueries = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->transformFeedbackQueries); - fprintf(out, - "\t\t\t\t\t\t<details><summary>transformFeedbackStreamsLinesTriangles = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->transformFeedbackStreamsLinesTriangles); - fprintf(out, - "\t\t\t\t\t\t<details><summary>transformFeedbackRasterizationStreamSelect = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->transformFeedbackRasterizationStreamSelect); - fprintf(out, - "\t\t\t\t\t\t<details><summary>transformFeedbackDraw = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - transform_feedback_properties->transformFeedbackDraw); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceTransformFeedbackProperties\n"); - printf("===========================================\n"); - printf("\tmaxTransformFeedbackStreams = %" PRIuLEAST32 "\n", - transform_feedback_properties->maxTransformFeedbackStreams); - printf("\tmaxTransformFeedbackBuffers = %" PRIuLEAST32 "\n", - transform_feedback_properties->maxTransformFeedbackBuffers); - printf("\tmaxTransformFeedbackBufferSize = %" PRIuLEAST64 "\n", - transform_feedback_properties->maxTransformFeedbackBufferSize); - printf("\tmaxTransformFeedbackStreamDataSize = %" PRIuLEAST32 "\n", - transform_feedback_properties->maxTransformFeedbackStreamDataSize); - printf("\tmaxTransformFeedbackBufferDataSize = %" PRIuLEAST32 "\n", - transform_feedback_properties->maxTransformFeedbackBufferDataSize); - printf("\tmaxTransformFeedbackBufferDataStride = %" PRIuLEAST32 "\n", - transform_feedback_properties->maxTransformFeedbackBufferDataStride); - printf("\ttransformFeedbackQueries = %" PRIuLEAST32 "\n", - transform_feedback_properties->transformFeedbackQueries); - printf("\ttransformFeedbackStreamsLinesTriangles = %" PRIuLEAST32 "\n", - transform_feedback_properties->transformFeedbackStreamsLinesTriangles); - printf("\ttransformFeedbackRasterizationStreamSelect = %" PRIuLEAST32 "\n", - transform_feedback_properties->transformFeedbackRasterizationStreamSelect); - printf("\ttransformFeedbackDraw = %" PRIuLEAST32 "\n", - transform_feedback_properties->transformFeedbackDraw); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceFragmentDensityMapPropertiesEXT *fragment_density_map_properties = - (VkPhysicalDeviceFragmentDensityMapPropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFragmentDensityMapProperties</summary>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>minFragmentDensityTexelSize</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>width = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_properties->minFragmentDensityTexelSize.width); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>height = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_properties->minFragmentDensityTexelSize.height); - fprintf(out, "\t\t\t\t\t\t<details><summary>maxFragmentDensityTexelSize</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>width = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_properties->maxFragmentDensityTexelSize.width); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>height = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_properties->maxFragmentDensityTexelSize.height); - fprintf(out, - "\t\t\t\t\t\t<details><summary>fragmentDensityInvocations = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - fragment_density_map_properties->fragmentDensityInvocations); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceFragmentDensityMapProperties\n"); - printf("============================================\n"); - printf("\tminFragmentDensityTexelSize\n"); - printf("\t\twidth = %" PRIuLEAST32 "\n", fragment_density_map_properties->minFragmentDensityTexelSize.width); - printf("\t\theight = %" PRIuLEAST32 "\n", fragment_density_map_properties->minFragmentDensityTexelSize.height); - printf("\tmaxFragmentDensityTexelSize\n"); - printf("\t\twidth = %" PRIuLEAST32 "\n", fragment_density_map_properties->maxFragmentDensityTexelSize.width); - printf("\t\theight = %" PRIuLEAST32 "\n", fragment_density_map_properties->maxFragmentDensityTexelSize.height); - printf("\tfragmentDensityInvocations = %" PRIuLEAST32 "\n", - fragment_density_map_properties->fragmentDensityInvocations); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR && - CheckPhysicalDeviceExtensionIncluded(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceDepthStencilResolvePropertiesKHR *depth_stencil_resolve_properties = - (VkPhysicalDeviceDepthStencilResolvePropertiesKHR *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceDepthStencilResolveProperties</summary>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>supportedDepthResolveModes</summary></details>\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes == 0) { - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_NONE_KHR</span></summary></details>\n"); - } else { - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR</span></summary></details>\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_AVERAGE_BIT_KHR</span></summary></details>\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_MIN_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_MIN_BIT_KHR</span></summary></details>\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_MAX_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_MAX_BIT_KHR</span></summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t\t<details><summary>supportedStencilResolveModes</summary></details>\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes == 0) { - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_NONE_KHR</span></summary></details>\n"); - } else { - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR</span></summary></details>\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_AVERAGE_BIT_KHR</span></summary></details>\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_MIN_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_MIN_BIT_KHR</span></summary></details>\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_MAX_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary><span " - "class='val'>VK_RESOLVE_MODE_MAX_BIT_KHR</span></summary></details>\n"); - } - fprintf(out, - "\t\t\t\t\t\t<details><summary>independentResolveNone = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - depth_stencil_resolve_properties->independentResolveNone); - fprintf(out, - "\t\t\t\t\t\t<details><summary>independentResolve = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - depth_stencil_resolve_properties->independentResolve); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceDepthStencilResolveProperties\n"); - printf("============================================\n"); - printf("\tsupportedDepthResolveModes:\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes == 0) { - printf("\t\tVK_RESOLVE_MODE_NONE_KHR\n"); - } else { - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_AVERAGE_BIT_KHR\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_MIN_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_MIN_BIT_KHR\n"); - if (depth_stencil_resolve_properties->supportedDepthResolveModes & VK_RESOLVE_MODE_MAX_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_MAX_BIT_KHR\n"); - } - printf("\tsupportedStencilResolveModes:\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes == 0) { - printf("\t\tVK_RESOLVE_MODE_NONE_KHR\n"); - } else { - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_AVERAGE_BIT_KHR\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_MIN_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_MIN_BIT_KHR\n"); - if (depth_stencil_resolve_properties->supportedStencilResolveModes & VK_RESOLVE_MODE_MAX_BIT_KHR) - printf("\t\tVK_RESOLVE_MODE_MAX_BIT_KHR\n"); - } - printf("\tindependentResolveNone = %" PRIuLEAST32 "\n", - depth_stencil_resolve_properties->independentResolveNone); - printf("\tindependentResolve = %" PRIuLEAST32 "\n", depth_stencil_resolve_properties->independentResolve); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceDescriptorIndexingPropertiesEXT *indexing_properties = - (VkPhysicalDeviceDescriptorIndexingPropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceDescriptorIndexingProperties</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxUpdateAfterBindDescriptorsInAllPools = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxUpdateAfterBindDescriptorsInAllPools); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>shaderUniformBufferArrayNonUniformIndexingNative = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->shaderUniformBufferArrayNonUniformIndexingNative); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>shaderSampledImageArrayNonUniformIndexingNative = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->shaderSampledImageArrayNonUniformIndexingNative); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>shaderStorageBufferArrayNonUniformIndexingNative = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->shaderStorageBufferArrayNonUniformIndexingNative); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>shaderStorageImageArrayNonUniformIndexingNative = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->shaderStorageImageArrayNonUniformIndexingNative); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>shaderInputAttachmentArrayNonUniformIndexingNative = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->shaderInputAttachmentArrayNonUniformIndexingNative); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>robustBufferAccessUpdateAfterBind = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - indexing_properties->robustBufferAccessUpdateAfterBind); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>quadDivergentImplicitLod = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - indexing_properties->quadDivergentImplicitLod); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUpdateAfterBindSamplers = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindSamplers); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUpdateAfterBindUniformBuffers = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUpdateAfterBindStorageBuffers = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUpdateAfterBindSampledImages = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindSampledImages); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUpdateAfterBindStorageImages = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindStorageImages); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUpdateAfterBindInputAttachments = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindInputAttachments); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxPerStageUpdateAfterBindResources = <span class='val'>%" PRIuLEAST32 - "</span></summary></details>\n", - indexing_properties->maxPerStageUpdateAfterBindResources); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindSamplers = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindSamplers); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindUniformBuffers = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindUniformBuffers); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindStorageBuffers = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindStorageBuffers); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindSampledImages = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindSampledImages); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindStorageImages = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindStorageImages); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxDescriptorSetUpdateAfterBindInputAttachments = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - indexing_properties->maxDescriptorSetUpdateAfterBindInputAttachments); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceDescriptorIndexingProperties\n"); - printf("============================================\n"); - printf("\tmaxUpdateAfterBindDescriptorsInAllPools = %" PRIuLEAST32 "\n", - indexing_properties->maxUpdateAfterBindDescriptorsInAllPools); - printf("\tshaderUniformBufferArrayNonUniformIndexingNative = %" PRIuLEAST32 "\n", - indexing_properties->shaderUniformBufferArrayNonUniformIndexingNative); - printf("\tshaderSampledImageArrayNonUniformIndexingNative = %" PRIuLEAST32 "\n", - indexing_properties->shaderSampledImageArrayNonUniformIndexingNative); - printf("\tshaderStorageBufferArrayNonUniformIndexingNative = %" PRIuLEAST32 "\n", - indexing_properties->shaderStorageBufferArrayNonUniformIndexingNative); - printf("\tshaderStorageImageArrayNonUniformIndexingNative = %" PRIuLEAST32 "\n", - indexing_properties->shaderStorageImageArrayNonUniformIndexingNative); - printf("\tshaderInputAttachmentArrayNonUniformIndexingNative = %" PRIuLEAST32 "\n", - indexing_properties->shaderInputAttachmentArrayNonUniformIndexingNative); - printf("\trobustBufferAccessUpdateAfterBind = %" PRIuLEAST32 "\n", - indexing_properties->robustBufferAccessUpdateAfterBind); - printf("\tquadDivergentImplicitLod = %" PRIuLEAST32 "\n", indexing_properties->quadDivergentImplicitLod); - printf("\tmaxPerStageDescriptorUpdateAfterBindSamplers = %" PRIuLEAST32 "\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindSamplers); - printf("\tmaxPerStageDescriptorUpdateAfterBindUniformBuffers = %" PRIuLEAST32 "\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers); - printf("\tmaxPerStageDescriptorUpdateAfterBindStorageBuffers = %" PRIuLEAST32 "\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers); - printf("\tmaxPerStageDescriptorUpdateAfterBindSampledImages = %" PRIuLEAST32 "\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindSampledImages); - printf("\tmaxPerStageDescriptorUpdateAfterBindStorageImages = %" PRIuLEAST32 "\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindStorageImages); - printf("\tmaxPerStageDescriptorUpdateAfterBindInputAttachments = %" PRIuLEAST32 "\n", - indexing_properties->maxPerStageDescriptorUpdateAfterBindInputAttachments); - printf("\tmaxPerStageUpdateAfterBindResources = %" PRIuLEAST32 "\n", - indexing_properties->maxPerStageUpdateAfterBindResources); - printf("\tmaxDescriptorSetUpdateAfterBindSamplers = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindSamplers); - printf("\tmaxDescriptorSetUpdateAfterBindUniformBuffers = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindUniformBuffers); - printf("\tmaxDescriptorSetUpdateAfterBindUniformBuffersDynamic = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic); - printf("\tmaxDescriptorSetUpdateAfterBindStorageBuffer = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindStorageBuffers); - printf("\tmaxDescriptorSetUpdateAfterBindStorageBuffersDynamic = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic); - printf("\tmaxDescriptorSetUpdateAfterBindSampledImages = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindSampledImages); - printf("\tmaxDescriptorSetUpdateAfterBindStorageImages = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindStorageImages); - printf("\tmaxDescriptorSetUpdateAfterBindInputAttachments = %" PRIuLEAST32 "\n", - indexing_properties->maxDescriptorSetUpdateAfterBindInputAttachments); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *texel_buffer_alignment = - (VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>storageTexelBufferOffsetAlignmentBytes = <span " - "class='val'>%" PRIuLEAST64 "</span></summary></details>\n", - texel_buffer_alignment->storageTexelBufferOffsetAlignmentBytes); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>storageTexelBufferOffsetSingleTexelAlignment = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - texel_buffer_alignment->storageTexelBufferOffsetSingleTexelAlignment); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>uniformTexelBufferOffsetAlignmentBytes = <span " - "class='val'>%" PRIuLEAST64 "</span></summary></details>\n", - texel_buffer_alignment->uniformTexelBufferOffsetAlignmentBytes); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>uniformTexelBufferOffsetSingleTexelAlignment = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - texel_buffer_alignment->uniformTexelBufferOffsetSingleTexelAlignment); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceTexelBufferAlignmentPropertiesEXT\n"); - printf("=================================================\n"); - printf("\t\tstorageTexelBufferOffsetAlignmentBytes = %" PRIuLEAST64 "\n", - texel_buffer_alignment->storageTexelBufferOffsetAlignmentBytes); - printf("\t\tstorageTexelBufferOffsetSingleTexelAlignment = %" PRIuLEAST32 "\n", - texel_buffer_alignment->storageTexelBufferOffsetSingleTexelAlignment); - printf("\t\tuniformTexelBufferOffsetAlignmentBytes = %" PRIuLEAST64 "\n", - texel_buffer_alignment->uniformTexelBufferOffsetAlignmentBytes); - printf("\t\tuniformTexelBufferOffsetSingleTexelAlignment = %" PRIuLEAST32 "\n", - texel_buffer_alignment->uniformTexelBufferOffsetSingleTexelAlignment); - } - } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *subgroup_properties = - (VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *)structure; - if (html_output) { - fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceSubgroupSizeControlPropertiesEXT</summary>\n"); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>minSubgroupSize = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - subgroup_properties->minSubgroupSize); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxSubgroupSize = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - subgroup_properties->maxSubgroupSize); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>maxComputeWorkgroupSubgroups = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - subgroup_properties->maxComputeWorkgroupSubgroups); - fprintf(out, - "\t\t\t\t\t\t\t<details><summary>requiredSubgroupSizeStages = <span " - "class='val'>%" PRIuLEAST32 "</span></summary></details>\n", - subgroup_properties->requiredSubgroupSizeStages); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\nVkPhysicalDeviceSubgroupSizeControlPropertiesEXT\n"); - printf("=================================================\n"); - printf("\tminSubgroupSize = %" PRIuLEAST32 "\n", subgroup_properties->minSubgroupSize); - printf("\tmaxSubgroupSize = %" PRIuLEAST32 "\n", subgroup_properties->maxSubgroupSize); - printf("\tmaxComputeWorkgroupSubgroups = %" PRIuLEAST32 "\n", - subgroup_properties->maxComputeWorkgroupSubgroups); - printf("\trequiredSubgroupSizeStages = %" PRIuLEAST32 "\n", subgroup_properties->requiredSubgroupSizeStages); - } - } - place = structure->pNext; - } - } - fflush(out); - fflush(stdout); -} -// Compare function for sorting extensions by name -static int CompareExtensionName(const void *a, const void *b) { - const char *this = ((const VkExtensionProperties *)a)->extensionName; - const char *that = ((const VkExtensionProperties *)b)->extensionName; - return strcmp(this, that); -} - -// Compare function for sorting layers by name -static int CompareLayerName(const void *a, const void *b) { - const char *this = ((const struct LayerExtensionList *)a)->layer_properties.layerName; - const char *that = ((const struct LayerExtensionList *)b)->layer_properties.layerName; - return strcmp(this, that); -} - -static void AppDumpExtensions(const char *indent, const char *layer_name, const uint32_t extension_count, - VkExtensionProperties *extension_properties, FILE *out) { - if (html_output) { - fprintf(out, "\t\t\t%s<details><summary>", indent); - } - if (layer_name && (strlen(layer_name) > 0)) { - if (html_output) { - fprintf(out, "%s Extensions", layer_name); - } else if (human_readable_output) { - printf("%s%s Extensions", indent, layer_name); - } - } else { - if (html_output) { - fprintf(out, "Extensions"); - } else if (human_readable_output) { - printf("%sExtensions", indent); - } - } - if (html_output) { - fprintf(out, "\tcount = <span class='val'>%d</span></summary>", extension_count); - if (extension_count > 0) { - fprintf(out, "\n"); - } - } else if (human_readable_output) { - printf("\tcount = %d\n", extension_count); - } - - const bool is_device_type = layer_name && (strcmp(layer_name, "Device") == 0); - if (is_device_type && json_output) { - printf(",\n"); - printf("\t\"ArrayOfVkExtensionProperties\": ["); - } - - qsort(extension_properties, extension_count, sizeof(VkExtensionProperties), CompareExtensionName); - - for (uint32_t i = 0; i < extension_count; ++i) { - VkExtensionProperties const *ext_prop = &extension_properties[i]; - if (html_output) { - fprintf(out, "\t\t\t\t%s<details><summary>", indent); - fprintf(out, "<span class='type'>%s</span>: extension revision <span class='val'>%d</span>", ext_prop->extensionName, - ext_prop->specVersion); - fprintf(out, "</summary></details>\n"); - } else if (human_readable_output) { - printf("%s\t", indent); - printf("%-36s: extension revision %2d\n", ext_prop->extensionName, ext_prop->specVersion); - } - if (is_device_type && json_output) { - if (i > 0) { - printf(","); - } - printf("\n"); - printf("\t\t{\n"); - printf("\t\t\t\"extensionName\": \"%s\",\n", ext_prop->extensionName); - printf("\t\t\t\"specVersion\": %u\n", ext_prop->specVersion); - printf("\t\t}"); - } - } - if (html_output) { - if (extension_count > 0) { - fprintf(out, "\t\t\t%s</details>\n", indent); - } else { - fprintf(out, "</details>\n"); - } - } - if (is_device_type && json_output) { - if (extension_count > 0) { - printf("\n\t"); - } - printf("]"); - } - - fflush(out); - fflush(stdout); -} - -static void AppGpuDumpQueueProps(const struct AppGpu *gpu, uint32_t id, FILE *out) { - VkQueueFamilyProperties props; - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - const VkQueueFamilyProperties *props2_const = &gpu->queue_props2[id].queueFamilyProperties; - props = *props2_const; - } else { - const VkQueueFamilyProperties *props_const = &gpu->queue_props[id]; - props = *props_const; - } - - bool is_present_platform_agnostic = true; - VkBool32 platforms_support_present = VK_FALSE; - for (struct SurfaceExtensionNode *sen = gpu->inst->surface_ext_infos_root; sen != NULL; sen = sen->next) { - VkResult err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu->obj, id, sen->surface, &sen->supports_present); - if (err) ERR_EXIT(err); - - const bool first = (sen == gpu->inst->surface_ext_infos_root); - if (!first && platforms_support_present != sen->supports_present) is_present_platform_agnostic = false; - platforms_support_present = sen->supports_present; - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkQueueFamilyProperties[<span class='val'>%d</span>]</summary>\n", id); - fprintf(out, "\t\t\t\t\t\t<details><summary>queueFlags = "); - } else if (human_readable_output) { - printf("VkQueueFamilyProperties[%d]:\n", id); - printf("===========================\n"); - printf("\tqueueFlags = "); - } - if (html_output || human_readable_output) { - char *sep = ""; // separator character - if (props.queueFlags & VK_QUEUE_GRAPHICS_BIT) { - fprintf(out, "GRAPHICS"); - sep = " | "; - } - if (props.queueFlags & VK_QUEUE_COMPUTE_BIT) { - fprintf(out, "%sCOMPUTE", sep); - sep = " | "; - } - if (props.queueFlags & VK_QUEUE_TRANSFER_BIT) { - fprintf(out, "%sTRANSFER", sep); - sep = " | "; - } - if (props.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) { - fprintf(out, "%sSPARSE", sep); - } - } - - if (html_output) { - fprintf(out, "</summary></details>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>queueCount = <span class='val'>%u</span></summary></details>\n", - props.queueCount); - fprintf(out, "\t\t\t\t\t\t<details><summary>timestampValidBits = <span class='val'>%u</span></summary></details>\n", - props.timestampValidBits); - fprintf(out, - "\t\t\t\t\t\t<details><summary>minImageTransferGranularity = (<span class='val'>%d</span>, <span " - "class='val'>%d</span>, <span class='val'>%d</span>)</summary></details>\n", - props.minImageTransferGranularity.width, props.minImageTransferGranularity.height, - props.minImageTransferGranularity.depth); - if (is_present_platform_agnostic) { - fprintf(out, "\t\t\t\t\t\t<details><summary>present support = <span class='val'>%s</span></summary></details>\n", - platforms_support_present ? "true" : "false"); - } else { - fprintf(out, "\t\t\t\t\t\t<details open><summary>present support</summary>\n"); - for (struct SurfaceExtensionNode *sen = gpu->inst->surface_ext_infos_root; sen != NULL; sen = sen->next) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>%s = <span class='val'>%s</span></summary></details>\n", sen->name, - sen->supports_present ? "true" : "false"); - } - fprintf(out, "\t\t\t\t\t\t</details>\n"); - } - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\n"); - printf("\tqueueCount = %u\n", props.queueCount); - printf("\ttimestampValidBits = %u\n", props.timestampValidBits); - printf("\tminImageTransferGranularity = (%d, %d, %d)\n", props.minImageTransferGranularity.width, - props.minImageTransferGranularity.height, props.minImageTransferGranularity.depth); - if (is_present_platform_agnostic) { - printf("\tpresent support = %s\n", platforms_support_present ? "true" : "false"); - } else { - printf("\tpresent support:\n"); - for (struct SurfaceExtensionNode *sen = gpu->inst->surface_ext_infos_root; sen != NULL; sen = sen->next) { - printf("\t\t%s = %s\n", sen->name, sen->supports_present ? "true" : "false"); - } - } - } - if (json_output) { - printf("\t\t{\n"); - printf("\t\t\t\"minImageTransferGranularity\": {\n"); - printf("\t\t\t\t\"depth\": %u,\n", props.minImageTransferGranularity.depth); - printf("\t\t\t\t\"height\": %u,\n", props.minImageTransferGranularity.height); - printf("\t\t\t\t\"width\": %u\n", props.minImageTransferGranularity.width); - printf("\t\t\t},\n"); - printf("\t\t\t\"queueCount\": %u,\n", props.queueCount); - printf("\t\t\t\"queueFlags\": %u,\n", props.queueFlags); - printf("\t\t\t\"timestampValidBits\": %u\n", props.timestampValidBits); - printf("\t\t}"); - } - - fflush(out); - fflush(stdout); -} - -// 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.). -#define kBufferSize 32 - -static char *HumanReadable(const size_t sz) { - const char prefixes[] = "KMGTPEZY"; - char buf[kBufferSize]; - int which = -1; - double result = (double)sz; - while (result > 1024 && which < 7) { - result /= 1024; - ++which; - } - - char unit[] = "\0i"; - if (which >= 0) { - unit[0] = prefixes[which]; - } -#ifdef _WIN32 - _snprintf_s(buf, kBufferSize * sizeof(char), kBufferSize, "%.2f %sB", result, unit); -#else - snprintf(buf, kBufferSize, "%.2f %sB", result, unit); -#endif - return strndup(buf, kBufferSize); -} - -static void AppGpuDumpMemoryProps(const struct AppGpu *gpu, FILE *out) { - VkPhysicalDeviceMemoryProperties props; - struct VkStructureHeader *structure = NULL; - - VkDeviceSize *heapBudget = NULL; - VkDeviceSize *heapUsage = NULL; - - if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, - gpu->inst->inst_extensions_count)) { - const VkPhysicalDeviceMemoryProperties *props2_const = &gpu->memory_props2.memoryProperties; - props = *props2_const; - structure = (struct VkStructureHeader *)gpu->memory_props2.pNext; - } else { - const VkPhysicalDeviceMemoryProperties *props_const = &gpu->memory_props; - props = *props_const; - } - - while (structure) { - if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT && - CheckPhysicalDeviceExtensionIncluded(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, gpu->device_extensions, - gpu->device_extension_count)) { - VkPhysicalDeviceMemoryBudgetPropertiesEXT *mem_budget_props = (VkPhysicalDeviceMemoryBudgetPropertiesEXT *)structure; - heapBudget = mem_budget_props->heapBudget; - heapUsage = mem_budget_props->heapUsage; - } - - structure = (struct VkStructureHeader *)structure->pNext; - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMemoryProperties</summary>\n"); - fprintf(out, "\t\t\t\t\t\t<details><summary>memoryHeapCount = <span class='val'>%u</span></summary>", - props.memoryHeapCount); - if (props.memoryHeapCount > 0) { - fprintf(out, "\n"); - } - } else if (human_readable_output) { - printf("VkPhysicalDeviceMemoryProperties:\n"); - printf("=================================\n"); - printf("\tmemoryHeapCount = %u\n", props.memoryHeapCount); - } - if (json_output) { - printf(",\n"); - printf("\t\"VkPhysicalDeviceMemoryProperties\": {\n"); - printf("\t\t\"memoryHeaps\": ["); - } - for (uint32_t i = 0; i < props.memoryHeapCount; ++i) { - const VkDeviceSize memSize = props.memoryHeaps[i].size; - char *mem_size_human_readable = HumanReadable((const size_t)memSize); - - if (html_output) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>memoryHeaps[<span class='val'>%u</span>]</summary>\n", i); - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary>size = <span class='val'>" PRINTF_SIZE_T_SPECIFIER - "</span> (<span class='val'>0x%" PRIxLEAST64 "</span>) (<span class='val'>%s</span>)</summary></details>\n", - (size_t)memSize, memSize, mem_size_human_readable); - if (heapBudget != NULL) { - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary>budget = <span class='val'>%" PRIuLEAST64 - "</span></summary></details>\n", - heapBudget[i]); - fprintf(out, - "\t\t\t\t\t\t\t\t<details><summary>usage = <span class='val'>%" PRIuLEAST64 "</span></summary></details>\n", - heapUsage[i]); - } - } else if (human_readable_output) { - printf("\tmemoryHeaps[%u] :\n", i); - printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER " (0x%" PRIxLEAST64 ") (%s)\n", (size_t)memSize, memSize, - mem_size_human_readable); - if (heapBudget != NULL) { - fprintf(out, "\t\tbudget = %" PRIuLEAST64 "\n", heapBudget[i]); - fprintf(out, "\t\tusage = %" PRIuLEAST64 "\n", heapUsage[i]); - } - } - free(mem_size_human_readable); - - const VkMemoryHeapFlags heap_flags = props.memoryHeaps[i].flags; - if (html_output) { - fprintf(out, "\t\t\t\t\t\t\t\t<details open><summary>flags</summary>\n"); - fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary>"); - fprintf(out, (heap_flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) - ? "<span class='type'>VK_MEMORY_HEAP_DEVICE_LOCAL_BIT</span>" - : "None"); - fprintf(out, "</summary></details>\n"); - fprintf(out, "\t\t\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\t\tflags:\n\t\t\t"); - printf((heap_flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? "VK_MEMORY_HEAP_DEVICE_LOCAL_BIT\n" : "None\n"); - } - if (json_output) { - if (i > 0) { - printf(","); - } - printf("\n"); - printf("\t\t\t{\n"); - printf("\t\t\t\t\"flags\": %u,\n", heap_flags); - printf("\t\t\t\t\"size\": " PRINTF_SIZE_T_SPECIFIER "\n", (size_t)memSize); - printf("\t\t\t}"); - } - } - if (html_output) { - if (props.memoryHeapCount > 0) { - fprintf(out, "\t\t\t\t\t\t"); - } - fprintf(out, "</details>\n"); - } - if (json_output) { - if (props.memoryHeapCount > 0) { - printf("\n\t\t"); - } - printf("]"); - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>memoryTypeCount = <span class='val'>%u</span></summary>", - props.memoryTypeCount); - if (props.memoryTypeCount > 0) { - fprintf(out, "\n"); - } - } else if (human_readable_output) { - printf("\tmemoryTypeCount = %u\n", props.memoryTypeCount); - } - if (json_output) { - printf(",\n"); - printf("\t\t\"memoryTypes\": ["); - } - for (uint32_t i = 0; i < props.memoryTypeCount; ++i) { - if (html_output) { - fprintf(out, "\t\t\t\t\t\t\t<details><summary>memoryTypes[<span class='val'>%u</span>]</summary>\n", i); - fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>heapIndex = <span class='val'>%u</span></summary></details>\n", - props.memoryTypes[i].heapIndex); - fprintf(out, - "\t\t\t\t\t\t\t\t<details open><summary>propertyFlags = <span class='val'>0x%" PRIxLEAST32 "</span></summary>", - props.memoryTypes[i].propertyFlags); - if (props.memoryTypes[i].propertyFlags == 0) { - fprintf(out, "</details>\n"); - } else { - fprintf(out, "\n"); - } - } else if (human_readable_output) { - printf("\tmemoryTypes[%u] :\n", i); - printf("\t\theapIndex = %u\n", props.memoryTypes[i].heapIndex); - printf("\t\tpropertyFlags = 0x%" PRIxLEAST32 ":\n", props.memoryTypes[i].propertyFlags); - } - if (json_output) { - if (i > 0) { - printf(","); - } - printf("\n"); - printf("\t\t\t{\n"); - printf("\t\t\t\t\"heapIndex\": %u,\n", props.memoryTypes[i].heapIndex); - printf("\t\t\t\t\"propertyFlags\": %u\n", props.memoryTypes[i].propertyFlags); - printf("\t\t\t}"); - } - - // Print each named flag to html or std output if it is set - const VkFlags flags = props.memoryTypes[i].propertyFlags; - if (html_output) { - if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) - fprintf(out, - "\t\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT</span></summary></details>\n"); - if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - fprintf(out, - "\t\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</span></summary></details>\n"); - if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) - fprintf(out, - "\t\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</span></summary></details>\n"); - if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) - fprintf(out, - "\t\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_MEMORY_PROPERTY_HOST_CACHED_BIT</span></summary></details>\n"); - if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) - fprintf(out, - "\t\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT</span></summary></details>\n"); - if (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) - fprintf(out, - "\t\t\t\t\t\t\t\t\t<details><summary><span " - "class='type'>VK_MEMORY_PROPERTY_PROTECTED_BIT</span></summary></details>\n"); - if (props.memoryTypes[i].propertyFlags > 0) fprintf(out, "\t\t\t\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT\n"); - if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT\n"); - if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_HOST_COHERENT_BIT\n"); - if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_HOST_CACHED_BIT\n"); - if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT\n"); - if (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_PROTECTED_BIT\n"); - } - - if (human_readable_output) { - printf("\t\tusable for:\n"); - const uint32_t memtype_bit = 1 << i; - - for (VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; tiling < ARRAY_SIZE(gpu->mem_type_res_support.image); ++tiling) { - printf("\t\t\t%s: ", VkTilingString(tiling)); - - bool first = true; - for (size_t fmt_i = 0; fmt_i < ARRAY_SIZE(gpu->mem_type_res_support.image[tiling]); ++fmt_i) { - const struct MemImageSupport *image_support = &gpu->mem_type_res_support.image[tiling][fmt_i]; - const bool regular_compatible = - image_support->regular_supported && (image_support->regular_memtypes & memtype_bit); - const bool sparse_compatible = - image_support->sparse_supported && (image_support->sparse_memtypes & memtype_bit); - const bool transient_compatible = - image_support->transient_supported && (image_support->transient_memtypes & memtype_bit); - - if (regular_compatible || sparse_compatible || transient_compatible) { - if (!first) printf(", "); - first = false; - - if (fmt_i == 0) { - printf("color images"); - } else { - printf("%s", VkFormatString(gpu->mem_type_res_support.image[tiling][fmt_i].format)); - } - - if (regular_compatible && !sparse_compatible && !transient_compatible && image_support->sparse_supported && - image_support->transient_supported) { - printf("(non-sparse, non-transient)"); - } else if (regular_compatible && !sparse_compatible && image_support->sparse_supported) { - if (image_support->sparse_supported) printf("(non-sparse)"); - } else if (regular_compatible && !transient_compatible && image_support->transient_supported) { - if (image_support->transient_supported) printf("(non-transient)"); - } else if (!regular_compatible && sparse_compatible && !transient_compatible && - image_support->sparse_supported) { - if (image_support->sparse_supported) printf("(sparse only)"); - } else if (!regular_compatible && !sparse_compatible && transient_compatible && - image_support->transient_supported) { - if (image_support->transient_supported) printf("(transient only)"); - } else if (!regular_compatible && sparse_compatible && transient_compatible && - image_support->sparse_supported && image_support->transient_supported) { - printf("(sparse and transient only)"); - } - } - } - - if (first) printf("None"); - - printf("\n"); - } - } else if (html_output) { - fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>usable for</summary>\n"); - const uint32_t memtype_bit = 1 << i; - - for (VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; tiling < ARRAY_SIZE(gpu->mem_type_res_support.image); ++tiling) { - fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary>%s</summary>\n", VkTilingString(tiling)); - - bool first = true; - for (size_t fmt_i = 0; fmt_i < ARRAY_SIZE(gpu->mem_type_res_support.image[tiling]); ++fmt_i) { - const struct MemImageSupport *image_support = &gpu->mem_type_res_support.image[tiling][fmt_i]; - const bool regular_compatible = - image_support->regular_supported && (image_support->regular_memtypes & memtype_bit); - const bool sparse_compatible = - image_support->sparse_supported && (image_support->sparse_memtypes & memtype_bit); - const bool transient_compatible = - image_support->transient_supported && (image_support->transient_memtypes & memtype_bit); - - if (regular_compatible || sparse_compatible || transient_compatible) { - first = false; - - if (fmt_i == 0) { - fprintf(out, "\t\t\t\t\t\t\t\t\t\t<details><summary>color images</summary>\n"); - } else { - fprintf(out, "\t\t\t\t\t\t\t\t\t\t<details><summary>%s</summary>\n", - VkFormatString(gpu->mem_type_res_support.image[tiling][fmt_i].format)); - } - - fprintf(out, - "\t\t\t\t\t\t\t\t\t\t\t<details><summary><span class=\"type\">regular image</span> = <span " - "class=\"val\">%s</span></summary></details>\n", - regular_compatible ? "supported" : "not supported"); - fprintf(out, - "\t\t\t\t\t\t\t\t\t\t\t<details><summary><span " - "class=\"type\">VK_IMAGE_CREATE_SPARSE_BINDING_BIT</span> " - "= <span class=\"val\">%s</span></summary></details>\n", - sparse_compatible ? "supported" : "not supported"); - fprintf(out, - "\t\t\t\t\t\t\t\t\t\t\t<details><summary><span " - "class=\"type\">VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT</span> = <span " - "class=\"val\">%s</span></summary></details>\n", - transient_compatible ? "supported" : "not supported"); - - fprintf(out, "\t\t\t\t\t\t\t\t\t\t</details>\n"); - } - } - - if (first) fprintf(out, "<details><summary><span class=\"type\">None</span></summary></details>"); - - fprintf(out, "\t\t\t\t\t\t\t\t\t</details>\n"); - } - - fprintf(out, "\t\t\t\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t\t\t\t</details>\n"); - } - } - - if (html_output) { - if (props.memoryTypeCount > 0) { - fprintf(out, "\t\t\t\t\t\t"); - } - fprintf(out, "</details>\n"); - fprintf(out, "\t\t\t\t\t</details>\n"); - } - if (json_output) { - if (props.memoryTypeCount > 0) { - printf("\n\t\t"); - } - printf("]\n"); - printf("\t}"); - } - - fflush(out); - fflush(stdout); -} - -static void AppGpuDump(const struct AppGpu *gpu, FILE *out) { - if (html_output) { - fprintf(out, "\t\t\t\t<details><summary>GPU%u</summary>\n", gpu->id); - } else if (human_readable_output) { - printf("\nDevice Properties and Extensions :\n"); - printf("==================================\n"); - printf("GPU%u\n", gpu->id); - } - - AppGpuDumpProps(gpu, out); - if (html_output) { - AppDumpExtensions("\t\t", "Device", gpu->device_extension_count, gpu->device_extensions, out); - } else if (human_readable_output) { - printf("\n"); - AppDumpExtensions("", "Device", gpu->device_extension_count, gpu->device_extensions, out); - printf("\n"); - } - - if (json_output) { - printf(",\n"); - printf("\t\"ArrayOfVkQueueFamilyProperties\": ["); - } - for (uint32_t i = 0; i < gpu->queue_count; ++i) { - if (json_output) { - if (i > 0) { - printf(","); - } - printf("\n"); - } - AppGpuDumpQueueProps(gpu, i, out); - if (human_readable_output) { - printf("\n"); - } - } - if (json_output) { - if (gpu->queue_count > 0) { - printf("\n\t"); - } - printf("]"); - } - - AppGpuDumpMemoryProps(gpu, out); - if (human_readable_output) { - printf("\n"); - } - - AppGpuDumpFeatures(gpu, out); - if (human_readable_output) { - printf("\n"); - } - - AppDevDump(gpu, out); - if (html_output) { - fprintf(out, "\t\t\t\t</details>\n"); - } -} - -static void AppGroupDump(const VkPhysicalDeviceGroupProperties *group, const uint32_t id, const struct AppInstance *inst, - FILE *out) { - if (html_output) { - fprintf(out, "\t\t\t\t<details><summary>Device Group Properties (Group %u)</summary>\n", id); - fprintf(out, "\t\t\t\t\t<details><summary>physicalDeviceCount = <span class='val'>%u</span></summary>\n", - group->physicalDeviceCount); - } else if (human_readable_output) { - printf("\tDevice Group Properties (Group %u) :\n", id); - printf("\t\tphysicalDeviceCount = %u\n", group->physicalDeviceCount); - } - - // Keep a record of all physical device properties to give the user clearer information as output. - VkPhysicalDeviceProperties *props = malloc(sizeof(props[0]) * group->physicalDeviceCount); - if (!props) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - for (uint32_t i = 0; i < group->physicalDeviceCount; ++i) { - vkGetPhysicalDeviceProperties(group->physicalDevices[i], &props[i]); - } - - // Output information to the user. - for (uint32_t i = 0; i < group->physicalDeviceCount; ++i) { - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>%s (ID: <span class='val'>%d</span>)</summary></details>\n", - props[i].deviceName, i); - } else if (human_readable_output) { - printf("\n\t\t\t%s (ID: %d)\n", props[i].deviceName, i); - } - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t</details>\n"); - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>subsetAllocation = <span class='val'>%u</span></summary></details>\n", - group->subsetAllocation); - } else if (human_readable_output) { - printf("\n\t\tsubsetAllocation = %u\n", group->subsetAllocation); - } - - if (html_output) { - fprintf(out, "\t\t\t\t</details>\n"); - } - - // Build create info for logical device made from all physical devices in this group. - const char *extensions_list[] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_EXTENSION_NAME}; - - VkDeviceGroupDeviceCreateInfoKHR dg_ci = {.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR, - .pNext = NULL, - .physicalDeviceCount = group->physicalDeviceCount, - .pPhysicalDevices = group->physicalDevices}; - - float queue_priority = 1.0f; - - VkDeviceQueueCreateInfo q_ci = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .pNext = NULL, - .queueFamilyIndex = 0, - .queueCount = 1, - .pQueuePriorities = &queue_priority}; - - VkDeviceCreateInfo device_ci = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = &dg_ci, - .queueCreateInfoCount = 1, - .pQueueCreateInfos = &q_ci, - .enabledExtensionCount = ARRAY_SIZE(extensions_list), - .ppEnabledExtensionNames = extensions_list}; - - VkDevice logical_device = VK_NULL_HANDLE; - - VkResult err = vkCreateDevice(group->physicalDevices[0], &device_ci, NULL, &logical_device); - if (err != VK_SUCCESS && err != VK_ERROR_EXTENSION_NOT_PRESENT) ERR_EXIT(err); - - if (!err) { - if (html_output) { - fprintf(out, "\t\t\t\t<details><summary>Device Group Present Capabilities (Group %d)</summary>\n", id); - } else if (human_readable_output) { - printf("\n\tDevice Group Present Capabilities (Group %d) :\n", id); - } - - VkDeviceGroupPresentCapabilitiesKHR group_capabilities = {.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR, - .pNext = NULL}; - - // If the KHR_device_group extension is present, write the capabilities of the logical device into a struct for - // later output to user. - PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR = - (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)vkGetInstanceProcAddr(inst->instance, - "vkGetDeviceGroupPresentCapabilitiesKHR"); - err = vkGetDeviceGroupPresentCapabilitiesKHR(logical_device, &group_capabilities); - if (err) ERR_EXIT(err); - - for (uint32_t i = 0; i < group->physicalDeviceCount; i++) { - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>%s (ID: <span class='val'>%d</span>)</summary></details>\n", - props[i].deviceName, i); - fprintf(out, "\t\t\t\t\t<details><summary>Can present images from the following devices:</summary>\n"); - if (group_capabilities.presentMask[i] != 0) { - for (uint32_t j = 0; j < group->physicalDeviceCount; ++j) { - uint32_t mask = 1 << j; - if (group_capabilities.presentMask[i] & mask) { - fprintf(out, "\t\t\t\t\t\t<details><summary>%s (ID: <span class='val'>%d</span>)</summary></details>\n", - props[j].deviceName, j); - } - } - } else { - fprintf(out, "\t\t\t\t\t\t<details><summary>None</summary></details>\n"); - } - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\n\t\t%s (ID: %d)\n", props[i].deviceName, i); - printf("\t\tCan present images from the following devices:\n"); - if (group_capabilities.presentMask[i] != 0) { - for (uint32_t j = 0; j < group->physicalDeviceCount; ++j) { - uint32_t mask = 1 << j; - if (group_capabilities.presentMask[i] & mask) { - printf("\t\t\t%s (ID: %d)\n", props[j].deviceName, j); - } - } - } else { - printf("\t\t\tNone\n"); - } - printf("\n"); - } - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>Present modes</summary>\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR) - fprintf(out, "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR</summary></details>\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR) - fprintf(out, "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR</summary></details>\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR) - fprintf(out, "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR</summary></details>\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR) - fprintf(out, - "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR</summary></" - "details>\n"); - fprintf(out, "\t\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\t\tPresent modes:\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR) - printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR) - printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR) - printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR\n"); - if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR) - printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR\n"); - } - - if (html_output) { - fprintf(out, "\t\t\t\t</details>\n"); - } - } - - // Clean up after ourselves. - free(props); - vkDestroyDevice(logical_device, NULL); -} - -#ifdef _WIN32 -// Enlarges the console window to have a large scrollback size. -static void ConsoleEnlarge() { - const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - // make the console window bigger - CONSOLE_SCREEN_BUFFER_INFO csbi; - COORD buffer_size; - if (GetConsoleScreenBufferInfo(console_handle, &csbi)) { - buffer_size.X = csbi.dwSize.X + 30; - buffer_size.Y = 20000; - SetConsoleScreenBufferSize(console_handle, buffer_size); - } - - SMALL_RECT r; - r.Left = r.Top = 0; - r.Right = csbi.dwSize.X - 1 + 30; - r.Bottom = 50; - SetConsoleWindowInfo(console_handle, true, &r); - - // change the console window title - SetConsoleTitle(TEXT(APP_SHORT_NAME)); -} -#endif - -void print_usage(char *argv0) { - printf("\nvulkaninfo - Summarize Vulkan information in relation to the current environment.\n\n"); - printf("USAGE: %s [options]\n\n", argv0); - printf("OPTIONS:\n"); - printf("-h, --help Print this help.\n"); - printf("--html Produce an html version of vulkaninfo output, saved as\n"); - printf(" \"vulkaninfo.html\" in the directory in which the command is\n"); - printf(" run.\n"); - printf("-j, --json Produce a json version of vulkaninfo output to standard\n"); - printf(" output.\n"); - printf("--json=<gpu-number> For a multi-gpu system, a single gpu can be targetted by\n"); - printf(" specifying the gpu-number associated with the gpu of \n"); - printf(" interest. This number can be determined by running\n"); - printf(" vulkaninfo without any options specified.\n\n"); -} - -int main(int argc, char **argv) { - uint32_t gpu_count; - VkResult err; - struct AppInstance inst = {0}; - FILE *out = stdout; - -#ifdef _WIN32 - if (ConsoleIsExclusive()) ConsoleEnlarge(); -#endif - - // Combinations of output: html only, html AND json, json only, human readable only - for (int i = 1; i < argc; ++i) { - if (!CheckForJsonOption(argv[i])) { - if (strcmp(argv[i], "--html") == 0) { - human_readable_output = false; - html_output = true; - continue; - } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { - print_usage(argv[0]); - return 1; - } else { - print_usage(argv[0]); - return 1; - } - } - } - - AppCreateInstance(&inst); - - if (html_output) { -#ifdef _WIN32 - if (fopen_s(&out, "vulkaninfo.html", "w") != 0) out = NULL; -#else - out = fopen("vulkaninfo.html", "w"); -#endif - if (!out) { - printf("Unable to open vulkaninfo.html for writing\n"); - return 1; - } - PrintHtmlHeader(out); - fprintf(out, "\t\t\t<details><summary>"); - } else if (human_readable_output) { - printf("==========\n"); - printf("VULKANINFO\n"); - printf("==========\n\n"); - } - if (html_output || human_readable_output) { - fprintf(out, "Vulkan Instance Version: "); - } - if (html_output) { - fprintf(out, "<span class='val'>%d.%d.%d</span></summary></details>\n", inst.vulkan_major, inst.vulkan_minor, - inst.vulkan_patch); - fprintf(out, "\t\t\t<br />\n"); - } else if (human_readable_output) { - printf("%d.%d.%d\n\n", inst.vulkan_major, inst.vulkan_minor, inst.vulkan_patch); - } - - err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL); - if (err) { - ERR_EXIT(err); - } - - VkPhysicalDevice *objs = malloc(sizeof(objs[0]) * gpu_count); - if (!objs) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - - err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs); - if (err) { - ERR_EXIT(err); - } - - struct AppGpu *gpus = malloc(sizeof(gpus[0]) * gpu_count); - if (!gpus) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - - for (uint32_t i = 0; i < gpu_count; ++i) { - AppGpuInit(&gpus[i], &inst, i, objs[i]); - if (human_readable_output) { - printf("\n\n"); - } - } - - // If json output, confirm the desired gpu exists - if (json_output) { - if (selected_gpu >= gpu_count) { - selected_gpu = 0; - } - PrintJsonHeader(inst.vulkan_major, inst.vulkan_minor, inst.vulkan_patch); - } - - if (human_readable_output) { - printf("Instance Extensions:\n"); - printf("====================\n"); - } - AppDumpExtensions("", "Instance", inst.global_extension_count, inst.global_extensions, out); - - //---Layer-Device-Extensions--- - if (html_output) { - fprintf(out, "\t\t\t<details><summary>Layers: count = <span class='val'>%d</span></summary>", inst.global_layer_count); - if (inst.global_layer_count > 0) { - fprintf(out, "\n"); - } - } else if (human_readable_output) { - printf("Layers: count = %d\n", inst.global_layer_count); - printf("=======\n"); - } - if (json_output && (inst.global_layer_count > 0)) { - printf(",\n"); - printf("\t\"ArrayOfVkLayerProperties\": ["); - } - - qsort(inst.global_layers, inst.global_layer_count, sizeof(struct LayerExtensionList), CompareLayerName); - - for (uint32_t i = 0; i < inst.global_layer_count; ++i) { - uint32_t layer_major, layer_minor, layer_patch; - char spec_version[64], layer_version[64]; - VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties; - - ExtractVersion(layer_prop->specVersion, &layer_major, &layer_minor, &layer_patch); -#ifdef _WIN32 - _snprintf_s(spec_version, sizeof(spec_version), 64, "%d.%d.%d", layer_major, layer_minor, layer_patch); - _snprintf_s(layer_version, sizeof(layer_version), 64, "%d", layer_prop->implementationVersion); -#else - snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", layer_major, layer_minor, layer_patch); - snprintf(layer_version, sizeof(layer_version), "%d", layer_prop->implementationVersion); -#endif - - if (html_output) { - fprintf(out, "\t\t\t\t<details><summary>"); - fprintf(out, "<span class='type'>%s</span> (%s) Vulkan version <span class='val'>%s</span>, ", layer_prop->layerName, - (char *)layer_prop->description, spec_version); - fprintf(out, "layer version <span class='val'>%s</span></summary>\n", layer_version); - AppDumpExtensions("\t\t", "Layer", inst.global_layers[i].extension_count, inst.global_layers[i].extension_properties, - out); - } else if (human_readable_output) { - printf("%s (%s) Vulkan version %s, layer version %s\n", layer_prop->layerName, (char *)layer_prop->description, - spec_version, layer_version); - AppDumpExtensions("\t", "Layer", inst.global_layers[i].extension_count, inst.global_layers[i].extension_properties, - out); - } - if (json_output) { - if (i > 0) { - printf(","); - } - printf("\n"); - printf("\t\t{\n"); - printf("\t\t\t\"layerName\": \"%s\",\n", layer_prop->layerName); - printf("\t\t\t\"specVersion\": %u,\n", layer_prop->specVersion); - printf("\t\t\t\"implementationVersion\": %u,\n", layer_prop->implementationVersion); - printf("\t\t\t\"description\": \"%s\"\n", layer_prop->description); - printf("\t\t}"); - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t<details><summary>Devices count = <span class='val'>%d</span></summary>\n", gpu_count); - } else if (human_readable_output) { - printf("\tDevices \tcount = %d\n", gpu_count); - } - - char *layer_name = inst.global_layers[i].layer_properties.layerName; - - for (uint32_t j = 0; j < gpu_count; ++j) { - if (html_output) { - fprintf(out, "\t\t\t\t\t\t<details><summary>"); - fprintf(out, "GPU id: <span class='val'>%u</span> (%s)</summary></details>\n", j, gpus[j].props.deviceName); - } else if (human_readable_output) { - printf("\t\tGPU id : %u (%s)\n", j, gpus[j].props.deviceName); - } - uint32_t count = 0; - VkExtensionProperties *props; - AppGetPhysicalDeviceLayerExtensions(&gpus[j], layer_name, &count, &props); - if (html_output) { - AppDumpExtensions("\t\t\t", "Layer-Device", count, props, out); - } else if (human_readable_output) { - AppDumpExtensions("\t\t", "Layer-Device", count, props, out); - } - free(props); - } - - if (html_output) { - fprintf(out, "\t\t\t\t\t</details>\n"); - fprintf(out, "\t\t\t\t</details>\n"); - } else if (human_readable_output) { - printf("\n"); - } - } - - if (html_output) { - fprintf(out, "\t\t\t</details>\n"); - } - if (json_output && (inst.global_layer_count > 0)) { - printf("\n\t]"); - } - - fflush(out); - fflush(stdout); - //----------------------------- - - if (html_output) { - fprintf(out, "\t\t\t<details><summary>Presentable Surfaces</summary>"); - if (gpu_count > 0) { - fprintf(out, "\n"); - } else { - fprintf(out, "</details>\n"); - } - } else if (human_readable_output) { - printf("Presentable Surfaces:\n"); - printf("=====================\n"); - } - inst.width = 256; - inst.height = 256; - int format_count = 0; - int present_mode_count = 0; - -#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) - bool has_display = true; - const char *display_var = getenv("DISPLAY"); - if (display_var == NULL || strlen(display_var) == 0) { - fprintf(stderr, "'DISPLAY' environment variable not set... skipping surface info\n"); - fflush(stderr); - has_display = false; - } -#endif - -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - struct wl_display *wayland_display = wl_display_connect(NULL); - bool has_wayland_display = false; - if (wayland_display != NULL) { - wl_display_disconnect(wayland_display); - has_wayland_display = true; - } -#endif - -//--WIN32-- -#ifdef VK_USE_PLATFORM_WIN32_KHR - struct SurfaceExtensionNode surface_ext_win32; - if (CheckExtensionEnabled(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { - surface_ext_win32.name = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; - surface_ext_win32.create_window = AppCreateWin32Window; - surface_ext_win32.create_surface = AppCreateWin32Surface; - surface_ext_win32.destroy_window = AppDestroyWin32Window; - - surface_ext_win32.next = inst.surface_ext_infos_root; - inst.surface_ext_infos_root = &surface_ext_win32; - } -#endif -//--XCB-- -#ifdef VK_USE_PLATFORM_XCB_KHR - struct SurfaceExtensionNode surface_ext_xcb; - if (CheckExtensionEnabled(VK_KHR_XCB_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { - surface_ext_xcb.name = VK_KHR_XCB_SURFACE_EXTENSION_NAME; - surface_ext_xcb.create_window = AppCreateXcbWindow; - surface_ext_xcb.create_surface = AppCreateXcbSurface; - surface_ext_xcb.destroy_window = AppDestroyXcbWindow; - if (has_display) { - surface_ext_xcb.next = inst.surface_ext_infos_root; - inst.surface_ext_infos_root = &surface_ext_xcb; - } - } -#endif -//--XLIB-- -#ifdef VK_USE_PLATFORM_XLIB_KHR - struct SurfaceExtensionNode surface_ext_xlib; - if (CheckExtensionEnabled(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { - surface_ext_xlib.name = VK_KHR_XLIB_SURFACE_EXTENSION_NAME; - surface_ext_xlib.create_window = AppCreateXlibWindow; - surface_ext_xlib.create_surface = AppCreateXlibSurface; - surface_ext_xlib.destroy_window = AppDestroyXlibWindow; - if (has_display) { - surface_ext_xlib.next = inst.surface_ext_infos_root; - inst.surface_ext_infos_root = &surface_ext_xlib; - } - } -#endif -//--MACOS-- -#ifdef VK_USE_PLATFORM_MACOS_MVK - struct SurfaceExtensionNode surface_ext_macos; - if (CheckExtensionEnabled(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { - surface_ext_macos.name = VK_MVK_MACOS_SURFACE_EXTENSION_NAME; - surface_ext_macos.create_window = AppCreateMacOSWindow; - surface_ext_macos.create_surface = AppCreateMacOSSurface; - surface_ext_macos.destroy_window = AppDestroyMacOSWindow; - - surface_ext_macos.next = inst.surface_ext_infos_root; - inst.surface_ext_infos_root = &surface_ext_macos; - } -#endif -//--WAYLAND-- -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - struct SurfaceExtensionNode surface_ext_wayland; - if (CheckExtensionEnabled(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { - surface_ext_wayland.name = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME; - surface_ext_wayland.create_window = AppCreateWaylandWindow; - surface_ext_wayland.create_surface = AppCreateWaylandSurface; - surface_ext_wayland.destroy_window = AppDestroyWaylandWindow; - if (has_wayland_display) { - surface_ext_wayland.next = inst.surface_ext_infos_root; - inst.surface_ext_infos_root = &surface_ext_wayland; - } - } -#endif - // TODO: Android - - for (struct SurfaceExtensionNode *sen = inst.surface_ext_infos_root; sen != NULL; sen = sen->next) { - sen->create_window(&inst); - sen->surface = sen->create_surface(&inst); - AppDumpSurfaceExtension(&inst, gpus, gpu_count, sen, &format_count, &present_mode_count, out); - } - - if (!inst.surface_ext_infos_root) { - if (html_output) { - fprintf(out, "\t\t\t\t<details><summary>None found</summary></details>\n"); - } else if (human_readable_output) { - printf("None found\n\n"); - } - } - - if (html_output) { - fprintf(out, "\t\t\t</details>\n"); - } - //--------- - - if (CheckExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { - PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR = - (PFN_vkEnumeratePhysicalDeviceGroupsKHR)vkGetInstanceProcAddr(inst.instance, "vkEnumeratePhysicalDeviceGroupsKHR"); - - uint32_t group_count; - err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, NULL); - if (err) { - ERR_EXIT(err); - } - - VkPhysicalDeviceGroupProperties *groups = malloc(sizeof(groups[0]) * group_count); - if (!groups) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); - } - - err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, groups); - if (err) { - ERR_EXIT(err); - } - - if (html_output) { - fprintf(out, "\t\t\t<details><summary>Groups</summary>\n"); - } else if (human_readable_output) { - printf("\nGroups :\n"); - printf("========\n"); - } - - for (uint32_t i = 0; i < group_count; ++i) { - AppGroupDump(&groups[i], i, &inst, out); - if (human_readable_output) { - printf("\n\n"); - } - } - - if (html_output) { - fprintf(out, "\t\t\t</details>\n"); - } - - free(groups); - } - - if (html_output) { - fprintf(out, "\t\t\t<details><summary>Device Properties and Extensions</summary>\n"); - } - - for (uint32_t i = 0; i < gpu_count; ++i) { - if (json_output && selected_gpu != i) { - // Toggle json_output to allow html output without json output - json_output = false; - AppGpuDump(&gpus[i], out); - json_output = true; - } else { - AppGpuDump(&gpus[i], out); - } - if (human_readable_output) { - printf("\n\n"); - } - } - - if (html_output) { - fprintf(out, "\t\t\t</details>\n"); - } - - for (uint32_t i = 0; i < gpu_count; ++i) { - AppGpuDestroy(&gpus[i]); - } - free(gpus); - free(objs); - - for (struct SurfaceExtensionNode *sen = inst.surface_ext_infos_root; sen != NULL; sen = sen->next) { - AppDestroySurface(&inst, sen->surface); - sen->destroy_window(&inst); - } - - AppDestroyInstance(&inst); - - if (html_output) { - PrintHtmlFooter(out); - fflush(out); - fclose(out); - } - if (json_output) { - printf("\n}\n"); - } - - fflush(stdout); - -#ifdef _WIN32 - if (ConsoleIsExclusive() && human_readable_output) { - Sleep(INFINITE); - } -#endif - - return 0; -} diff --git a/vulkaninfo/vulkaninfo.cpp b/vulkaninfo/vulkaninfo.cpp new file mode 100644 index 00000000..f51a59e3 --- /dev/null +++ b/vulkaninfo/vulkaninfo.cpp @@ -0,0 +1,751 @@ +/* + * Copyright (c) 2015-2019 The Khronos Group Inc. + * Copyright (c) 2015-2019 Valve Corporation + * Copyright (c) 2015-2019 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> + * Author: David Pinedo <david@lunarg.com> + * Author: Mark Lobodzinski <mark@lunarg.com> + * Author: Rene Lindsay <rene@lunarg.com> + * Author: Jeremy Kniager <jeremyk@lunarg.com> + * Author: Shannon McPherson <shannon@lunarg.com> + * Author: Bob Ellison <bob@lunarg.com> + * Author: Charles Giessen <charles@lunarg.com> + * + */ + +#include "vulkaninfo.hpp" + +// =========== Dump Functions ========= // + +void DumpExtensions(Printer &p, std::string layer_name, std::vector<VkExtensionProperties> extensions) { + std::sort(extensions.begin(), extensions.end(), [](VkExtensionProperties &a, VkExtensionProperties &b) -> int { + return std::string(a.extensionName) < std::string(b.extensionName); + }); + + if (p.Type() == OutputType::json) return; + + int max_length = 0; + if (extensions.size() > 0) { + max_length = strlen(extensions.at(0).extensionName); + for (auto &ext : extensions) { + int len = strlen(ext.extensionName); + if (len > max_length) max_length = len; + } + } + + p.ArrayStart(layer_name + " Extensions", extensions.size()); + for (auto &ext : extensions) { + p.PrintExtension(ext.extensionName, ext.specVersion, max_length); + } + p.ArrayEnd(); +} + +void DumpLayers(Printer &p, std::vector<LayerExtensionList> layers, std::vector<AppGpu *> gpus) { + std::sort(layers.begin(), layers.end(), [](LayerExtensionList &left, LayerExtensionList &right) -> int { + const char *a = left.layer_properties.layerName; + const char *b = right.layer_properties.layerName; + return a && (!b || std::strcmp(a, b) < 0); + }); + + if (p.Type() == OutputType::text || p.Type() == OutputType::html) { + p.SetHeader().ArrayStart("Layers", layers.size()); + p.IndentDecrease(); + for (auto &layer : layers) { + auto v_str = VkVersionString(layer.layer_properties.specVersion); + auto props = layer.layer_properties; + + std::string header; + if (p.Type() == OutputType::text) + header = std::string(props.layerName) + " (" + props.description + ") Vulkan version " + v_str + + ", layer version " + std::to_string(props.implementationVersion); + else if (p.Type() == OutputType::html) + header = std::string("<span class='type'>") + props.layerName + "</span> (" + props.description + + ") Vulkan version <span class='val'>" + v_str + "</span>, layer version <span class='val'>" + + std::to_string(props.implementationVersion) + "</span>"; + + p.ObjectStart(header); + DumpExtensions(p, "Layer", layer.extension_properties); + + p.ArrayStart("Devices", gpus.size()); + for (auto &gpu : gpus) { + p.PrintElement(std::string("GPU id \t: ") + std::to_string(gpu->id), gpu->props.deviceName); + auto exts = gpu->AppGetPhysicalDeviceLayerExtensions(props.layerName); + DumpExtensions(p, "Layer-Device", exts); + p.AddNewline(); + } + p.ArrayEnd(); + p.ObjectEnd(); + } + p.IndentIncrease(); + p.ArrayEnd(); + } else if (p.Type() == OutputType::json) { + p.ArrayStart("ArrayOfVkLayerProperties", layers.size()); + int i = 0; + for (auto &layer : layers) { + p.SetElementIndex(i++); + DumpVkLayerProperties(p, "layerProperty", layer.layer_properties); + } + p.ArrayEnd(); + } +} + +void DumpSurfaceFormats(Printer &p, AppInstance &inst, AppSurface &surface) { + p.ArrayStart("Formats", surface.surf_formats2.size()); + int i = 0; + if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { + for (auto &format : surface.surf_formats2) { + p.SetElementIndex(i++); + DumpVkSurfaceFormatKHR(p, "SurfaceFormat", format.surfaceFormat); + } + } else { + for (auto &format : surface.surf_formats) { + p.SetElementIndex(i++); + DumpVkSurfaceFormatKHR(p, "SurfaceFormat", format); + } + } + p.ArrayEnd(); +} + +void DumpPresentModes(Printer &p, AppInstance &inst, AppSurface &surface) { + p.ArrayStart("Present Modes", surface.surf_present_modes.size()); + for (auto &mode : surface.surf_present_modes) { + p.SetAsType().PrintElement(VkPresentModeKHRString(mode)); + } + p.ArrayEnd(); +} + +void DumpSurfaceCapabilities(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurface &surface) { + auto &surf_cap = surface.surface_capabilities; + p.SetSubHeader(); + DumpVkSurfaceCapabilitiesKHR(p, "VkSurfaceCapabilitiesKHR", surf_cap); + + p.SetSubHeader().ObjectStart("VkSurfaceCapabilities2EXT"); + { + p.ObjectStart("supportedSurfaceCounters"); + if (surface.surface_capabilities2_ext.supportedSurfaceCounters == 0) p.PrintElement("None"); + if (surface.surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) { + p.SetAsType().PrintElement("VK_SURFACE_COUNTER_VBLANK_EXT"); + } + p.ObjectEnd(); + } + p.ObjectEnd(); // VkSurfaceCapabilities2EXT + + chain_iterator_surface_capabilities2(p, inst, gpu, surface.surface_capabilities2_khr.pNext); +} + +void DumpSurface(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurface &surface) { + std::string header; + if (p.Type() == OutputType::text) + header = std::string("GPU id : ") + std::to_string(gpu.id) + " (" + gpu.props.deviceName + ")"; + else if (p.Type() == OutputType::html) + header = std::string("GPU id : <span class='val'>") + std::to_string(gpu.id) + "</span> (" + gpu.props.deviceName + ")"; + p.ObjectStart(header); + + p.SetAsType().PrintKeyValue("Surface type", surface.surface_extension.name); + + DumpSurfaceFormats(p, inst, surface); + + DumpPresentModes(p, inst, surface); + + DumpSurfaceCapabilities(p, inst, gpu, surface); + + p.ObjectEnd(); + p.AddNewline(); +} + +void DumpPresentableSurfaces(Printer &p, AppInstance &inst, std::vector<AppGpu *> &gpus, std::vector<AppSurface *> &surfaces) { + p.SetHeader().ObjectStart("Presentable Surfaces"); + p.IndentDecrease(); + for (auto &surface : surfaces) { + for (auto &gpu : gpus) { + DumpSurface(p, inst, *gpu, *surface); + } + } + p.ObjectEnd(); + p.IndentIncrease(); + p.AddNewline(); +} + +void DumpGroups(Printer &p, AppInstance &inst) { + if (inst.CheckExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) { + p.SetHeader().ObjectStart("Groups"); + auto groups = GetGroups(inst); + int group_id = 0; + for (auto &group : groups) { + p.ObjectStart("Device Group Properties (Group " + std::to_string(group_id) + ")"); + auto group_props = GetGroupProps(group); + p.ArrayStart("physicalDeviceCount", group.physicalDeviceCount); + int id = 0; + for (auto &prop : group_props) { + std::string device_out; + if (p.Type() == OutputType::text) { + device_out = std::string(prop.deviceName) + " (ID: " + std::to_string(id++) + ")"; + } else if (p.Type() == OutputType::html) { + device_out = std::string(prop.deviceName) + " (ID: <span class='val'>" + std::to_string(id++) + "</span>)"; + } + p.PrintElement(device_out); + } + p.ArrayEnd(); + p.PrintKeyValue("subsetAllocation", group.subsetAllocation); + p.ObjectEnd(); + p.AddNewline(); + + p.ObjectStart("Device Group Present Capabilities (Group " + std::to_string(group_id) + ")"); + + auto group_capabilities = GetGroupCapabilities(inst, group); + for (uint32_t i = 0; i < group.physicalDeviceCount; i++) { + std::string device_out; + if (p.Type() == OutputType::text) { + device_out = std::string(group_props[i].deviceName) + " (ID: " + std::to_string(i) + ")"; + } else if (p.Type() == OutputType::html) { + device_out = + std::string(group_props[i].deviceName) + " (ID: <span class='val'>" + std::to_string(i) + "</span>)"; + } + p.PrintElement(device_out); + p.ObjectStart("Can present images from the following devices"); + for (uint32_t j = 0; j < group.physicalDeviceCount; j++) { + uint32_t mask = 1 << j; + if (group_capabilities.presentMask[i] & mask) { + if (p.Type() == OutputType::text) + p.PrintElement(std::string(group_props[j].deviceName) + " (ID: " + std::to_string(j) + ")"); + if (p.Type() == OutputType::html) + p.PrintElement(std::string(group_props[j].deviceName) + " (ID: <span class='val'>" + std::to_string(j) + + "</span>)"); + } + } + p.ObjectEnd(); + } + DumpVkDeviceGroupPresentModeFlagsKHR(p, "Present modes", group_capabilities.modes); + p.ObjectEnd(); + p.AddNewline(); + group_id++; + } + p.ObjectEnd(); + p.AddNewline(); + } +} + +void GpuDumpProps(Printer &p, AppGpu &gpu) { + auto props = gpu.GetDeviceProperties(); + p.SetSubHeader().ObjectStart("VkPhysicalDeviceProperties"); + p.PrintKeyValue("apiVersion", props.apiVersion, 14, VkVersionString(props.apiVersion)); + p.PrintKeyValue("driverVersion", props.driverVersion, 14, to_hex_str(props.driverVersion)); + if (p.Type() == OutputType::json) { + p.PrintKeyValue("vendorID", props.vendorID, 14); + p.PrintKeyValue("deviceID", props.deviceID, 14); + p.PrintKeyValue("deviceType", props.deviceType, 14); + } else { + p.PrintKeyValue("vendorID", to_hex_str(props.vendorID), 14); + p.PrintKeyValue("deviceID", to_hex_str(props.deviceID), 14); + p.PrintKeyString("deviceType", VkPhysicalDeviceTypeString(props.deviceType), 14); + } + p.PrintKeyString("deviceName", props.deviceName, 14); + if (p.Type() == OutputType::json) { + p.ArrayStart("pipelineCacheUUID"); + for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) { + p.PrintElement(static_cast<uint32_t>(props.pipelineCacheUUID[i])); + } + p.ArrayEnd(); + } + p.AddNewline(); + if (p.Type() != OutputType::json) { + p.ObjectEnd(); // limits and sparse props are not sub objects in the text and html output + } + + if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", gpu.props2.properties.limits); + } else { + DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", gpu.props.limits); + } + p.AddNewline(); + if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", gpu.props2.properties.sparseProperties); + } else { + DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", gpu.props.sparseProperties); + } + p.AddNewline(); + if (p.Type() == OutputType::json) { + p.ObjectEnd(); // limits and sparse props are sub objects in the json output + } + + if (p.Type() != OutputType::json) { + 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, place); + } + } + p.AddNewline(); +} +void GpuDumpQueueProps(Printer &p, std::vector<SurfaceExtension> &surfaces, AppQueueFamilyProperties &queue) { + p.SetHeader().SetElementIndex(queue.queue_index).ObjectStart("VkQueueFamilyProperties"); + if (p.Type() == OutputType::json) { + DumpVkExtent3D(p, "minImageTransferGranularity", queue.props.minImageTransferGranularity); + } else { + p.PrintKeyString("minImageTransferGranularity", VkExtent3DString(queue.props.minImageTransferGranularity), 27); + } + p.PrintKeyValue("queueCount", queue.props.queueCount, 27); + if (p.Type() == OutputType::json) { + p.PrintKeyValue("queueFlags", queue.props.queueFlags, 27); + } else { + p.PrintKeyValue("queueFlags", VkQueueFlagsString(queue.props.queueFlags), 27); + } + + p.PrintKeyValue("timestampValidBits", queue.props.timestampValidBits, 27); + + if (p.Type() != OutputType::json) { + if (queue.is_present_platform_agnostic) { + p.PrintKeyString("present support", queue.platforms_support_present ? "true" : "false"); + } else { + p.ObjectStart("present support"); + for (auto &surface : surfaces) { + p.PrintKeyString(surface.name, surface.supports_present ? "true" : "false", 19); + } + p.ObjectEnd(); + } + } + p.ObjectEnd(); + p.AddNewline(); +} + +// 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.). +#define kBufferSize 32 + +static char *NumToNiceStr(const size_t sz) { + const char prefixes[] = "KMGTPEZY"; + char buf[kBufferSize]; + int which = -1; + double result = (double)sz; + while (result > 1024 && which < 7) { + result /= 1024; + ++which; + } + + char unit[] = "\0i"; + if (which >= 0) { + unit[0] = prefixes[which]; + } +#ifdef _WIN32 + _snprintf_s(buf, kBufferSize * sizeof(char), kBufferSize, "%.2f %sB", result, unit); +#else + snprintf(buf, kBufferSize, "%.2f %sB", result, unit); +#endif + return strndup(buf, kBufferSize); +} + +void GpuDumpMemoryProps(Printer &p, AppGpu &gpu) { + p.SetHeader().ObjectStart("VkPhysicalDeviceMemoryProperties"); + p.IndentDecrease(); + p.ArrayStart("memoryHeaps", gpu.memory_props.memoryHeapCount); + for (uint32_t i = 0; i < gpu.memory_props.memoryHeapCount; ++i) { + const VkDeviceSize memSize = gpu.memory_props.memoryHeaps[i].size; + std::string mem_size_human_readable = std::string(NumToNiceStr(static_cast<size_t>(memSize))); + + std::string mem_size_str = std::to_string(memSize) + " (" + to_hex_str(memSize) + ") (" + mem_size_human_readable + ")"; + + p.SetElementIndex(i).ObjectStart("memoryHeaps"); + if (p.Type() != OutputType::json) { + p.PrintKeyValue("size", mem_size_str, 6); + p.PrintKeyValue("budget", gpu.heapBudget[i], 6); + p.PrintKeyValue("usage", gpu.heapUsage[i], 6); + DumpVkMemoryHeapFlags(p, "flags", gpu.memory_props.memoryHeaps[i].flags, 6); + } else { + p.PrintKeyValue("flags", gpu.memory_props.memoryHeaps[i].flags); + p.PrintKeyValue("size", memSize); + } + p.ObjectEnd(); + } + p.ArrayEnd(); + + p.ArrayStart("memoryTypes", gpu.memory_props.memoryTypeCount); + for (uint32_t i = 0; i < gpu.memory_props.memoryTypeCount; ++i) { + p.SetElementIndex(i).ObjectStart("memoryTypes"); + p.PrintKeyValue("heapIndex", gpu.memory_props.memoryTypes[i].heapIndex, 13); + if (p.Type() == OutputType::json) { + p.PrintKeyValue("propertyFlags", gpu.memory_props.memoryTypes[i].propertyFlags, 13); + } else { + auto flags = gpu.memory_props.memoryTypes[i].propertyFlags; + DumpVkMemoryPropertyFlags(p, "propertyFlags = " + to_hex_str(flags), flags); + + p.ObjectStart("usable for"); + const uint32_t memtype_bit = 1 << i; + + // only linear and optimal tiling considered + for (uint32_t tiling = VK_IMAGE_TILING_OPTIMAL; tiling < gpu.mem_type_res_support.image.size(); ++tiling) { + std::string usable; + usable += std::string(VkImageTilingString(VkImageTiling(tiling))) + ": "; + size_t orig_usable_str_size = usable.size(); + bool first = true; + for (size_t fmt_i = 0; fmt_i < gpu.mem_type_res_support.image[tiling].size(); ++fmt_i) { + const MemImageSupport *image_support = &gpu.mem_type_res_support.image[tiling][fmt_i]; + const bool regular_compatible = + image_support->regular_supported && (image_support->regular_memtypes & memtype_bit); + const bool sparse_compatible = + image_support->sparse_supported && (image_support->sparse_memtypes & memtype_bit); + const bool transient_compatible = + image_support->transient_supported && (image_support->transient_memtypes & memtype_bit); + + if (regular_compatible || sparse_compatible || transient_compatible) { + if (!first) usable += ", "; + first = false; + + if (fmt_i == 0) { + usable += "color images"; + } else { + usable += VkFormatString(gpu.mem_type_res_support.image[tiling][fmt_i].format); + } + + if (regular_compatible && !sparse_compatible && !transient_compatible && image_support->sparse_supported && + image_support->transient_supported) { + usable += "(non-sparse, non-transient)"; + } else if (regular_compatible && !sparse_compatible && image_support->sparse_supported) { + if (image_support->sparse_supported) usable += "(non-sparse)"; + } else if (regular_compatible && !transient_compatible && image_support->transient_supported) { + if (image_support->transient_supported) usable += "(non-transient)"; + } else if (!regular_compatible && sparse_compatible && !transient_compatible && + image_support->sparse_supported) { + if (image_support->sparse_supported) usable += "(sparse only)"; + } else if (!regular_compatible && !sparse_compatible && transient_compatible && + image_support->transient_supported) { + if (image_support->transient_supported) usable += "(transient only)"; + } else if (!regular_compatible && sparse_compatible && transient_compatible && + image_support->sparse_supported && image_support->transient_supported) { + usable += "(sparse and transient only)"; + } + } + } + if (usable.size() == orig_usable_str_size) // not usable for anything + { + usable += "None"; + } + p.PrintElement(usable); + } + p.ObjectEnd(); + } + + p.ObjectEnd(); + } + p.ArrayEnd(); + p.IndentIncrease(); + p.ObjectEnd(); + p.AddNewline(); +} + +void GpuDumpFeatures(Printer &p, AppGpu &gpu) { + p.SetHeader(); + DumpVkPhysicalDeviceFeatures(p, "VkPhysicalDeviceFeatures", gpu.features); + p.AddNewline(); + if (p.Type() != OutputType::json) { + if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + void *place = gpu.features2.pNext; + chain_iterator_phys_device_features2(p, gpu, place); + } + } +} + +void GpuDumpFormatProperty(Printer &p, VkFormatProperties prop) { + p.SetOpenDetails(); + DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures); + p.SetOpenDetails(); + DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures); + p.SetOpenDetails(); + DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures); +} + +void GpuDevDump(Printer &p, AppGpu &gpu, pNextChainInfos &chainInfos) { + if (p.Type() == OutputType::json) { + p.ArrayStart("ArrayOfVkFormatProperties"); + } else { + p.SetHeader().ObjectStart("Format Properties"); + p.IndentDecrease(); + } + + if (p.Type() == OutputType::text) { + auto fmtPropMap = FormatPropMap(gpu); + + int counter = 0; + std::vector<VkFormat> unsupported_formats; + for (auto &prop : fmtPropMap) { + VkFormatProperties props; + props.linearTilingFeatures = prop.first.linear; + props.optimalTilingFeatures = prop.first.optimal; + props.bufferFeatures = prop.first.buffer; + if (props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0 && props.bufferFeatures == 0) { + unsupported_formats = prop.second; + continue; + } + + p.SetElementIndex(counter++).ObjectStart("Common Format Group"); + p.IndentDecrease(); + p.ObjectStart("Formats"); + for (auto &fmt : prop.second) { + p.SetAsType().PrintElement(VkFormatString(fmt)); + } + p.ObjectEnd(); + + p.ObjectStart("Properies"); + GpuDumpFormatProperty(p, props); + p.ObjectEnd(); + + p.IndentIncrease(); + p.ObjectEnd(); + p.AddNewline(); + } + + p.ObjectStart("Unsupported Formats"); + for (auto &fmt : unsupported_formats) { + p.SetAsType().PrintElement(VkFormatString(fmt)); + } + p.ObjectEnd(); + + } else { + for (auto &format : gpu.supported_format_ranges) { + if (gpu.FormatRangeSupported(format)) { + for (uint32_t fmt_counter = format.first_format; fmt_counter <= format.last_format; ++fmt_counter) { + VkFormat fmt = static_cast<VkFormat>(fmt_counter); + + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props); + + if (p.Type() == OutputType::html) { + p.SetTitleAsType().ObjectStart(VkFormatString(fmt)); + GpuDumpFormatProperty(p, props); + p.ObjectEnd(); + } else if (p.Type() == OutputType::json && + (props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures)) { + p.SetTitleAsType().ObjectStart(""); + p.PrintKeyValue("formatID", fmt); + p.PrintKeyValue("linearTilingFeatures", props.linearTilingFeatures); + p.PrintKeyValue("optimalTilingFeatures", props.optimalTilingFeatures); + p.PrintKeyValue("bufferFeatures", props.bufferFeatures); + p.ObjectEnd(); + } + } + } + } + } + + if (p.Type() == OutputType::json) { + p.ArrayEnd(); + } else { + p.ObjectEnd(); + p.IndentIncrease(); + } + + p.AddNewline(); +} + +void DumpGpu(Printer &p, AppGpu &gpu, bool show_formats, pNextChainInfos &chainInfos) { + if (p.Type() != OutputType::json) { + p.ObjectStart("GPU" + std::to_string(gpu.id)); + p.IndentDecrease(); + } + GpuDumpProps(p, gpu); + + if (p.Type() != OutputType::json) { + DumpExtensions(p, "Device", gpu.device_extensions); + p.AddNewline(); + } + + if (p.Type() == OutputType::json) p.ArrayStart("ArrayOfVkQueueFamilyProperties"); + for (uint32_t i = 0; i < gpu.queue_count; i++) { + AppQueueFamilyProperties queue_props = AppQueueFamilyProperties(gpu, i); + GpuDumpQueueProps(p, gpu.inst.surface_extensions, queue_props); + } + if (p.Type() == OutputType::json) p.ArrayEnd(); + + GpuDumpMemoryProps(p, gpu); + GpuDumpFeatures(p, gpu); + if (p.Type() != OutputType::text || show_formats) { + GpuDevDump(p, gpu, chainInfos); + } + + if (p.Type() != OutputType::json) { + p.ObjectEnd(); + p.IndentIncrease(); + } + p.AddNewline(); +} + +// ============ Printing Logic ============= // + +#ifdef _WIN32 +// Enlarges the console window to have a large scrollback size. +static void ConsoleEnlarge() { + const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // make the console window bigger + CONSOLE_SCREEN_BUFFER_INFO csbi; + COORD buffer_size; + if (GetConsoleScreenBufferInfo(console_handle, &csbi)) { + buffer_size.X = csbi.dwSize.X + 30; + buffer_size.Y = 20000; + SetConsoleScreenBufferSize(console_handle, buffer_size); + } + + SMALL_RECT r; + r.Left = r.Top = 0; + r.Right = csbi.dwSize.X - 1 + 30; + r.Bottom = 50; + SetConsoleWindowInfo(console_handle, true, &r); + + // change the console window title + SetConsoleTitle(TEXT(app_short_name)); +} +#endif + +void print_usage(const char *argv0) { + 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 << "--html Produce an html version of vulkaninfo output, saved as\n"; + std::cout << " \"vulkaninfo.html\" in the directory in which the command is\n"; + std::cout << " run.\n"; + std::cout << "-j, --json Produce a json version of vulkaninfo output to standard\n"; + std::cout << " output.\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\n"; +} + +int main(int argc, char **argv) { +#ifdef _WIN32 + if (ConsoleIsExclusive()) ConsoleEnlarge(); +#endif + + bool human_readable_output = true; + bool html_output = false; + bool json_output = false; + uint32_t selected_gpu = 0; + bool show_formats = false; + + // Combinations of output: html only, html AND json, json only, human readable only + for (int i = 1; i < argc; ++i) { + if (strncmp("--json", argv[i], 6) == 0 || strcmp(argv[i], "-j") == 0) { + if (strlen(argv[i]) > 7 && strncmp("--json=", argv[i], 7) == 0) { + selected_gpu = strtol(argv[i] + 7, nullptr, 10); + } + human_readable_output = false; + json_output = true; + } else if (strcmp(argv[i], "--html") == 0) { + human_readable_output = false; + html_output = true; + } else if (strcmp(argv[i], "--show-formats") == 0) { + show_formats = true; + } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { + print_usage(argv[0]); + return 1; + } else { + print_usage(argv[0]); + return 1; + } + } + + AppInstance instance = {}; + SetupWindowExtensions(instance); + + auto pNext_chains = get_chain_infos(); + + auto gpu_holder = FindGpus(instance, pNext_chains); + + std::vector<AppGpu *> gpus; + for (auto &gpu : gpu_holder) { + gpus.push_back(gpu.get()); + } + + if (selected_gpu >= gpus.size()) { + selected_gpu = 0; + } + + std::vector<std::unique_ptr<AppSurface>> surfaces_holder; +#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ + defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) + for (auto &surface_extension : instance.surface_extensions) { + surface_extension.create_window(instance); + surface_extension.surface = surface_extension.create_surface(instance); + for (auto &gpu : gpus) { + surfaces_holder.push_back( + std::unique_ptr<AppSurface>(new AppSurface(instance, gpu, surface_extension, pNext_chains.surface_capabilities2))); + } + } + + std::vector<AppSurface *> surfaces; + for (auto &surface : surfaces_holder) { + surfaces.push_back(surface.get()); + } +#endif + + std::vector<std::unique_ptr<Printer>> printers; + + std::streambuf *buf; + buf = std::cout.rdbuf(); + std::ostream out(buf); + std::ofstream html_out; + + if (human_readable_output) { + printers.push_back(std::unique_ptr<Printer>(new Printer(OutputType::text, out, selected_gpu, instance.vk_version))); + } + if (html_output) { + html_out = std::ofstream("vulkaninfo.html"); + printers.push_back(std::unique_ptr<Printer>(new Printer(OutputType::html, html_out, selected_gpu, instance.vk_version))); + } + if (json_output) { + printers.push_back(std::unique_ptr<Printer>(new Printer(OutputType::json, out, selected_gpu, instance.vk_version))); + } + + for (auto &p : printers) { + p->SetHeader(); + DumpExtensions(*p.get(), "Instance", instance.global_extensions); + p->AddNewline(); + + DumpLayers(*p.get(), instance.global_layers, gpus); + + if (p->Type() != OutputType::json) { +#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ + defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) + DumpPresentableSurfaces(*p.get(), instance, gpus, surfaces); +#endif + DumpGroups(*p.get(), instance); + + p->SetHeader().ObjectStart("Device Properties and Extensions"); + p->IndentDecrease(); + } + for (auto &gpu : gpus) { + if ((p->Type() == OutputType::json && gpu->id == selected_gpu) || p->Type() == OutputType::text || + p->Type() == OutputType::html) { + DumpGpu(*p.get(), *gpu, show_formats, pNext_chains); + } + } + if (p->Type() != OutputType::json) { + p->ObjectEnd(); + p->IndentIncrease(); + } + } + +#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ + defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) + + for (auto &surface_extension : instance.surface_extensions) { + AppDestroySurface(instance, surface_extension.surface); + surface_extension.destroy_window(instance); + } +#endif + + return 0; +} diff --git a/vulkaninfo/vulkaninfo.h b/vulkaninfo/vulkaninfo.h new file mode 100644 index 00000000..3142cc63 --- /dev/null +++ b/vulkaninfo/vulkaninfo.h @@ -0,0 +1,1341 @@ +/* + * Copyright (c) 2015-2019 The Khronos Group Inc. + * Copyright (c) 2015-2019 Valve Corporation + * Copyright (c) 2015-2019 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> + * Author: David Pinedo <david@lunarg.com> + * Author: Mark Lobodzinski <mark@lunarg.com> + * Author: Rene Lindsay <rene@lunarg.com> + * Author: Jeremy Kniager <jeremyk@lunarg.com> + * Author: Shannon McPherson <shannon@lunarg.com> + * Author: Bob Ellison <bob@lunarg.com> + * Author: Charles Giessen <charles@lunarg.com> + * + */ + +#include <algorithm> +#include <array> +#include <iostream> +#include <fstream> +#include <memory> +#include <ostream> +#include <string> +#include <unordered_map> +#include <vector> + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <cstring> + +#ifdef __GNUC__ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif +#else +#define strndup(p, n) strdup(p) +#endif + +#ifdef _WIN32 +#include <fcntl.h> +#include <io.h> +#endif // _WIN32 + +#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) +#include <X11/Xutil.h> +#endif + +#if defined(VK_USE_PLATFORM_MACOS_MVK) +#include "metal_view.h" +#endif + +#include <vulkan/vulkan.h> + +#define ERR(err) std::cerr << __FILE__ << ":" << __LINE__ << ": failed with " << VkResultString(err) << "\n"; + +#ifdef _WIN32 + +#define strdup _strdup + +// Returns nonzero if the console is used only for this process. Will return +// zero if another process (such as cmd.exe) is also attached. +static int ConsoleIsExclusive(void) { + DWORD pids[2]; + DWORD num_pids = GetConsoleProcessList(pids, ARRAYSIZE(pids)); + return num_pids <= 1; +} + +#define WAIT_FOR_CONSOLE_DESTROY \ + do { \ + if (ConsoleIsExclusive()) Sleep(INFINITE); \ + } while (0) +#else +#define WAIT_FOR_CONSOLE_DESTROY +#endif + +#define ERR_EXIT(err) \ + do { \ + ERR(err); \ + fflush(stdout); \ + fflush(stderr); \ + WAIT_FOR_CONSOLE_DESTROY; \ + exit(-1); \ + } while (0) + +static const char *VkResultString(VkResult err); + +const char *app_short_name = "vulkaninfo"; + +std::vector<const char *> get_c_str_array(std::vector<std::string> const &vec) { + std::vector<const char *> ret; + for (auto &str : vec) ret.push_back(str.c_str()); + return ret; +} + +static const char *VkDebugReportFlagsEXTString(const VkDebugReportFlagsEXT flags) { + switch (flags) { + case VK_DEBUG_REPORT_ERROR_BIT_EXT: + return "ERROR"; + case VK_DEBUG_REPORT_WARNING_BIT_EXT: + return "WARNING"; + case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT: + return "PERF"; + case VK_DEBUG_REPORT_INFORMATION_BIT_EXT: + return "INFO"; + case VK_DEBUG_REPORT_DEBUG_BIT_EXT: + return "DEBUG"; + default: + return "UNKNOWN"; + } +} +static VKAPI_ATTR VkBool32 VKAPI_CALL DbgCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, + uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, + const char *pMsg, void *pUserData) { + std::cerr << VkDebugReportFlagsEXTString(msgFlags) << ": [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg << "\n"; + + // True is reserved for layer developers, and MAY mean calls are not distributed down the layer chain after validation error. + // False SHOULD always be returned by apps: + return VK_FALSE; +} + +// ----------- Instance Setup ------- // + +struct VkStructureHeader { + VkStructureType sType; + VkStructureHeader *pNext; +}; + +struct pNextChainBuildingBlockInfo { + VkStructureType sType; + uint32_t mem_size; +}; + +struct LayerExtensionList { + VkLayerProperties layer_properties; + std::vector<VkExtensionProperties> extension_properties; +}; + +struct AppInstance; + +struct SurfaceExtension { + std::string name; + void (*create_window)(AppInstance &); + VkSurfaceKHR (*create_surface)(AppInstance &); + void (*destroy_window)(AppInstance &); + VkSurfaceKHR surface; + VkBool32 supports_present = 0; + + bool operator==(const SurfaceExtension &other) { + return name == other.name && surface == other.surface && supports_present == other.supports_present; + } +}; + +struct VulkanVersion { + uint32_t major; + uint32_t minor; + uint32_t patch; +}; + +struct AppInstance { + VkInstance instance; + uint32_t instance_version; + VulkanVersion vk_version; + + std::vector<LayerExtensionList> global_layers; + + std::vector<VkExtensionProperties> global_extensions; // Instance Extensions + + std::vector<std::string> inst_extensions; + + // Functions from vkGetInstanceProcAddress + PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; + PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; + PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; + PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR; + PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; + PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT; + + std::vector<SurfaceExtension> surface_extensions; + + int width = 256, height = 256; + + VkSurfaceCapabilitiesKHR surface_capabilities; + +#ifdef VK_USE_PLATFORM_WIN32_KHR + HINSTANCE h_instance; // Windows Instance + HWND h_wnd; // window handle +#endif +#ifdef VK_USE_PLATFORM_XCB_KHR + xcb_connection_t *xcb_connection; + xcb_screen_t *xcb_screen; + xcb_window_t xcb_window; +#endif +#ifdef VK_USE_PLATFORM_XLIB_KHR + Display *xlib_display; + Window xlib_window; +#endif +#ifdef VK_USE_PLATFORM_MACOS_MVK + void *window; +#endif +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + wl_display *wayland_display; + wl_surface *wayland_surface; +#endif +#ifdef VK_USE_PLATFORM_ANDROID_KHR // TODO + ANativeWindow *window; +#endif + AppInstance() { + PFN_vkEnumerateInstanceVersion enumerate_instance_version = + (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"); + + if (!enumerate_instance_version) { + instance_version = VK_API_VERSION_1_0; + } else { + const VkResult err = enumerate_instance_version(&instance_version); + if (err) ERR_EXIT(err); + } + + vk_version = {VK_VERSION_MAJOR(instance_version), VK_VERSION_MINOR(instance_version), VK_VERSION_PATCH(VK_HEADER_VERSION)}; + + AppGetInstanceExtensions(); + + const VkDebugReportCallbackCreateInfoEXT dbg_info = {VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, nullptr, + VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, + DbgCallback}; + + const VkApplicationInfo app_info = { + VK_STRUCTURE_TYPE_APPLICATION_INFO, nullptr, app_short_name, 1, nullptr, 0, VK_API_VERSION_1_0}; + + AppCompileInstanceExtensionsToEnable(); + + std::vector<const char *> inst_exts; + for (auto &ext : inst_extensions) inst_exts.push_back(ext.c_str()); + + const VkInstanceCreateInfo inst_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, &dbg_info, 0, &app_info, 0, nullptr, + static_cast<uint32_t>(inst_exts.size()), inst_exts.data()}; + + VkResult err = vkCreateInstance(&inst_info, nullptr, &instance); + if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { + std::cerr << "Cannot create Vulkan instance.\n"; + std::cerr << "This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU " + "that does not support Vulkan.\n"; + ERR_EXIT(err); + } else if (err) { + ERR_EXIT(err); + } + + AppLoadInstanceCommands(); + } + + ~AppInstance() { vkDestroyInstance(instance, nullptr); } + + bool CheckExtensionEnabled(std::string extension_to_check) { + for (auto &extension : inst_extensions) { + if (extension_to_check == extension) { + return true; + } + } + return false; + } + + /* Gets a list of layer and instance extensions */ + void AppGetInstanceExtensions() { + /* Scan layers */ + std::vector<VkLayerProperties> global_layer_properties; + + VkResult err; + uint32_t count = 0; + do { + err = vkEnumerateInstanceLayerProperties(&count, nullptr); + if (err) ERR_EXIT(err); + + global_layer_properties.resize(count); + + err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties.data()); + } while (err == VK_INCOMPLETE); + if (err) ERR_EXIT(err); + + global_layers.resize(count); + assert(global_layer_properties.size() == global_layers.size()); + + for (size_t i = 0; i < global_layer_properties.size(); i++) { + global_layers[i].layer_properties = global_layer_properties[i]; + + global_layers[i].extension_properties = AppGetGlobalLayerExtensions(global_layer_properties[i].layerName); + } + + // Collect global extensions + // Gets instance extensions, if no layer was specified in the first paramteter + global_extensions = AppGetGlobalLayerExtensions(nullptr); + } + void AppCompileInstanceExtensionsToEnable() { + // Get all supported Instance extensions (excl. layer-provided ones) + for (auto &ext : global_extensions) { + inst_extensions.push_back(ext.extensionName); + } + } + void AppLoadInstanceCommands() { +#define LOAD_INSTANCE_VK_CMD(cmd) cmd = (PFN_##cmd)vkGetInstanceProcAddr(instance, #cmd) + + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceSupportKHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormatsKHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormats2KHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfacePresentModesKHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceProperties2KHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFormatProperties2KHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceQueueFamilyProperties2KHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFeatures2KHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceMemoryProperties2KHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2KHR); + LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2EXT); + +#undef LOAD_INSTANCE_VK_CMD + } + + void AddSurfaceExtension(SurfaceExtension ext) { surface_extensions.push_back(ext); } + + static std::vector<VkExtensionProperties> AppGetGlobalLayerExtensions(char *layer_name) { + std::vector<VkExtensionProperties> ext_props; + VkResult err; + uint32_t ext_count = 0; + do { + // gets the extension count if the last parameter is nullptr + err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, nullptr); + if (err) ERR_EXIT(err); + + ext_props.resize(ext_count); + // gets the extension properties if the last parameter is not nullptr + err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_props.data()); + } while (err == VK_INCOMPLETE); + if (err) ERR_EXIT(err); + return ext_props; + } +}; + +// --------- Platform Specific Presentation Calls --------- // + +//---------------------------Win32--------------------------- +#ifdef VK_USE_PLATFORM_WIN32_KHR + +// MS-Windows event handling function: +LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } + +static void AppCreateWin32Window(AppInstance &inst) { + inst.h_instance = GetModuleHandle(nullptr); + + WNDCLASSEX win_class; + + // Initialize the window class structure: + win_class.cbSize = sizeof(WNDCLASSEX); + win_class.style = CS_HREDRAW | CS_VREDRAW; + win_class.lpfnWndProc = WndProc; + win_class.cbClsExtra = 0; + win_class.cbWndExtra = 0; + win_class.hInstance = inst.h_instance; + win_class.hIcon = LoadIcon(nullptr, IDI_APPLICATION); + win_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + win_class.lpszMenuName = nullptr; + win_class.lpszClassName = app_short_name; + win_class.hInstance = inst.h_instance; + win_class.hIconSm = LoadIcon(nullptr, IDI_WINLOGO); + // Register window class: + if (!RegisterClassEx(&win_class)) { + // It didn't work, so try to give a useful error: + fprintf(stderr, "Failed to register the window class!\n"); + exit(1); + } + // Create window with the registered class: + RECT wr = {0, 0, inst.width, inst.height}; + AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); + inst.h_wnd = CreateWindowEx(0, + app_short_name, // class name + app_short_name, // app name + // WS_VISIBLE | WS_SYSMENU | + WS_OVERLAPPEDWINDOW, // window style + 100, 100, // x/y coords + wr.right - wr.left, // width + wr.bottom - wr.top, // height + nullptr, // handle to parent + nullptr, // handle to menu + inst.h_instance, // hInstance + nullptr); // no extra parameters + if (!inst.h_wnd) { + // It didn't work, so try to give a useful error: + fprintf(stderr, "Failed to create a window!\n"); + exit(1); + } +} + +static VkSurfaceKHR AppCreateWin32Surface(AppInstance &inst) { + VkWin32SurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = nullptr; + createInfo.flags = 0; + createInfo.hinstance = inst.h_instance; + createInfo.hwnd = inst.h_wnd; + + VkSurfaceKHR surface; + VkResult err = vkCreateWin32SurfaceKHR(inst.instance, &createInfo, nullptr, &surface); + if (err) ERR_EXIT(err); + return surface; +} + +static void AppDestroyWin32Window(AppInstance &inst) { DestroyWindow(inst.h_wnd); } +#endif // VK_USE_PLATFORM_WIN32_KHR +//----------------------------------------------------------- + +#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ + defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || defined(VK_USE_PLATFORM_ANDROID_KHR) +static void AppDestroySurface(AppInstance &inst, VkSurfaceKHR surface) { // same for all platforms + vkDestroySurfaceKHR(inst.instance, surface, nullptr); +} +#endif + +//----------------------------XCB---------------------------- + +#ifdef VK_USE_PLATFORM_XCB_KHR +static void AppCreateXcbWindow(AppInstance &inst) { + //--Init Connection-- + const xcb_setup_t *setup; + xcb_screen_iterator_t iter; + int scr; + + // API guarantees non-null xcb_connection + inst.xcb_connection = xcb_connect(nullptr, &scr); + int conn_error = xcb_connection_has_error(inst.xcb_connection); + if (conn_error) { + fprintf(stderr, "XCB failed to connect to the X server due to error:%d.\n", conn_error); + fflush(stderr); + inst.xcb_connection = nullptr; + } + + setup = xcb_get_setup(inst.xcb_connection); + iter = xcb_setup_roots_iterator(setup); + while (scr-- > 0) { + xcb_screen_next(&iter); + } + + inst.xcb_screen = iter.data; + //------------------- + + inst.xcb_window = xcb_generate_id(inst.xcb_connection); + xcb_create_window(inst.xcb_connection, XCB_COPY_FROM_PARENT, inst.xcb_window, inst.xcb_screen->root, 0, 0, inst.width, + inst.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, inst.xcb_screen->root_visual, 0, nullptr); + + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst.xcb_connection, 1, 12, "WM_PROTOCOLS"); + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(inst.xcb_connection, cookie, 0); + free(reply); +} + +static VkSurfaceKHR AppCreateXcbSurface(AppInstance &inst) { + if (!inst.xcb_connection) { + ERR_EXIT(VK_ERROR_INITIALIZATION_FAILED); + } + + VkXcbSurfaceCreateInfoKHR xcb_createInfo; + xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + xcb_createInfo.pNext = nullptr; + xcb_createInfo.flags = 0; + xcb_createInfo.connection = inst.xcb_connection; + xcb_createInfo.window = inst.xcb_window; + + VkSurfaceKHR surface; + VkResult err = vkCreateXcbSurfaceKHR(inst.instance, &xcb_createInfo, nullptr, &surface); + if (err) ERR_EXIT(err); + return surface; +} + +static void AppDestroyXcbWindow(AppInstance &inst) { + if (!inst.xcb_connection) { + return; // Nothing to destroy + } + + xcb_destroy_window(inst.xcb_connection, inst.xcb_window); + xcb_disconnect(inst.xcb_connection); +} +#endif // VK_USE_PLATFORM_XCB_KHR +//----------------------------------------------------------- + +//----------------------------XLib--------------------------- +#ifdef VK_USE_PLATFORM_XLIB_KHR +static void AppCreateXlibWindow(AppInstance &inst) { + long visualMask = VisualScreenMask; + int numberOfVisuals; + + inst.xlib_display = XOpenDisplay(nullptr); + if (inst.xlib_display == nullptr) { + fprintf(stderr, "XLib failed to connect to the X server.\nExiting ...\n"); + exit(1); + } + + XVisualInfo vInfoTemplate = {}; + vInfoTemplate.screen = DefaultScreen(inst.xlib_display); + XVisualInfo *visualInfo = XGetVisualInfo(inst.xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); + inst.xlib_window = XCreateWindow(inst.xlib_display, RootWindow(inst.xlib_display, vInfoTemplate.screen), 0, 0, inst.width, + inst.height, 0, visualInfo->depth, InputOutput, visualInfo->visual, 0, nullptr); + + XSync(inst.xlib_display, false); + XFree(visualInfo); +} + +static VkSurfaceKHR AppCreateXlibSurface(AppInstance &inst) { + VkXlibSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = nullptr; + createInfo.flags = 0; + createInfo.dpy = inst.xlib_display; + createInfo.window = inst.xlib_window; + + VkSurfaceKHR surface; + VkResult err = vkCreateXlibSurfaceKHR(inst.instance, &createInfo, nullptr, &surface); + if (err) ERR_EXIT(err); + return surface; +} + +static void AppDestroyXlibWindow(AppInstance &inst) { + XDestroyWindow(inst.xlib_display, inst.xlib_window); + XCloseDisplay(inst.xlib_display); +} +#endif // VK_USE_PLATFORM_XLIB_KHR +//----------------------------------------------------------- + +//------------------------MACOS_MVK-------------------------- +#ifdef VK_USE_PLATFORM_MACOS_MVK +static void AppCreateMacOSWindow(AppInstance &inst) { + inst.window = CreateMetalView(inst.width, inst.height); + if (inst.window == nullptr) { + fprintf(stderr, "Could not create a native Metal view.\nExiting...\n"); + exit(1); + } +} + +static VkSurfaceKHR AppCreateMacOSSurface(AppInstance &inst) { + VkMacOSSurfaceCreateInfoMVK createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = nullptr; + createInfo.flags = 0; + createInfo.pView = inst.window; + + VkSurfaceKHR surface; + VkResult err = vkCreateMacOSSurfaceMVK(inst.instance, &createInfo, nullptr, &surface); + if (err) ERR_EXIT(err); + return surface; +} + +static void AppDestroyMacOSWindow(AppInstance &inst) { DestroyMetalView(inst.window); } +#endif // VK_USE_PLATFORM_MACOS_MVK +//----------------------------------------------------------- + +//-------------------------WAYLAND--------------------------- +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +static void wayland_registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, + uint32_t version) { + AppInstance &inst = *static_cast<AppInstance *>(data); + if (strcmp(interface, "wl_compositor") == 0) { + struct wl_compositor *compositor = (struct wl_compositor *)wl_registry_bind(registry, id, &wl_compositor_interface, 1); + inst.wayland_surface = wl_compositor_create_surface(compositor); + } +} +static void wayland_registry_global_remove(void *data, struct wl_registry *registry, uint32_t id) {} +static const struct wl_registry_listener wayland_registry_listener = {wayland_registry_global, wayland_registry_global_remove}; + +static void AppCreateWaylandWindow(AppInstance &inst) { + inst.wayland_display = wl_display_connect(nullptr); + struct wl_registry *registry = wl_display_get_registry(inst.wayland_display); + wl_registry_add_listener(wl_display_get_registry(inst.wayland_display), &wayland_registry_listener, static_cast<void *>(&inst)); + wl_display_roundtrip(inst.wayland_display); + wl_registry_destroy(registry); +} + +static VkSurfaceKHR AppCreateWaylandSurface(AppInstance &inst) { + VkWaylandSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = nullptr; + createInfo.flags = 0; + createInfo.display = inst.wayland_display; + createInfo.surface = inst.wayland_surface; + + VkSurfaceKHR surface; + VkResult err = vkCreateWaylandSurfaceKHR(inst.instance, &createInfo, nullptr, &surface); + if (err) ERR_EXIT(err); + return surface; +} + +static void AppDestroyWaylandWindow(AppInstance &inst) { wl_display_disconnect(inst.wayland_display); } +#endif // VK_USE_PLATFORM_WAYLAND_KHR +//----------------------------------------------------------- + +//-------------------------ANDROID--------------------------- +#ifdef VK_USE_PLATFORM_ANDROID_KHR +static void AppCreateAndroidWindow(AppInstance &inst) {} +static VkSurfaceKHR AppCreateAndroidSurface(AppInstance &inst) { + VkAndroidSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.window = (struct ANativeWindow *)(inst.window); + + err = vkCreateAndroidSurfaceKHR(inst.inst, &createInfo, NULL, &inst.surface); + EXIT_ERR(err); +} +static VkSurfaceKHR AppDestroyAndroidSurface(AppInstance &inst) {} +#endif +//----------------------------------------------------------- + +// ------------ Setup Windows ------------- // + +void SetupWindowExtensions(AppInstance &inst) { +#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) + bool has_display = true; + const char *display_var = getenv("DISPLAY"); + if (display_var == nullptr || strlen(display_var) == 0) { + fprintf(stderr, "'DISPLAY' environment variable not set... skipping surface info\n"); + fflush(stderr); + has_display = false; + } +#endif + +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + wl_display *wayland_display = wl_display_connect(nullptr); + bool has_wayland_display = false; + if (wayland_display != nullptr) { + wl_display_disconnect(wayland_display); + has_wayland_display = true; + } +#endif + +//--WIN32-- +#ifdef VK_USE_PLATFORM_WIN32_KHR + SurfaceExtension surface_ext_win32; + if (inst.CheckExtensionEnabled(VK_KHR_WIN32_SURFACE_EXTENSION_NAME)) { + surface_ext_win32.name = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; + surface_ext_win32.create_window = AppCreateWin32Window; + surface_ext_win32.create_surface = AppCreateWin32Surface; + surface_ext_win32.destroy_window = AppDestroyWin32Window; + + inst.AddSurfaceExtension(surface_ext_win32); + } +#endif +//--XCB-- +#ifdef VK_USE_PLATFORM_XCB_KHR + SurfaceExtension surface_ext_xcb; + if (inst.CheckExtensionEnabled(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) { + surface_ext_xcb.name = VK_KHR_XCB_SURFACE_EXTENSION_NAME; + surface_ext_xcb.create_window = AppCreateXcbWindow; + surface_ext_xcb.create_surface = AppCreateXcbSurface; + surface_ext_xcb.destroy_window = AppDestroyXcbWindow; + if (has_display) { + inst.AddSurfaceExtension(surface_ext_xcb); + } + } +#endif +//--XLIB-- +#ifdef VK_USE_PLATFORM_XLIB_KHR + SurfaceExtension surface_ext_xlib; + if (inst.CheckExtensionEnabled(VK_KHR_XLIB_SURFACE_EXTENSION_NAME)) { + surface_ext_xlib.name = VK_KHR_XLIB_SURFACE_EXTENSION_NAME; + surface_ext_xlib.create_window = AppCreateXlibWindow; + surface_ext_xlib.create_surface = AppCreateXlibSurface; + surface_ext_xlib.destroy_window = AppDestroyXlibWindow; + if (has_display) { + inst.AddSurfaceExtension(surface_ext_xlib); + } + } +#endif +//--MACOS-- +#ifdef VK_USE_PLATFORM_MACOS_MVK + SurfaceExtension surface_ext_macos; + if (inst.CheckExtensionEnabled(VK_MVK_MACOS_SURFACE_EXTENSION_NAME)) { + surface_ext_macos.name = VK_MVK_MACOS_SURFACE_EXTENSION_NAME; + surface_ext_macos.create_window = AppCreateMacOSWindow; + surface_ext_macos.create_surface = AppCreateMacOSSurface; + surface_ext_macos.destroy_window = AppDestroyMacOSWindow; + + inst.AddSurfaceExtension(surface_ext_macos); + } +#endif +//--WAYLAND-- +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + SurfaceExtension surface_ext_wayland; + if (inst.CheckExtensionEnabled(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) { + surface_ext_wayland.name = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME; + surface_ext_wayland.create_window = AppCreateWaylandWindow; + surface_ext_wayland.create_surface = AppCreateWaylandSurface; + surface_ext_wayland.destroy_window = AppDestroyWaylandWindow; + if (has_wayland_display) { + inst.AddSurfaceExtension(surface_ext_wayland); + } + } +#endif +//--ANDROID-- +#ifdef VK_USE_PLATFORM_ANDROID_KHR + SurfaceExtension surface_ext_android; + if (inst.CheckExtensionEnabled(VK_ANDROID_SURFACE_EXTENSION_NAME)) { + surface_ext_android.name = VK_ANDROID_SURFACE_EXTENSION_NAME; + surface_ext_android.create_window = AppCreateAndroidWindow; + surface_ext_android.create_surface = AppCreateAndroidSurface; + surface_ext_android.destroy_window = AppDestroyAndroidWindow; + + inst.AddSurfaceExtension(surface_ext_android); + } +#endif +} + +// -------------------- Device Groups ------------------------// + +std::vector<VkPhysicalDeviceGroupProperties> GetGroups(AppInstance &inst) { + if (inst.CheckExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) { + PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR = + (PFN_vkEnumeratePhysicalDeviceGroupsKHR)vkGetInstanceProcAddr(inst.instance, "vkEnumeratePhysicalDeviceGroupsKHR"); + + uint32_t group_count; + VkResult err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, NULL); + if (err) ERR_EXIT(err); + + std::vector<VkPhysicalDeviceGroupProperties> groups(group_count); + err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, groups.data()); + if (err) ERR_EXIT(err); + + return groups; + } + return {}; +} + +std::vector<VkPhysicalDeviceProperties> GetGroupProps(VkPhysicalDeviceGroupProperties group) { + std::vector<VkPhysicalDeviceProperties> props(group.physicalDeviceCount); + + for (uint32_t i = 0; i < group.physicalDeviceCount; ++i) { + vkGetPhysicalDeviceProperties(group.physicalDevices[i], &props[i]); + } + + return props; +} + +VkDeviceGroupPresentCapabilitiesKHR GetGroupCapabilities(AppInstance &inst, VkPhysicalDeviceGroupProperties group) { + // Build create info for logical device made from all physical devices in this group. + std::vector<std::string> extensions_list = {VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_EXTENSION_NAME}; + VkDeviceGroupDeviceCreateInfoKHR dg_ci = {VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR, nullptr, + group.physicalDeviceCount, group.physicalDevices}; + + float queue_priority = 1.0f; + + auto ext_list = get_c_str_array(extensions_list); + + VkDeviceQueueCreateInfo q_ci = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, nullptr, 0, 0, 1, &queue_priority}; + VkDeviceCreateInfo device_ci = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, &dg_ci, 0, 1, &q_ci, 0, nullptr, + static_cast<uint32_t>(ext_list.size()), ext_list.data()}; + + VkDevice logical_device = VK_NULL_HANDLE; + + VkResult err = vkCreateDevice(group.physicalDevices[0], &device_ci, nullptr, &logical_device); + if (err != VK_SUCCESS && err != VK_ERROR_EXTENSION_NOT_PRESENT) ERR_EXIT(err); + + VkDeviceGroupPresentCapabilitiesKHR group_capabilities = {VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR, nullptr}; + + // If the KHR_device_group extension is present, write the capabilities of the logical device into a struct for later + // output to user. + PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR = + (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)vkGetInstanceProcAddr(inst.instance, "vkGetDeviceGroupPresentCapabilitiesKHR"); + err = vkGetDeviceGroupPresentCapabilitiesKHR(logical_device, &group_capabilities); + if (err) ERR_EXIT(err); + + vkDestroyDevice(logical_device, nullptr); + + return group_capabilities; +} + +// -------------------- Device Setup ------------------- // + +void buildpNextChain(VkStructureHeader *first, const std::vector<pNextChainBuildingBlockInfo> &chain_info) { + VkStructureHeader *place = first; + + for (uint32_t i = 0; i < chain_info.size(); i++) { + place->pNext = static_cast<VkStructureHeader *>(malloc(chain_info[i].mem_size)); + if (!place->pNext) { + ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); + } + std::memset(place->pNext, 0, chain_info[i].mem_size); + place = place->pNext; + place->sType = chain_info[i].sType; + } + + place->pNext = nullptr; +} + +void freepNextChain(VkStructureHeader *first) { + VkStructureHeader *place = first; + VkStructureHeader *next = nullptr; + + while (place) { + next = place->pNext; + free(place); + place = next; + } +} + +struct MemImageSupport { + bool regular_supported, sparse_supported, transient_supported; + VkFormat format; + uint32_t regular_memtypes, sparse_memtypes, transient_memtypes; +}; + +struct MemResSupport { + std::array<std::array<MemImageSupport, 8>, 2> image; + // TODO: buffers +}; + +struct pNextChainInfos { + std::vector<pNextChainBuildingBlockInfo> phys_device_props2; + std::vector<pNextChainBuildingBlockInfo> phys_device_mem_props2; + std::vector<pNextChainBuildingBlockInfo> phys_device_features2; + std::vector<pNextChainBuildingBlockInfo> surface_capabilities2; + std::vector<pNextChainBuildingBlockInfo> format_properties2; +}; + +struct FormatRange { + // the Vulkan standard version that supports this format range, or 0 if non-standard + uint32_t minimum_instance_version; + + // The name of the extension that supports this format range, or NULL if the range + // is only part of the standard + const char *extension_name; + + // The first and last supported formats within this range. + VkFormat first_format; + VkFormat last_format; +}; + +struct AppGpu { + AppInstance &inst; + uint32_t id; + VkPhysicalDevice phys_device; + + VkPhysicalDeviceProperties props; + VkPhysicalDeviceProperties2KHR props2; + + uint32_t queue_count; + std::vector<VkQueueFamilyProperties> queue_props; + std::vector<VkQueueFamilyProperties2KHR> queue_props2; + + VkPhysicalDeviceMemoryProperties memory_props; + VkPhysicalDeviceMemoryProperties2KHR memory_props2; + + MemResSupport mem_type_res_support; + + VkPhysicalDeviceFeatures features; + VkPhysicalDeviceFeatures2KHR features2; + VkPhysicalDevice limits; + + std::vector<VkExtensionProperties> device_extensions; + + VkDevice dev; + VkPhysicalDeviceFeatures enabled_features; + + std::array<VkDeviceSize, VK_MAX_MEMORY_HEAPS> heapBudget; + std::array<VkDeviceSize, VK_MAX_MEMORY_HEAPS> heapUsage; + + std::vector<FormatRange> supported_format_ranges; + + AppGpu(AppInstance &inst, uint32_t id, VkPhysicalDevice phys_device, pNextChainInfos chainInfos) + : inst(inst), id(id), phys_device(phys_device) { + vkGetPhysicalDeviceProperties(phys_device, &props); + + if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; + buildpNextChain((VkStructureHeader *)&props2, chainInfos.phys_device_props2); + + inst.vkGetPhysicalDeviceProperties2KHR(phys_device, &props2); + } + + /* get queue count */ + vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, nullptr); + + queue_props.resize(queue_count); + + vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, queue_props.data()); + + if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + queue_props2.resize(queue_count); + + for (size_t i = 0; i < queue_count; ++i) { + queue_props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR; + queue_props2[i].pNext = nullptr; + } + + inst.vkGetPhysicalDeviceQueueFamilyProperties2KHR(phys_device, &queue_count, queue_props2.data()); + } + + vkGetPhysicalDeviceMemoryProperties(phys_device, &memory_props); + + vkGetPhysicalDeviceFeatures(phys_device, &features); + + if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + memory_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR; + buildpNextChain((VkStructureHeader *)&memory_props2, chainInfos.phys_device_mem_props2); + + inst.vkGetPhysicalDeviceMemoryProperties2KHR(phys_device, &memory_props2); + + features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; + buildpNextChain((VkStructureHeader *)&features2, chainInfos.phys_device_features2); + + inst.vkGetPhysicalDeviceFeatures2KHR(phys_device, &features2); + } + + device_extensions = AppGetPhysicalDeviceLayerExtensions(nullptr); + + const float queue_priority = 1.0f; + const VkDeviceQueueCreateInfo q_ci = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + nullptr, + 0, + 0, // just pick the first one and hope for the best + 1, + &queue_priority}; + VkPhysicalDeviceFeatures features = {0}; + // if (features.sparseBinding ) features.sparseBinding = VK_TRUE; + enabled_features = features; + const VkDeviceCreateInfo device_ci = { + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, nullptr, 0, 1, &q_ci, 0, nullptr, 0, nullptr, &enabled_features}; + + VkResult err = vkCreateDevice(phys_device, &device_ci, nullptr, &dev); + if (err) ERR_EXIT(err); + + const VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; + const std::vector<VkFormat> formats = { + color_format, VK_FORMAT_D16_UNORM, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT, + VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT}; + assert(mem_type_res_support.image[0].size() == formats.size()); + const std::array<VkImageUsageFlags, 2> usages = {0, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT}; + const std::array<VkImageCreateFlags, 2> flagss = {0, VK_IMAGE_CREATE_SPARSE_BINDING_BIT}; + + for (size_t fmt_i = 0; fmt_i < formats.size(); ++fmt_i) { + // only iterate over VK_IMAGE_TILING_OPTIMAL and VK_IMAGE_TILING_LINEAR (0 and 1) + for (int tiling = VK_IMAGE_TILING_OPTIMAL; tiling <= VK_IMAGE_TILING_LINEAR; ++tiling) { + mem_type_res_support.image[tiling][fmt_i].format = formats[fmt_i]; + mem_type_res_support.image[tiling][fmt_i].regular_supported = true; + mem_type_res_support.image[tiling][fmt_i].sparse_supported = true; + mem_type_res_support.image[tiling][fmt_i].transient_supported = true; + + VkFormatProperties fmt_props; + vkGetPhysicalDeviceFormatProperties(phys_device, formats[fmt_i], &fmt_props); + if ((tiling == VK_IMAGE_TILING_OPTIMAL && fmt_props.optimalTilingFeatures == 0) || + (tiling == VK_IMAGE_TILING_LINEAR && fmt_props.linearTilingFeatures == 0)) { + mem_type_res_support.image[tiling][fmt_i].regular_supported = false; + mem_type_res_support.image[tiling][fmt_i].sparse_supported = false; + mem_type_res_support.image[tiling][fmt_i].transient_supported = false; + continue; + } + + for (size_t u_i = 0; u_i < usages.size(); ++u_i) { + for (size_t flg_i = 0; flg_i < flagss.size(); ++flg_i) { + VkImageCreateInfo image_ci = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + nullptr, + flagss[flg_i], + VK_IMAGE_TYPE_2D, + formats[fmt_i], + {8, 8, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + static_cast<VkImageTiling>(tiling), + usages[u_i], + VK_SHARING_MODE_EXCLUSIVE, + 0, + nullptr, + VK_IMAGE_LAYOUT_UNDEFINED}; + + if ((image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && + (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { + continue; + } + + if (image_ci.usage == 0 || (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { + if (image_ci.format == color_format) + image_ci.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + else + image_ci.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + + if (!enabled_features.sparseBinding && (image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { + mem_type_res_support.image[tiling][fmt_i].sparse_supported = false; + continue; + } + + VkImageFormatProperties img_props; + err = vkGetPhysicalDeviceImageFormatProperties(phys_device, image_ci.format, image_ci.imageType, + image_ci.tiling, image_ci.usage, image_ci.flags, &img_props); + + uint32_t *memtypes; + bool *support; + + if (image_ci.flags == 0 && !(image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { + memtypes = &mem_type_res_support.image[tiling][fmt_i].regular_memtypes; + support = &mem_type_res_support.image[tiling][fmt_i].regular_supported; + } else if ((image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && + !(image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { + memtypes = &mem_type_res_support.image[tiling][fmt_i].sparse_memtypes; + support = &mem_type_res_support.image[tiling][fmt_i].sparse_supported; + } else if (image_ci.flags == 0 && (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) { + memtypes = &mem_type_res_support.image[tiling][fmt_i].transient_memtypes; + support = &mem_type_res_support.image[tiling][fmt_i].transient_supported; + } else { + assert(false); + return; + } + + if (err == VK_ERROR_FORMAT_NOT_SUPPORTED) { + *support = false; + } else { + if (err) ERR_EXIT(err); + + VkImage dummy_img; + err = vkCreateImage(dev, &image_ci, nullptr, &dummy_img); + if (err) ERR_EXIT(err); + + VkMemoryRequirements mem_req; + vkGetImageMemoryRequirements(dev, dummy_img, &mem_req); + *memtypes = mem_req.memoryTypeBits; + + vkDestroyImage(dev, dummy_img, nullptr); + } + } + } + } + } + + // Memory // + + struct VkStructureHeader *structure = NULL; + if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + structure = (struct VkStructureHeader *)memory_props2.pNext; + + while (structure) { + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT && + CheckPhysicalDeviceExtensionIncluded(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) { + VkPhysicalDeviceMemoryBudgetPropertiesEXT *mem_budget_props = + (VkPhysicalDeviceMemoryBudgetPropertiesEXT *)structure; + for (int i = 0; i < VK_MAX_MEMORY_HEAPS; i++) { + heapBudget[i] = mem_budget_props->heapBudget[i]; + heapUsage[i] = mem_budget_props->heapUsage[i]; + } + } + + structure = (struct VkStructureHeader *)structure->pNext; + } + } + // TODO buffer - memory type compatibility + + supported_format_ranges = { + { + // Standard formats in Vulkan 1.0 + VK_MAKE_VERSION(1, 0, 0), + NULL, + VK_FORMAT_BEGIN_RANGE, + VK_FORMAT_END_RANGE, + }, + { + // YCBCR extension, standard in Vulkan 1.1 + VK_MAKE_VERSION(1, 1, 0), + VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, + VK_FORMAT_G8B8G8R8_422_UNORM, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, + }, + { + // PVRTC extension, not standardized + 0, + VK_IMG_FORMAT_PVRTC_EXTENSION_NAME, + VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, + VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG, + }, + }; + } + ~AppGpu() { + vkDestroyDevice(dev, nullptr); + + if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + freepNextChain(static_cast<VkStructureHeader *>(features2.pNext)); + freepNextChain(static_cast<VkStructureHeader *>(props2.pNext)); + freepNextChain(static_cast<VkStructureHeader *>(memory_props2.pNext)); + } + } + + bool CheckPhysicalDeviceExtensionIncluded(std::string extension_to_check) { + for (auto &extension : device_extensions) { + if (extension_to_check == std::string(extension.extensionName)) { + return true; + } + } + return false; + } + + std::vector<VkExtensionProperties> AppGetPhysicalDeviceLayerExtensions(char *layer_name) { + std::vector<VkExtensionProperties> extension_properties; + + VkResult err; + uint32_t ext_count = 0; + + /* repeat get until VK_INCOMPLETE goes away */ + do { + err = vkEnumerateDeviceExtensionProperties(phys_device, layer_name, &ext_count, nullptr); + if (err) ERR_EXIT(err); + + extension_properties.resize(ext_count); + err = vkEnumerateDeviceExtensionProperties(phys_device, layer_name, &ext_count, extension_properties.data()); + if (err) ERR_EXIT(err); + extension_properties.resize(ext_count); + } while (err == VK_INCOMPLETE); + + return extension_properties; + } + + // Helper function to determine whether a format range is currently supported. + bool FormatRangeSupported(FormatRange &format_range) { + // True if standard and supported by both this instance and this GPU + if (format_range.minimum_instance_version > 0 && inst.instance_version >= format_range.minimum_instance_version && + props.apiVersion >= format_range.minimum_instance_version) { + return true; + } + + // True if this extension is present + if (format_range.extension_name != nullptr) { + return inst.CheckExtensionEnabled(format_range.extension_name); + } + + // Otherwise, not supported. + return false; + } + + VkPhysicalDeviceProperties GetDeviceProperties() { + if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + return props2.properties; + } else { + return props; + } + } +}; + +std::vector<std::unique_ptr<AppGpu>> FindGpus(AppInstance &instance, pNextChainInfos chainInfos) { + uint32_t gpu_count; + VkResult err = vkEnumeratePhysicalDevices(instance.instance, &gpu_count, nullptr); + if (err) ERR_EXIT(err); + + std::vector<VkPhysicalDevice> phys_devices(gpu_count); + + err = vkEnumeratePhysicalDevices(instance.instance, &gpu_count, phys_devices.data()); + if (err) ERR_EXIT(err); + + std::vector<std::unique_ptr<AppGpu>> gpus; + + uint32_t i = 0; + for (auto &phys_device : phys_devices) { + gpus.push_back(std::unique_ptr<AppGpu>(new AppGpu(instance, i++, phys_device, chainInfos))); + } + return gpus; +} + +struct AppQueueFamilyProperties { + VkQueueFamilyProperties props; + uint32_t queue_index; + bool is_present_platform_agnostic = true; + VkBool32 platforms_support_present = VK_FALSE; + + AppQueueFamilyProperties(AppGpu &gpu, uint32_t queue_index) : queue_index(queue_index) { + if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + props = gpu.queue_props2[queue_index].queueFamilyProperties; + } else { + props = gpu.queue_props[queue_index]; + } + + for (auto &surface_ext : gpu.inst.surface_extensions) { + VkResult err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu.phys_device, queue_index, surface_ext.surface, + &surface_ext.supports_present); + if (err) ERR_EXIT(err); + + const bool first = (surface_ext == gpu.inst.surface_extensions.at(0)); + if (!first && platforms_support_present != surface_ext.supports_present) { + is_present_platform_agnostic = false; + + platforms_support_present = surface_ext.supports_present; + } + } + } +}; + +// ---------- Surfaces -------------- // + +class AppSurface { + public: + AppInstance &inst; + SurfaceExtension surface_extension; + + uint32_t present_mode_count = 0; + std::vector<VkPresentModeKHR> surf_present_modes; + + uint32_t format_count = 0; + std::vector<VkSurfaceFormatKHR> surf_formats; + std::vector<VkSurfaceFormat2KHR> surf_formats2; + + VkSurfaceCapabilitiesKHR surface_capabilities; + VkSurfaceCapabilities2KHR surface_capabilities2_khr; + VkSurfaceCapabilities2EXT surface_capabilities2_ext; + + AppSurface(AppInstance &inst, AppGpu *gpu, SurfaceExtension surface_extension, + std::vector<pNextChainBuildingBlockInfo> &sur_extension_pNextChain) + : inst(inst), surface_extension(surface_extension) { + uint32_t present_mode_count = 0; + VkResult err = inst.vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->phys_device, surface_extension.surface, + &present_mode_count, nullptr); + if (err) ERR_EXIT(err); + + surf_present_modes.resize(present_mode_count); + err = inst.vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->phys_device, surface_extension.surface, &present_mode_count, + surf_present_modes.data()); + if (err) ERR_EXIT(err); + + const VkPhysicalDeviceSurfaceInfo2KHR surface_info2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, + surface_extension.surface}; + + if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { + VkResult err = inst.vkGetPhysicalDeviceSurfaceFormats2KHR(gpu->phys_device, &surface_info2, &format_count, nullptr); + if (err) ERR_EXIT(err); + surf_formats2.resize(format_count); + for (uint32_t i = 0; i < format_count; ++i) { + surf_formats2[i].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR; + surf_formats2[i].pNext = nullptr; + } + err = inst.vkGetPhysicalDeviceSurfaceFormats2KHR(gpu->phys_device, &surface_info2, &format_count, surf_formats2.data()); + if (err) ERR_EXIT(err); + } else { + VkResult err = + inst.vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->phys_device, surface_extension.surface, &format_count, nullptr); + if (err) ERR_EXIT(err); + surf_formats.resize(format_count); + err = inst.vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->phys_device, surface_extension.surface, &format_count, + surf_formats.data()); + if (err) ERR_EXIT(err); + } + + if (inst.CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME)) { + VkResult err = + inst.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu->phys_device, surface_extension.surface, &surface_capabilities); + if (err) ERR_EXIT(err); + } + + if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { + surface_capabilities2_khr.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR; + buildpNextChain((VkStructureHeader *)&surface_capabilities2_khr, sur_extension_pNextChain); + + VkPhysicalDeviceSurfaceInfo2KHR surface_info; + surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR; + surface_info.pNext = nullptr; + surface_info.surface = surface_extension.surface; + + VkResult err = + inst.vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu->phys_device, &surface_info, &surface_capabilities2_khr); + if (err) ERR_EXIT(err); + } + + if (inst.CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) { + surface_capabilities2_ext.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT; + surface_capabilities2_ext.pNext = nullptr; + VkResult err = inst.vkGetPhysicalDeviceSurfaceCapabilities2EXT(gpu->phys_device, surface_extension.surface, + &surface_capabilities2_ext); + if (err) ERR_EXIT(err); + } + } + + ~AppSurface() { + if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { + freepNextChain(static_cast<VkStructureHeader *>(surface_capabilities2_khr.pNext)); + } + } +}; + +// --------- Format Properties ----------// + +struct PropFlags { + uint32_t linear; + uint32_t optimal; + uint32_t buffer; + + bool operator==(const PropFlags &other) const { + return (linear == other.linear && optimal == other.optimal && buffer == other.buffer); + } +}; + +namespace std { +template <> +struct hash<PropFlags> { + std::size_t operator()(const PropFlags &k) const { + return ((std::hash<uint32_t>()(k.linear) ^ (std::hash<uint32_t>()(k.optimal) << 1)) >> 1) ^ + (std::hash<uint32_t>()(k.buffer) << 1); + } +}; +} // namespace std + +// Used to sort the formats into buckets by their properties. +std::unordered_map<PropFlags, std::vector<VkFormat>> FormatPropMap(AppGpu &gpu) { + std::unordered_map<PropFlags, std::vector<VkFormat>> map; + for (auto fmtRange : gpu.supported_format_ranges) { + for (uint32_t fmt = fmtRange.first_format; fmt <= fmtRange.last_format; ++fmt) { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(gpu.phys_device, static_cast<VkFormat>(fmt), &props); + + PropFlags pf = {props.linearTilingFeatures, props.optimalTilingFeatures, props.bufferFeatures}; + + map[pf].push_back(static_cast<VkFormat>(fmt)); + } + } + return map; +} + +VkFormatProperties2 GetFormatProperties2(AppGpu &gpu, VkFormat format, pNextChainInfos &chainInfos) { + VkFormatProperties2 props; + props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + buildpNextChain((VkStructureHeader *)&props, chainInfos.format_properties2); + + gpu.inst.vkGetPhysicalDeviceFormatProperties2KHR(gpu.phys_device, format, &props); + return props; +} |
