# Copyright 2013-2023 The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # Relax NG schema for Khronos Vulkan API Registry XML # # See https://www.khronos.org/vulkan/ # # This definition is subject to change (mostly in the form of additions) namespace xsd = "http://www.w3.org/2001/XMLSchema-datatypes" # Toplevel is a tag. # May be led by an optional tag containing e.g. copyrights. start = element registry { ( element comment { text } ? | Platforms * | Tags * | Types * | Enums * | Commands * | Feature * | Extensions * | Formats * | Sync * | SpirvExtensions * | SpirvCapabilities * ) * } # defines a group of platform names Platforms = element platforms { Comment ? , Platform * } # defines a single platform name. # name - string name of the platform, used as part of extension names # protect - preprocessor symbol to include platform headers from # comment - platform description Platform = element platform { attribute name { text } , attribute protect { text } , Comment } # defines a group of author tags Tags = element tags { Comment ? , Tag * } # defines a single author tag. # name - name of the tag # author - name of the author (usually a company or project name) # contact - contact responsible for the tag (name and contact information) Tag = element tag { attribute name { text } , attribute author { text } , attribute contact { text } } # defines a group of types Types = element types { Comment ? , ( Type | element comment { text } ) * } # defines a single type. It is usually a C typedef but # may contain arbitrary C code. # name - name of this type, if not present in the tag # api - matches a api attribute, if present # alias - name of a type this type aliases # requires - name of another type definition required by this one # bitvalues - for a *Flags type, name of an enum definition that # defines the valid values for parameters of that type # name - name of the type being defined # category - if present, 'enum' indicates a matching # block to generate an enumerated type for, and 'struct' # causes special interpretation of the contents of the type # tag including ... TBD ... # Other allowed values are 'include', 'define', 'handle' and 'bitmask', # which do not change syntactic interpretation but allow organization # in the generated header. # deprecated - denotes that this type is deprecated, and why. # Valid values: 'aliased', 'true'. # parent - only applicable if category is 'handle'. Notes another type with # the 'handle' category that acts as a parent object for this type. # returnedonly - only applicable if category is 'struct'. Notes that this # struct is going to be filled in by the API, rather than an application # filling it out and passing it to the API. # structextends - only applicable if category is 'struct'. Lists parent # structures which this structure may extend via the pNext chain # of the parent. # When present it suppresses generation of automatic validity for the # pNext member of that structure, and instead the structure is added # to pNext chain validity for the parent structures it extends. # allowduplicate - only applicable if category is 'struct'. pNext can include # multiple structures of this type. # objtypeenum - name of VK_OBJECT_TYPE_* API enumerant which corresponds # to this type. Currently only specified for category="handle" types. # comment - descriptive text with no semantic meaning # For types without a category, contents include # - substitutes for an APIENTRY-style macro on output # - contains name of the type being defined # - contains name of types used to define this type. There # may be multiple imbedded tags # For types with category 'enum', contents should be empty # For types with category 'struct', contents should be one or more # - like for a struct or union member # len - if the member is an array, len may be one or more of the following # things, separated by commas (one for each array indirection): # another member of that struct, 'null-terminated' for a string, # '1' to indicate it is just a pointer (used for nested pointers), # or a latex equation (prefixed with 'latexmath:') # altlen - if len has latexmath equations, this contains equivalent C99 # expressions separated by commas. # deprecated - denotes that this member is deprecated, and why. # Valid values: 'ignored', 'true'. # externsync - denotes that the member should be externally synchronized # when accessed by Vulkan # optional - whether this value can be omitted by providing NULL (for # pointers), VK_NULL_HANDLE (for handles) or 0 (for bitmasks/values) # selector - for a union member, identifies a separate enum member that # selects which of the union's members are valid # selection - for a member of a union, identifies an enum value indicating the member is valid # noautovalidity - tag stating that no automatic validity language should be generated # values - comma-separated list of legal values, usually used only for sType enums # limittype - only applicable for members of VkPhysicalDeviceProperties and # VkPhysicalDeviceProperties2, their substructures, and extensions. # Specifies the type of a device limit. # Valid values: 'min', 'max', 'pot', 'mul', 'bits', bitmask', 'range', 'struct', 'exact', 'noauto' # objecttype - only applicable for members representing a handle as # a uint64_t value. Specifies the name of another member which is # a VkObjectType or VkDebugReportObjectTypeEXT value specifying # the type of object the handle references. # - containing arbitrary text (unused) # # *** There is a problem here: I am not sure how to represent the # syntax where it may contain arbitrarily interleaved text, , and # child tags. This allows only the syntax # text name text name text # where and are both optional and occur in the specified # order, which might eventually be a problem. Type = element type { attribute api { text } ? , attribute alias { text } ? , attribute requires { text } ? , attribute bitvalues { text } ? , attribute name { TypeName } ? , attribute category { text } ? , attribute deprecated { text } ? , attribute parent { TypeName } ? , attribute returnedonly { text } ? , attribute structextends { text } ? , attribute allowduplicate { text } ? , attribute objtypeenum { text } ? , Comment ? , ( ( ( text , element type { text } * ) * , element apientry { text } ? , ( text , element type { text } * ) * , element name { TypeName } ? , ( text , element type { text } * ) * ) | ( element member { attribute api { text } ? , attribute len { text } ? , attribute altlen { text } ? , attribute externsync { text } ? , attribute optional { text } ? , attribute selector { text } ? , attribute selection { EnumName } ? , attribute noautovalidity { text } ? , attribute values { text } ? , attribute limittype { text } ? , attribute objecttype { text } ? , attribute deprecated { text } ? , mixed { element type { TypeName } ? , element name { text } ? , element enum { EnumName } ? , element comment { text } ? } + } | element comment { text } ) * ) } # defines a group of enumerants # name - identifies a type name associated with this group. Should # match a name to trigger generation of the type. # type - 'enum' or 'bitmask', if present # bitwidth - bit width of the enum value type. # comment - descriptive text with no semantic meaning Enums = element enums { attribute name { text } ? , attribute type { text } ? , attribute bitwidth { Integer } ? , Comment ? , ( Enum | Unused | element comment { text} ) * } # defines or references a single enumerant. There are two places it # can be used: in an block, providing a global definition which # may later be required by a feature or extension; or in a feature or # extension, defining an enumerant specific to that feature. The second # form has more possible attributes. Some combinations of attributes are # nonsensical in on or the other place, but these are not detected by the # validator. # # Ways to specify the enumerant value: # value - integer (including hex) value of the enumerant # bitpos - integer bit position of the enumerant in a bitmask # [extnumber], offset, [dir] - integer extension number specifying a # base block value (inherited from surrounding if # not specified); integer offset in that block; and direction # of offset ('-' for negative, positive if not specified). # alias - name of another enum this is an alias of # # value and bitpos allow, and extnumber/offset/dir require: # extends - type name of the enumerant being extended # # Other attributes: # api - matches a api attribute, if present # type - 'uint32_t', 'uint64_t', or 'float', if present. There are # certain conditions under which the tag must be present, or absent, # but they are context-dependent and difficult to express in the # RNC syntax. # name - enumerant name # alias - another enumerant this is semantically identical to # protect - additional #ifdef symbol to place around the enum # comment - descriptive text with no semantic meaning # deprecated - denotes that this enum is deprecated, and why. # Valid values: 'aliased', 'ignored', 'true'. Enum = element enum { ( ( ( attribute value { Integer } & attribute extends { TypeName } ? ) | ( attribute bitpos { Integer } & attribute extends { TypeName } ? ) | ( attribute extnumber { Integer } ? & attribute offset { Integer } & attribute dir { text } ? & attribute extends { TypeName } ) | ( attribute extends { TypeName } ? & attribute alias { TypeName } ) ) ? & attribute protect { text } ? & attribute api { text } ? & attribute type { TypeSuffix } ? & attribute name { text } & attribute deprecated { text } ? & Comment ? ) } # defines a range of enumerants not currently being used # start, end - beginning and end of an unused numeric range # vendor - unused # comment - descriptive text with no semantic meaning Unused = element unused { attribute start { Integer } , attribute end { Integer } ? , Vendor ? , Comment ? } # defines a group of commands Commands = element commands { Comment ? , Command * } # defines a single command # # There are two forms of the tag. # # Either form may have an 'api' attribute # api - matches a api attribute, if present # # The first form only has 'name' and 'alias' attributes, and no contents. # It defines a command alias. # # The second form fully defines a command, and has the following structure: # The possible attributes are not described in this comment block yet, but # are in registry.html. The "prefix" and "suffix" attributes are currently # present only in the OpenCL XML registry, where they are currently unused. # # is the C function prototype, including the return type # are function parameters, in order # len - if the member is an array, len may be one or more of the following # things, separated by commas (one for each array indirection): # another member of that struct, 'null-terminated' for a string, # '1' to indicate it is just a pointer (used for nested pointers), # or a latex equation (prefixed with 'latexmath:') # altlen - if len has latexmath equations, this contains equivalent C99 # expressions separated by commas. # externsync - denotes that the member should be externally synchronized # when accessed by Vulkan # optional - whether this value can be omitted by providing NULL (for # pointers), VK_NULL_HANDLE (for handles) or 0 (for bitmasks/values) # selector - for a union parameter, identifies a separate enum parameter that # selects which of the union's members are valid # noautovalidity - tag stating that no automatic validity language should be # generated # objecttype - only applicable for parameters representing a handle as # a uint64_t value. Specifies the name of another parameter which is # a VkObjectType or VkDebugReportObjectTypeEXT value specifying # the type of object the handle references. # validstructs - only applicable for parameters which are pointers to # VkBaseInStructure or VkBaseOutStructure types, used as abstract # placeholders. Specifies a comma-separated list of structures which # may be passed in place of the parameter, or anywhere in the pNext # chain of the parameter. # stride - if the member is an array, stride specifies the name of # another member containing the byte stride between consecutive # elements in the array. Is assumed tightly packed if omitted. # is a name, if present # is the function / parameter name, if present (normally should # be, except for void parameters). # The textual contents of and should be legal C # for those parts of a function declaration. # - denotes function aliasing, if present # name - name of aliased function # - unused text # are spec-language descriptions of # objects that are not parameters of the command, but # are related to them and also require external synchronization. Command = element command { ( attribute name { text } , attribute alias { text } , attribute api { text } ? ) | ( attribute tasks { text } ? , attribute queues { text } ? , attribute successcodes { text } ? , attribute errorcodes { text } ? , attribute renderpass { text } ? , attribute videocoding { text } ? , attribute cmdbufferlevel { text } ? , attribute prefix { text } ? , attribute suffix { text } ? , attribute api { text } ? , Comment ? , element proto { mixed { element type { TypeName } ? , element name { text } } } , element param { attribute api { text } ? , attribute len { text } ? , attribute altlen { text } ? , attribute externsync { text } ? , attribute optional { text } ? , attribute selector { text } ? , attribute noautovalidity { text } ? , attribute objecttype { text } ? , attribute validstructs { text } ? , attribute stride { text } ? , mixed { element type { TypeName } ? , element name { text } ? } } * , ( element alias { Name } ? & element description { text } ? & element implicitexternsyncparams { element param { text } * } ? ) ) } # Each defines the interface of an API version (e.g. OpenGL 1.2) # api - API tag (e.g. 'gl', 'gles2', etc. - used internally, not # necessarily an actual API name # name - version name (C preprocessor name, e.g. GL_VERSION_4_2) # number - version number, e.g. 4.2 # protect - additional #ifdef symbol to place around the feature # sortorder - order relative to other features, default 0 # / contains features to require or remove in # this version # profile - only require/remove when generated profile matches # comment - descriptive text with no semantic meaning Feature = element feature { attribute api { text } , Name , attribute number { xsd:float } , attribute protect { text } ? , attribute sortorder { xsd:integer } ?, Comment ? , ( element require { ProfileName ? , Depends ? , Comment ? , ( InterfaceElement | element comment { text } ) * } | element remove { ProfileName ? , Comment ? , ( InterfaceElement | element comment { text } ) * } ) * } Extensions = element extensions { Comment ? , Extension * } # Each defines the interface of an API . # Like a tag, but with slightly different attributes: # api - regexp pattern matching one or more API tags, indicating # which APIs the extension is known to work with. The only # syntax supported is {|}* and each name must # exactly match an API being generated (implicit ^$ surrounding). # name - extension name string # number - extension number (positive integer, should be unique) # sortorder - order relative to other extensions, default 0 # protect - C preprocessor symbol to conditionally define the interface # platform - should be one of the platform names defined in the # tag. Currently unused. # author - name of the author (usually a company or project name) # contact - contact responsible for the tag (name and contact information) # type - 'device' or 'instance', if present # requires - commas-separated list of extension names required by this # extension # requiresCore - core version of Vulkan required by the extension, e.g. # "1.1". Defaults to "1.0". # supported - comma-separated list of API name(s) supporting this extension, # e.g. 'vulkan', or 'disabled' to never generate output. # ratified - comma-separated list of API name(s) for which this extension # has been ratified by Khronos. Defaults to "" if not specified. # promotedto - Vulkan version or a name of an extension that this # extension was promoted to; e.g. 'VK_VERSION_1_1', or # 'VK_KHR_draw_indirect_county' # deprecatedby - Vulkan version or a name of an extension that deprecates # this extension. It may be empty string. # e.g. 'VK_VERSION_1_1', or 'VK_EXT_debug_utils', or '' # obsoletedby - Vulkan version or a name of an extension that obsoletes # this extension. It may be empty string. # e.g. 'VK_VERSION_1_1', or 'VK_EXT_debug_utils', or '' # provisional - 'true' if this extension is released provisionally # specialuse - contains one or more tokens separated by commas, indicating # a special purpose of the extension. Tokens may include 'cadsupport', # 'd3demulation', 'devtools', 'debugging', and 'glemulation'. Others # may be added in the future. # In addition, / tags also support an api attribute: # api - only require/remove these features for the matching API. # Not a regular expression. Extension = element extension { Name , attribute number { Integer } ? , attribute sortorder { xsd:integer } ?, attribute protect { text } ? , attribute platform { text } ? , attribute author { text } ? , attribute contact { text } ? , attribute type { text } ? , attribute depends { text } ?, attribute supported { StringGroup } ? , attribute ratified { text } ? , attribute promotedto { text } ? , attribute deprecatedby { text } ? , attribute obsoletedby { text } ? , attribute provisional { text } ? , attribute specialuse { text } ? , Comment ? , ( element require { attribute api { text } ? , ProfileName ? , Depends ? , Comment ? , ( InterfaceElement | element comment { text } ) * } | element remove { attribute api { text } ? , ProfileName ? , Comment ? , ( InterfaceElement | element comment { text } ) * } ) * } # Each define information about a VkFormat in a machine readable format Formats = element formats { Format * } # name - Format name, matching a VkFormat enum name # class - Used for 'Compatible Formats' table # blockSize - Used for 'Compatible Formats' table # texelsPerBlock - Used for 'Compatible Formats' table # blockExtent - 3D extent, no attribute is same as blockExtent=1,1,1 # packed - number of bits data type # compressed - compression format class # planes - number of planes, no attribute is same as planes=1 # chroma - can be one of [420, 422, 444] and used to mark if YCbCr Sampler are required by default Format = element format { Name , attribute class { text } , attribute blockSize { text } , attribute texelsPerBlock { text } , attribute blockExtent { text } ? , attribute packed { text } ? , attribute compressed { text } ? , attribute chroma { text } ? , Component + , Plane * , SpirvImageFormat * } # bits - size of component or "compressed" if part of block-compression format # numericFormat - as per Interpretation of Numeric Format table # some formats (depth/stencil) will have different numeric per component # planeIndex - For multi-planar formats to map to the plane element Component = element component { Name , attribute bits { text } , attribute numericFormat { text }, attribute planeIndex { text } ? } # For multi-planar formats Plane = element plane { attribute index { text } , attribute widthDivisor { text } , attribute heightDivisor { text } , attribute compatible { text } } # labels a SPIR-V Image Format SpirvImageFormat = element spirvimageformat { Name } # is a set of all sync objects Sync = element sync { Comment ? , SyncStage *, SyncAccess *, SyncPipeline * } SyncSupport = element syncsupport { attribute queues { text } ? , attribute stage { text } ? } SyncEquivalent = element syncequivalent { attribute stage { text } ?, attribute access { text } ? } # describes all Pipeline Stages SyncStage = element syncstage { Name , attribute alias { text } ? , SyncSupport ? , SyncEquivalent ? } # describes all Access Flags SyncAccess = element syncaccess { element comment { text } ?, Name , attribute alias { text } ? , SyncSupport ? , SyncEquivalent ? } SyncPipelineStage = element syncpipelinestage { attribute order { text } ? , attribute before { text } ? , attribute after { text } ?, text } # describes pipelines SyncPipeline = element syncpipeline { Name , attribute depends { text } ? , SyncPipelineStage * } # Each define a SPIR-V extension that can be used in the API. # Each define a SPIR-V capability that can be used in the API. # Contains information to both generate table in spec as well as validating # what needs to be enabled or supported to be used in Vulkan SpirvExtensions = element spirvextensions { Comment ? , SpirvExtension * } SpirvExtension = element spirvextension { Name , Enable + } SpirvCapabilities = element spirvcapabilities { Comment ? , SpirvCapability * } SpirvCapability = element spirvcapability { Name , Enable + } # defines a way to enable the parent element in the API. # If anyone of the elements are valid then the parent element # can be used. # # There are four forms of the tag. # # The first only has the minimal version of Vulkan of the application # # The second only has a single Vulkan extension that must be enabled # # The third has a single Vulkan feature with the struct where it is from # # The fourth has a property struct, the member field in it, and the value # that must be present # # To make scripting easier, each has a require attribute to map # to the asciidoctor conditional logic in the spec. For version and # extension attribute variations, there is no need for the require attribute # since it is a redundant 1:1 mapping. # # The 'alias' attribute is used in cases where the anchor link cannot be # properly resolved and needs a manual name to link to Enable = element enable { ( attribute version { text } ) | ( attribute extension { text } ) | ( attribute struct { text }, attribute feature { text }, attribute requires { text }, attribute alias { text } ? ) | ( attribute property { text }, attribute member { text }, attribute value { text }, attribute requires { text } ? ) } # Contents of a / tag, defining a group # of features to require or remove. # / / all have attributes # name - feature name which must match InterfaceElement = element type { Name , Comment ? } | Enum | element command { Name , Comment ? } # Integers are allowed to be either decimal or C-hex (0x[0-9A-F]+), but # XML Schema types do not seem to support hex notation, so we use this # as a placeholder. Integer = text # EnumName is an compile-time constant name EnumName = text # TypeName is an argument/return value C type name TypeName = text # TypeSuffix is a C numeric type suffix, e.g. 'u' or 'ull' TypeSuffix = text # StringGroup is a regular expression with an implicit # '^(' and ')$' bracketing it. StringGroup = text # Repeatedly used attributes ProfileName = attribute profile { text } ExtensionName = attribute extension { text } # Boolean expression of core version and extension names using (),+ operators Depends = attribute depends { text } Vendor = attribute vendor { text } Comment = attribute comment { text } Name = attribute name { text }