Mercurial > games > semicongine
comparison fuhtark_test/Vulkan-Headers-1.4.334/registry/vkconventions.py @ 1501:f40d9d814c08 default tip main
did: correct vulkan-api generator
| author | sam <sam@basx.dev> |
|---|---|
| date | Wed, 26 Nov 2025 23:34:29 +0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1500:91c8c3b7cbf0 | 1501:f40d9d814c08 |
|---|---|
| 1 #!/usr/bin/env python3 -i | |
| 2 # | |
| 3 # Copyright 2013-2025 The Khronos Group Inc. | |
| 4 # | |
| 5 # SPDX-License-Identifier: Apache-2.0 | |
| 6 | |
| 7 # Working-group-specific style conventions, | |
| 8 # used in generation. | |
| 9 | |
| 10 import re | |
| 11 import os | |
| 12 | |
| 13 from spec_tools.conventions import ConventionsBase | |
| 14 | |
| 15 # Modified from default implementation - see category_requires_validation() below | |
| 16 CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask')) | |
| 17 | |
| 18 # Tokenize into "words" for structure types, approximately per spec "Implicit Valid Usage" section 2.7.2 | |
| 19 # This first set is for things we recognize explicitly as words, | |
| 20 # as exceptions to the general regex. | |
| 21 # Ideally these would be listed in the spec as exceptions, as OpenXR does. | |
| 22 SPECIAL_WORDS = set(( | |
| 23 '16Bit', # VkPhysicalDevice16BitStorageFeatures | |
| 24 '2D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT | |
| 25 '3D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT | |
| 26 '8Bit', # VkPhysicalDevice8BitStorageFeaturesKHR | |
| 27 'AABB', # VkGeometryAABBNV | |
| 28 'ASTC', # VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT | |
| 29 'D3D12', # VkD3D12FenceSubmitInfoKHR | |
| 30 'Float16', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR | |
| 31 'Bfloat16', # VkPhysicalDeviceShaderBfloat16FeaturesKHR | |
| 32 'Float8', # VkPhysicalDeviceShaderFloat8FeaturesEXT | |
| 33 'ImagePipe', # VkImagePipeSurfaceCreateInfoFUCHSIA | |
| 34 'Int64', # VkPhysicalDeviceShaderAtomicInt64FeaturesKHR | |
| 35 'Int8', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR | |
| 36 'MacOS', # VkMacOSSurfaceCreateInfoMVK | |
| 37 'RGBA10X6', # VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT | |
| 38 'Uint8', # VkPhysicalDeviceIndexTypeUint8FeaturesEXT | |
| 39 'Win32', # VkWin32SurfaceCreateInfoKHR | |
| 40 )) | |
| 41 # A regex to match any of the SPECIAL_WORDS | |
| 42 EXCEPTION_PATTERN = r'(?P<exception>{})'.format( | |
| 43 '|'.join(f'({re.escape(w)})' for w in SPECIAL_WORDS)) | |
| 44 MAIN_RE = re.compile( | |
| 45 # the negative lookahead is to prevent the all-caps pattern from being too greedy. | |
| 46 r'({}|([0-9]+)|([A-Z][a-z]+)|([A-Z][A-Z]*(?![a-z])))'.format(EXCEPTION_PATTERN)) | |
| 47 | |
| 48 | |
| 49 class VulkanConventions(ConventionsBase): | |
| 50 @property | |
| 51 def null(self): | |
| 52 """Preferred spelling of NULL.""" | |
| 53 return '`NULL`' | |
| 54 | |
| 55 def formatVersion(self, name, apivariant, major, minor): | |
| 56 """Mark up an API version name as a link in the spec.""" | |
| 57 version = f'{major}.{minor}' | |
| 58 if apivariant == 'VKSC': | |
| 59 # Vulkan SC has a different anchor pattern for version appendices | |
| 60 if version == '1.0': | |
| 61 return 'Vulkan SC 1.0' | |
| 62 else: | |
| 63 return f'<<versions-sc-{version}, Vulkan SC Version {version}>>' | |
| 64 else: | |
| 65 return f'<<versions-{version}, Vulkan Version {version}>>' | |
| 66 | |
| 67 def formatExtension(self, name): | |
| 68 """Mark up an extension name as a link in the spec.""" | |
| 69 return f'apiext:{name}' | |
| 70 | |
| 71 @property | |
| 72 def struct_macro(self): | |
| 73 """Get the appropriate format macro for a structure. | |
| 74 | |
| 75 Primarily affects generated valid usage statements. | |
| 76 """ | |
| 77 | |
| 78 return 'slink:' | |
| 79 | |
| 80 @property | |
| 81 def constFlagBits(self): | |
| 82 """Returns True if static const flag bits should be generated, False if an enumerated type should be generated.""" | |
| 83 return False | |
| 84 | |
| 85 @property | |
| 86 def structtype_member_name(self): | |
| 87 """Return name of the structure type member""" | |
| 88 return 'sType' | |
| 89 | |
| 90 @property | |
| 91 def nextpointer_member_name(self): | |
| 92 """Return name of the structure pointer chain member""" | |
| 93 return 'pNext' | |
| 94 | |
| 95 @property | |
| 96 def valid_pointer_prefix(self): | |
| 97 """Return prefix to pointers which must themselves be valid""" | |
| 98 return 'valid' | |
| 99 | |
| 100 def is_structure_type_member(self, paramtype, paramname): | |
| 101 """Determine if member type and name match the structure type member.""" | |
| 102 return paramtype == 'VkStructureType' and paramname == self.structtype_member_name | |
| 103 | |
| 104 def is_nextpointer_member(self, paramtype, paramname): | |
| 105 """Determine if member type and name match the next pointer chain member.""" | |
| 106 return paramtype == 'void' and paramname == self.nextpointer_member_name | |
| 107 | |
| 108 def generate_structure_type_from_name(self, structname): | |
| 109 """Generate a structure type name, like VK_STRUCTURE_TYPE_CREATE_INSTANCE_INFO""" | |
| 110 | |
| 111 structure_type_parts = [] | |
| 112 # Tokenize into "words" | |
| 113 for elem in MAIN_RE.findall(structname): | |
| 114 word = elem[0] | |
| 115 if word == 'Vk': | |
| 116 structure_type_parts.append('VK_STRUCTURE_TYPE') | |
| 117 else: | |
| 118 structure_type_parts.append(word.upper()) | |
| 119 name = '_'.join(structure_type_parts) | |
| 120 | |
| 121 # The simple-minded rules need modification for some structure names | |
| 122 subpats = [ | |
| 123 [ r'_H_(26[45])_', r'_H\1_' ], | |
| 124 [ r'_VP_9_', r'_VP9_' ], | |
| 125 [ r'_AV_1_', r'_AV1_' ], | |
| 126 [ r'_VULKAN_([0-9])([0-9])_', r'_VULKAN_\1_\2_' ], | |
| 127 [ r'_VULKAN_SC_([0-9])([0-9])_',r'_VULKAN_SC_\1_\2_' ], | |
| 128 [ r'_DIRECT_FB_', r'_DIRECTFB_' ], | |
| 129 [ r'_VULKAN_SC_10', r'_VULKAN_SC_1_0' ], | |
| 130 | |
| 131 ] | |
| 132 | |
| 133 for subpat in subpats: | |
| 134 name = re.sub(subpat[0], subpat[1], name) | |
| 135 return name | |
| 136 | |
| 137 @property | |
| 138 def warning_comment(self): | |
| 139 """Return warning comment to be placed in header of generated Asciidoctor files""" | |
| 140 return '// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry' | |
| 141 | |
| 142 @property | |
| 143 def file_suffix(self): | |
| 144 """Return suffix of generated Asciidoctor files""" | |
| 145 return '.adoc' | |
| 146 | |
| 147 def api_name(self, spectype='api'): | |
| 148 """Return API or specification name for citations in ref pages.ref | |
| 149 pages should link to for | |
| 150 | |
| 151 spectype is the spec this refpage is for: 'api' is the Vulkan API | |
| 152 Specification. Defaults to 'api'. If an unrecognized spectype is | |
| 153 given, returns None. | |
| 154 """ | |
| 155 if spectype == 'api' or spectype is None: | |
| 156 return 'Vulkan' | |
| 157 else: | |
| 158 return None | |
| 159 | |
| 160 @property | |
| 161 def api_prefix(self): | |
| 162 """Return API token prefix""" | |
| 163 return 'VK_' | |
| 164 | |
| 165 @property | |
| 166 def write_contacts(self): | |
| 167 """Return whether contact list should be written to extension appendices""" | |
| 168 return True | |
| 169 | |
| 170 @property | |
| 171 def write_refpage_include(self): | |
| 172 """Return whether refpage include should be written to extension appendices""" | |
| 173 return True | |
| 174 | |
| 175 @property | |
| 176 def member_used_for_unique_vuid(self): | |
| 177 """Return the member name used in the VUID-...-...-unique ID.""" | |
| 178 return self.structtype_member_name | |
| 179 | |
| 180 def is_externsync_command(self, protoname): | |
| 181 """Returns True if the protoname element is an API command requiring | |
| 182 external synchronization | |
| 183 """ | |
| 184 return protoname is not None and 'vkCmd' in protoname | |
| 185 | |
| 186 def is_api_name(self, name): | |
| 187 """Returns True if name is in the reserved API namespace. | |
| 188 For Vulkan, these are names with a case-insensitive 'vk' prefix, or | |
| 189 a 'PFN_vk' function pointer type prefix. | |
| 190 """ | |
| 191 return name[0:2].lower() == 'vk' or name.startswith('PFN_vk') | |
| 192 | |
| 193 def specURL(self, spectype='api'): | |
| 194 """Return public registry URL which ref pages should link to for the | |
| 195 current all-extensions HTML specification, so xrefs in the | |
| 196 asciidoc source that are not to ref pages can link into it | |
| 197 instead. N.b. this may need to change on a per-refpage basis if | |
| 198 there are multiple documents involved. | |
| 199 """ | |
| 200 return 'https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html' | |
| 201 | |
| 202 @property | |
| 203 def xml_api_name(self): | |
| 204 """Return the name used in the default API XML registry for the default API""" | |
| 205 return 'vulkan' | |
| 206 | |
| 207 @property | |
| 208 def registry_path(self): | |
| 209 """Return relpath to the default API XML registry in this project.""" | |
| 210 return 'xml/vk.xml' | |
| 211 | |
| 212 @property | |
| 213 def specification_path(self): | |
| 214 """Return relpath to the Asciidoctor specification sources in this project.""" | |
| 215 return '{generated}/meta' | |
| 216 | |
| 217 @property | |
| 218 def special_use_section_anchor(self): | |
| 219 """Return asciidoctor anchor name in the API Specification of the | |
| 220 section describing extension special uses in detail.""" | |
| 221 return 'extendingvulkan-compatibility-specialuse' | |
| 222 | |
| 223 @property | |
| 224 def extension_index_prefixes(self): | |
| 225 """Return a list of extension prefixes used to group extension refpages.""" | |
| 226 return ['VK_KHR', 'VK_EXT', 'VK'] | |
| 227 | |
| 228 @property | |
| 229 def unified_flag_refpages(self): | |
| 230 """Return True if Flags/FlagBits refpages are unified, False if | |
| 231 they are separate. | |
| 232 """ | |
| 233 return False | |
| 234 | |
| 235 @property | |
| 236 def spec_reflow_path(self): | |
| 237 """Return the path to the spec source folder to reflow""" | |
| 238 return os.getcwd() | |
| 239 | |
| 240 @property | |
| 241 def spec_no_reflow_dirs(self): | |
| 242 """Return a set of directories not to automatically descend into | |
| 243 when reflowing spec text | |
| 244 """ | |
| 245 return ('scripts', 'style') | |
| 246 | |
| 247 @property | |
| 248 def zero(self): | |
| 249 return '`0`' | |
| 250 | |
| 251 def category_requires_validation(self, category): | |
| 252 """Return True if the given type 'category' always requires validation. | |
| 253 | |
| 254 Overridden because Vulkan does not require "valid" text for basetype | |
| 255 in the spec right now.""" | |
| 256 return category in CATEGORIES_REQUIRING_VALIDATION | |
| 257 | |
| 258 @property | |
| 259 def should_skip_checking_codes(self): | |
| 260 """Return True if more than the basic validation of return codes should | |
| 261 be skipped for a command. | |
| 262 | |
| 263 Vulkan mostly relies on the validation layers rather than API | |
| 264 builtin error checking, so these checks are not appropriate. | |
| 265 | |
| 266 For example, passing in a VkFormat parameter will not potentially | |
| 267 generate a VK_ERROR_FORMAT_NOT_SUPPORTED code.""" | |
| 268 | |
| 269 return True | |
| 270 | |
| 271 def extension_file_path(self, name): | |
| 272 """Return file path to an extension appendix relative to a directory | |
| 273 containing all such appendices. | |
| 274 - name - extension name""" | |
| 275 | |
| 276 return f'{name}{self.file_suffix}' | |
| 277 | |
| 278 def valid_flag_bit(self, bitpos): | |
| 279 """Return True if bitpos is an allowed numeric bit position for | |
| 280 an API flag bit. | |
| 281 | |
| 282 Vulkan uses 32 bit Vk*Flags types, and assumes C compilers may | |
| 283 cause Vk*FlagBits values with bit 31 set to result in a 64 bit | |
| 284 enumerated type, so disallows such flags.""" | |
| 285 return bitpos >= 0 and bitpos < 31 | |
| 286 | |
| 287 @property | |
| 288 def extra_refpage_headers(self): | |
| 289 """Return any extra text to add to refpage headers.""" | |
| 290 return 'include::{config}/attribs.adoc[]' | |
| 291 | |
| 292 @property | |
| 293 def extra_refpage_body(self): | |
| 294 """Return any extra text (following the title) for generated | |
| 295 reference pages.""" | |
| 296 return 'include::{generated}/specattribs.adoc[]' | |
| 297 | |
| 298 | |
| 299 class VulkanSCConventions(VulkanConventions): | |
| 300 | |
| 301 def specURL(self, spectype='api'): | |
| 302 """Return public registry URL which ref pages should link to for the | |
| 303 current all-extensions HTML specification, so xrefs in the | |
| 304 asciidoc source that are not to ref pages can link into it | |
| 305 instead. N.b. this may need to change on a per-refpage basis if | |
| 306 there are multiple documents involved. | |
| 307 """ | |
| 308 return 'https://registry.khronos.org/vulkansc/specs/1.0-extensions/html/vkspec.html' | |
| 309 | |
| 310 @property | |
| 311 def xml_api_name(self): | |
| 312 """Return the name used in the default API XML registry for the default API""" | |
| 313 return 'vulkansc' | |
| 314 | |
| 315 class VulkanBaseConventions(VulkanConventions): | |
| 316 | |
| 317 def specURL(self, spectype='api'): | |
| 318 """Return public registry URL which ref pages should link to for the | |
| 319 current all-extensions HTML specification, so xrefs in the | |
| 320 asciidoc source that are not to ref pages can link into it | |
| 321 instead. N.b. this may need to change on a per-refpage basis if | |
| 322 there are multiple documents involved. | |
| 323 """ | |
| 324 return 'https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html' | |
| 325 | |
| 326 @property | |
| 327 def xml_api_name(self): | |
| 328 """Return the name used in the default API XML registry for the default API""" | |
| 329 return 'vulkanbase' | |
| 330 |
