# Copyright (c) 2013-2018 The Khronos Group Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # 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 } ? | Vendorids * | Platforms * | Tags * | Types * | Enums * | Commands * | Feature * | Extensions * ) * } # defines a group of vendor IDs Vendorids = element vendorids { Comment ? , Vendorid * } # defines a single vendor ID. # name - author ID of the vendor # id - Khronos vendor ID (hexadecimal constant starting at 0x10000) # comment - unused Vendorid = element vendorid { attribute name { text } , attribute id { text } , Comment ? } # 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 # requires - name of another type definition required by this one # 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 don't change syntactic interpretation but allow organization in # the generated header. # comment - unused # 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. # 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's # 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) # noautovalidity - tag stating that no automatic validity language should be generated # values - comma-separated list of legal values, usually used only for sType enums # - containing arbitrary text (unused) # # *** There's a problem here: I'm 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 name { TypeName } ? , attribute category { text } ? , attribute parent { TypeName } ? , attribute returnedonly { text } ? , attribute structextends { text } ? , Comment ? , ( ( ( text , element type { text } * ) * , element apientry { text } ? , ( text , element type { text } * ) * , element name { TypeName } ? , ( text , element type { text } * ) * ) | ( element member { attribute len { text } ? , attribute altlen { text } ? , attribute externsync { text } ? , attribute optional { text } ? , attribute noautovalidity { text } ? , attribute values { 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. # start, end - beginning and end of a numeric range # vendor - owner of the numeric range # type - 'enum' or 'bitmask', if present # comment - unused Enums = element enums { attribute name { text } ? , attribute type { text } ? , attribute start { Integer } ? , attribute end { Integer } ? , Vendor ? , 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 - 'u' (unsigned), 'ull' (uint64), or integer if not present # name - enumerant name # alias - another enumerant this is semantically identical to # comment - unused 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 api { text } ? & attribute type { TypeSuffix } ? & attribute name { text } & Comment ? ) } # defines a range of enumerants not currently being used # start, end - beginning and end of an unused numeric range # vendor - unused # comment - unused 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. # # The first only has 'name' and 'alias' attributes, and no contents. # It defines a command alias. # # The second fully defines a command, and has the following structure: # The possible attributes are not described in this comment block yet, but # are in readme.pdf. # # 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's # 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) # noautovalidity - tag stating that no automatic validity language should be generated # is a name, if present # is the function / parameter name # 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 queues { text } ? , attribute successcodes { text } ? , attribute errorcodes { text } ? , attribute renderpass { text } ? , attribute cmdbufferlevel { text } ? , attribute pipeline { text } ? , Comment ? , element proto { mixed { element type { TypeName } ? , element name { text } } } , element param { attribute len { text } ? , attribute altlen { text } ? , attribute externsync { text } ? , attribute optional { text } ? , attribute noautovalidity { 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 # / contains features to require or remove in # this version # profile - only require/remove when generated profile matches # comment - unused Feature = element feature { attribute api { text } , Name , attribute number { xsd:float } , attribute protect { text } ? , Comment ? , ( element require { ProfileName ? , ExtensionName ? , Comment ? , ( InterfaceElement | element comment { text } ) * } | element remove { ProfileName ? , Comment ? , ( InterfaceElement | element comment { text } ) * } ) * } Extensions = element extensions { Comment ? , Extension * } # 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) # 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 - profile name(s) supporting this extension, e.g. 'vulkan' # or 'disabled' to never generate output. # 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 protect { text } ? , attribute platform { text } ? , attribute author { text } ? , attribute contact { text } ? , attribute type { text } ? , attribute requires { text } ? , attribute requiresCore { text } ? , attribute supported { StringGroup } ? , Comment ? , ( element require { attribute api { text } ? , ProfileName ? , ExtensionName ? , FeatureName ? , Comment ? , ( InterfaceElement | element comment { text } ) * } | element remove { attribute api { text } ? , ProfileName ? , Comment ? , ( InterfaceElement | element comment { 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 don't 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 } FeatureName = attribute feature { text } Vendor = attribute vendor { text } Comment = attribute comment { text } Name = attribute name { text }