diff options
| author | Charles Giessen <charles@lunarg.com> | 2019-08-13 11:16:59 -0600 |
|---|---|---|
| committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2019-10-04 09:14:44 -0600 |
| commit | 623d1cc06173a7e209affe6030311abc464beb74 (patch) | |
| tree | 68c33ef0491ab8d5515e5a9a3019bb1680f53124 | |
| parent | 7513420a385869903b907d2d42e3ee93f93fa551 (diff) | |
| download | usermoji-623d1cc06173a7e209affe6030311abc464beb74.tar.xz | |
vulkaninfo: Major Refactor
Rewrote vulkan info to use C++ and include autogen capabilities
Properties and Features are now populated based on the xml spec
Improved readability and robustness by seperating vulkan
info gathering, formatting, and printing into seperate files
Files Added:
- scripts/generate_vulkaninfo.py
- vulkaninfo/vulkaninfo.h
- vulkaninfo/vulkaninfo.cpp
- vulkaninfo/outputprinter.h
- vulkaninfo/generated/vulkaninfo.hpp
- vulkaninfo/generated/.clang-format
Files Modified:
- scripts/kvt_genvk.py
- vulkaninfo/CMakeLists.txt
- vulkaninfo/macOS/vulkaninfo.cmake
Files Removed:
- vulkaninfo/vulkaninfo.c
Change-Id: I8042a6a7949595b75f03d1f3ba48e221d2cc0e8a
| -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; +} |
