1#!/usr/bin/env python3 2# 3# Copyright 2025 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17"""Generates the vkjson files. 18""" 19import dataclasses 20import os 21import re 22from typing import get_origin 23 24import generator_common as gencom 25import vk as VK 26 27dataclass_field = dataclasses.field 28 29 30COPYRIGHT_WARNINGS = """/////////////////////////////////////////////////////////////////////////////// 31// 32// Copyright (c) 2015-2016 The Khronos Group Inc. 33// Copyright (c) 2015-2016 Valve Corporation 34// Copyright (c) 2015-2016 LunarG, Inc. 35// Copyright (c) 2015-2016 Google, Inc. 36// 37// Licensed under the Apache License, Version 2.0 (the "License"); 38// you may not use this file except in compliance with the License. 39// You may obtain a copy of the License at 40// 41// http://www.apache.org/licenses/LICENSE-2.0 42// 43// Unless required by applicable law or agreed to in writing, software 44// distributed under the License is distributed on an "AS IS" BASIS, 45// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 46// See the License for the specific language governing permissions and 47// limitations under the License. 48/////////////////////////////////////////////////////////////////////////////// 49""" 50 51 52def get_copyright_warnings(): 53 return COPYRIGHT_WARNINGS 54 55 56def get_vkjson_struct_name(extension_name): 57 """Gets the corresponding structure name from a Vulkan extension name. 58 Example: "VK_KHR_shader_float16_int8" → "VkJsonKHRShaderFloat16Int8" 59 """ 60 prefix_map = { 61 "VK_KHR": "VkJsonKHR", 62 "VK_EXT": "VkJsonExt", 63 "VK_IMG": "VkJsonIMG" 64 } 65 66 for prefix, replacement in prefix_map.items(): 67 if extension_name.startswith(prefix): 68 struct_name = replacement + extension_name[len(prefix):] 69 break 70 else: 71 struct_name = f"VkJsonExt{extension_name}" 72 73 # Convert underscores to camel case 74 # Example: "VK_KHR_shader_float16_int8" → "VkJsonKHRShaderFloat16Int8" 75 struct_name = re.sub(r"_(.)", lambda m: m.group(1).upper(), struct_name) 76 77 return struct_name 78 79 80def get_vkjson_struct_variable_name(extension_name): 81 """Gets corresponding instance name from a Vulkan extension name. 82 Example: "VK_KHR_shader_float16_int8" → "khr_shader_float16_int8" 83 """ 84 prefix_map = { 85 "VK_KHR_": "khr_", 86 "VK_EXT_": "ext_", 87 "VK_IMG_": "img_" 88 } 89 90 for prefix, replacement in prefix_map.items(): 91 if extension_name.startswith(prefix): 92 return replacement + extension_name[len(prefix):] 93 94 return extension_name.lower() # Default case if no known prefix matches 95 96 97def get_struct_name(struct_name): 98 """Gets corresponding instance name 99 Example: "VkPhysicalDeviceShaderFloat16Int8FeaturesKHR" → "shader_float16_int8_features_khr" 100 """ 101 # Remove "VkPhysicalDevice" prefix and any of the known suffixes 102 base_name = struct_name.removeprefix("VkPhysicalDevice").removesuffix("KHR").removesuffix("EXT").removesuffix("IMG") 103 104 # Convert CamelCase to snake_case 105 # Example: "ShaderFloat16Int8Features" → "shader_float16_int8_features" 106 variable_name = re.sub(r"(?<!^)(?=[A-Z])", "_", base_name).lower() 107 108 # Fix special cases 109 variable_name = variable_name.replace("2_d_", "_2d_").replace("3_d_", "_3d_") 110 111 # Add back the correct suffix if it was removed 112 suffix_map = {"KHR": "_khr", "EXT": "_ext", "IMG": "_img"} 113 for suffix, replacement in suffix_map.items(): 114 if struct_name.endswith(suffix): 115 variable_name += replacement 116 break 117 118 # Handle specific exceptions 119 special_cases = { 120 "8_bit_storage_features_khr": "bit8_storage_features_khr", 121 "memory_properties": "memory", 122 "16_bit_storage_features": "bit16_storage_features", 123 "i_d_properties": "id_properties" 124 } 125 126 return special_cases.get(variable_name, variable_name) 127 128 129def generate_extension_struct_definition(f): 130 """Generates struct definition code for extension based structs 131 Example: 132 struct VkJsonKHRShaderFloatControls { 133 VkJsonKHRShaderFloatControls() { 134 reported = false; 135 memset(&float_controls_properties_khr, 0, 136 sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)); 137 } 138 bool reported; 139 VkPhysicalDeviceFloatControlsPropertiesKHR float_controls_properties_khr; 140 }; 141 """ 142 vkJson_entries = [] 143 144 for extension_name, struct_list in VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"].items(): 145 vkjson_struct_name = get_vkjson_struct_name(extension_name) 146 vkjson_struct_variable_name = get_vkjson_struct_variable_name(extension_name) 147 vkJson_entries.append(f"{vkjson_struct_name} {vkjson_struct_variable_name}") 148 149 struct_entries = [] 150 151 f.write(f"struct {vkjson_struct_name} {{\n") 152 f.write(f" {vkjson_struct_name}() {{\n") 153 f.write(" reported = false;\n") 154 155 for struct_map in struct_list: 156 for struct_name, _ in struct_map.items(): 157 variable_name = get_struct_name(struct_name) 158 f.write(f" memset(&{variable_name}, 0, sizeof({struct_name}));\n") 159 struct_entries.append(f"{struct_name} {variable_name}") 160 161 f.write(" }\n") # End of constructor 162 f.write(" bool reported;\n") 163 164 for entry in struct_entries: 165 f.write(f" {entry};\n") 166 167 f.write("};\n\n") # End of struct 168 169 return vkJson_entries 170 171 172def generate_vk_core_struct_definition(f): 173 """Generates struct definition code for vulkan cores 174 Example: 175 struct VkJsonCore11 { 176 VkPhysicalDeviceVulkan11Properties properties; 177 VkPhysicalDeviceVulkan11Features features; 178 }; 179 """ 180 vkJson_core_entries = [] 181 182 for version, items in VK.VULKAN_CORES_AND_STRUCTS_MAPPING["versions"].items(): 183 struct_name = f"VkJson{version}" 184 vkJson_core_entries.append(f"{struct_name} {version.lower()}") 185 186 f.write(f"struct {struct_name} {{\n") 187 f.write(f" {struct_name}() {{\n") # Start of constructor 188 for item in items: 189 for struct_type, _ in item.items(): 190 field_name = "properties" if "Properties" in struct_type else "features" 191 f.write(f" memset(&{field_name}, 0, sizeof({struct_type}));\n") 192 f.write(" }\n") # End of constructor 193 194 for item in items: 195 for struct_type, _ in item.items(): 196 field_name = "properties" if "Properties" in struct_type else "features" 197 f.write(f" {struct_type} {field_name};\n") 198 199 if version == "Core14": 200 f.write(f"std::vector<VkImageLayout> copy_src_layouts;\n") 201 f.write(f"std::vector<VkImageLayout> copy_dst_layouts;\n") 202 203 f.write("};\n\n") 204 205 return vkJson_core_entries 206 207 208def generate_memset_statements(f): 209 """Generates memset statements for all independent Vulkan structs and core Vulkan versions. 210 This initializes struct instances to zero before use. 211 212 Example: 213 memset(&properties, 0, sizeof(VkPhysicalDeviceProperties)); 214 VkPhysicalDeviceProperties properties; 215 """ 216 entries = [] 217 218 # Process independent structs 219 for dataclass_type in VK.EXTENSION_INDEPENDENT_STRUCTS: 220 class_name = dataclass_type.__name__ 221 variable_name = get_struct_name(class_name) 222 f.write(f"memset(&{variable_name}, 0, sizeof({class_name}));\n") 223 entries.append(f"{class_name} {variable_name}") 224 225 return entries 226 227 228def gen_h(): 229 """Generates vkjson.h file. 230 """ 231 genfile = os.path.join(os.path.dirname(__file__), 232 "..", "vkjson", "vkjson.h") 233 234 with open(genfile, "w") as f: 235 f.write(f'{get_copyright_warnings()}\n') 236 237 f.write("""\ 238#ifndef VKJSON_H_ 239#define VKJSON_H_ 240 241#include <string.h> 242#include <vulkan/vulkan.h> 243 244#include <map> 245#include <string> 246#include <vector> 247 248#ifdef WIN32 249#undef min 250#undef max 251#endif 252 253/* 254 * This file is autogenerated by vkjson_generator.py. Do not edit directly. 255 */ 256struct VkJsonLayer { 257 VkLayerProperties properties; 258 std::vector<VkExtensionProperties> extensions; 259}; 260 261\n""") 262 263 vkjson_extension_structs = generate_extension_struct_definition(f) 264 vkjson_core_structs = generate_vk_core_struct_definition(f) 265 266 f.write("""\ 267struct VkJsonDevice { 268 VkJsonDevice() {""") 269 270 feature_property_structs = generate_memset_statements(f) 271 272 f.write("""\ 273 }\n""") 274 for struct_entries in (vkjson_extension_structs, vkjson_core_structs, feature_property_structs): 275 for entry in struct_entries: 276 f.write(entry + ";\n") 277 278 f.write("""\ 279 std::vector<VkQueueFamilyProperties> queues; 280 std::vector<VkExtensionProperties> extensions; 281 std::vector<VkLayerProperties> layers; 282 std::map<VkFormat, VkFormatProperties> formats; 283 std::map<VkExternalFenceHandleTypeFlagBits, VkExternalFenceProperties> 284 external_fence_properties; 285 std::map<VkExternalSemaphoreHandleTypeFlagBits, VkExternalSemaphoreProperties> 286 external_semaphore_properties; 287}; 288 289struct VkJsonDeviceGroup { 290 VkJsonDeviceGroup() { 291 memset(&properties, 0, sizeof(VkPhysicalDeviceGroupProperties)); 292 } 293 VkPhysicalDeviceGroupProperties properties; 294 std::vector<uint32_t> device_inds; 295}; 296 297struct VkJsonInstance { 298 VkJsonInstance() : api_version(0) {} 299 uint32_t api_version; 300 std::vector<VkJsonLayer> layers; 301 std::vector<VkExtensionProperties> extensions; 302 std::vector<VkJsonDevice> devices; 303 std::vector<VkJsonDeviceGroup> device_groups; 304}; 305 306VkJsonInstance VkJsonGetInstance(); 307std::string VkJsonInstanceToJson(const VkJsonInstance& instance); 308bool VkJsonInstanceFromJson(const std::string& json, 309 VkJsonInstance* instance, 310 std::string* errors); 311 312VkJsonDevice VkJsonGetDevice(VkPhysicalDevice device); 313std::string VkJsonDeviceToJson(const VkJsonDevice& device); 314bool VkJsonDeviceFromJson(const std::string& json, 315 VkJsonDevice* device, 316 std::string* errors); 317 318std::string VkJsonImageFormatPropertiesToJson( 319 const VkImageFormatProperties& properties); 320bool VkJsonImageFormatPropertiesFromJson(const std::string& json, 321 VkImageFormatProperties* properties, 322 std::string* errors); 323 324// Backward-compatibility aliases 325typedef VkJsonDevice VkJsonAllProperties; 326inline VkJsonAllProperties VkJsonGetAllProperties( 327 VkPhysicalDevice physicalDevice) { 328 return VkJsonGetDevice(physicalDevice); 329} 330inline std::string VkJsonAllPropertiesToJson( 331 const VkJsonAllProperties& properties) { 332 return VkJsonDeviceToJson(properties); 333} 334inline bool VkJsonAllPropertiesFromJson(const std::string& json, 335 VkJsonAllProperties* properties, 336 std::string* errors) { 337 return VkJsonDeviceFromJson(json, properties, errors); 338} 339 340#endif // VKJSON_H_""") 341 342 f.close() 343 gencom.run_clang_format(genfile) 344 345 346def generate_extension_struct_template(): 347 """Generates templates for extensions 348 Example: 349 template <typename Visitor> 350 inline bool Iterate(Visitor* visitor, VkJsonKHRVariablePointers* structs) { 351 return visitor->Visit("variablePointerFeaturesKHR", 352 &structs->variable_pointer_features_khr) && 353 visitor->Visit("variablePointersFeaturesKHR", 354 &structs->variable_pointers_features_khr); 355 } 356 """ 357 template_code = [] 358 359 for extension, struct_mappings in VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"].items(): 360 struct_type = get_vkjson_struct_name(extension) 361 362 template_code.append(f"template <typename Visitor>") 363 template_code.append(f"inline bool Iterate(Visitor* visitor, {struct_type}* structs) {{") 364 template_code.append(" return ") 365 366 visitor_calls = [] 367 for struct_map in struct_mappings: 368 for struct_name in struct_map: 369 json_field_name = struct_name.replace("VkPhysicalDevice", "") 370 json_field_name = json_field_name[0].lower() + json_field_name[1:] 371 372 # Special case renaming 373 if json_field_name == "8BitStorageFeaturesKHR": 374 json_field_name = "bit8StorageFeaturesKHR" 375 376 visitor_calls.append( 377 f'visitor->Visit("{json_field_name}", &structs->{get_struct_name(struct_name)})' 378 ) 379 380 template_code.append(" &&\n ".join(visitor_calls) + ";") 381 template_code.append("}\n") 382 383 return "\n".join(template_code) 384 385 386def generate_core_template(): 387 """Generates templates for vulkan cores. 388 template <typename Visitor> 389 inline bool Iterate(Visitor* visitor, VkJsonCore11* core) { 390 return visitor->Visit("properties", &core->properties) && 391 visitor->Visit("features", &core->features); 392 } 393 """ 394 template_code = [] 395 396 for version, struct_list in VK.VULKAN_CORES_AND_STRUCTS_MAPPING["versions"].items(): 397 struct_type = f"VkJson{version}" 398 399 template_code.append(f"template <typename Visitor>") 400 template_code.append(f"inline bool Iterate(Visitor* visitor, {struct_type}* core) {{") 401 template_code.append(" return") 402 403 visitor_calls = [] 404 for struct_map in struct_list: 405 for struct_name in struct_map: 406 member_name = "properties" if "Properties" in struct_name else "features" 407 visitor_calls.append(f'visitor->Visit("{member_name}", &core->{member_name})') 408 409 template_code.append(" &&\n ".join(visitor_calls) + ";") 410 template_code.append("}\n") 411 412 return "\n".join(template_code) 413 414 415def generate_struct_template(data_classes): 416 """Generates templates for all the structs 417 template <typename Visitor> 418 inline bool Iterate(Visitor* visitor, 419 VkPhysicalDevicePointClippingProperties* properties) { 420 return visitor->Visit("pointClippingBehavior", 421 &properties->pointClippingBehavior); 422 } 423 """ 424 template_code = [] 425 processed_classes = set() # Track processed class names 426 427 for dataclass_type in data_classes: 428 struct_name = dataclass_type.__name__ 429 430 if struct_name in processed_classes: 431 continue # Skip already processed struct 432 processed_classes.add(struct_name) 433 434 struct_fields = dataclasses.fields(dataclass_type) 435 template_code.append("template <typename Visitor>") 436 437 # Determine the correct variable name based on the struct type 438 struct_var = "properties" if "Properties" in struct_name else "features" if "Features" in struct_name else "limits" if "Limits" in struct_name else None 439 440 if not struct_var: 441 continue # Skip structs that don't match expected patterns 442 443 template_code.append(f"inline bool Iterate(Visitor* visitor, {struct_name}* {struct_var}) {{") 444 template_code.append(f"return\n") 445 446 visitor_calls = [] 447 for struct_field in struct_fields: 448 field_name = struct_field.name 449 field_type = struct_field.type 450 451 if get_origin(field_type) is list: 452 # Handle list types (VisitArray) 453 size_field_name = VK.LIST_TYPE_FIELD_AND_SIZE_MAPPING[field_name] 454 visitor_calls.append(f'visitor->VisitArray("{field_name}", {struct_var}->{size_field_name}, &{struct_var}->{field_name})') 455 else: 456 # Handle other types (Visit) 457 visitor_calls.append(f'visitor->Visit("{field_name}", &{struct_var}->{field_name})') 458 459 template_code.append(" &&\n ".join(visitor_calls) + ";") 460 template_code.append("}\n\n") 461 462 return "\n".join(template_code) 463 464 465def emit_struct_visits_by_vk_version(f, version): 466 """Emits visitor calls for Vulkan version structs 467 """ 468 for struct_map in VK.VULKAN_VERSIONS_AND_STRUCTS_MAPPING[version]: 469 for struct_name, _ in struct_map.items(): 470 struct_var = get_struct_name(struct_name) 471 # Converts struct_var from snake_case (e.g., point_clipping_properties) 472 # to camelCase (e.g., pointClippingProperties) for struct_display_name. 473 struct_display_name = re.sub(r"_([a-z])", lambda match: match.group(1).upper(), struct_var) 474 f.write(f'visitor->Visit("{struct_display_name}", &device->{struct_var}) &&\n') 475 476 477def gen_cc(): 478 """Generates vkjson.cc file. 479 """ 480 genfile = os.path.join(os.path.dirname(__file__), 481 "..", "vkjson", "vkjson.cc") 482 483 with open(genfile, "w") as f: 484 485 f.write(get_copyright_warnings()) 486 f.write("\n") 487 488 f.write("""\ 489#include "vkjson.h" 490 491#include <assert.h> 492#include <stdlib.h> 493#include <string.h> 494 495#include <json/json.h> 496 497#include <algorithm> 498#include <cinttypes> 499#include <cmath> 500#include <cstdio> 501#include <limits> 502#include <memory> 503#include <sstream> 504#include <type_traits> 505#include <utility> 506 507/* 508 * This file is autogenerated by vkjson_generator.py. Do not edit directly. 509 */ 510namespace { 511 512/* 513 * Annotation to tell clang that we intend to fall through from one case to 514 * another in a switch. Sourced from android-base/macros.h. 515 */ 516#define FALLTHROUGH_INTENDED [[clang::fallthrough]] 517 518inline bool IsIntegral(double value) { 519#if defined(ANDROID) 520 // Android NDK doesn't provide std::trunc yet 521 return trunc(value) == value; 522#else 523 return std::trunc(value) == value; 524#endif 525} 526 527// Floating point fields of Vulkan structure use single precision. The string 528// output of max double value in c++ will be larger than Java double's infinity 529// value. Below fake double max/min values are only to serve the safe json text 530// parsing in between C++ and Java, because Java json library simply cannot 531// handle infinity. 532static const double SAFE_DOUBLE_MAX = 0.99 * std::numeric_limits<double>::max(); 533static const double SAFE_DOUBLE_MIN = -SAFE_DOUBLE_MAX; 534 535template <typename T> struct EnumTraits; 536template <> struct EnumTraits<VkPhysicalDeviceType> { 537 static bool exist(uint32_t e) { 538 switch (e) { 539 case VK_PHYSICAL_DEVICE_TYPE_OTHER: 540 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: 541 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: 542 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: 543 case VK_PHYSICAL_DEVICE_TYPE_CPU: 544 return true; 545 } 546 return false; 547 } 548}; 549 550template <> struct EnumTraits<VkFormat> { 551 static bool exist(uint32_t e) { 552 switch (e) { 553 case VK_FORMAT_UNDEFINED: 554 case VK_FORMAT_R4G4_UNORM_PACK8: 555 case VK_FORMAT_R4G4B4A4_UNORM_PACK16: 556 case VK_FORMAT_B4G4R4A4_UNORM_PACK16: 557 case VK_FORMAT_R5G6B5_UNORM_PACK16: 558 case VK_FORMAT_B5G6R5_UNORM_PACK16: 559 case VK_FORMAT_R5G5B5A1_UNORM_PACK16: 560 case VK_FORMAT_B5G5R5A1_UNORM_PACK16: 561 case VK_FORMAT_A1R5G5B5_UNORM_PACK16: 562 case VK_FORMAT_R8_UNORM: 563 case VK_FORMAT_R8_SNORM: 564 case VK_FORMAT_R8_USCALED: 565 case VK_FORMAT_R8_SSCALED: 566 case VK_FORMAT_R8_UINT: 567 case VK_FORMAT_R8_SINT: 568 case VK_FORMAT_R8_SRGB: 569 case VK_FORMAT_R8G8_UNORM: 570 case VK_FORMAT_R8G8_SNORM: 571 case VK_FORMAT_R8G8_USCALED: 572 case VK_FORMAT_R8G8_SSCALED: 573 case VK_FORMAT_R8G8_UINT: 574 case VK_FORMAT_R8G8_SINT: 575 case VK_FORMAT_R8G8_SRGB: 576 case VK_FORMAT_R8G8B8_UNORM: 577 case VK_FORMAT_R8G8B8_SNORM: 578 case VK_FORMAT_R8G8B8_USCALED: 579 case VK_FORMAT_R8G8B8_SSCALED: 580 case VK_FORMAT_R8G8B8_UINT: 581 case VK_FORMAT_R8G8B8_SINT: 582 case VK_FORMAT_R8G8B8_SRGB: 583 case VK_FORMAT_B8G8R8_UNORM: 584 case VK_FORMAT_B8G8R8_SNORM: 585 case VK_FORMAT_B8G8R8_USCALED: 586 case VK_FORMAT_B8G8R8_SSCALED: 587 case VK_FORMAT_B8G8R8_UINT: 588 case VK_FORMAT_B8G8R8_SINT: 589 case VK_FORMAT_B8G8R8_SRGB: 590 case VK_FORMAT_R8G8B8A8_UNORM: 591 case VK_FORMAT_R8G8B8A8_SNORM: 592 case VK_FORMAT_R8G8B8A8_USCALED: 593 case VK_FORMAT_R8G8B8A8_SSCALED: 594 case VK_FORMAT_R8G8B8A8_UINT: 595 case VK_FORMAT_R8G8B8A8_SINT: 596 case VK_FORMAT_R8G8B8A8_SRGB: 597 case VK_FORMAT_B8G8R8A8_UNORM: 598 case VK_FORMAT_B8G8R8A8_SNORM: 599 case VK_FORMAT_B8G8R8A8_USCALED: 600 case VK_FORMAT_B8G8R8A8_SSCALED: 601 case VK_FORMAT_B8G8R8A8_UINT: 602 case VK_FORMAT_B8G8R8A8_SINT: 603 case VK_FORMAT_B8G8R8A8_SRGB: 604 case VK_FORMAT_A8B8G8R8_UNORM_PACK32: 605 case VK_FORMAT_A8B8G8R8_SNORM_PACK32: 606 case VK_FORMAT_A8B8G8R8_USCALED_PACK32: 607 case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: 608 case VK_FORMAT_A8B8G8R8_UINT_PACK32: 609 case VK_FORMAT_A8B8G8R8_SINT_PACK32: 610 case VK_FORMAT_A8B8G8R8_SRGB_PACK32: 611 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: 612 case VK_FORMAT_A2R10G10B10_SNORM_PACK32: 613 case VK_FORMAT_A2R10G10B10_USCALED_PACK32: 614 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: 615 case VK_FORMAT_A2R10G10B10_UINT_PACK32: 616 case VK_FORMAT_A2R10G10B10_SINT_PACK32: 617 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: 618 case VK_FORMAT_A2B10G10R10_SNORM_PACK32: 619 case VK_FORMAT_A2B10G10R10_USCALED_PACK32: 620 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: 621 case VK_FORMAT_A2B10G10R10_UINT_PACK32: 622 case VK_FORMAT_A2B10G10R10_SINT_PACK32: 623 case VK_FORMAT_R16_UNORM: 624 case VK_FORMAT_R16_SNORM: 625 case VK_FORMAT_R16_USCALED: 626 case VK_FORMAT_R16_SSCALED: 627 case VK_FORMAT_R16_UINT: 628 case VK_FORMAT_R16_SINT: 629 case VK_FORMAT_R16_SFLOAT: 630 case VK_FORMAT_R16G16_UNORM: 631 case VK_FORMAT_R16G16_SNORM: 632 case VK_FORMAT_R16G16_USCALED: 633 case VK_FORMAT_R16G16_SSCALED: 634 case VK_FORMAT_R16G16_UINT: 635 case VK_FORMAT_R16G16_SINT: 636 case VK_FORMAT_R16G16_SFLOAT: 637 case VK_FORMAT_R16G16B16_UNORM: 638 case VK_FORMAT_R16G16B16_SNORM: 639 case VK_FORMAT_R16G16B16_USCALED: 640 case VK_FORMAT_R16G16B16_SSCALED: 641 case VK_FORMAT_R16G16B16_UINT: 642 case VK_FORMAT_R16G16B16_SINT: 643 case VK_FORMAT_R16G16B16_SFLOAT: 644 case VK_FORMAT_R16G16B16A16_UNORM: 645 case VK_FORMAT_R16G16B16A16_SNORM: 646 case VK_FORMAT_R16G16B16A16_USCALED: 647 case VK_FORMAT_R16G16B16A16_SSCALED: 648 case VK_FORMAT_R16G16B16A16_UINT: 649 case VK_FORMAT_R16G16B16A16_SINT: 650 case VK_FORMAT_R16G16B16A16_SFLOAT: 651 case VK_FORMAT_R32_UINT: 652 case VK_FORMAT_R32_SINT: 653 case VK_FORMAT_R32_SFLOAT: 654 case VK_FORMAT_R32G32_UINT: 655 case VK_FORMAT_R32G32_SINT: 656 case VK_FORMAT_R32G32_SFLOAT: 657 case VK_FORMAT_R32G32B32_UINT: 658 case VK_FORMAT_R32G32B32_SINT: 659 case VK_FORMAT_R32G32B32_SFLOAT: 660 case VK_FORMAT_R32G32B32A32_UINT: 661 case VK_FORMAT_R32G32B32A32_SINT: 662 case VK_FORMAT_R32G32B32A32_SFLOAT: 663 case VK_FORMAT_R64_UINT: 664 case VK_FORMAT_R64_SINT: 665 case VK_FORMAT_R64_SFLOAT: 666 case VK_FORMAT_R64G64_UINT: 667 case VK_FORMAT_R64G64_SINT: 668 case VK_FORMAT_R64G64_SFLOAT: 669 case VK_FORMAT_R64G64B64_UINT: 670 case VK_FORMAT_R64G64B64_SINT: 671 case VK_FORMAT_R64G64B64_SFLOAT: 672 case VK_FORMAT_R64G64B64A64_UINT: 673 case VK_FORMAT_R64G64B64A64_SINT: 674 case VK_FORMAT_R64G64B64A64_SFLOAT: 675 case VK_FORMAT_B10G11R11_UFLOAT_PACK32: 676 case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: 677 case VK_FORMAT_D16_UNORM: 678 case VK_FORMAT_X8_D24_UNORM_PACK32: 679 case VK_FORMAT_D32_SFLOAT: 680 case VK_FORMAT_S8_UINT: 681 case VK_FORMAT_D16_UNORM_S8_UINT: 682 case VK_FORMAT_D24_UNORM_S8_UINT: 683 case VK_FORMAT_D32_SFLOAT_S8_UINT: 684 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: 685 case VK_FORMAT_BC1_RGB_SRGB_BLOCK: 686 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: 687 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: 688 case VK_FORMAT_BC2_UNORM_BLOCK: 689 case VK_FORMAT_BC2_SRGB_BLOCK: 690 case VK_FORMAT_BC3_UNORM_BLOCK: 691 case VK_FORMAT_BC3_SRGB_BLOCK: 692 case VK_FORMAT_BC4_UNORM_BLOCK: 693 case VK_FORMAT_BC4_SNORM_BLOCK: 694 case VK_FORMAT_BC5_UNORM_BLOCK: 695 case VK_FORMAT_BC5_SNORM_BLOCK: 696 case VK_FORMAT_BC6H_UFLOAT_BLOCK: 697 case VK_FORMAT_BC6H_SFLOAT_BLOCK: 698 case VK_FORMAT_BC7_UNORM_BLOCK: 699 case VK_FORMAT_BC7_SRGB_BLOCK: 700 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: 701 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 702 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: 703 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 704 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: 705 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 706 case VK_FORMAT_EAC_R11_UNORM_BLOCK: 707 case VK_FORMAT_EAC_R11_SNORM_BLOCK: 708 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: 709 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 710 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: 711 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: 712 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: 713 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: 714 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: 715 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: 716 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: 717 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: 718 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: 719 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: 720 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: 721 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: 722 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: 723 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: 724 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: 725 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: 726 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: 727 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: 728 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: 729 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: 730 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: 731 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: 732 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: 733 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: 734 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: 735 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: 736 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: 737 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: 738 case VK_FORMAT_G8B8G8R8_422_UNORM: 739 case VK_FORMAT_B8G8R8G8_422_UNORM: 740 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 741 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 742 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 743 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 744 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 745 case VK_FORMAT_R10X6_UNORM_PACK16: 746 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: 747 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: 748 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 749 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 750 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 751 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 752 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 753 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 754 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 755 case VK_FORMAT_R12X4_UNORM_PACK16: 756 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: 757 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: 758 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 759 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 760 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 761 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 762 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 763 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 764 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 765 case VK_FORMAT_G16B16G16R16_422_UNORM: 766 case VK_FORMAT_B16G16R16G16_422_UNORM: 767 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 768 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 769 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 770 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 771 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 772 case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: 773 case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: 774 case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: 775 case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: 776 case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: 777 case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: 778 case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: 779 case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: 780 case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT: 781 case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT: 782 case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT: 783 case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT: 784 case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT: 785 case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT: 786 case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT: 787 case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT: 788 case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT: 789 case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT: 790 case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT: 791 case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT: 792 case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT: 793 case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT: 794 case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT: 795 case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT: 796 return true; 797 } 798 return false; 799 } 800}; 801 802template <> 803struct EnumTraits<VkPointClippingBehavior> { 804 static bool exist(uint32_t e) { 805 switch (e) { 806 case VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES: 807 case VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY: 808 return true; 809 } 810 return false; 811 } 812}; 813 814template <> 815struct EnumTraits<VkExternalFenceHandleTypeFlagBits> { 816 static bool exist(uint32_t e) { 817 switch (e) { 818 case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT: 819 case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 820 case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 821 case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT: 822 return true; 823 } 824 return false; 825 } 826}; 827 828template <> 829struct EnumTraits<VkExternalSemaphoreHandleTypeFlagBits> { 830 static bool exist(uint32_t e) { 831 switch (e) { 832 case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: 833 case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 834 case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 835 case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT: 836 case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: 837 return true; 838 } 839 return false; 840 } 841}; 842 843template <> 844struct EnumTraits<VkDriverIdKHR> { 845 static bool exist(uint32_t e) { 846 switch (e) { 847 case VK_DRIVER_ID_AMD_PROPRIETARY: 848 case VK_DRIVER_ID_AMD_OPEN_SOURCE: 849 case VK_DRIVER_ID_MESA_RADV: 850 case VK_DRIVER_ID_NVIDIA_PROPRIETARY: 851 case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS: 852 case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA: 853 case VK_DRIVER_ID_IMAGINATION_PROPRIETARY: 854 case VK_DRIVER_ID_QUALCOMM_PROPRIETARY: 855 case VK_DRIVER_ID_ARM_PROPRIETARY: 856 case VK_DRIVER_ID_GOOGLE_SWIFTSHADER: 857 case VK_DRIVER_ID_GGP_PROPRIETARY: 858 case VK_DRIVER_ID_BROADCOM_PROPRIETARY: 859 case VK_DRIVER_ID_MESA_LLVMPIPE: 860 case VK_DRIVER_ID_MOLTENVK: 861 return true; 862 } 863 return false; 864 } 865}; 866 867template <> 868struct EnumTraits<VkShaderFloatControlsIndependence> { 869 static bool exist(uint32_t e) { 870 switch (e) { 871 case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY: 872 case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL: 873 case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE: 874 return true; 875 } 876 return false; 877 } 878}; 879 880template <> 881struct EnumTraits<VkPipelineRobustnessBufferBehavior> { 882 static bool exist(uint32_t e) { 883 switch (e) { 884 case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT: 885 case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED: 886 case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS: 887 case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2: 888 return true; 889 } 890 return false; 891 } 892}; 893 894template <> 895struct EnumTraits<VkPipelineRobustnessImageBehavior> { 896 static bool exist(uint32_t e) { 897 switch (e) { 898 case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT: 899 case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED: 900 case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS: 901 case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2: 902 return true; 903 } 904 return false; 905 } 906}; 907 908template <> 909struct EnumTraits<VkImageLayout> { 910 static bool exist(uint32_t e) { 911 switch (e) { 912 case VK_IMAGE_LAYOUT_UNDEFINED: 913 case VK_IMAGE_LAYOUT_GENERAL: 914 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 915 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 916 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 917 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 918 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 919 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 920 case VK_IMAGE_LAYOUT_PREINITIALIZED: 921 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: 922 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: 923 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: 924 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: 925 case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: 926 case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: 927 case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL: 928 case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL: 929 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: 930 case VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR: 931 case VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR: 932 case VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR: 933 case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: 934 case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT: 935 case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR: 936#ifdef VK_ENABLE_BETA_EXTENSIONS 937 case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR: 938#endif 939#ifdef VK_ENABLE_BETA_EXTENSIONS 940 case VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR: 941#endif 942#ifdef VK_ENABLE_BETA_EXTENSIONS 943 case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR: 944#endif 945 case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT: 946 return true; 947 } 948 return false; 949 } 950}; 951 952// VkSparseImageFormatProperties 953 954template <typename Visitor> 955inline bool Iterate(Visitor* visitor, VkExtent3D* extents) { 956 return 957 visitor->Visit("width", &extents->width) && 958 visitor->Visit("height", &extents->height) && 959 visitor->Visit("depth", &extents->depth); 960} 961 962template <typename Visitor> 963inline bool Iterate(Visitor* visitor, 964 VkConformanceVersionKHR* version) { 965 return visitor->Visit("major", &version->major) && 966 visitor->Visit("minor", &version->minor) && 967 visitor->Visit("subminor", &version->subminor) && 968 visitor->Visit("patch", &version->patch); 969} 970 971template <typename Visitor> 972inline bool Iterate(Visitor* visitor, VkMemoryType* type) { 973 return 974 visitor->Visit("propertyFlags", &type->propertyFlags) && 975 visitor->Visit("heapIndex", &type->heapIndex); 976} 977 978template <typename Visitor> 979inline bool Iterate(Visitor* visitor, VkMemoryHeap* heap) { 980 return 981 visitor->Visit("size", &heap->size) && 982 visitor->Visit("flags", &heap->flags); 983}\n\n""") 984 985 f.write(f"{generate_core_template()}\n\n{generate_extension_struct_template()}\n\n") 986 f.write(generate_struct_template(VK.ALL_STRUCTS)) 987 988 f.write("""\ 989template <typename Visitor> 990inline bool Iterate(Visitor* visitor, VkExternalFenceProperties* properties) { 991 return visitor->Visit("exportFromImportedHandleTypes", 992 &properties->exportFromImportedHandleTypes) && 993 visitor->Visit("compatibleHandleTypes", 994 &properties->compatibleHandleTypes) && 995 visitor->Visit("externalFenceFeatures", 996 &properties->externalFenceFeatures); 997} 998 999template <typename Visitor> 1000inline bool Iterate(Visitor* visitor, 1001 VkExternalSemaphoreProperties* properties) { 1002 return visitor->Visit("exportFromImportedHandleTypes", 1003 &properties->exportFromImportedHandleTypes) && 1004 visitor->Visit("compatibleHandleTypes", 1005 &properties->compatibleHandleTypes) && 1006 visitor->Visit("externalSemaphoreFeatures", 1007 &properties->externalSemaphoreFeatures); 1008} 1009 1010template <typename Visitor> 1011inline bool Iterate(Visitor* visitor, VkJsonLayer* layer) { 1012 return visitor->Visit("properties", &layer->properties) && 1013 visitor->Visit("extensions", &layer->extensions); 1014} 1015 1016template <typename Visitor> 1017inline bool Iterate(Visitor* visitor, VkJsonDeviceGroup* device_group) { 1018 return visitor->Visit("devices", &device_group->device_inds) && 1019 visitor->Visit("subsetAllocation", 1020 &device_group->properties.subsetAllocation); 1021} 1022 1023template <typename Visitor> 1024inline bool Iterate(Visitor* visitor, VkJsonDevice* device) { 1025 bool ret = true; 1026 switch (device->properties.apiVersion ^ 1027 VK_API_VERSION_PATCH(device->properties.apiVersion)) { 1028 case VK_API_VERSION_1_4: 1029 ret &= visitor->Visit("core14", &device->core14); 1030 FALLTHROUGH_INTENDED; 1031 case VK_API_VERSION_1_3: 1032 ret &= visitor->Visit("core13", &device->core13); 1033 FALLTHROUGH_INTENDED; 1034 case VK_API_VERSION_1_2: 1035 ret &= visitor->Visit("core11", &device->core11); 1036 ret &= visitor->Visit("core12", &device->core12); 1037 FALLTHROUGH_INTENDED; 1038 case VK_API_VERSION_1_1: 1039 ret &=\n""") 1040 1041 emit_struct_visits_by_vk_version(f, "VK_VERSION_1_1") 1042 1043 f.write("""\ 1044 visitor->Visit("externalFenceProperties", 1045 &device->external_fence_properties) && 1046 visitor->Visit("externalSemaphoreProperties", 1047 &device->external_semaphore_properties); 1048 FALLTHROUGH_INTENDED; 1049 case VK_API_VERSION_1_0: 1050 ret &=\n""") 1051 1052 emit_struct_visits_by_vk_version(f, "VK_VERSION_1_0") 1053 1054 f.write("""\ 1055 visitor->Visit("queues", &device->queues) && 1056 visitor->Visit("extensions", &device->extensions) && 1057 visitor->Visit("layers", &device->layers) && 1058 visitor->Visit("formats", &device->formats);\n\n""") 1059 1060 for extension_name, _ in VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"].items(): 1061 struct_var = get_vkjson_struct_variable_name(extension_name) 1062 f.write(f" if (device->{struct_var}.reported) {{\n") 1063 f.write(f" ret &= visitor->Visit(\"{extension_name}\", &device->{struct_var});\n") 1064 f.write(" }\n") 1065 1066 f.write("""\ 1067 } return ret; } 1068 1069template <typename Visitor> 1070inline bool Iterate(Visitor* visitor, VkJsonInstance* instance) { 1071 bool ret = true; 1072 switch (instance->api_version ^ VK_API_VERSION_PATCH(instance->api_version)) { 1073 case VK_API_VERSION_1_4: 1074 FALLTHROUGH_INTENDED; 1075 case VK_API_VERSION_1_3: 1076 FALLTHROUGH_INTENDED; 1077 case VK_API_VERSION_1_2: 1078 ret &= visitor->Visit("apiVersion", &instance->api_version); 1079 FALLTHROUGH_INTENDED; 1080 case VK_API_VERSION_1_1: 1081 ret &= visitor->Visit("deviceGroups", &instance->device_groups); 1082 FALLTHROUGH_INTENDED; 1083 case VK_API_VERSION_1_0: 1084 char depString[] = 1085 "vkjson is deprecated, and will be replaced in a future release"; 1086 ret &= visitor->Visit("layers", &instance->layers) && 1087 visitor->Visit("extensions", &instance->extensions) && 1088 visitor->Visit("devices", &instance->devices) && 1089 visitor->Visit("_comment", &depString); 1090 } 1091 return ret; 1092} 1093 1094template <typename T> 1095using EnableForArithmetic = 1096 typename std::enable_if<std::is_arithmetic<T>::value, void>::type; 1097 1098template <typename T> 1099using EnableForStruct = 1100 typename std::enable_if<std::is_class<T>::value, void>::type; 1101 1102template <typename T> 1103using EnableForEnum = 1104 typename std::enable_if<std::is_enum<T>::value, void>::type; 1105 1106template <typename T, typename = EnableForStruct<T>, typename = void> 1107Json::Value ToJsonValue(const T& value); 1108 1109template <typename T, typename = EnableForArithmetic<T>> 1110inline Json::Value ToJsonValue(const T& value) { 1111 return Json::Value( 1112 std::clamp(static_cast<double>(value), SAFE_DOUBLE_MIN, SAFE_DOUBLE_MAX)); 1113} 1114 1115inline Json::Value ToJsonValue(const uint64_t& value) { 1116 char string[19] = {0}; // "0x" + 16 digits + terminal \\0 1117 snprintf(string, sizeof(string), "0x%016" PRIx64, value); 1118 return Json::Value(string); 1119} 1120 1121template <typename T, typename = EnableForEnum<T>, typename = void, 1122 typename = void> 1123inline Json::Value ToJsonValue(const T& value) { 1124 return Json::Value(static_cast<double>(value)); 1125} 1126 1127template <typename T> 1128inline Json::Value ArrayToJsonValue(uint32_t count, const T* values) { 1129 Json::Value array(Json::arrayValue); 1130 for (unsigned int i = 0; i < count; ++i) array.append(ToJsonValue(values[i])); 1131 return array; 1132} 1133 1134template <typename T, size_t N> 1135inline Json::Value ToJsonValue(const T (&value)[N]) { 1136 return ArrayToJsonValue(N, value); 1137} 1138 1139template <size_t N> 1140inline Json::Value ToJsonValue(const char (&value)[N]) { 1141 assert(strlen(value) < N); 1142 return Json::Value(value); 1143} 1144 1145template <typename T> 1146inline Json::Value ToJsonValue(const std::vector<T>& value) { 1147 assert(value.size() <= std::numeric_limits<uint32_t>::max()); 1148 return ArrayToJsonValue(static_cast<uint32_t>(value.size()), value.data()); 1149} 1150 1151template <typename F, typename S> 1152inline Json::Value ToJsonValue(const std::pair<F, S>& value) { 1153 Json::Value array(Json::arrayValue); 1154 array.append(ToJsonValue(value.first)); 1155 array.append(ToJsonValue(value.second)); 1156 return array; 1157} 1158 1159template <typename F, typename S> 1160inline Json::Value ToJsonValue(const std::map<F, S>& value) { 1161 Json::Value array(Json::arrayValue); 1162 for (auto& kv : value) array.append(ToJsonValue(kv)); 1163 return array; 1164} 1165 1166class JsonWriterVisitor { 1167 public: 1168 JsonWriterVisitor() : object_(Json::objectValue) {} 1169 1170 ~JsonWriterVisitor() {} 1171 1172 template <typename T> bool Visit(const char* key, const T* value) { 1173 object_[key] = ToJsonValue(*value); 1174 return true; 1175 } 1176 1177 template <typename T, uint32_t N> 1178 bool VisitArray(const char* key, uint32_t count, const T (*value)[N]) { 1179 assert(count <= N); 1180 object_[key] = ArrayToJsonValue(count, *value); 1181 return true; 1182 } 1183 1184 template <typename T> 1185 bool VisitArray(const char* key, uint32_t count, const T *value) { 1186 object_[key] = ArrayToJsonValue(count, *value); 1187 return true; 1188 } 1189 1190 Json::Value get_object() const { return object_; } 1191 1192 private: 1193 Json::Value object_; 1194}; 1195 1196template <typename Visitor, typename T> 1197inline void VisitForWrite(Visitor* visitor, const T& t) { 1198 Iterate(visitor, const_cast<T*>(&t)); 1199} 1200 1201template <typename T, typename /*= EnableForStruct<T>*/, typename /*= void*/> 1202Json::Value ToJsonValue(const T& value) { 1203 JsonWriterVisitor visitor; 1204 VisitForWrite(&visitor, value); 1205 return visitor.get_object(); 1206} 1207 1208template <typename T, typename = EnableForStruct<T>> 1209bool AsValue(Json::Value* json_value, T* t); 1210 1211inline bool AsValue(Json::Value* json_value, int32_t* value) { 1212 if (json_value->type() != Json::realValue) return false; 1213 double d = json_value->asDouble(); 1214 if (!IsIntegral(d) || 1215 d < static_cast<double>(std::numeric_limits<int32_t>::min()) || 1216 d > static_cast<double>(std::numeric_limits<int32_t>::max())) 1217 return false; 1218 *value = static_cast<int32_t>(d); 1219 return true; 1220} 1221 1222inline bool AsValue(Json::Value* json_value, uint64_t* value) { 1223 if (json_value->type() != Json::stringValue) return false; 1224 int result = 1225 std::sscanf(json_value->asString().c_str(), "0x%016" PRIx64, value); 1226 return result == 1; 1227} 1228 1229inline bool AsValue(Json::Value* json_value, uint32_t* value) { 1230 if (json_value->type() != Json::realValue) return false; 1231 double d = json_value->asDouble(); 1232 if (!IsIntegral(d) || d < 0.0 || 1233 d > static_cast<double>(std::numeric_limits<uint32_t>::max())) 1234 return false; 1235 *value = static_cast<uint32_t>(d); 1236 return true; 1237} 1238 1239inline bool AsValue(Json::Value* json_value, uint8_t* value) { 1240 uint32_t value32 = 0; 1241 AsValue(json_value, &value32); 1242 if (value32 > std::numeric_limits<uint8_t>::max()) 1243 return false; 1244 *value = static_cast<uint8_t>(value32); 1245 return true; 1246} 1247 1248inline bool AsValue(Json::Value* json_value, float* value) { 1249 if (json_value->type() != Json::realValue) return false; 1250 *value = static_cast<float>(json_value->asDouble()); 1251 return true; 1252} 1253 1254inline bool AsValue(Json::Value* json_value, VkImageLayout* t) { 1255 uint32_t value = 0; 1256 if (!AsValue(json_value, &value)) 1257 return false; 1258 if (!EnumTraits<VkImageLayout>::exist(value)) return false; 1259 *t = static_cast<VkImageLayout>(value); 1260 return true; 1261} 1262 1263template <typename T> 1264inline bool AsArray(Json::Value* json_value, uint32_t count, T* values) { 1265 if (json_value->type() != Json::arrayValue || json_value->size() != count) 1266 return false; 1267 for (uint32_t i = 0; i < count; ++i) { 1268 if (!AsValue(&(*json_value)[i], values + i)) return false; 1269 } 1270 return true; 1271} 1272 1273template <typename T, size_t N> 1274inline bool AsValue(Json::Value* json_value, T (*value)[N]) { 1275 return AsArray(json_value, N, *value); 1276} 1277 1278template <size_t N> 1279inline bool AsValue(Json::Value* json_value, char (*value)[N]) { 1280 if (json_value->type() != Json::stringValue) return false; 1281 size_t len = json_value->asString().length(); 1282 if (len >= N) 1283 return false; 1284 memcpy(*value, json_value->asString().c_str(), len); 1285 memset(*value + len, 0, N-len); 1286 return true; 1287} 1288 1289template <typename T, typename = EnableForEnum<T>, typename = void> 1290inline bool AsValue(Json::Value* json_value, T* t) { 1291 uint32_t value = 0; 1292 if (!AsValue(json_value, &value)) 1293 return false; 1294 if (!EnumTraits<T>::exist(value)) return false; 1295 *t = static_cast<T>(value); 1296 return true; 1297} 1298 1299template <typename T> 1300inline bool AsValue(Json::Value* json_value, std::vector<T>* value) { 1301 if (json_value->type() != Json::arrayValue) return false; 1302 int size = json_value->size(); 1303 value->resize(size); 1304 return AsArray(json_value, size, value->data()); 1305} 1306 1307template <typename F, typename S> 1308inline bool AsValue(Json::Value* json_value, std::pair<F, S>* value) { 1309 if (json_value->type() != Json::arrayValue || json_value->size() != 2) 1310 return false; 1311 return AsValue(&(*json_value)[0], &value->first) && 1312 AsValue(&(*json_value)[1], &value->second); 1313} 1314 1315template <typename F, typename S> 1316inline bool AsValue(Json::Value* json_value, std::map<F, S>* value) { 1317 if (json_value->type() != Json::arrayValue) return false; 1318 int size = json_value->size(); 1319 for (int i = 0; i < size; ++i) { 1320 std::pair<F, S> elem; 1321 if (!AsValue(&(*json_value)[i], &elem)) return false; 1322 if (!value->insert(elem).second) 1323 return false; 1324 } 1325 return true; 1326} 1327 1328template <typename T> 1329bool ReadValue(Json::Value* object, const char* key, T* value, 1330 std::string* errors) { 1331 Json::Value json_value = (*object)[key]; 1332 if (!json_value) { 1333 if (errors) 1334 *errors = std::string(key) + " missing."; 1335 return false; 1336 } 1337 if (AsValue(&json_value, value)) return true; 1338 if (errors) 1339 *errors = std::string("Wrong type for ") + std::string(key) + "."; 1340 return false; 1341} 1342 1343template <typename Visitor, typename T> 1344inline bool VisitForRead(Visitor* visitor, T* t) { 1345 return Iterate(visitor, t); 1346} 1347 1348class JsonReaderVisitor { 1349 public: 1350 JsonReaderVisitor(Json::Value* object, std::string* errors) 1351 : object_(object), errors_(errors) {} 1352 1353 template <typename T> bool Visit(const char* key, T* value) const { 1354 return ReadValue(object_, key, value, errors_); 1355 } 1356 1357 template <typename T, uint32_t N> 1358 bool VisitArray(const char* key, uint32_t count, T (*value)[N]) { 1359 if (count > N) 1360 return false; 1361 Json::Value json_value = (*object_)[key]; 1362 if (!json_value) { 1363 if (errors_) 1364 *errors_ = std::string(key) + " missing."; 1365 return false; 1366 } 1367 if (AsArray(&json_value, count, *value)) return true; 1368 if (errors_) 1369 *errors_ = std::string("Wrong type for ") + std::string(key) + "."; 1370 return false; 1371 } 1372 1373 template <typename T> 1374 bool VisitArray(const char* key, uint32_t count, T *value) { 1375 Json::Value json_value = (*object_)[key]; 1376 if (!json_value) { 1377 if (errors_) 1378 *errors_ = std::string(key) + " missing."; 1379 return false; 1380 } 1381 if (AsArray(&json_value, count, *value)) return true; 1382 if (errors_) 1383 *errors_ = std::string("Wrong type for ") + std::string(key) + "."; 1384 return false; 1385 } 1386 1387 1388 private: 1389 Json::Value* object_; 1390 std::string* errors_; 1391}; 1392 1393template <typename T, typename /*= EnableForStruct<T>*/> 1394bool AsValue(Json::Value* json_value, T* t) { 1395 if (json_value->type() != Json::objectValue) return false; 1396 JsonReaderVisitor visitor(json_value, nullptr); 1397 return VisitForRead(&visitor, t); 1398} 1399 1400 1401template <typename T> std::string VkTypeToJson(const T& t) { 1402 JsonWriterVisitor visitor; 1403 VisitForWrite(&visitor, t); 1404 return visitor.get_object().toStyledString(); 1405} 1406 1407template <typename T> bool VkTypeFromJson(const std::string& json, 1408 T* t, 1409 std::string* errors) { 1410 *t = T(); 1411 Json::Value object(Json::objectValue); 1412 Json::CharReaderBuilder builder; 1413 builder["collectComments"] = false; 1414 std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); 1415 if (!reader->parse(json.data(), json.data() + json.size(), &object, errors)) { 1416 return false; 1417 } 1418 return AsValue(&object, t); 1419} 1420 1421} // anonymous namespace 1422 1423std::string VkJsonInstanceToJson(const VkJsonInstance& instance) { 1424 return VkTypeToJson(instance); 1425} 1426 1427bool VkJsonInstanceFromJson(const std::string& json, 1428 VkJsonInstance* instance, 1429 std::string* errors) { 1430 return VkTypeFromJson(json, instance, errors); 1431} 1432 1433std::string VkJsonDeviceToJson(const VkJsonDevice& device) { 1434 return VkTypeToJson(device); 1435} 1436 1437bool VkJsonDeviceFromJson(const std::string& json, 1438 VkJsonDevice* device, 1439 std::string* errors) { 1440 return VkTypeFromJson(json, device, errors); 1441}; 1442 1443std::string VkJsonImageFormatPropertiesToJson( 1444 const VkImageFormatProperties& properties) { 1445 return VkTypeToJson(properties); 1446} 1447 1448bool VkJsonImageFormatPropertiesFromJson(const std::string& json, 1449 VkImageFormatProperties* properties, 1450 std::string* errors) { 1451 return VkTypeFromJson(json, properties, errors); 1452}; 1453""") 1454 f.close() 1455 gencom.run_clang_format(genfile) 1456 1457 1458def generate_vk_core_structs_init_code(version): 1459 """Generates code to initialize properties and features 1460 for structs based on its vulkan API version dependency. 1461 """ 1462 properties_code, features_code = [], [] 1463 1464 for item in VK.VULKAN_CORES_AND_STRUCTS_MAPPING["versions"].get(version, []): 1465 for struct_name, struct_type in item.items(): 1466 version_lower = version.lower() 1467 1468 if "Properties" in struct_name: 1469 properties_code.extend([ 1470 f"device.{version_lower}.properties.sType = {struct_type};", 1471 f"device.{version_lower}.properties.pNext = properties.pNext;", 1472 f"properties.pNext = &device.{version_lower}.properties;\n\n" 1473 ]) 1474 1475 elif "Features" in struct_name: 1476 features_code.extend([ 1477 f"device.{version_lower}.features.sType = {struct_type};", 1478 f"device.{version_lower}.features.pNext = features.pNext;", 1479 f"features.pNext = &device.{version_lower}.features;\n\n" 1480 ]) 1481 1482 return "\n".join(properties_code), "\n".join(features_code) 1483 1484 1485def generate_vk_extension_structs_init_code(mapping, struct_category, next_pointer): 1486 """Generates Vulkan struct initialization code for given struct category (Properties/Features) 1487 based on its extension dependency. 1488 """ 1489 generated_code = [] 1490 1491 for extension, struct_mappings in mapping.items(): 1492 struct_var_name = get_vkjson_struct_variable_name(extension) 1493 extension_code = [ 1494 f" if (HasExtension(\"{extension}\", device.extensions)) {{", 1495 f" device.{struct_var_name}.reported = true;" 1496 ] 1497 1498 struct_count = 0 1499 for struct_mapping in struct_mappings: 1500 for struct_name, struct_type in struct_mapping.items(): 1501 if struct_category in struct_name: 1502 struct_count += 1 1503 struct_instance = get_struct_name(struct_name) 1504 extension_code.extend([ 1505 f" device.{struct_var_name}.{struct_instance}.sType = {struct_type};", 1506 f" device.{struct_var_name}.{struct_instance}.pNext = {next_pointer}.pNext;", 1507 f" {next_pointer}.pNext = &device.{struct_var_name}.{struct_instance};" 1508 ]) 1509 1510 extension_code.append(" }\n") 1511 1512 if struct_count > 0: 1513 generated_code.extend(extension_code) 1514 1515 return "\n".join(generated_code) 1516 1517 1518def generate_vk_version_structs_initialization(version_data, struct_type_keyword, next_pointer): 1519 """Generates Vulkan struct initialization code for given struct category (Properties/Features) 1520 of vulkan api version s. 1521 """ 1522 struct_initialization_code = [] 1523 1524 for struct_mapping in version_data: 1525 for struct_name, struct_type in struct_mapping.items(): 1526 if struct_type_keyword in struct_name: 1527 struct_variable = get_struct_name(struct_name) 1528 struct_initialization_code.extend([ 1529 f"device.{struct_variable}.sType = {struct_type};", 1530 f"device.{struct_variable}.pNext = {next_pointer}.pNext;", 1531 f"{next_pointer}.pNext = &device.{struct_variable};\n" 1532 ]) 1533 1534 return "\n".join(struct_initialization_code) 1535 1536 1537def gen_instance_cc(): 1538 """Generates vkjson_instance.cc file. 1539 """ 1540 genfile = os.path.join(os.path.dirname(__file__), 1541 "..", "vkjson", "vkjson_instance.cc") 1542 1543 with open(genfile, "w") as f: 1544 f.write(get_copyright_warnings()) 1545 f.write("\n") 1546 1547 f.write("""\ 1548#ifndef VK_PROTOTYPES 1549#define VK_PROTOTYPES 1550#endif 1551 1552#include "vkjson.h" 1553 1554#include <algorithm> 1555#include <utility> 1556 1557/* 1558 * This file is autogenerated by vkjson_generator.py. Do not edit directly. 1559 */ 1560namespace { 1561 1562bool EnumerateExtensions(const char* layer_name, 1563 std::vector<VkExtensionProperties>* extensions) { 1564 VkResult result; 1565 uint32_t count = 0; 1566 result = vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr); 1567 if (result != VK_SUCCESS) 1568 return false; 1569 extensions->resize(count); 1570 result = vkEnumerateInstanceExtensionProperties(layer_name, &count, 1571 extensions->data()); 1572 if (result != VK_SUCCESS) 1573 return false; 1574 return true; 1575} 1576 1577bool HasExtension(const char* extension_name, 1578 const std::vector<VkExtensionProperties>& extensions) { 1579 return std::find_if(extensions.cbegin(), extensions.cend(), 1580 [extension_name](const VkExtensionProperties& extension) { 1581 return strcmp(extension.extensionName, 1582 extension_name) == 0; 1583 }) != extensions.cend(); 1584} 1585} // anonymous namespace 1586 1587VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { 1588 VkJsonDevice device; 1589 1590 uint32_t extension_count = 0; 1591 vkEnumerateDeviceExtensionProperties(physical_device, nullptr, 1592 &extension_count, nullptr); 1593 if (extension_count > 0) { 1594 device.extensions.resize(extension_count); 1595 vkEnumerateDeviceExtensionProperties( 1596 physical_device, nullptr, &extension_count, device.extensions.data()); 1597 } 1598 1599 uint32_t layer_count = 0; 1600 vkEnumerateDeviceLayerProperties(physical_device, &layer_count, nullptr); 1601 if (layer_count > 0) { 1602 device.layers.resize(layer_count); 1603 vkEnumerateDeviceLayerProperties(physical_device, &layer_count, 1604 device.layers.data()); 1605 } 1606 1607 VkPhysicalDeviceProperties2 properties = { 1608 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, 1609 nullptr, 1610 {}, 1611 };\n\n""") 1612 1613 cc_code_properties = generate_vk_extension_structs_init_code( 1614 VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"], "Properties", "properties" 1615 ) 1616 f.write(f'{cc_code_properties}\n') 1617 1618 f.write("""\ 1619 1620 vkGetPhysicalDeviceProperties2(physical_device, &properties); 1621 device.properties = properties.properties; 1622 1623 VkPhysicalDeviceFeatures2 features = { 1624 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, 1625 nullptr, 1626 {}, 1627 };\n\n""") 1628 1629 cc_code_features = generate_vk_extension_structs_init_code( 1630 VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"], "Features", "features" 1631 ) 1632 f.write(f'{cc_code_features}\n') 1633 1634 f.write("""\ 1635 1636 vkGetPhysicalDeviceFeatures2(physical_device, &features); 1637 device.features = features.features; 1638 1639 vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory); 1640 1641 uint32_t queue_family_count = 0; 1642 vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, 1643 nullptr); 1644 if (queue_family_count > 0) { 1645 device.queues.resize(queue_family_count); 1646 vkGetPhysicalDeviceQueueFamilyProperties( 1647 physical_device, &queue_family_count, device.queues.data()); 1648 } 1649 1650 VkFormatProperties format_properties = {}; 1651 for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8; 1652 // TODO(http://b/171403054): avoid hard-coding last value in the 1653 // contiguous range 1654 format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; 1655 format = static_cast<VkFormat>(format + 1)) { 1656 vkGetPhysicalDeviceFormatProperties(physical_device, format, 1657 &format_properties); 1658 if (format_properties.linearTilingFeatures || 1659 format_properties.optimalTilingFeatures || 1660 format_properties.bufferFeatures) { 1661 device.formats.insert(std::make_pair(format, format_properties)); 1662 } 1663 } 1664 1665 if (device.properties.apiVersion >= VK_API_VERSION_1_1) { 1666 for (VkFormat format = VK_FORMAT_G8B8G8R8_422_UNORM; 1667 // TODO(http://b/171403054): avoid hard-coding last value in the 1668 // contiguous range 1669 format <= VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM; 1670 format = static_cast<VkFormat>(format + 1)) { 1671 vkGetPhysicalDeviceFormatProperties(physical_device, format, 1672 &format_properties); 1673 if (format_properties.linearTilingFeatures || 1674 format_properties.optimalTilingFeatures || 1675 format_properties.bufferFeatures) { 1676 device.formats.insert(std::make_pair(format, format_properties)); 1677 } 1678 }\n\n""") 1679 1680 # Vulkan version data for VK_VERSION_1_1 1681 vk_version_data = VK.VULKAN_VERSIONS_AND_STRUCTS_MAPPING["VK_VERSION_1_1"] 1682 f.write(generate_vk_version_structs_initialization(vk_version_data, "Properties", "properties") + "\n") 1683 1684 f.write("""\ 1685 vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n""") 1686 1687 features_initialization_code = generate_vk_version_structs_initialization(vk_version_data, "Features", "features") 1688 f.write(features_initialization_code) 1689 1690 f.write("""\ 1691 1692 vkGetPhysicalDeviceFeatures2(physical_device, &features); 1693 1694 VkPhysicalDeviceExternalFenceInfo external_fence_info = { 1695 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, nullptr, 1696 VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT}; 1697 VkExternalFenceProperties external_fence_properties = {}; 1698 1699 for (VkExternalFenceHandleTypeFlagBits handle_type = 1700 VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT; 1701 handle_type <= VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT; 1702 handle_type = 1703 static_cast<VkExternalFenceHandleTypeFlagBits>(handle_type << 1)) { 1704 external_fence_info.handleType = handle_type; 1705 vkGetPhysicalDeviceExternalFenceProperties( 1706 physical_device, &external_fence_info, &external_fence_properties); 1707 if (external_fence_properties.exportFromImportedHandleTypes || 1708 external_fence_properties.compatibleHandleTypes || 1709 external_fence_properties.externalFenceFeatures) { 1710 device.external_fence_properties.insert( 1711 std::make_pair(handle_type, external_fence_properties)); 1712 } 1713 } 1714 1715 VkPhysicalDeviceExternalSemaphoreInfo external_semaphore_info = { 1716 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, nullptr, 1717 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT}; 1718 VkExternalSemaphoreProperties external_semaphore_properties = {}; 1719 1720 for (VkExternalSemaphoreHandleTypeFlagBits handle_type = 1721 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT; 1722 handle_type <= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; 1723 handle_type = static_cast<VkExternalSemaphoreHandleTypeFlagBits>( 1724 handle_type << 1)) { 1725 external_semaphore_info.handleType = handle_type; 1726 vkGetPhysicalDeviceExternalSemaphoreProperties( 1727 physical_device, &external_semaphore_info, 1728 &external_semaphore_properties); 1729 if (external_semaphore_properties.exportFromImportedHandleTypes || 1730 external_semaphore_properties.compatibleHandleTypes || 1731 external_semaphore_properties.externalSemaphoreFeatures) { 1732 device.external_semaphore_properties.insert( 1733 std::make_pair(handle_type, external_semaphore_properties)); 1734 } 1735 } 1736 } 1737 1738 if (device.properties.apiVersion >= VK_API_VERSION_1_2) {\n""") 1739 1740 cc_code_properties_11, cc_code_features_11 = generate_vk_core_structs_init_code("Core11") 1741 cc_code_properties_12, cc_code_features_12 = generate_vk_core_structs_init_code("Core12") 1742 cc_code_properties_13, cc_code_features_13 = generate_vk_core_structs_init_code("Core13") 1743 cc_code_properties_14, cc_code_features_14 = generate_vk_core_structs_init_code("Core14") 1744 1745 f.write(cc_code_properties_11) 1746 f.write(cc_code_properties_12) 1747 f.write(f"vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n") 1748 f.write(cc_code_features_11) 1749 f.write(cc_code_features_12) 1750 f.write(f"vkGetPhysicalDeviceFeatures2(physical_device, &features);\n\n") 1751 f.write("""\ 1752 } 1753 1754 if (device.properties.apiVersion >= VK_API_VERSION_1_3) {\n""") 1755 f.write(cc_code_properties_13) 1756 f.write(f"vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n") 1757 f.write(cc_code_features_13) 1758 f.write(f"vkGetPhysicalDeviceFeatures2(physical_device, &features);\n\n") 1759 f.write("""\ 1760 } 1761 1762 if (device.properties.apiVersion >= VK_API_VERSION_1_4) {\n""") 1763 f.write(cc_code_properties_14) 1764 f.write(f"vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n") 1765 1766 f.write("""\ 1767if (device.core14.properties.copySrcLayoutCount > 0 || device.core14.properties.copyDstLayoutCount > 0 ) { 1768 if (device.core14.properties.copySrcLayoutCount > 0) { 1769 device.core14.copy_src_layouts.resize(device.core14.properties.copySrcLayoutCount); 1770 device.core14.properties.pCopySrcLayouts = device.core14.copy_src_layouts.data(); 1771 } 1772 if (device.core14.properties.copyDstLayoutCount > 0) { 1773 device.core14.copy_dst_layouts.resize(device.core14.properties.copyDstLayoutCount); 1774 device.core14.properties.pCopyDstLayouts = device.core14.copy_dst_layouts.data(); 1775 } 1776 vkGetPhysicalDeviceProperties2(physical_device, &properties); 1777} 1778 \n""") 1779 1780 f.write(cc_code_features_14) 1781 f.write(f"vkGetPhysicalDeviceFeatures2(physical_device, &features);\n\n") 1782 f.write("""\ 1783 } 1784 1785 return device; 1786} 1787 1788VkJsonInstance VkJsonGetInstance() { 1789 VkJsonInstance instance; 1790 VkResult result; 1791 uint32_t count; 1792 1793 count = 0; 1794 result = vkEnumerateInstanceLayerProperties(&count, nullptr); 1795 if (result != VK_SUCCESS) 1796 return VkJsonInstance(); 1797 if (count > 0) { 1798 std::vector<VkLayerProperties> layers(count); 1799 result = vkEnumerateInstanceLayerProperties(&count, layers.data()); 1800 if (result != VK_SUCCESS) 1801 return VkJsonInstance(); 1802 instance.layers.reserve(count); 1803 for (auto& layer : layers) { 1804 instance.layers.push_back(VkJsonLayer{layer, std::vector<VkExtensionProperties>()}); 1805 if (!EnumerateExtensions(layer.layerName, 1806 &instance.layers.back().extensions)) 1807 return VkJsonInstance(); 1808 } 1809 } 1810 1811 if (!EnumerateExtensions(nullptr, &instance.extensions)) 1812 return VkJsonInstance(); 1813 1814 const VkApplicationInfo app_info = { 1815 VK_STRUCTURE_TYPE_APPLICATION_INFO, 1816 nullptr, 1817 "vkjson_info", 1818 1, 1819 "", 1820 0, 1821 VK_API_VERSION_1_1, 1822 }; 1823 VkInstanceCreateInfo instance_info = { 1824 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 1825 nullptr, 1826 0, 1827 &app_info, 1828 0, 1829 nullptr, 1830 0, 1831 nullptr, 1832 }; 1833 VkInstance vkinstance; 1834 result = vkCreateInstance(&instance_info, nullptr, &vkinstance); 1835 if (result != VK_SUCCESS) 1836 return VkJsonInstance(); 1837 1838 count = 0; 1839 result = vkEnumeratePhysicalDevices(vkinstance, &count, nullptr); 1840 if (result != VK_SUCCESS) { 1841 vkDestroyInstance(vkinstance, nullptr); 1842 return VkJsonInstance(); 1843 } 1844 1845 std::vector<VkPhysicalDevice> devices(count, VK_NULL_HANDLE); 1846 result = vkEnumeratePhysicalDevices(vkinstance, &count, devices.data()); 1847 if (result != VK_SUCCESS) { 1848 vkDestroyInstance(vkinstance, nullptr); 1849 return VkJsonInstance(); 1850 } 1851 1852 std::map<VkPhysicalDevice, uint32_t> device_map; 1853 const uint32_t sz = devices.size(); 1854 instance.devices.reserve(sz); 1855 for (uint32_t i = 0; i < sz; ++i) { 1856 device_map.insert(std::make_pair(devices[i], i)); 1857 instance.devices.emplace_back(VkJsonGetDevice(devices[i])); 1858 } 1859 1860 result = vkEnumerateInstanceVersion(&instance.api_version); 1861 if (result != VK_SUCCESS) { 1862 vkDestroyInstance(vkinstance, nullptr); 1863 return VkJsonInstance(); 1864 } 1865 1866 count = 0; 1867 result = vkEnumeratePhysicalDeviceGroups(vkinstance, &count, nullptr); 1868 if (result != VK_SUCCESS) { 1869 vkDestroyInstance(vkinstance, nullptr); 1870 return VkJsonInstance(); 1871 } 1872 1873 VkJsonDeviceGroup device_group; 1874 std::vector<VkPhysicalDeviceGroupProperties> group_properties; 1875 group_properties.resize(count); 1876 for (auto& properties : group_properties) { 1877 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES; 1878 properties.pNext = nullptr; 1879 } 1880 result = vkEnumeratePhysicalDeviceGroups(vkinstance, &count, 1881 group_properties.data()); 1882 if (result != VK_SUCCESS) { 1883 vkDestroyInstance(vkinstance, nullptr); 1884 return VkJsonInstance(); 1885 } 1886 for (auto properties : group_properties) { 1887 device_group.properties = properties; 1888 for (uint32_t i = 0; i < properties.physicalDeviceCount; ++i) { 1889 device_group.device_inds.push_back( 1890 device_map[properties.physicalDevices[i]]); 1891 } 1892 instance.device_groups.push_back(device_group); 1893 } 1894 1895 vkDestroyInstance(vkinstance, nullptr); 1896 return instance; 1897} 1898 1899\n""") 1900 1901 f.close() 1902 gencom.run_clang_format(genfile)