# Vulkan® Documentation and Extensions: Procedures and Conventions

Jon Leech, Tobias Hector
version 1.0.39, Sun, 29 Jan 2017 22:42:53 +0000
from git branch: makepkg commit: ca4abe0d34ca8ed8410c65c177f8658da183576d

Copyright (c) 2014-2017 Khronos Group. This work is licensed under a Creative Commons Attribution 4.0 International License.

## 1. Introduction

This document contains required procedures and conventions when writing specifications for new Vulkan APIs, extensions and layers, or related Khronos documentation such as white papers and tutorials; or contributing to existing Vulkan specifications. These are collectively referred to as Vulkan Documentation or just documentation below. The primary focus is the API Specification and API extensions, although all of the markup and most of the writing style is equally applicable to other documentation.

The primary purpose is to achieve consistency across the API, as well as across all of our source and output documents. Consistency makes it easier for developers, editors, reviewers, and users of our documentation to understand and modify it.

This document is now formally voted on and approved by the Vulkan Working Group. This means that unless explicitly stated otherwise, the procedures and conventions must be followed If you have a strong desire to modify the procedures and conventions, such changes must be made through the normal Vulkan Working Group processes.

### 1.1. Terminology

The key words must, must not, required, shall, shall not, should, should not, recommend, may, and optional in this document are to be interpreted as described in RFC 2119 and by the Vulkan 1.0 Specification in the “Terminology” section.

### 1.2. Document Structure

The style guide is broken into four sections:

- API Naming Conventions - the required rules for choosing names of Vulkan identifiers of all types.

- Extensions and Layers - the required procedures for creating formal Vulkan extensions and layers.

- Markup Style - the required and recommended markup style for writing asciidoc and XML source that follows consistent formatting and layout guidelines, tags special terms and phrases for proper processing by the spec generation tools, etc.

- Writing Style - the required and recommended writing style for overall and fine-grained structure and conventions, normative language use, API naming conventions, common words and phrases to use and to avoid, linking and cross-referencing, etc.

### 1.3. Asciidoc Markup

Vulkan Documentation is primarily written in Asciidoc, a form of text markup language. Asciidoc is documented on its website at http://www.asciidoc.org/.

References to the Asciidoc User Guide are to sections in the document at http://asciidoc.org/userguide.html .

Asciidoc packages are available for Linux, MacOS, and Microsoft Windows, together with the other toolchain components required to generate output documents corresponding to the markup.

Note | Note We are currently using the original asciidoc tool. Other tools to process Asciidoc markup, such as asciidoctor, are also available, but are not currently usable for our documents. While asciidoctor supports the basic Asciidoc markup syntax, it does not support asciidoc macros, which are used extensively in the documentation. We expect to transition from asciidoc to asciidoctor eventually. There may be minor effects on markup and if so, we will document them at the time of the transition.

The asciidoc toolchain and build process are not addressed by this document, which concentrates solely on source documents.

### 1.4. Normative References

Normative references are references to external documents or resources to which documentation authors must comply.

International Organization for Standardization, Data elements and interchange formats — Information interchange — Representation of dates and times, http://www.iso.org/iso/catalogue_detail?csnumber=40874, 2004-12-01. Also see https://www.w3.org/QA/Tips/iso-date for colloquial examples.

Khronos Vulkan Working Group, KhronosGroup/Vulkan-Docs project on GitHub, https://github.com/KhronosGroup/Vulkan-Docs, 2016-07-05.

Vulkan Working Group, Vulkan 1.0.27 - A Specification, https://www.khronos.org/registry/vulkan/, 2016-09-16

Version 1.0.27 is the latest patch release of the Vulkan API Specification as of the time this reference was created, but that Specification is frequently updated with minor bugfixes and clarifications. When a more recent patch release is made, it becomes the normative reference for the API.

## 2. API Naming Conventions

Identifiers in the Vulkan API (e.g. types, parameters, constants, etc.) all follow a set of naming rules, providing a consistent scheme for developers.

The Vulkan C API uses prefixes as an implicit namespace control mechanism. Bindings to other languages can choose not to use these prefixes if the language provides an explicit namespace mechanism.

### 2.1. General Naming Rules

Names of identifiers should generally be written with full words, avoiding abbreviations, as a concise description of what that identifier is. For example, the type of a structure containing information about how to create an instance is `VkInstanceCreateInfo`.

Abbreviations and prefixes are sometimes used in the API when they are in common use. All abbreviations and prefixes used in the API must be approved by the Vulkan working group, and be added to the Common Abbreviations and Standard Prefixes sections, respectively.

Whenever an abbreviation exists for a particular word, it should be used in place of the full word unless there is good reason not to.

### 2.2. Preprocessor Defines

Preprocessor definitions include an underscore _ as a delimiter between words, with every character in upper case.

Each definition is prefixed with VK_, followed by the name.

This rule applies to most declarations with the C Preprocessor’s #define token, including macros and constants. There are however a few exceptions:

- The header guard for each header includes an additional underscore _ at the end of the identifier.

  - Example: VULKAN_H_

- Definitions that denote the presence of an extension follow the extension name string convention.

  - Example: VK_KHR_sampler_mirror_clamp_to_edge

- Three VKAPI_* definitions are defined by the platform header to alias certain platform-specific identifiers related to calling conventions.

  - Examples: VKAPI_ATTR, VKAPI_CALL and VKAPI_PTR

- Preprocessor defines are occasionally used to create aliases between other Vulkan identifiers, which usually happens when something was originally misnamed. In these cases, the fixed name is added to the API, and the old name is made into an alias of that. In these cases, the name will be whatever the original misnamed identifier was.

Example

    // VK_VERSION_MAJOR (Macro)
    #define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)

    // VK_HEADER_VERSION (Base type)
    #define VK_HEADER_VERSION 10

### 2.3. Type Names

Type names are declared with no separator between words. Each word starts with a capital letter, and every other character in each word is lower case.

Each type name is prefixed with Vk.

This rule applies to all type definitions except function pointer types, including struct and union types, handles, base typedefs, and enumerant types.

Example

    // VkImage (Handle)
    VK_NONDISP_HANDLE(VkImage)

    // VkFlags (Base type)
    typedef uint32_t VkFlags;

    // VkResult (Enum type)
    typedef enum VkResult {
        ...
    };

    // VkApplicationInfo (Struct)
    typedef struct VkApplicationInfo {
        ...
    } VkApplicationInfo;

    // VkClearColorValue (Union)
    typedef union VkClearColorValue {
        ...
    } VkClearColorValue;

### 2.4. Enumerant Names

Enumerants include an underscore _ as a delimiter between words, with every character in upper case.

Each enumerant name is prefixed with VK_.

Enumerants are prefixed with the exact name of the type it belongs to, converted to the correct case (e.g. VkStructureType → VK_STRUCTURE_TYPE_APPLICATION_INFO).

This rule applies to all enumerants, with one exception.

- The "VkResult" enumerants are split into two sub types: error and success codes.

  - Success codes are not prefixed with anything other than VK_.

  - Error codes are prefixed with VK_ERROR_.

Example

    // VK_FORMAT_UNDEFINED, VK_FORMAT_R4G4_UNORM_PACK8 (Enumerants)
    typedef enum VkFormat {
        VK_FORMAT_UNDEFINED = 0,
        VK_FORMAT_R4G4_UNORM_PACK8 = 1,
        ...
    };

    // VkResult codes (Exception)
    typedef enum VkResult {
        VK_SUCCESS = 0,
        ...
        VK_ERROR_OUT_OF_HOST_MEMORY = -1,
        ...
    } VkResult;

### 2.5. Function Names

Function names are declared with no separator between words. Each word starts with a capital letter, and every other character in each word is lower case.

Function names are prefixed with vk, with the exception of functions that record commands into a command buffer and are instead prefixed with vkCmd.

This rule applies to all function declarations.

Example

    // Function call
    VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( ... );

    // Command buffer function
    VKAPI_ATTR VkResult VKAPI_CALL vkCmdBindPipeline( ... );

#### 2.5.1. Function Pointer Type Names

Function pointer names are declared exactly as the equivalent statically declared function would be declared, but prefixed with PFN_, standing for "Pointer to FunctioN".

Example

    // PFN_vkCreateInstance (Function Pointer)
    typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)( ... );

### 2.6. Function Parameter and Struct/Union Member Names

Function parameter names are declared with no separator between words. Each new word, except for the first, starts with a capital letter. All other characters in the parameter name are in lower case.

Members/parameters of a type that is not a base type should generally be named in a similar way to the type itself, with additional context added for clarity when necessary.

Pointer members/parameters are prefixed with a number of p characters, with one p for each level of indirection.

Function pointer members/parameters are prefixed with pfn.

Any member that describes the size of a memory allocation should be suffixed with Size. If the context is self-evident from the structure name, then it may simply be named size.

Any member that describes the number of something, such as an array length or number of internal allocations, should be suffixed with Count. The size rule overrides this rule, though it is possible to have multiple sizes (e.g. sizeCount). If the member is an array length, then the name of length should correspond to the name of the array member, usually XYZCount for an array named pXYZs. If a member of a chained extension structure is an array whose length must match the length of an array of the base structure, then the chained extension structure should include an array length member with the same name as the length in the base structure.

These rules apply to all function parameters and struct/union members, with a single exception:

- The sType member of structures is abbreviated as it is used in almost every structure.

  - The slightly odd naming prevents it clashing with any future variables.

  - The s stands for "structure", referring to its enumerant type.

Example

    // Function parameters, including a twice indirected pointer.
    VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(
        VkDevice                                    device,
        VkDeviceMemory                              memory,
        VkDeviceSize                                offset,
        VkDeviceSize                                size,
        VkMemoryMapFlags                            flags,
        void**                                      ppData);

    // Structure members, including the sType exception and a single indirected
    // pointer.
    typedef struct VkMemoryBarrier {
        VkStructureType    sType;
        const void*        pNext;
        VkAccessFlags      srcAccessMask;
        VkAccessFlags      dstAccessMask;
    } VkMemoryBarrier;

    // Function pointer members
    typedef struct VkAllocationCallbacks {
        void*                                   pUserData;
        PFN_vkAllocationFunction                pfnAllocation;
        PFN_vkReallocationFunction              pfnReallocation;
        PFN_vkFreeFunction                      pfnFree;
        PFN_vkInternalAllocationNotification    pfnInternalAllocation;
        PFN_vkInternalFreeNotification          pfnInternalFree;
    } VkAllocationCallbacks;

    // Size member (pCode is not a specific array of anything, it is just a
    // pointer to memory)
    typedef struct VkShaderModuleCreateInfo {
        VkStructureType              sType;
        const void*                  pNext;
        VkShaderModuleCreateFlags    flags;
        size_t                       codeSize;
        const uint32_t*              pCode;
    } VkShaderModuleCreateInfo;

    // Count member
    typedef struct VkSparseImageMemoryBindInfo {
        VkImage                           image;
        uint32_t                          bindCount;
        const VkSparseImageMemoryBind*    pBinds;
    } VkSparseImageMemoryBindInfo;

### 2.7. Extension Identifier Naming Conventions

Identifiers defined by an extension are modified by appending the extension’s author ID to the end of the identifier, as described below. Author IDs are obtained as described in the Extension and Layer Naming Conventions section.

#### 2.7.1. Extension Type Names

Types defined by extensions have the author ID appended to the end of the type name.

Example

    // VkSurfaceFormatKHR (structure type with KHR appended)
    typedef struct VkSurfaceFormatKHR {
        VkFormat           format;
        VkColorSpaceKHR    colorSpace;
    } VkSurfaceFormatKHR;

#### 2.7.2. Extension Enumerant Names

Enumerants defined by extensions have the author ID appended to the end of the enumerant name, separated by an underscore. This includes the begin, end, range and max values added to enumeranted type definitions by the generator scripts.

Note | There is one exception to this rule in the VK_KHR_sampler_mirror_clamp_to_edge extension. This functionality was included in the original spec, but quickly separated out at release. Due to this late change, the single enum exposed has retained its original identifier to avoid compatibility issues: `VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE`

Example

    // VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR (enumerant with _KHR appended)
    typedef enum VkCompositeAlphaFlagBitsKHR {
        VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
        ...
    } VkCompositeAlphaFlagBitsKHR;

#### 2.7.3. Extension Function Names

Function and function pointer type names defined by extensions have the author ID appended to the end of the name.

Example

    // vkDestroySurfaceKHR (function with KHR appended)
    VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(
        VkInstance                                  instance,
        VkSurfaceKHR                                surface,
        const VkAllocationCallbacks*                pAllocator);

    typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(
        VkInstance                                  instance,
        VkSurfaceKHR                                surface,
        const VkAllocationCallbacks*                pAllocator);

### 2.8. Common Abbreviations

Abbreviations and acronyms are sometimes used in the Vulkan API Specification and the Vulkan API where they are considered clear and commonplace. All such abbrevations used in the core API are defined here. Extensions should also use these abbreviations where appropriate.

Src

  Source

Dst

  Destination

Min

  Minimum

Max

  Maximum

Rect

  Rectangle

Info

  Information

Lod

  Level of Detail

Mip

  Related to a mipmap. Use “mipmap” in full only when it is a standalone term. If referred to some associating with a mipmap, such as levels, sampling mode, size, tail images, etc., use “mip” as a standalone prefix word, e.g. `maxMipLevels`, `VK_MIP_MODE`, etc. This is analogous to the spelling conventions for mip-related terms

Note | The names `mipmapMode`, `mipmapPrecisionBits`, `VkSamplerMipmapMode`, and `VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT` are exceptions to this general usage guideline, for historical reasons.

ID

  Identifier

UUID

  Universally Unique Identifier

Op

  Operation

R

  Red color component

G

  Green color component

B

  Blue color component

A

  Alpha color component

### 2.9. Standard Prefixes

Prefixes are used in the API to denote specific semantic meaning of here:

VK/Vk/vk

  Vulkan namespace
  All types, commands, enumerants and C macro definitions in the Vulkan specification are prefixed with these two characters, according to the rules defined above.

PFN/pfn

  Function Pointer
  Denotes that a type is a function pointer, or that a variable is of a pointer type.

p

  Pointer
  Variable is a pointer.

vkCmd

  Commands that record commands in command buffers
  These API commands do not result in immediate processing on the device. Instead, they record the requested action in a command buffer for execution when the command buffer is submitted to a queue.

s

  Structure
  Used to denote the `VK_STRUCTURE_TYPE*` member of each structure in `sType`.

## 3. Layers & Extensions

This chapter describes required and recommended processes for writing formal extensions and layers for the Vulkan API. It is concerned with processes and registration, while fine-grained naming conventions are included in the API Naming Conventions chapter. Prior to revision 1.0.19 of the Vulkan API Specification, most of the content in this chapter existed as part of Appendix C of that document.

Note | Note The mechanism and process of specifying extensions is subject to change, as we receive feedback from authors and further requirements of documentation tooling. This document will be updated as changes are made.

### 3.1. Introduction

The Khronos extension registries and extension naming conventions serve several purposes:

- Avoiding naming collisions between extensions developed by mutually unaware parties, both in the extension names themselves, as well as their token, command, and type names.

- Allocating enumerant values for tokens added by extensions

- Creating a defined order between extensions. Extensions with higher numbers may have dependencies upon extensions with lower numbers, and must define any relevant interactions with lower-numbered extensions.

- Provides a central repository for documentation and header changes associated with extensions

Vulkan’s design and general software development trends introduces two new paradigms that require rethinking the existing mechanisms:

- Layers, and with them a focus on a more open ecosystem where non-Khronos members are expected to extend a Khronos API using the Layer mechanism.

- Namespaced constants (enumerations) that do not necessarily draw from a single global set of token values.

### 3.2. General Rules/Guidelines

Some general rules to simplify the specific rules below:

- Extensions and layers must each have a globally unique name.

- All commands and tokens must have a globally unique name.

- Extensions can expose new commands, types, and/or tokens, but layers must not.

  - However, layers can expose their own extensions, which in turn are allowed to expose new commands and tokens.

- All extensions must be registered with Khronos.

- Extensions must be strictly additive and backwards-compatible. That is, extensions must not remove existing functionality, or change existing default behaviors. A Vulkan implementation may support any combination of extensions, but applications written using only the core API, or a subset of the supported extensions, must continue to work in such an implementation without changes in behavior.

### 3.3. Extension and Layer Naming Conventions

Extensions and layers have formal names. These names are used in a variety of places:

- When specifying extensions and layers to enable in the API.

- As a preprocessor symbol in the vulkan.h header file indicating that an extension interface is defined at compile time.

- To control building the Vulkan Specification from asciidoc source containing many extension, by explicitly enabling inclusion of one or more extensions.

Note | Note In version 1.0.24 and earlier versions of the Vulkan Specification, extensions were maintained in separate git branches from the core Specification source. This proved to be unwieldy and difficult to maintain as the core was repeatedly updated, and as of version 1.0.25, we have moved to a “single-branch” model in which most extensions can optionally be included or not from a single set of source documents. It is possible that some vendors will choose to continue maintaining their extension branches, and the existing extension branches will not be removed from GitHub.

There is a rigid syntax for these names:

- Extensions are named with the syntax: VK_AUTHOR_<name>.

- Layers are named with the syntax: VK_LAYER_{AUTHOR|FQDN}_<name>.

Both extensions and layer names include a VK_ prefix, as described in the Preprocessor Defines section above. In addition, layers add a LAYER_ prefix.

Extension and layer names must both be valid C language identifiers.

#### 3.3.1. Extension and Layer Name Strings

The <name> portion of extension and layer names is a concise name describing the purpose or functionality of the extension or layer. The underscore (_) character is used as a delimiter between words. Every character of the name must be in lower case.

#### 3.3.2. Author IDs

Extension and layer names also contain an author ID, indicated by AUTHOR above, identifying the author of the extension/layer. This ID is a short, capitalized string identifying an author, such as a Khronos member developing Vulkan implementations for their devices, or a non-Khronos developer creating Vulkan layers. Author IDs must be registered with Khronos.

Some authors have platform communities they wish to distinguish between, and can register additional author IDs for that purpose. For example, Google has separate Android and Chrome communities.

Details on how to register an author ID are provided below. Layer authors not wishing to register an author ID with Khronos can instead use a fully-qualified domain name (FQDN) as the ID. The FQDN should be a domain name owned by the author. FQDNs cannot be used for extensions, only for layers.

- The following are examples of extension and layer names, demonstrating the above syntax:

  - Extension names all use the base prefix VK_.

  - Khronos-ratified extensions add the reserved author ID KHR, and will use the prefix VK_KHR_.

  - The following author IDs are reserved and must not be used:

    - VK - To avoid confusion with the top-level VK_ prefix.

    - VULKAN - To avoid confusion with the name of the Vulkan API.

    - LAYER - To avoid confusion with the higher-level “LAYER” prefix.

    - KHRONOS - To avoid confusion with the Khronos organization.

  - Multi-author extensions that have not been ratified by Khronos (those developed via cooperation between, and intended to be supported by two or more registered authors) add the special author ID EXT to the base prefix, and will use the prefix VK_EXT_.

  - Traditional author-specific extensions developed by one author (or one author in cooperation with non-authors) add the author ID to the base prefix. For example, NVIDIA will use the prefix VK_NV_, and Valve will use the prefix VK_VALVE_. Some authors can have additional registered author IDs for special purposes. For example, an Android extension developed by Google - but part of an Android open-source community project, and so not a proprietary Google extension - will use the author ID ANDROID.

  - Layer names follow the same conventions as extensions, but use the base prefix VK_LAYER_.

  - Because layers need not be registered with Khronos, an alternative mechanism is needed to allow creating unique layer names without registering an author ID. Layer authors that prefer not to register an author ID can instead use a fully-qualified domain name (FQDN) in reverse-order as an author ID, replacing . (period) with _ (underscore) characters. The restriction that layer names must be valid C identifiers means that some FQDNs cannot be used as part of layer names.

Example

    // Khronos extension name
    VK_KHR_mirror_clamp_to_edge

    // Multivendor extension name
    VK_EXT_debug_marker

    // Vendor extension name using author ID NV
    VK_NV_glsl_shader

    // Vendor layer name using author ID LUNARG
    VK_LAYER_LUNARG_vktrace

    // Layer name using the FQDN www.3dxcl.invalid instead of an author ID
    VK_LAYER_invalid_3dxcl_www

Note | Note To avoid linking to a nonexistent domain, the reserved TLD .invalid is used in the example above.

### 3.4. Extension Command, Type, and Token Naming Conventions

Extensions may add new commands, types, and tokens, or collectively “objects”, to the Vulkan API. These objects are given globally unique names by appending the author ID defined above for the extension name as described in the Extension Identifier Naming Conventions section above.

### 3.5. The Vulkan Registry

The canonical definition of the Vulkan APIs is kept in an XML file known as the Vulkan registry. The registry is kept in src/spec/vk.xml in the branch of the vulkan project containing the most recently released core API specification. The registry contains reserved author IDs, core and extension interface definitions, definitions of individual commands and structures, and other information which must be agreed on by all implementations. The registry is used to maintain a single, consistent global namespace for the registered entities, to generate the Khronos-supplied vulkan.h, and to create a variety of related documentation used in generating the API specification and reference pages.

### 3.6. Registering an Author ID with Khronos

Previous Khronos APIs could only officially be modified by Khronos members. In an effort to build a more flexible platform, Vulkan allows non-Khronos developers to extend and modify the API via layers and extensions in the same manner as Khronos members. However, extensions must still be registered with Khronos. A mechanism for non-members to register layers and extensions is provided.

Extension authors will be able to create an account on GitHub and register an author ID with Khronos through the KhronosGroup/Vulkan-Docs project. The author ID must be used for any extensions that author registers. The same mechanism will be used to request registration of extensions or layers with Khronos, as described below.

To reserve an author ID, propose a merge request against vk.xml in the 1.0 branch. The merge must add a <tag> XML tag and fill in the name, author and contact attributes with the requested author ID, the author’s formal name (e.g. company or project name), and contact email address, respectively. The author ID will only be reserved once this merge request is accepted.

Please do not try to reserve author IDs which clearly belong to another existing company or software project which may wish to develop Vulkan extensions or layers in the future, as a matter of courtesy and respect. Khronos may decline to register author IDs that are not requested in good faith.

### 3.7. Registering a Vendor ID with Khronos

Vulkan implementers must report a valid vendor ID for their implementation when queried by `vkGetPhysicalDeviceProperties`, as described in the “Devices and Queues” section of the Vulkan API Specification. If there is no valid PCI vendor ID defined for the physical device, implementations must obtain a Khronos vendor ID.

Khronos vendor IDs are reserved in a similar fashion to author IDs. While vendor IDs are not directly related to API extensions, the reservation process is very similar and so is described in this section.

To reserve an Khronos vendor ID, you must first have a Khronos author ID. Propose a merge request against vk.xml in the 1.0 branch. The merge must add a <vendorid> tag and fill in the name and id attributes. The name attribute must be set to the author ID. The id attribute must be the first sequentially available ID in the list of <vendorid> tags. The vendor ID will be reserved only once this merge request has been accepted.

Please do not try to reserve vendor IDs unless you are making a good faith effort to develop a Vulkan implementation and require one for that purpose.

### 3.8. Registering Extensions and Layers

Extensions must be registered with Khronos. Layers may be registered, and registration is strongly recommended. Registration means:

- Receiving an extension number.

- Adding the extension or layer name to the list in vk.xml and appearing on the Khronos registry website, which will link to associated documentation hosted on Khronos.

- For extensions which add to the Vulkan API, including definitions of those additions to vk.xml.

Registration for Khronos members is handled by filing a merge request in the internal gitlab repository against the branch containing the core specification against which the extension or layer will be written. The merge must modify vk.xml to define extension names, API interfaces, and related information. Registration is not complete until the registry maintainer has validated and accepted the merge.

Since this process could in principle be completely automated, this suggests a scalable mechanism for accepting registration of non-Khronos extensions. Non-Khronos members who want to create extensions must register with Khronos by creating a GitHub account, and registering their author ID and/or FQDNs to that account. They can then submit new extension registration requests by proposing merges to vk.xml. On acceptance of the merge, the extension will be registered, though its specification need not be checked into the Khronos GitHub repository at that point.

The registration process can be split into several steps to accommodate extension number assignment prior to extension publication:

- Acquire an extension number. This is done by proposing a merge request against vk.xml similarly to how author IDs are reserved. The merge should add a new <extension> tag at the end of the file with attributes specifying the proposed extension name, the next unused sequential extension number, the author and contact information (if different than that already specified for the author ID used in the extension name), and finally, specifying supported="disabled". The extension number will be reserved only once this merge request is accepted into the 1.0 branch.

- Develop and test the extension using the registered extension number.

- Publish the extension to Khronos using the previously registered extension number, by submitting merge requests to the 1.0 branch defining the changes specific to the extension. Changes to both the specification source, and to vk.xml will be needed.

  - Extension changes to the specification source must be protected by asciidoc conditionals as described in the Documenting Extensions section.

  - Changes to vk.xml must define the extension interfaces in the <extension> block, and must also change the supported attribute value of the <extension> to supported="vulkan".

  - When publishing an extension, mark it as enabled by proposing a merge to the 1.0 branch changing the supported attribute value of the <extension> to supported="vulkan". This should be completely automated and under the control of the publishers, to allow them to align publication on Khronos with product releases. However, complete automation might be difficult, since steps such as regenerating and validating vulkan.h are involved. Once the merge is accepted and the corresponding updated header with the new extension interface is committed to the 1.0 branch, publication is complete.

  - Publishing on the Khronos public GitHub repository is preferred whenever possible. Khronos members may instead create branches on Khronos' internal gitlab server, but those branches will eventually be mirrored to GitHub.

  - Once the merge request defining an extension has been accepted into the 1.0 branch, publication is complete - although it may not be visible on GitHub until the next regular core Specification update is pushed out.

- It is still possible to publish a separate branch of the repository with appropriate changes relative to the core Vulkan API branch instead, but this approach is deprecated and discouraged. If this is done, all changes to vk.xml must still be made in the 1.0 branch.

Note | editing-note TODO: This section is subject to change and not complete yet, but in broad is how we expect extension registration and specifications to work. The process will be refined as members and outside authors define further extensions.

### 3.9. Documenting Extensions

Extensions are documented as modifications to the Vulkan specification. Changes specific to an extension are protected by asciidoc conditionals. The changes are only visible in generated documentation when the Specification is built with an asciidoc attribute of that name defined.

Note | Note This is referred to as the “single-branch” model, in contrast to the earlier model where each extension lived in a separate branch from the 1.0 core Specification source.

For example, the VK_KHR_surface extension is now documented in the 1.0 branch of the GitHub KhronosGroup/Vulkan-Docs project. However, specifications generated from this branch will only include the extension when the Makefile is invoked appropriately.

Most language defining extensions can be localized either into a small number of asciidoc include files which are conditionally included in the core specification chapters and appendices, or into parts of vk.xml defining the extension interfaces.

Note | Note We do not yet fully document an example of including an extension in the single-branch model. Instead, authors should refer to the 1.0 branch and search for the names of existing extensions, such as VK_KHR_surface, as examples. Some aspects of the changes for this example extension are described below.

The WSI extensions were used to help prototype what changes need to be made for extensions, which include (but may not be limited to) the following:

- All extensions should add an appendix to the Vulkan specification. This can be modeled after what was done for the VK_KHR_surface extension in doc/specs/vulkan/appendices/VK_KHR_surface/wsi.txt, which contains metainformation about the extension (as well as code examples, and revision history). This example is complicated because VK_KHR_surface is a base extension on which many window system-specific extensions are layered.

- Each extension’s appendix file is included by adding an include statement to the doc/specs/vulkan/vkspec.txt file. The include statement must be protected by appropriate asciidoc conditionals. For example:

  Example Markup

      ifdef::VK_KHR_surface[]
      include::appendices/VK_KHR_surface/wsi.txt[]
      endif::VK_KHR_surface[]

- If an extension is more of an addition to the Vulkan specification, the extension should add a chapter to the Vulkan specification. For example, in the case of the VK_KHR_surface example a new chapter is added in vkspec.txt by including at the end of the core Specification chapters:

  Example Markup

      ifdef::VK_KHR_surface[]
      include::chapters/VK_KHR_surface/wsi.txt[]
      endif::VK_KHR_surface[]

- In every other place where the extension modifies the core Specification, modify the core files and protect the modifications with the same asciidoc conditionals. For example, VK_KHR_surface adds new error codes to Vulkan. These are added to chapters/fundamentals.txt in the “Return Codes” section as follows:

  Example Markup

      ... list of existing error codes
      ifdef::VK_KHR_surface[]
      include::VK_KHR_surface/VkResultErrorDescriptions_surface.txt[]
      endif::VK_KHR_surface[]

- For vendor extensions, changes made to existing core Specification source files and to vk.xml all fall under the Contributor License Agreement. Vendors may use their own copyright on new files they add to the 1.0 branch, although that copyright must be compatible with the Specification copyright.

### 3.10. Assigning Extension Token Values

Extensions can define their own enumeration types and assign any values to their enumerants that they like. Each enumeration has a private namespace, so collisions are not a problem. However, when extending existing enumeration objects with new values, care must be taken to preserve global uniqueness of values. Enumerations which define new bits in a bitmask are treated specially as described in Reserving Bitmask Values below.

Each extension is assigned a range of values that can be used to create globally-unique enum values. Most values will be negative numbers, but positive numbers are also reserved. The ability to create both positive and negative extension values is necessary to enable extending enumerations such as `VkResult` that assign special meaning to negative and positive values. Therefore, 1000 positive and 1000 negative values are reserved for each extension. Extensions must not define enum values outside their reserved range without explicit permission from the owner of those values (e.g. from the author of another extension whose range is infringed on, or from the Khronos Registrar if the values do not belong to any extension’s range).

Note | Note Typically, extensions use a unique offset for each enumeration constant they add, yielding 1000 distinct token values per extension. Since each enumeration object has its own namespace, if an extension needs to add many enumeration constant values, it can reuse offsets on a per-type basis.

The information needed to add new values to the XML are as follows:

- The extension name (e.g. VK_KHR_swapchain) that is adding the new enumeration constant.

- The existing enumeration type being extended (e.g. `VkStructureType`).

- The name of the new enumeration token being added (e.g. `VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR`).

- The offset, which is an integer between 0 and 999 relative to the base being used for the extension.

- The direction may be specified to indicate a negative value (dir="-") when needed for negative `VkResult` values indicating errors, like `VK_ERROR_SURFACE_LOST_KHR`. The default direction is positive, if not specified.

Implicit is the registered number of an extension, which is used to create a range of unused values offset against a global extension base value. Individual enumerant values are calculated as offsets in that range. Values are calculated as follows:

- base_value = 1000000000

- range_size = 1000

- enum_offset(extension_number,offset) = base_value + (extension_number - 1) × range_size + offset

- Positive values: enum_offset(extension_number,offset)

- Negative values: -enum_offset(extension_number,offset)

The exact syntax for specifying extension enumerant values is defined in the readme.pdf specifying the format of vk.xml, and extension authors can also refer to existing extensions for examples.

#### 3.10.1. Reserving Bitmask Values

Enumerants which define bitmask values are a special case, since there are only a small number of unused bits available for extensions. For core Vulkan API and KHR extension bitmask types, reservations must be approved by a vote of the Vulkan Working Group. For EXT and vendor extension bitmask types, reservations must be approved by the listed contact of the extension. Bits are not reserved, and must not be used in a published implementation or specification until the reservation is merged into vk.xml by the registry maintainer.

### 3.11. Required Extension Tokens

In addition to any tokens specific to the functionality of an extension, all extensions must define two additional tokens.

- VK_EXTNAME_SPEC_VERSION is an integer constant which is the revision of the extension named VK_extname (EXTNAME is all upper-case, while extname is the capitalization of the actual extension name) in vulkan.h. This value begins at 1 with the initial version of an extension specification, and is incremented when significant changes (bugfixes or added functionality) are made. Note that the revision of an extension defined in vulkan.h and the revision supported by the Vulkan implementation (the `specVersion` field of the `VkExtensionProperties` structure corresponding to the extension and returned by one of the extension queries) may differ. In such cases, only the functionality and behavior of the lowest-numbered revision can be used.

- VK_EXTNAME_EXTENSION_NAME is a string constant which is the name of the extension.

For example, for the WSI extension VK_KHR_surface, at the time of writing the following definitions were in effect:

    #define VK_KHR_SURFACE_SPEC_VERSION 24
    #define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface"

### 3.12. Extension Objects, Enums, and Typedefs

Expanding on previous discussion, extensions can add values to existing enums; and can add their own commands, enums, typedefs, etc. This is done by adding to vk.xml. All such additions will be included in the vulkan.h header supplied by Khronos.

Note | Note Application developers are encouraged to be careful when using switch statements with Vulkan API enums. This is because extensions can add new values to existing enums. The use of a default: statement, within a switch, may avoid future compilation issues.

### 3.13. Extension Function Prototypes

Function pointer declarations and function prototypes for all core Vulkan API commands are included in the vulkan.h file. These come from the official XML specification of the Vulkan API hosted by Khronos.

Function pointer declarations are also included in the vulkan.h file for all commands defined by registered extensions. Function prototypes for extensions may be included in vulkan.h. Extension commands that are part of the Vulkan ABI must be flagged in the XML. Function prototypes will be included in vulkan.h for all extension commands that are part of the Vulkan ABI.

An extension can be considered platform specific, in which case its interfaces in vulkan.h are protected by #ifdefs. This is orthogonal to whether an extension command is considered to be part of the Vulkan ABI.

The initial set of WSI extension commands (i.e. for VK_KHR_surface, VK_KHR_swapchain, and VK_KHR_*_surface) are considered to be part of the Vulkan ABI. Function prototypes for these WSI commands are included in the vulkan.h provided by Khronos, though the platform-specific portions of vulkan.h are protected by #ifdefs.

Note | Note Based on feedback from implementers, Khronos expects that the Android, Linux, and Windows Vulkan SDKs will include our vulkan.h and export the supported WSI functions for those platforms from their loader libraries. Other implementations can make different choices for their headers and loader libraries, but are encouraged to be consistent with these implementations.

### 3.14. Accessing Extension Functions from Programs

`vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` can be used in order to obtain function pointer addresses for core and extension commands (per the description in the “Command Function Pointers” section of the Vulkan API Specification). Different Vulkan API loaders can choose to statically export functions for some or all of the core Vulkan API commands, and can statically export functions for some or all extension commands. If a loader statically exports a function, an application can link against that function without needing to call one of the `vkGet*ProcAddr` commands.

Note | Note The Vulkan API loader for Android, Linux, and Windows exports functions for all core Vulkan API commands, and for a set of WSI extension commands that are applicable to those operating systems (see Vulkan loader documentation for the relevant platform/OS for details). The WSI functions are considered special, because they are required for many applications.

### 3.15. Extension Interactions

Extensions modifying the behavior of existing commands should provide additional parameters by using the `pNext` field of an existing structure, pointing to a new structure defined by the extension, as described in the “Valid Usage” section of the Vulkan API Specification. Extension structures defined by multiple extensions affecting the same structure can be chained together in this fashion. Any structure which can be chained in this fashion must begin with the following two members:

    VkStructureType        sType;
    const void*            pNext;

It is in principle possible for extensions to provide additional parameters through alternate means, such as passing a handle parameter to a structure with a `sType` defined by the extension, but this approach is discouraged and should not be used.

When chaining multiple extensions to a structure, the implementation will process the chain starting with the base parameter and proceeding through each successive chained structure in turn. Extensions should be defined to accept any order of chaining, and must define their interactions with other extensions such that the results are deterministic. If an extension needs a specific ordering of its extension structure with respect to other extensions in a chain to provide deterministic results, it must define the required ordering and expected behavior as part of its specification.

## 4. Markup Style

This chapter demonstrates Asciidoc and Specification structure, including text layout and markup style.

Chapters and sections follow a rigid template consisting of an optional anchor (if other parts of the document cross-reference the section) followed by a one line title (see section 11.2 of the User Guide) and a blank line. The anchor is typically the base name of the file containing the chapter, with a lowercased version of the section name following, with spaces replaced by dashes.

Always use the one-line title form, with one to four = signs preceding the chapter/section title. The two-line title form cannot be easily searched for and often looks like other types of asciidoc delimiters.

Always precede the anchor by two blank lines (except at the beginning of a file), and follow the title by a blank line, to set off sections visibly.

Example Markup

    [[markup]]
    = Markup Style

    [[markup-sample-section]]
    == Sample Section

### 4.1. Sample Section

This is a sample section structurally similar to the Vulkan API Specification, nested one level inside a chapter. Sections can be nested up to level 5, although not all levels are included in the Table of Contents.

### 4.2. Asciidoc Markup And Text Layout

Asciidoc source should be text filled to 76 columns with hard line breaks. Each sentence in a paragraph ends with a newline to minimize git diff conflicts. Except when necessary for lists or other markup, text should begin at the first column of each line (leading spaces are often semantically meaningful in asciidoc markup).

UTF-8 characters outside the ASCII subset should be used sparingly, only when needed for non-English names. Instead use asciidoc markup for special characters, if required. For example, two hyphens produces an en-dash:

Note | Example Markup An -- en-dash → An — en-dash

As an exception, multiplication should be marked with the unicode multiplication symbol “×” (and not an asterisk) when used in plain text. You may also use the {times} asciidoc attribute for this symbol. In math sections, the same symbol should be referred to as \times. In code sections, a conventional asterisk (*) should be used instead.

See chapter 10 of the User Guide for supported special characters, as well as use of entity references.

Quotation marks should use the 66/99 convention. That is, double asymmetric quotation marks, indicated by double back-ticks as opening marks and double apostrophes as closing marks (``like this''), which renders “like this”.

Never use hard tabs or trailing blanks.

- In some cases, limitations of asciidoc markup may result in lines that are longer than 76 characters and cannot easily be shortened without compromising the output documents.

#### 4.2.1. Blocks

There are a variety of asciidoc block constructs. With the exception of tables and of open blocks used to group markup together, blocks should be delimited by exactly four repeated characters indicating the block type, for consistency. The block types and delimiters are shown in the following table.

Table 1. Asciidoc Block Delimiters
Table Type | Delimiter | Comments
--- | --- | ---
Open | -- | For continuation blocks
Example | ==== | For Notes
Passthrough | ++++ | For some kinds of math markup
Comment | //// |
Listing | ---- | For source code listings
Sidebar | ** | For implementor’s notes
Table | |==== | For tables
Quote | ____ | Currently unused in the Vulkan Specification
Literal | …. | Currently unused in the Vulkan Specification

#### 4.2.2. Footnotes

Use manually marked-up footnotes (the asciidoc footnote construct is OK for PDF outputs, but does not work well with long HTML documents since it places all footnotes at the end of the document).

Refer to footnotes with asciidoc superscript notation1, and mark up the footnotes below, but near the references as labelled lists. Manually assigned footnote numbers will inevitably be reused, which is OK as long as the colliding numbers are not in the same section.

1

  Like this example footnote.

Note | Example Markup See reference^2^ → See reference2.
    2::
        Reference 2.
→ 2 Reference 2.

#### 4.2.3. Lists

##### Bullet Lists and Continuation Blocks

- Bullet lists are the preferred form of list, aside from glossary definitions.

- Lists should have text indented by 4 spaces and the list item delimiter (e.g. one or more asterisks, for bullet lists) indented by two spaces.

  Note that continuation blocks for list items longer than one paragraph cannot be indented, only the first paragraph.

  In general, successive list items should not be separated by white space. However, list continuation blocks should be followed by a + on a line by itself, or by a blank line, due to limitations of the asciidoc parser.

- Indent bullet lists two spaces (to the bullet), 4 spaces (to the text, if it extends over multiple lines). This lets us visually distinguish lists from other kinds of markup.

  - Nested lists should align the leftmost list item delimiter (bullet, etc.) with the parent delimiter.

Example Markup

      * This is the first item in a bullet list.
      * The second item is described with two paragraphs. The second
        paragraph is in a continuation block:
    +
    --
    This is a continuation block containing the second paragraph,
    --
    +
      ** This is a nested list item for the second item. Since it
         follows a continuation block, it must be separated by a
         blank line or `+` from that block.

##### Labelled Lists

Labelled lists may be used in some cases such as footnotes; glossary entries; and long lists of information about similar names, such as the “Features, Limits, and Formats” chapter of the Vulkan Specification. Whenever labelled lists are used the label and its terminating double colon must be alone on a line, followed by the contents of that list entry.

For consistency do not use labels ending in three or four colons, or two semicolons, even though these forms are allowed in asciidoc markup.

Example Markup

      Glossary Entry::
        This is a glossary entry.

      Last Modified Date::
        2016-02-16

##### Numbered Lists

Numbered lists may be used if strictly necessary to place an ordering on list items. Always use implicit numbering, with the bullet point being a single period.

1. Explicit numbering with a number preceding the period is prone to accumulating errors as edits are made.

2. In addition, the markup is harder to recognize for scripts and tools (other than asciidoc itself) operating on the document source.

Example Markup

      . First list item.
      . Second list item.
      . Etc.

#### 4.2.4. Anchors and Cross-references

In general, chapters and sections should always have anchors, following the naming convention discussed above. Anchors to other sections of the document may be inserted as needed. In addition, the autogenerated include files defining commands, structures, enumerations and flags all define anchors whose name is the name of the command or type being defined, so it is easy to link to a (for example) a command name such as vkCreateCommandPool. However, using the markup macros described below is preferred when linking to anchors corresponding to API names, such as `vkCreateCommandPool`.

If you want a cross-reference to an anchor to appear as something other than the raw anchor name, always make sure to include that text as part of the cross-reference. There are several different toolchains followed for various forms of asciidoc output, and not all of them treat anchors without alt-text the same way.

Example Markup

    In general, chapters and sections should always have anchors, following the
    naming convention <<markup,discussed above>>.
    ...
    so it is easy to link to a (for example) a command name such as
    <<vkCreateCommandPool,vkCreateCommandPool>>. However, using the
    <<markup-macros,markup macros>> described below is preferred when linking to
    anchors corresponding to API names, such as flink:vkCreateCommandPool.

#### 4.2.5. Tables

Asciidoc tables should use the block prefix |====. Where feasible, align the | separating cells across rows. This will sometimes result in very wide tables in the source document, but makes it easier to see which cells belong to which column. Alternatively, long cells can be broken onto a separate line with the | separator appearing first, except for the first row of the table, which must all appear on a single line.

Tables should usually be preceded with a short title.

Example Markup

    .Normative Terminology Macros
    [width="100%",options="header"]
    |====
    | Macro Name     | Output
    | can{cl}        | can:
    | cannot{cl}     | cannot:
    |====

#### 4.2.6. Figures

All figures (images) must be marked up as follows, to ensure there is an anchor and that the figure is given a caption which shows the figure number and is added to the list of figures:

Example Markup

    [[fig-anchorname]]
    image::images/imagename.{svgpdf}[align="center",title="Figure caption",{fullimagewidth}]

There must be both .svg and .pdf versions of each figure checked into the images/ directory, to support generating both HTML and PDF outputs. It is best to create images in Inkscape as SVG files and then use the conversion rule in doc/specs/vulkan/images/Makefile to generate PDF.

Asciidoc restricts captions in figures to be a single line in the source document. If a longer caption is required, follow the figure directive with a sidebar block including the full caption preceded by a link to the figure:

Example Markup

    .Caption
    ****
    In the <<fig-anchorname,Figure caption>> diagram, the diagram represents
    ... long caption text here.
    ****

### 4.3. Markup Macros and Normative Terminology

This section discusses Asciidoc macros used in the document. In addition to the macros defined by asciidoc itself, additional macros are defined by the Vulkan API Specification and Reference Page configuration files.

#### 4.3.1. API Markup Macros

These macros must be used to tag command, structure, enumeration, enumerant, and other Vulkan-specific names so they can be rendered in a distinctive fashion, link to definitions of those names, and be easily searched for in the source documents. The validation scripts (make allchecks output) also rely on these macros being used consistently and correctly. The API markup macros, with examples of their use, are in the following table:

Table 2. API Markup Macros
Macro Name | Usage and Meaning
--- | ---
flink: | Generates a cross-reference or link to the definition of the command name in the macro argument. Example: flink:vkCreateCommandPool → `vkCreateCommandPool`.
fname: | Formats the macro argument like flink:. Does not generate a cross-reference. Example: fname:vkCreateCommandPool → `vkCreateCommandPool`. The flink: macro is preferred.
ftext: | Formats the macro argument like fname:. May contain asterisks for wildcards. Not validated. Example: ftext:vkCmd* → `vkCmd*`. Only use ftext: when it is necessary to describe something that should be rendered like a command name, but is not actually one (e.g. is a wildcard or subset of an actual command name).
slink: | Generates a cross-reference or link to the definition of the structure in the macro argument. Example: slink:VkMemoryHeap → `VkMemoryHeap`.
sname: | Formats the macro argument like slink:. Does not generate a cross-reference. May also be an abstract structure or handle name. Example: sname:VkCommandPoolCreateInfo → `VkCommandPoolCreateInfo`. The slink: macro is preferred if a definition of the target type with an anchor exists in the document.
stext: | Formats the macro argument like sname:. May contain asterisks for wildcards. Not validated. Example: stext:Vk*CreateInfo → `Vk*CreateInfo`. Only use stext: when it is necessary to describe something that should be rendered like a structure name, but is not actually one (e.g. is a wildcard or subset of an actual structure name).
elink: | Formats the macro argument as a Vulkan enumeration name and links to the definition of that enumeration type. Example: ename:VkResult → `VkResult`.
ename: | Formats the macro argument as a Vulkan enumerant name. Example: ename:VK_EVENT_SET → `VK_EVENT_SET`.
etext: | Formats the macro argument like ename:. Not validated. Examples: etext:_RANGE_SIZE → `_RANGE_SIZE`, etext:VK_IMAGE_CREATE_SPARSE_* → `VK_IMAGE_CREATE_SPARSE_*` Only use etext: when it is necessary to describe something that should be rendered like a enumerant name, but is not actually one (e.g. is a wildcard or subset of an actual enumerant name).
pname: | Formats the macro argument as a Vulkan parameter or structure member name. Example: pname:device → `device`.
ptext: | Formats the macro argument like pname:. May contain asterisks for wildcards. Not validated. Example: ptext:sparseResidency* → `sparseResidency*`. Only use ptext: when it is necessary to describe something that should be rendered like a parameter name, but is not actually one (e.g. is a wildcard or subset of an actual parameter name).
tlink: | Generates a cross-reference or link to the definition of the Vulkan type in the macro argument. Example: tlink:PFN_vkAllocationFunction → `PFN_vkAllocationFunction`. This is only used for function pointer types at present.
tname: | Formats the macro argument like tlink:. Does not generate a cross-reference. Example: tname:PFN_vkAllocationFunction → `PFN_vkAllocationFunction`. The tlink: macro is preferred.
dlink: | Generates a cross-reference or link to the definition of the Vulkan C macro in the macro argument. Example: dlink:VK_NULL_HANDLE → `VK_NULL_HANDLE`. There are only a few macros in the Vulkan API, described in the “API Boilerplate” appendix of the Vulkan API Specification
dname: | Formats the macro argument like dlink:. Does not generate a cross-reference. The dlink: macro is preferred.
basetype: | Formats the macro argument like a basic scalar type or API handle name. Not validated. Examples: basetype:VkBool32 → `VkBool32`, basetype:VkDeviceSize → `VkDeviceSize`.
code: | Formats the macro argument as a code sample. Primarily used for SPIR-V keywords and builtin C types. Examples: code:uint32_t → `uint32_t`, code:ClipDistance → `ClipDistance`, code:VK_NULL_HANDLE → `VK_NULL_HANDLE`, code:NULL → `NULL`.

When referring to a compound name (function-parameter, or structure-member), combine the macros separated by two colons, resulting in `vkCmdBindIndexBuffer`::`indexType` and `VkMemoryHeap`::`flags`. This is often done when referring to a particular parameter or member in a part of the document other than the description of the corresponding function or structure.

Example Markup

    flink:vkCmdBindIndexBuffer::pname:indexType
    slink:VkMemoryHeap::pname:flags

##### Other Markup

Uses of standard Asciidoc markup are less common. Occasional asterisk markup is used for emphasis. Backtick markup is sometimes used for the C NULL macro, but the code: macro should be used for `NULL` instead.

Example Markup

    *emphasis*
    `NULL`
    code:NULL

##### Glossary Terms

Glossary terms are currently marked up using underscore markup where they are defined in the documents, as well as being added to the formal Glossary appendix in the Vulkan API Specification. However, we will probably change to using custom macros soon, to enable linkage between the glossary and definitions in the spec body.

Example Markup

    _Glossary terms_

#### 4.3.2. Normative Terminology

Normative terminology is precisely defined in section 1.3 of the Vulkan API Specification, and is used to visually tag terms which express mandatory and optional behavior of Vulkan implementations, and of applications using Vulkan.

Whenever one of these terms appears in the Vulkan API Specification, it must be tagged using the macros, to indicate that its use has been carefully considered and is consistent with the definitions in section 1.3. This is extremely important for determining IP that is in and out of Scope during Ratification reviews. The normative terminology macros are defined in the following table:

Table 3. Normative Terminology Macros
Macro Name | Output
--- | ---
can: | can
cannot: | cannot
may: | may
may: not | may not
must: | must
must: not | must not
optional: | optional
optionally: | optionally
recommend: | recommend
required: | required
should: | should
should: not | should not

Note that the macros are lower-case only, so language should be written such that these terms do not appear at the beginning of a sentence (if really necessary, additional capitalized macros could be added).

##### Optional Behavior

If a described behavior of the implementation is not necessary for conformance, use the terms may: or optional: to describe it.

If a described usage pattern by the application is allowed but not necessary, use the term can: to describe it.

If language flows more logically using the term "may not", use the term may: not to describe it.

##### Optional Functionality

If functionality (rather than behavior) is optional, it should be described as

Example Markup

    not required:

Implementations are not mandated to support functionality which is not required, but if they do, they must behave as described by the Vulkan API Specification. The term functionality includes API features, extensions, and layers.

### 4.4. Informative, Editing and Implementor’s Notes

There are several possible types of notes. Depending on the type of output, they are rendered in different styles, but always include a note title, and are usually set off in a box or with an icon. While asciidoc supports a wide set of admonition paragraphs such as TIP, IMPORTANT, WARNING, and CAUTION, we always use the NOTE form, augmented by a note title. Each type of note is discussed below.

#### 4.4.1. Informative Notes

Informative notes always appear as part of the document, but are considered non-normative. They usually describe usage advice for applications, and are always given the title Note, as in the following example:

Note | Note This is an informative note.

Example Markup

    [NOTE]
    .Note
    ====
    This is an informative note.
    ====

If an entire chapter or section is considered informative, it should begin with the sentence:

Example Markup

    This chapter/section is Informative.

#### 4.4.2. Editing Notes

Editing notes usually only appear in internal (non-published) versions of documents, via asciidoc conditionals. If they are not resolved, or are internal issues that should not be visible in public, they should be removed from the source before pushing content to a canonical (1.0 or per-extension) public repository. They usually tag places where an outstanding Gitlab/GitHub issue is being worked, and are always given the title editing-note, as in the following example:

Note | editing-note This is an editing note, marked up as follows:

Example Markup

    ifdef::editing-notes[]
    [NOTE]
    .editing-note
    ====
    Contents of an editing note go here.
    It is good practice to include a Gitlab/GitHub issue number, or link to the
    issue, in the editing note.
    ====
    endif::editing-notes[]

#### 4.4.3. Implementor’s Notes

Implementor’s notes may or may not appear in published versions of documents, via asciidoc conditionals. They describe suggested approaches or guidelines for people writing Vulkan implementations, and are rare because the hardware being targeted varies so widely. They are always given the title Implementor’s Note, as in the following example:

Example 1. Implementor’s Note

This is an implementor’s note, marked up as follows:

Example Markup

    ifdef::implementation-guide[]
    .Implementor's Note
    ====
    Contents of an implementor's note go here.
    ====
    endif::implementation-guide[]

### 4.5. Word Choices

There are a variety of common terms that have several equivalent word choices. Always use the words in the first column instead of the alternate terms. This list may not be comprehensive; when in doubt, be guided by the existing Vulkan API Specification.

Table 4. Word Choices
Use This | Instead Of | Comments
--- | --- | ---
allocate | create | When describing objects or memory resulting from `vkAllocate*` commands.
application | client |
bitmask | bit field | Technically correct. Vulkan bitmasks are just integers and are not logically addressable at the bit level.
command | function | Except when talking about function pointers returned by `vkGet*ProcAddr` commands.
create | allocate | When describing objects resulting from `vkCreate*` commands.
depth/stencil | packed (interleaved, combined, other prefix) depth/stencil, depth-stencil, DepthStencil, etc. | Combined format implicit in the name.
device | GPU | Implementations on non-GPU devices are possible.
heterogeneous | heterogenous | More common
homogeneous | homogenous | More common
host endianness | platform endianness |
image subresource | subresource | Except when referring to host-accessible subresources
implementation | system |
indices | indexes | More common
member | field |
`parameter` are/is | `parameter` specifies (denotes, indicates) | In rare cases when are or if are not grammatically appropriate, specifies may be used instead.
`parameter` is | the value of `parameter` is | In rare cases, the value of is appropriate. See the existing specification language for examples.
begins / begun | starts / started | For `vkBegin*` - also see “finish”
finishes / finished | ends / ended | For `vkEnd*` - also see “begins”
used | referenced | When describing attachments specified in a subpass description.
statically used | referenced | When describing resources or push constants accessed by shader code
a more specific term | referenced | For all other situations.
component | channel | Specifically this refers to color channels/components

Note | Note The “begin/start” and “end/finish” distinction is still being sorted out. See Gitlab issue #61.

#### 4.5.1. Avoid Contractions

Contractions make the specification sound less formal and using them would be inconsistent with the many non-contraction forms already in use in the spec.

Table 5. Word Choices
Use This | Instead Of
--- | ---
are not | aren’t
cannot: | can’t
does not | doesn’t
do not | don’t
has not | hasn’t
is not | isn’t
it is | it’s
that is | that’s
there is | there’s
we are | we’re
will not | won’t

#### 4.5.2. Terms to Use With Caution

The term subset is sometimes used to refer to a strict subset, and sometimes used to refer to a subset which may be equal to the entire set. This is particularly likely to come up when describing bitmasks. Make sure to use either subset or strict subset as appropriate.

#### 4.5.3. Terms to Avoid

Do not describe anything in the documentation using vague or wishy-washy terms. Our goal is to precisely describe behavior of implementations.

The normative terms may:, optional:, and should: are available when implementations may make choices of behavior, but when such choices are allowed, each choice still must have well-defined behavior.

Table 6. Terms to Avoid
Bad Term | Comments
--- | ---
expect | And variants such as expected
likely | And variants such as will likely
allowed, could, generally, might, probably, perhaps | And all other such terms of choice. Use may: or can: depending on the context.
may: or may: not | Just use may:.

## 5. Writing Style

### 5.1. Miscellaneous Grammar, Spelling, and Punctuation Issues

#### 5.1.1. Use the Oxford Comma (Serial Comma)

When writing a sentence listing a series of items, include a comma before the “and” separating the last item.

Correct: The red, green, blue, and alpha components.

Incorrect: The red, green, blue and alpha components.

Also see http://blog.oxforddictionaries.com/2011/06/oxford-comma/

#### 5.1.2. Date Format

Whenever possible, write dates in the ISO 8601 format: YYYY-MM-DD.

If needed for consistency with existing dates, e.g. in appendix changelogs, you can also write “Month DD, YYYY” where “Month” is the English name of the month.

Never use ambigious formats such as “09/12/16”.

Example Markup

      * 2016-09-12
      * September 12, 2016

#### 5.1.3. A/An and Markup Macros

Use “a” and “an” correctly, based on the sound of the letter beginning the following word.

It is easy to get this wrong when talking about Vulkan API names tagged with the markup macros. For example, if you wanted to say:

    A VK_ERROR_DEVICE_LOST error

the correct way to mark this up in asciidoc would be:

    A ename:VK_ERROR_DEVICE_LOST error

However, on first glance at this it appears wrong, because the “word” following “a” is the macro name, “ename:”. That starts with a vowel, so the temptation is to say

    An ename:VK_ERROR_DEVICE_LOST error may occur.

What matters here is how the output document is formatted.

#### 5.1.4. Numbers in Text

When describing the need for a small number of objects, smaller than ten, spell the number out (e.g. “one”). If you are describing a literal value that is a small number, you may use a numeric value (e.g. “1”).

For example, instead of writing that a bitmask “contains 1 or more bits”, write that it “contains one or more bits”. A counter example is that it is okay to write “For non-stereoscopic-3D applications, this value is 1.”

#### 5.1.5. Use American Spelling Conventions

In case of conflict, use American rather than British spelling conventions, except for noted exceptions in the table below.

Table 7. Spelling
Use Spelling | Instead Of | Comments
--- | --- | ---
color | colour |
signaled | signalled |
tessellation | tesselation | Historical exception

#### 5.1.6. Compound Words and Preferred Orthography

Unless there is longstanding precedent in computer science literature, or the word is a noted exception in the table below, do not arbitrarily cram terms together.

This does not apply to parameter names in the API, where capitalization is used to distinguish words. For example, it is proper to refer to the use of a `colorSpace` member of a structure as a “color space” value.

Table 8. Spelling
Use Spelling | Instead Of | Comments
--- | --- | ---
bit plane | bitplane |
compile time | compile-time | Per Wikipedia “compile time”
color space | colorspace |
double-buffer | doublebuffer |
entry point | entry-point | Except if needed to disambiguate from surrounding terms
flat shading | flatshading |
GitHub | Github | Site’s preferred spelling
LOD | lod | Acronym for “Level Of Detail”
mip level mip layer mip size mip tail | miplevel miplayer mipsize miptail | “mipmap term” may be used in time
Exceptions
mipmap | mip map | Exception for historical reasons
swapchain | swap chain | Exception due to heavy use in WSI extensions
happen-before happen-after | happen before happen after | As used in concurrent languages such as C++11, Java and OpenCL C.

##### Words With "Pre-" Prefixes

When using the prefix “pre” to indicate “prior to”, such as in the words “preinitialized”, “preprocess”, and “pretransform”, do not separate the prefix from the word with a hyphen.

### 5.2. Describing Commands and Parameters

The Vulkan API Specification describes API commands followed by descriptions of their parameters, which are usually simple scalar types, handles or pointers to Vulkan objects or arrays of objects, or structures containing combinations of scalar types and objects. The templates and examples shown and annotated here are based on the Vulkan API Specification. Do not vary from them without compelling need.

Normative parts of the Vulkan API Specification should describe what something does, rather than how or why an application would want to use it.

When explicitly allowed by the Specification, the reserved value `NULL` may be used for Vulkan dispatchable objects, pointer parameters and members, and the reserved value `VK_NULL_HANDLE` may be used for Vulkan non-dispatchable object handle parameters and members. Otherwise, pointers and handles must refer to valid memory and valid Vulkan objects, respectively.

Note | Guideline As a simple example, say “To create a command pool, call `vkCreateCommandPool`” rather than “You/The application/The user can create a command pool by calling `vkCreateCommandPool`”.

Explanations of why and how should largely be confined to reference documentation, sample code, tutorials, and other such documents. Occasional non-normative explanations can be included in the Vulkan API Specification using informative notes.

### 5.3. Math Markup

There is a considerable amount of math in the documentation, ranging from simple arithmetic expressions to complicated conditionals. There are two ways of marking up math expressions, described below.

#### 5.3.1. Asciidoc Math Markup

Where possible, math is marked up using straight asciidoc features. For commonality with LaTeX math (see below), some common LaTeX operators and names are defined as asciidoc attributes using the same names, expanding to the corresponding Unicode entities. The complete set of these attributes is found in config/attribs.txt.

Table 9. Spelling
Feature | Result | Sample Markup
--- | --- | ---
Subscripts | ax | [eq]#a~x~#
Superscripts | -2(b-1) | [eq]#-2^(b-1)^#
Struct/parameter names as variables | 2`bits` | [eq]#2^pname:bits^#
Greek Letters (selected) | α, β, γ, δ, Δ, ε, λ, ρ, τ | [eq]#{alpha}, {beta}, {gamma}, {delta}, {DeltaUpper}, {epsilon}, {lambda}, {rho}, {tau}#
Fractions | ¼ + ½ | [eq]#{onequarter} + {onehalf}#
Closed Ranges | [0,1] | [eq]#[0,1]#
Open Ranges | [0,1) | [eq]#[0,1)#
Arithmetic and Relational Operators | a × b, a ≤ b, a ≠ b, a ≥ b, |x| | [eq]#a {times} b#, [eq]#a {leq} b#, [eq]#a {neq} b#, [eq]#a {geq} b#, [eq]#{vert}x{vert}#
Floor | ⌊w - ½⌋ | [eq]#{lfloor}w - {onehalf}{rfloor}#
Ceiling | ⌈log2(max(`width`, `height`))⌉ + 1 | [eq]#{lceil}log~2~(max(pname:width, pname:height)){rceil} + 1#
Logical and Set Operators | ∧ ¬ ∨ ⊕ ∈ | [eq]#{land} {lnot} {lor} {oplus} {elem}#
Partial Derivatives | ∂rx / ∂x = 0 | [eq]#{partial}r~x~ / {partial}x = 0#
Matrix/Vector Parameter Names | P = t P1 + (1-t) P2 | [eq]#**P** = t **P**~1~ + (1-t) **P**~2~#

#### 5.3.2. LaTeX Math Markup

Math markup more complex than easily supported in straight asciidoc markup (examples found in the Vulkan Specification include matrices, tensors, summation notation, conditional assignments, and division of complex expressions) are marked up using LaTeX math notation, which is either passed through to the Mathjax browser renderer for HTML outputs, or passed through to LaTeX for PDF outputs.

Note | Note There are font and style differences between LaTeX and asciidoc math markup which lead to minor visual inconsistencies. We’ll try to make this better over time, but it’s not significant enough to be a big priority.

While LaTeX math macros, including the amsmath package, are supported, general LaTeX constructs are not.

Inline math is encoded using the latexmath: macro. For example:

- $[0,1]$

- $\frac{1 - \frac{x}{2}}{x - 1}$

- $\mathbf{c} = t \mathbf{c}_1 + (1-t) \mathbf{c}_2. $

Example Markup

        latexmath:[$[0,1\]$]
        latexmath:[$\frac{1 - \frac{x}{2}}{x - 1}$]
        latexmath:[$\mathbf{c} = t \mathbf{c}_1 + (1-t) \mathbf{c}_2. $]

Note the escaped bracket in markup for the first expression, which is necessary to work around asciidoc macro parsing.

Block math is used for more complex equations. This example uses the aligned environment to delimit the expression.

\[ \begin{aligned} c_{RGB} & = \begin{cases} \frac{c_{sRGB}}{12.92} & \text{for } c_{sRGB} \leq 0.04045 \\ \left ( \frac{c_{sRGB}+0.055}{1.055} \right )^{2.4} & \text{for } c_{sRGB} > 0.04045 \end{cases} \end{aligned} \]
Example Markup

    [latexmath]
    +++++++++++++++++++
    \[ \begin{aligned}
    c_{RGB} & =
      \begin{cases}
        \frac{c_{sRGB}}{12.92}                              & \text{for } c_{sRGB} \leq 0.04045 \\
        \left ( \frac{c_{sRGB}+0.055}{1.055} \right )^{2.4} & \text{for } c_{sRGB} > 0.04045
      \end{cases}
    \end{aligned} \]
    +++++++++++++++++++

Note | Note The KaTeX processor used to render LaTeX math inside HTML documents does not support all features of LaTeX math. Some workarounds we’ve had to make are:
Table 10. LaTeX math replacements for KaTeX compatibility
Replace | With | Comments
--- | --- | ---
\begin{equation} | \[ |
\end{equation} | \] |
\begin{align*} | \[ \begin{aligned} |
\end{align*} | \end{aligned} \] |
\operatorname{foo} | \mathop{foo} |
{\rm A} | \mathrm{A} |
See https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX for a list of currently supported LaTeX functionality which may be used in the Vulkan spec.

This example uses normal LaTeX math brackets to delimit the expression:

\[ V = \begin{cases} (-1)^S \times 0.0, & E = 0, M = 0 \\ (-1)^S \times 2^{-14} \times { M \over 2^{10} }, & E = 0, M \neq 0 \\ (-1)^S \times 2^{E-15} \times { \left( 1 + { M \over 2^{10} } \right) }, & 0 < E < 31 \\ (-1)^S \times Inf, & E = 31, M = 0 \\ NaN, & E = 31, M \neq 0 \end{cases} \]
Example Markup

    [latexmath]
    +++++++++++++++++++
    \[
    V =
      \begin{cases}
        (-1)^S \times 0.0,                      & E = 0, M = 0     \\
        (-1)^S \times 2^{-14} \times { M \over 2^{10} },
                                                & E = 0,  M \neq 0 \\
        (-1)^S \times 2^{E-15} \times { \left( 1 + { M \over 2^{10} } \right) },
                                                & 0 < E < 31       \\
        (-1)^S \times Inf,             & E = 31, M = 0             \\
        NaN,                           & E = 31, M \neq 0
      \end{cases}
    \]
    +++++++++++++++++++

### 5.4. Describing Extension Structure Chains

When describing an extension structure which is passed to an existing command by placing it in the `pNext` chain of a structure parameter of that command, introduce the structure description in this fashion:

    When *performing an operation described by the extension struct*, add
    the slink:VkExtensionStructNameID to the pname:pNext chain of the
    slink:VkBaseExtensionStructName structure passed to the
    flink:vkBaseFunctionName command *saying what the extension struct
    does*.

### 5.5. An Example Command Description

The next section is a sample based on the Vulkan API Specification, and describes a command in enough detail to see the different usage patterns and layout / markup used. Informative notes discussing markup and guidelines are interspersed with the example description to explain how and why it looks as it does.

### 5.6. Sample Command Description: Creating Command Pools

To create a command pool, call:

    VkResult vkCreateCommandPool(
        VkDevice                                    device,
        const VkCommandPoolCreateInfo*              pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkCommandPool*                              pCommandPool);

Note | Guideline Begin the command description with a comment delimiting the language for automatic extraction into a reference page. Use a short, active sentence when describing what commands do, instead of more passive phrasing like “A command pool is created by calling:” or “The application may create a command pool by calling:”. After the description, include the autogenerated prototype for the command from the ../protos/ directory:
    // refBegin vkCreateCommandPool Create a new command pool object
    To create a command pool, call:
    include::../api/protos/vkCreateCommandPool.txt[]
Note that each autogenerated command, enumeration, flag, or structure definition include file also defines a corresponding asciidoc anchor which is the base name of the file. In this case, the anchor is named vkCreateCommandPool.

- `device` is the logical device that the command pool is created on.

- `pCreateInfo` points to an instance of the `VkCommandPoolCreateInfo` structure containing information used to create the command pool.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

- `pCommandPool` points to a handle in which the created command pool object is returned.

Note | Guideline Each command parameter is described in a separate bullet list entry, followed by validity rules, then detailed descriptions of any new structures, flags, or enumerations introduced by this command. Each parameter should appear as a separate bullet list item beginning with the parameter name, in the same order as parameters appear in the command. This aids in extracting short descriptions of parameters for inclusion in annotated headers and similar documentation. Make sure to tag each parameter with the pname: macro. Strive for compact notation, and in particular always try to use the phrasing “pname:param is” rather than wordier forms such as “pname:param specifies” or “The pname:param parameter specifies”. In general there is no need to describe a parameter which is a Vulkan object handle as a handle; for example, say “pname:device is the logical device” rather than “pname:device is a handle to the logical device”. An exception is object creation functions, where a pointer to a handle of the proper type is used to return the newly created object.

Valid Usage (Implicit)

- `device` must be a valid `VkDevice` handle

- `pCreateInfo` must be a pointer to a valid `VkCommandPoolCreateInfo` structure

- If `pAllocator` is not NULL, `pAllocator` must be a pointer to a valid `VkAllocationCallbacks` structure

- `pCommandPool` must be a pointer to a `VkCommandPool` handle

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

Note | Guideline Some parameter and member validation language for commands and structures is implicit (autogenerated from vk.xml), and included from the ../validity/ directories. There may be additional validation language which is explicit, and such language is written in a separate block in the specification preceding the validity include. The `vkCreateCommandPool` used as an example here has no such explicit language, but the `VkCommandPoolCreateInfo` used below does have explicit language.
    include::../validity/protos/vkCreateCommandPool.txt[]
Structures and enumerations first used as parameters of a command are described next.

The `VkCommandPoolCreateInfo` structure is defined as:

    typedef struct VkCommandPoolCreateInfo {
        VkStructureType             sType;
        const void*                 pNext;
        VkCommandPoolCreateFlags    flags;
        uint32_t                    queueFamilyIndex;
    } VkCommandPoolCreateInfo;

Note | Guideline Begin the structure description with a refBegin comment delimiting the language for automatic extraction into a reference page and including a summary line for the reference page. Use a short, active paragraph to introduce the structure, usually just “The `VkStructureName` structure is defined as:”. After the description, include the autogenerated definition for the structure from the ../structs/ directory:
    // refBegin VkCommandPoolCreateInfo - Structure specifying parameters of
    a newly created command pool
    The sname:VkCommandPoolCreateInfo structure is defined as:
    include::../api/structs/VkCommandPoolCreateInfo.txt[]

- `sType` is the type of this structure.

- `pNext` is NULL or a pointer to an extension-specific structure.

- `flags` is a combination of bitmask flags indicating usage behavior for the pool and command buffers allocated from it. Possible values include:

      typedef enum VkCommandPoolCreateFlagBits {
          VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001,
          VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002,
      } VkCommandPoolCreateFlagBits;

  - `VK_COMMAND_POOL_CREATE_TRANSIENT_BIT` indicates that command buffers allocated from the pool will be short-lived.

  - `VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT` controls whether command buffers allocated from the pool can be individually reset.

- `queueFamilyIndex` designates a queue family. Command buffers in this command pool must be submitted on queues from the same family.

Note | Guideline Each structure member is described in a separate bullet list entry. For the `Vk*CreateInfo` structures in particular, there is standard boilerplate for the `sType` and `pNext` members, followed by the members specific to the structure.
      * pname:sType is the type of this structure.
      * pname:pNext is `NULL` or a pointer to an extension-specific structure.
In some cases, such as when the type of a member is itself a new type, the entry will cover multiple paragraphs. In these cases the normal list nesting and indentation guidelines cannot be applied due to limitations of the asciidoc parser. It is usually best to append a continuation block following the first paragraph of such a list item:
      * pname:flags is a bitmask indicating usage behavior for the pool and
        command buffers allocated from it. Bits which can: be set include:
    +
    --
    // refBegin VkCommandPoolCreateFlagBits - Bitmask specifying usage behavior for a command pool
    include::../api/enums/VkCommandPoolCreateFlagBits.txt[]
    --
    +
      ** ename:VK_COMMAND_POOL_CREATE_TRANSIENT_BIT
         indicates that command buffers allocated
         from the pool will be short-lived.
      ** ename:VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
         controls whether command buffers allocated from
         the pool can: be individually reset.

Valid Usage

- `queueFamilyIndex` must be the index of a queue family available in the calling command’s `device` parameter

Valid Usage (Implicit)

- `sType` must be `VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO`

- `pNext` must be NULL

- `flags` must be a valid combination of `VkCommandPoolCreateFlagBits` values

Note | Guideline Following the definition of structure members, add explicit validity language, following by including the implicit (automatically generated) validity language include for this structure:
    .Valid Usage ****
      * pname:queueFamilyIndex must: be the index of a queue family
        available in the calling command's pname:device parameter
    ****
    include::../validity/structs/VkCommandPoolCreateInfo.txt[]

### 5.7. Markup For Automatic Reference Page Extraction

The Vulkan reference pages are (mostly) being extracted from corresponding sections of the API Specification. This requires that the markup and writing conventions described above be adhered to rigidly.

The extraction scripts for a given page rely on the existence of the asciidoc include of the autogenerated definition of that command, structure, or other API interface element. Various heuristics are used to determine which text to extract for that page; the general model is:

- Optional (but usually specified) comment line specifying the interface name and the short description used in the title of the corresponding ref page:

          // refBegin name - description

- A paragraph of text introducing the definition of the interface. If the refBegin comment does not exist, this paragraph must be present.

- The include line for the interface, which must be consistent with the interface name in the comment line.

- A bullet list describing function parameters, structure members, enumerants in an enumerated type, etc. This list should contain no empty lines, as the extraction script classifies the uninterrupted block of text following the include directive as the Parameters or Members section of the ref page.

- Optional paragraphs of text making up the Description section of the ref page. If it is necessary due to constraints of asciidoc markup to have an empty line in the bullet list section1, add a refBody comment immediately following the bullet list and preceding this section:

          // refBody name

- The include line for the validity statement of commands and structures. Other interfaces such as enumerated types do not have validity statements.

- Comment line specifying the end of the extracted text for the reference page and optional page names to link to in the See Also section of the page. If the validity include is not present, this line must be present:

          // refEnd name [seeAlsoNames]*

  1

    The only example of such markup in the 1.0.28 Vulkan Specification source is the `VkPhysicalDeviceLimits` structure description.

All elements specifying an interface name (refBegin, refBody, and refEnd comments, interface include line, and validity include line) must use the same interface name, if present. Otherwise the extraction script is either unable to extract that page, or will extract the wrong text. The extraction process is somewhat fragile, so care should be taken and the results of reference page extraction verified after making changes to that portion of the specification source.

## 6. Still To Be Done

- Something about Image formats

- Something about validation scripts

- Something about pictures

- Glossary lists

- New param/enum macros

## 7. Revision History

- 2016-09-28 - Add asciidoc math markup guidelines.

- 2016-09-16 - Make style guide markup more consistent with its own recommendations. Simplify some tables of preferred terms. Add sections on block and table markup.

- 2016-09-12 - Describe writing and markup style for labelled lists. Require use of the ISO 8601 date format except in rare legacy cases. Expand the description of Line Lengths and add a description of markup for Footnotes.

- 2016-09-08 - Add a writing section about proper use of “a” and “an” (internal issue 432).

- 2016-08-30 - Remove mustnot: and shouldnot: macro definitions, which are no longer used in the Specification (internal issue 407).

- 2016-08-29 - Add spelling and compound word rules (public issue 352).

- 2016-08-23 - Modify description of specifying extensions in the Layers and Extensions chapter to refer to the new single-branch model for extensions (internal issue 397).

- 2016-07-26 - Add section describing markup for automatic reference page extraction.

- 2016-07-18 - Add examples of function-parameter and structure-member markup (based on public issue 286).

- 2016-07-11 - Change the document title.

- 2016-07-07 - Rename document, change license to CC BY, clarify required and recommended actions, and reserve use of “normative” for the Specifications.

- 2016-06-26 - Move Layers and Extensions chapter from Appendix C of the Vulkan API Specification and merge content with the naming guide. Put extension and naming chapters into their own source files.

- 2016-06-20 - Add API naming guide.

- 2016-05-22 - Add markup and image creation rules, after fixing missing figure captions for public issue 219.

- 2016-05-01 - Include feedback from public issues 120 and 190. Use consistent conventions for defining structures. Use American rather than British spelling conventions.

- 2016-03-12 - Recommend against "the value of".

- 2016-02-26 - Replace use of the "maynot:" macro with "may: not".

- 2016-02-16 - Place asciidoc conversion post-release.

- 2016-02-09 - Added quotation mark convention.

- 2016-02-01 - Add the Oxford Comma section and issue resolution.

- 2016-01-26 - Add bullet-list style description of command parameters.

- 2016-01-11 - Add “Numbers in Text” section from WSI work.

- 2015-12-16 - Make “begin / end” preferred terms to “start / finish”.

- 2015-12-15 - Make “implementation” preferred term instead of “system”.

- 2015-12-13 - Add tlink:/tname: macros for function pointer types.

- 2015-12-10 - Initial release for feedback.