• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3 -i
2#
3# Copyright 2023-2025 The Khronos Group Inc.
4#
5# SPDX-License-Identifier: Apache-2.0
6
7from dataclasses import dataclass, field
8from enum import IntFlag, Enum, auto
9
10@dataclass
11class Extension:
12    """<extension>"""
13    name: str # ex) VK_KHR_SURFACE
14    nameString: str # marco with string, ex) VK_KHR_SURFACE_EXTENSION_NAME
15    specVersion: str # marco with string, ex) VK_KHR_SURFACE_SPEC_VERSION
16
17    # Only one will be True, the other is False
18    instance: bool
19    device: bool
20
21    depends: (str | None)
22    vendorTag: (str | None)  # ex) EXT, KHR, etc
23    platform: (str | None)   # ex) android
24    protect: (str | None)    # ex) VK_USE_PLATFORM_ANDROID_KHR
25    provisional: bool
26    promotedTo: (str | None) # ex) VK_VERSION_1_1
27    deprecatedBy: (str | None)
28    obsoletedBy: (str | None)
29    specialUse: list[str]
30
31    # These are here to allow for easy reverse lookups
32    # Quotes allow us to forward declare the dataclass
33    commands: list['Command'] = field(default_factory=list, init=False)
34    enums:    list['Enum']    = field(default_factory=list, init=False)
35    bitmasks: list['Bitmask'] = field(default_factory=list, init=False)
36    # Use the Enum name to see what fields are extended
37    enumFields: dict[str, list['EnumField']] = field(default_factory=dict, init=False)
38    # Use the Bitmaks name to see what flags are extended
39    flags: dict[str, list['Flag']] = field(default_factory=dict, init=False)
40
41@dataclass
42class Version:
43    """
44    <feature> which represents a version
45    This will NEVER be Version 1.0, since having 'no version' is same as being 1.0
46    """
47    name: str       # ex) VK_VERSION_1_1
48    nameString: str # ex) "VK_VERSION_1_1" (no marco, so has quotes)
49    nameApi: str    # ex) VK_API_VERSION_1_1
50
51@dataclass
52class Handle:
53    """<type> which represents a dispatch handle"""
54    name: str # ex) VkBuffer
55    type: str # ex) VK_OBJECT_TYPE_BUFFER
56    protect: (str | None) # ex) VK_USE_PLATFORM_ANDROID_KHR
57
58    parent: 'Handle' # Chain of parent handles, can be None
59
60    # Only one will be True, the other is False
61    instance: bool
62    device: bool
63
64    dispatchable: bool
65
66    def __lt__(self, other):
67        return self.name < other.name
68
69@dataclass
70class Param:
71    """<command/param>"""
72    name: str
73    alias: str
74    type: str # ex) void, VkFormat, etc
75
76    noAutoValidity: bool
77
78    const: bool           # type contains 'const'
79    length:  (str | None) # the known length of pointer, will never be 'null-terminated'
80    nullTerminated: bool  # If a UTF-8 string, it will be null-terminated
81    pointer: bool         # type contains a pointer (include 'PFN' function pointers)
82    fixedSizeArray: list[str] # for VkTransformMatrixKHR:matrix this is [3, 4]
83
84    optional: bool
85    optionalPointer: bool # if type contains a pointer, is the pointer value optional
86
87    externSync: bool
88    externSyncPointer: list[str] # if type contains a pointer, might only specific members modified
89
90    # C string of member, example:
91    #   - const void* pNext
92    #   - VkFormat format
93    #   - VkStructureType sType
94    cDeclaration: str
95
96    def __lt__(self, other):
97        return self.name < other.name
98
99class Queues(IntFlag):
100    TRANSFER       = auto() # VK_QUEUE_TRANSFER_BIT
101    GRAPHICS       = auto() # VK_QUEUE_GRAPHICS_BIT
102    COMPUTE        = auto() # VK_QUEUE_COMPUTE_BIT
103    PROTECTED      = auto() # VK_QUEUE_PROTECTED_BIT
104    SPARSE_BINDING = auto() # VK_QUEUE_SPARSE_BINDING_BIT
105    OPTICAL_FLOW   = auto() # VK_QUEUE_OPTICAL_FLOW_BIT_NV
106    DECODE         = auto() # VK_QUEUE_VIDEO_DECODE_BIT_KHR
107    ENCODE         = auto() # VK_QUEUE_VIDEO_ENCODE_BIT_KHR
108    ALL = TRANSFER | GRAPHICS | COMPUTE | PROTECTED | SPARSE_BINDING | OPTICAL_FLOW | DECODE | ENCODE
109
110class CommandScope(Enum):
111    NONE    = auto()
112    INSIDE  = auto()
113    OUTSIDE = auto()
114    BOTH    = auto()
115
116@dataclass
117class Command:
118    """<command>"""
119    name: str # ex) vkCmdDraw
120    alias: str # Because commands are interfaces into layers/drivers, we need all command alias
121    protect: (str | None) # ex) 'VK_ENABLE_BETA_EXTENSIONS'
122
123    extensions: list[Extension] # All extensions that enable the struct
124    version: (Version | None) # None if Version 1.0
125
126    returnType: str # ex) void, VkResult, etc
127
128    params: list[Param] # Each parameter of the command
129
130    # Only one will be True, the other is False
131    instance: bool
132    device: bool
133
134    tasks: list[str]        # ex) [ action, state, synchronization ]
135    queues: Queues          # zero == No Queues found
136    successCodes: list[str] # ex) [ VK_SUCCESS, VK_INCOMPLETE ]
137    errorCodes: list[str]   # ex) [ VK_ERROR_OUT_OF_HOST_MEMORY ]
138
139    # Shows support if command can be in a primary and/or secondary command buffer
140    primary: bool
141    secondary: bool
142
143    renderPass: CommandScope
144    videoCoding: CommandScope
145
146    implicitExternSyncParams: list[str]
147
148    # C prototype string - ex:
149    # VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
150    #   const VkInstanceCreateInfo* pCreateInfo,
151    #   const VkAllocationCallbacks* pAllocator,
152    #   VkInstance* pInstance);
153    cPrototype: str
154
155    # function pointer typedef  - ex:
156    # typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)
157    #   (const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
158    cFunctionPointer: str
159
160    def __lt__(self, other):
161        return self.name < other.name
162
163@dataclass
164class Member:
165    """<member>"""
166    name: str # ex) sharingMode
167    type: str # ex) VkSharingMode
168
169    noAutoValidity: bool
170    limitType: (str | None) # ex) 'max', 'bitmask', 'bits', 'min,mul'
171
172    const: bool           # type contains 'const'
173    length:  (str | None) # the known length of pointer, will never be 'null-terminated'
174    nullTerminated: bool  # If a UTF-8 string, it will be null-terminated
175    pointer: bool         # type contains a pointer (include 'PFN' function pointers)
176    fixedSizeArray: list[str] # for VkTransformMatrixKHR:matrix this is [3, 4]
177
178    optional: bool
179    optionalPointer: bool # if type contains a pointer, is the pointer value optional
180
181    externSync: bool
182
183    # C string of member, example:
184    #   - const void* pNext
185    #   - VkFormat format
186    #   - VkStructureType sType
187    cDeclaration: str
188
189    def __lt__(self, other):
190        return self.name < other.name
191
192@dataclass
193class Struct:
194    """<type category="struct"> or <type category="union">"""
195    name: str # ex. VkBufferCreateInfo
196    extensions: list[Extension] # All extensions that enable the struct
197    version: (Version | None) # None if Version 1.0
198    protect: (str | None) # ex) VK_ENABLE_BETA_EXTENSIONS
199
200    members: list[Member]
201
202    union: bool # Unions are just a subset of a Structs
203    returnedOnly: bool
204
205    sType: (str | None) # ex) VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
206    allowDuplicate: bool # can have a pNext point to itself
207
208    # These use to be list['Struct'] but some circular loops occur and cause
209    # pydevd warnings and made debugging slow (30 seconds to index a Struct)
210    extends: list[str] # Struct names that this struct extends
211    extendedBy: list[str] # Struct names that can be extended by this struct
212
213    def __lt__(self, other):
214        return self.name < other.name
215
216@dataclass
217class EnumField:
218    """<enum> of type enum"""
219    name: str # ex) VK_DYNAMIC_STATE_SCISSOR
220    negative: bool # True if negative values are allowed (ex. VkResult)
221    protect: (str | None) # ex) VK_ENABLE_BETA_EXTENSIONS
222
223    # some fields are enabled from 2 extensions (ex) VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR)
224    extensions: list[Extension] # None if part of 1.0 core
225
226    def __lt__(self, other):
227        return self.name < other.name
228
229@dataclass
230class Enum:
231    """<enums> of type enum"""
232    name: str # ex) VkDynamicState
233    protect: (str | None) # ex) VK_ENABLE_BETA_EXTENSIONS
234
235    bitWidth: int # 32 or 64
236    returnedOnly: bool
237
238    fields: list[EnumField]
239
240    extensions: list[Extension] # None if part of 1.0 core
241    # Unique list of all extension that are involved in 'fields' (superset of 'extensions')
242    fieldExtensions: list[Extension]
243
244    def __lt__(self, other):
245        return self.name < other.name
246
247@dataclass
248class Flag:
249    """<enum> of type bitmask"""
250    name: str # ex) VK_ACCESS_2_SHADER_READ_BIT
251    protect: (str | None) # ex) VK_ENABLE_BETA_EXTENSIONS
252
253    value: int
254    multiBit: bool # if true, more than one bit is set (ex) VK_SHADER_STAGE_ALL_GRAPHICS)
255    zero: bool     # if true, the value is zero (ex) VK_PIPELINE_STAGE_NONE)
256
257    # some fields are enabled from 2 extensions (ex) VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT)
258    extensions: list[Extension] # None if part of 1.0 core
259
260    def __lt__(self, other):
261        return self.name < other.name
262
263@dataclass
264class Bitmask:
265    """<enums> of type bitmask"""
266    name: str     # ex) VkAccessFlagBits2
267    flagName: str # ex) VkAccessFlags2
268    protect: (str | None) # ex) VK_ENABLE_BETA_EXTENSIONS
269
270    bitWidth: int # 32 or 64
271    returnedOnly: bool
272
273    flags: list[Flag]
274
275    extensions: list[Extension] # None if part of 1.0 core
276    # Unique list of all extension that are involved in 'flag' (superset of 'extensions')
277    flagExtensions: list[Extension]
278
279    def __lt__(self, other):
280        return self.name < other.name
281
282@dataclass
283class FormatComponent:
284    """<format/component>"""
285    type: str # ex) R, G, B, A, D, S, etc
286    bits: str # will be an INT or 'compressed'
287    numericFormat: str # ex) UNORM, SINT, etc
288    planeIndex: (int | None) # None if no planeIndex in format
289
290@dataclass
291class FormatPlane:
292    """<format/plane>"""
293    index: int
294    widthDivisor: int
295    heightDivisor: int
296    compatible: str
297
298@dataclass
299class Format:
300    """<format>"""
301    name: str
302    className: str
303    blockSize: int
304    texelsPerBlock: int
305    blockExtent: list[str]
306    packed: (int | None) # None == not-packed
307    chroma: (str | None)
308    compressed: (str | None)
309    components: list[FormatComponent] # <format/component>
310    planes: list[FormatPlane]  # <format/plane>
311    spirvImageFormat: (str | None)
312
313@dataclass
314class SyncSupport:
315    """<syncsupport>"""
316    queues: Queues
317    stages: list[Flag] # VkPipelineStageFlagBits2
318    max: bool # If this supports max values
319
320@dataclass
321class SyncEquivalent:
322    """<syncequivalent>"""
323    stages: list[Flag] # VkPipelineStageFlagBits2
324    accesses: list[Flag] # VkAccessFlagBits2
325    max: bool # If this equivalent to everything
326
327@dataclass
328class SyncStage:
329    """<syncstage>"""
330    flag: Flag # VkPipelineStageFlagBits2
331    support: SyncSupport
332    equivalent: SyncEquivalent
333
334@dataclass
335class SyncAccess:
336    """<syncaccess>"""
337    flag: Flag # VkAccessFlagBits2
338    support: SyncSupport
339    equivalent: SyncEquivalent
340
341@dataclass
342class SyncPipelineStage:
343    """<syncpipelinestage>"""
344    order: (str | None)
345    before: (str | None)
346    after: (str | None)
347    value: str
348
349@dataclass
350class SyncPipeline:
351    """<syncpipeline>"""
352    name: str
353    depends: list[str]
354    stages: list[SyncPipelineStage]
355
356@dataclass
357class SpirvEnables:
358    """What is needed to enable the SPIR-V element"""
359    version: (str | None)
360    extension: (str | None)
361    struct: (str | None)
362    feature: (str | None)
363    requires: (str | None)
364    property: (str | None)
365    member: (str | None)
366    value: (str | None)
367
368@dataclass
369class Spirv:
370    """<spirvextension> and <spirvcapability>"""
371    name: str
372    # Only one will be True, the other is False
373    extension: bool
374    capability: bool
375    enable: list[SpirvEnables]
376
377# This is the global Vulkan Object that holds all the information from parsing the XML
378# This class is designed so all generator scripts can use this to obtain data
379@dataclass
380class VulkanObject():
381    headerVersion: int = 0 # value of VK_HEADER_VERSION
382
383    extensions: dict[str, Extension] = field(default_factory=dict, init=False)
384    versions:   dict[str, Version]   = field(default_factory=dict, init=False)
385
386    handles:  dict[str, Handle]      = field(default_factory=dict, init=False)
387    commands: dict[str, Command]     = field(default_factory=dict, init=False)
388    structs:  dict[str, Struct]      = field(default_factory=dict, init=False)
389    enums:    dict[str, Enum]        = field(default_factory=dict, init=False)
390    bitmasks: dict[str, Bitmask]     = field(default_factory=dict, init=False)
391    formats:  dict[str, Format]      = field(default_factory=dict, init=False)
392
393    syncStage:    list[SyncStage]    = field(default_factory=list, init=False)
394    syncAccess:   list[SyncAccess]   = field(default_factory=list, init=False)
395    syncPipeline: list[SyncPipeline] = field(default_factory=list, init=False)
396
397    spirv: list[Spirv]               = field(default_factory=list, init=False)
398
399    # ex) [ xlib : VK_USE_PLATFORM_XLIB_KHR ]
400    platforms: dict[str, str]        = field(default_factory=dict, init=False)
401    # list of all vendor Suffix names (KHR, EXT, etc. )
402    vendorTags: list[str]            = field(default_factory=list, init=False)
403    # ex) [ Queues.COMPUTE : VK_QUEUE_COMPUTE_BIT ]
404    queueBits: dict[IntFlag, str]    = field(default_factory=dict, init=False)
405