| // Copyright 2015-2023 The Khronos Group Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[writing]] |
| = Writing Style |
| |
| |
| [[writing-misc]] |
| == Miscellaneous Grammar, Spelling, and Punctuation Issues |
| |
| === 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 this |
| link:https://blog.oxforddictionaries.com/2015/01/21/video-oxford-comma/[video |
| discussion of the Oxford comma] provided by the Oxford Dictionary. |
| |
| |
| [[writing-titlecase]] |
| === Use AP Title Case for Chapter and Section Titles |
| |
| Here is a link:https://titlecaseconverter.com/rules/[summary] of the rules: |
| |
| * Capitalize the first word and the last word of the title. |
| * Capitalize the principal words. |
| * Capitalize "`to`" in infinitives. |
| * Capitalize all words of four letters or more. |
| * Do not capitalize articles, conjunctions, and prepositions of three |
| letters or fewer. |
| |
| [NOTE] |
| .Note |
| ==== |
| The actual AP style guide is behind a paywall. |
| The summary here is from a commercial website. |
| ==== |
| |
| |
| === Date Format |
| |
| Whenever possible, write dates in the <<iso-8601,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 ambiguous formats such as "`09/12/16`". |
| |
| [source,asciidoc] |
| .Example Markup |
| ---- |
| * 2016-09-12 |
| * September 12, 2016 |
| ---- |
| |
| |
| [[writing-misc-a-an]] |
| === A/An and Markup Macros |
| |
| Use "`a`" and "`an`" |
| link:https://www.grammar.com/a-vs-an-when-to-use/[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,markup macros>>. |
| For example, if you wanted to say: |
| |
| A ename:VK_ERROR_DEVICE_LOST error |
| |
| the correct way to mark this up in asciidoctor would be: |
| |
| [source,asciidoc] |
| ---- |
| 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{cl}`". |
| That starts with a vowel, so the temptation is to say |
| |
| [source,asciidoc] |
| ---- |
| An ename:VK_ERROR_DEVICE_LOST error may occur. |
| ---- |
| |
| What matters here is how the *output* document is formatted. |
| |
| |
| === 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.`" |
| |
| |
| [[writing-conventions]] |
| === Use American Spelling Conventions |
| |
| In case of conflict, use American rather than British spelling conventions, |
| except for noted exceptions in the table below. |
| |
| .Spelling |
| [width="60%",options="header"] |
| |==== |
| | Use Spelling | Instead Of | Comments |
| | color | colour | |
| | signaled | signalled | |
| | tessellation | tesselation | Historical exception |
| |==== |
| |
| [NOTE] |
| .Note |
| ==== |
| There are a few exceptions to `color` in the Vulkan Video extensions, such |
| as ename:VK_VIDEO_ENCODE_H264_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT. |
| This is for because those extensions refer to externally defined video |
| compression standards and headers using that spelling. |
| ==== |
| |
| |
| [[writing-inclusivity]] |
| === Use Inclusive Language |
| |
| The Vulkan Working Group has begun to apply the |
| link:https://www.khronos.org/about/inclusive-language[Khronos Inclusive |
| Language] list to our specifications and other documents. |
| The Khronos Inclusive Language list contains terms to avoid due to their use |
| in discriminatory contexts that make people uncomfortable, or cause |
| division. |
| |
| We are working through the Vulkan Specification repository to make |
| appropriate changes, and enhancing the repository continuous integration |
| scripts to report questionable terminology usage. |
| This process will take some time. |
| |
| Some files in the repository are incorporated unmodified from external |
| projects we do not control, and which may not comply with the Inclusive |
| Language list. |
| We will ask those projects to update their terminology usage, but cannot |
| control their choices. |
| |
| |
| [[writing-pointers-instances]] |
| === Describing Pointers, Handles, Structures, and Arrays |
| |
| When describing pointer parameters or members, use "`is a pointer to`" |
| rather than more informal phrasing such as "`points to`". |
| |
| When describing individual structures, use "`VkStructname structure`" rather |
| than longer phrasing such as "`instance of the VkStructname structure`" or |
| "`structure of type VkStructname`". |
| |
| When describing array parameters or members, use "`is a pointer to an array |
| of`" rather than "`is an array of`" unless it is a structure member that is |
| a fixed-size array. |
| Reference the dynamic size of the array that is pointed to (usually another |
| structure member), or the static size for fixed-size arrays, in the |
| description. |
| |
| When describing pointers which may be `NULL`, use "`is `NULL` or a pointer |
| to`" rather than "`is an optional pointer`". |
| The same principle applies when describing a handle which may be |
| dname:VK_NULL_HANDLE. |
| "`Optional pointer/handle`" are not well-defined terms in the Specification. |
| |
| [source,asciidoc] |
| .Example Markup |
| ---- |
| * pname:pInfo is a pointer to a slink:VkDebugUtilsLabelEXT structure |
| specifying the parameters of the label to insert. |
| * pname:pBindInfos is a pointer to an array of pname:bindInfoCount |
| slink:VkBindBufferMemoryInfo structures describing buffers and memory to |
| bind. |
| * pname:pStrides is `NULL` or a pointer to an array |
| of buffer strides. |
| * pname:image is dlink:VK_NULL_HANDLE or a handle of an image which this |
| memory will be bound to. |
| ---- |
| |
| |
| [[writing-arrays]] |
| === Describing Properties of Array Elements |
| |
| Many Vulkan parameters are arrays, or pointers to arrays. |
| When describing array elements, use the terminology "`each element`" when |
| the description applies uniformly and independently to every element of the |
| array. |
| For example: |
| |
| [source,asciidoc] |
| .Example Markup |
| ---- |
| * Each element of the pname:pCommandBuffers member of each element of |
| pname:pSubmits must: be in the <<commandbuffers-lifecycle, pending or |
| executable state>>. |
| ---- |
| |
| Use the terminology "`any element`" when the description is of zero or more |
| elements of the array sharing a property. |
| For example: |
| |
| [source,asciidoc] |
| .Example Markup |
| ---- |
| * If any element of the pname:pCommandBuffers member of any element |
| of pname:pSubmits was not recorded with the |
| ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must: not be in |
| the <<commandbuffers-lifecycle, pending state>>. |
| ---- |
| |
| Never use the redundant terminology "`any *given* element`". |
| |
| |
| [[writing-compound-words]] |
| === Compound Words and Preferred Orthography |
| |
| Unless there is longstanding precedent in computer science literature, or |
| the word is a <<spelling-exception-table, noted exception>>, do not |
| arbitrarily combine terms together with hyphens, or as a single compound |
| word without hyphens. |
| |
| 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 pname:colorSpace member |
| of a structure as a "`color space`" value. |
| |
| .Spelling |
| [width="70%",options="header",cols="20%,20%,60%"] |
| |==== |
| | Use Spelling | Instead Of | Comments |
| | bit plane | bitplane | |
| | compile time | compile-time | Per Wikipedia "`compile time`" |
| | color space | colorspace | |
| | cube map | cubemap | |
| | double-buffer | doublebuffer | |
| | entry point | entry-point, + |
| entrypoint |
| | Except if needed to disambiguate from surrounding terms |
| | flat shading | flatshading | |
| | GitHub | Github | Site's preferred spelling |
| | indirect (drawing/dispatching) command |
| | indirect command (draw/dispatch) |
| | Even though related commands are named |
| ftext:vk*Draw*Indirect |
| | LOD | lod, + |
| level of detail, + |
| level-of-detail| Acronym for "`Level of Detail`" |
| | mip level + |
| mip layer + |
| mip size + |
| mip tail |
| | miplevel + |
| miplayer + |
| mipsize + |
| miptail | "`mipmap *term*`" may be used in time |
| | render pass | renderpass | |
| | reuse | re-use | |
| | side effect | side-effect | |
| | use case | use-case | |
| |==== |
| |
| [[spelling-exception-table]] |
| .Spelling Exceptions |
| [width="70%",options="header",cols="20%,20%,60%"] |
| |==== |
| | general-purpose |
| | general purpose| When used as an adjective |
| | happen-before + |
| happen-after | happen before + |
| happen after | As used in concurrent languages such as |
| C++11, Java and OpenCL C. |
| | implementation-dependent |
| | implementation dependent |
| | When used as an adjective |
| | mipmap | mip map | Exception for historical reasons |
| | pname:pNext chain |
| | pname:pNext-chain, + |
| pname:pNext extension chain |
| | |
| | swapchain | swap chain | Exception due to heavy use in WSI extensions |
| |==== |
| |
| [NOTE] |
| .Note |
| ==== |
| These examples are not complete, and will be added to over time when there |
| is reason to. |
| |
| Different sources and individuals can and do reasonably disagree with regard |
| to some of the examples. |
| ==== |
| |
| |
| ==== Words With "Pre-" Prefixes |
| |
| // also: premultiply preorder prerotation predefined |
| |
| 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. |
| This list is not intended to be complete. |
| |
| |
| [[writing-references]] |
| === References |
| |
| When citing external references, use the appropriate <<acm-references, |
| Association for Computing Machinery Citation Style>>. |
| Most citations in our specifications should follow the _For an online |
| document/WWW resource_ style, using the actual date on the document being |
| referenced rather than the document retrieval date. |
| See the <<vulkan-spec, Vulkan API Specification>> citation in this document |
| for an example. |
| |
| |
| [[writing-undefined]] |
| == Describing Undefined Behavior |
| |
| When describing undefined behavior that results only in the values of |
| specified variables, or the contents of specified memory, becoming undefined |
| or implementation-defined, use the undefined{cl} macro to indicate that each |
| use of the term "`undefined`" has been carefully considered and accurately |
| represents the degree of undefined behavior allowed. |
| |
| The word "`undefined`" should not be used without the trailing {cl}. |
| This is enforced by internal CI tests. |
| |
| The undefined{cl} macro does not result in visible markup in the output |
| document, and is not itself a normative term. |
| The macro is simply markup to help ensure that use of the word has been |
| consciously chosen. |
| |
| When describing more general types of undefined behavior (up to and |
| including termination of the application), do *not* use the term |
| "`undefined`". |
| Instead, specify that the application must{cl} not create circumstances that |
| would lead to such behavior. |
| Such statements should be written as valid usage statements, if possible. |
| |
| |
| [[writing-describing]] |
| == Describing Commands and Parameters |
| |
| The <<vulkan-spec,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; enumerated types |
| specifying values or bitmasks which affect the operation of a command; or |
| structures containing combinations of scalar types and objects. |
| The templates and examples shown and annotated here are based on the |
| <<vulkan-spec,Vulkan API Specification>>. |
| Do not vary from them without compelling need. |
| |
| Normative parts of the <<vulkan-spec,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 pointer parameters and members and dispatchable object handles, |
| and the reserved value dname:VK_NULL_HANDLE may: be used for |
| non-dispatchable Vulkan 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 fname:vkCreateCommandPool`" |
| |
| rather than |
| |
| "`You/The application/The user can create a command pool by calling |
| fname: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-spec,Vulkan API Specification>> using |
| <<markup-informative-notes,informative notes>>. |
| |
| |
| [[writing-describing-errors]] |
| === Commands Which Return Error Codes |
| |
| Commands which return elink:VkResult values must list all possible error |
| codes for the command in the `errorcodes` XML attribute for the command. |
| Almost all such commands may return the ename:VK_ERROR_OUT_OF_HOST_MEMORY |
| error code. |
| Any exceptions to this rule should be carefully considered by the |
| specification author, and a rationale for this anomalous behavior may be |
| provided in a NOTE or in the Issues section of the extension appendix |
| corresponding to the new command. |
| |
| See the "`Return Codes`" section of the <<vulkan-spec,Vulkan API |
| Specification>> for additional information. |
| |
| |
| [[writing-describing-layers]] |
| == Extensions and Grouping Related Language |
| |
| Language specifying behavior of a command or structure that does not |
| originate in an extension should be placed in a single contiguous region of |
| the specification. |
| |
| When defining a new command or structure from an extension that introduces |
| additional behavior or options, do not insert such new language in a way |
| that "`orphans`" part of an existing description by splitting up the |
| existing language. |
| |
| This constraint does not apply to enumerated types. |
| Language for new enumerants defined by extensions should be added to the |
| existing enumerant definition, <<extensions-documenting-extensions, |
| protected by asciidoctor conditionals>> for the new extension. |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Specification language should be structured, whenever possible, so it fits |
| into a single open block defining a <<writing-refpages, reference page>>. |
| ==== |
| |
| |
| [[writing-math]] |
| == 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. |
| |
| |
| === Asciidoc Math Markup |
| |
| Where possible, math is marked up using straight asciidoctor features. |
| For commonality with LaTeX math (see below), some common LaTeX operators and |
| names are defined as asciidoctor attributes using the same names, expanding |
| to the corresponding Unicode entities. |
| The complete set of these attributes is found in `config/attribs.adoc`. |
| |
| .Spelling |
| [width="100%",options="header",cols="20%,20%,60%"] |
| |==== |
| | Feature | Result | Sample Markup |
| |
| | Subscripts |
| | [eq]#a~x~# |
| | +++[eq]#a~x~#+++ |
| |
| | Superscripts |
| | [eq]#-2^(b-1)^# |
| | +++[eq]#-2^(b-1)^#+++ |
| |
| | Struct/parameter names as variables |
| | [eq]#2^pname:bits^# |
| | +++[eq]#2^pname:bits^#+++ |
| |
| | Greek Letters (selected) |
| | [eq]#{alpha}, {beta}, {gamma}, {delta}, {DeltaUpper}, {epsilon}, {lambda}, |
| {rho}, {tau}# |
| | +++[eq]#{alpha}, {beta}, {gamma}, {delta}, {DeltaUpper}, {epsilon}, {lambda}, |
| {rho}, {tau}#+++ |
| |
| | Fractions |
| | [eq]#{onequarter} {plus} {onehalf}# |
| | +++[eq]#{onequarter} {plus} {onehalf}#+++ |
| |
| | Closed Ranges |
| | [eq]#[0,1]# |
| | +++[eq]#[0,1]#+++ |
| |
| | Open Ranges |
| | [eq]#[0,1)# |
| | +++[eq]#[0,1)#+++ |
| |
| | Arithmetic and Relational Operators |
| | [eq]#a {times} b#, [eq]#a {leq} b#, [eq]#a {neq} b#, [eq]#a {geq} b#, [eq]#{vert}x{vert}# |
| | +++[eq]#a {times} b#+++, +++[eq]#a {leq} b#+++, +++[eq]#a {neq} b#+++, +++[eq]#a {geq} b#+++, +++[eq]#{vert}x{vert}#+++ |
| |
| | Floor |
| | [eq]#{lfloor}w - {onehalf}{rfloor}# |
| | +++[eq]#{lfloor}w - {onehalf}{rfloor}#+++ |
| |
| | Ceiling |
| | [eq]#{lceil}log~2~(max(pname:width, pname:height)){rceil} {plus} 1# |
| | +++[eq]#{lceil}log~2~(max(pname:width, pname:height)){rceil} {plus} 1#+++ |
| |
| | Logical and Set Operators |
| | [eq]#{land} {lnot} {lor} {oplus} {elem}# |
| | +++[eq]#{land} {lnot} {lor} {oplus} {elem}#+++ |
| |
| | Partial Derivatives |
| | [eq]#{partial}r~x~ / {partial}x = 0# |
| | +++[eq]#{partial}r~x~ / {partial}x = 0#+++ |
| |
| | Matrix/Vector Parameter Names |
| | [eq]#**P** = t **P**~1~ {plus} (1-t) **P**~2~# |
| | +++[eq]#**P** = t **P**~1~ {plus} (1-t) **P**~2~#+++ |
| |
| |==== |
| |
| |
| [[writing-math-latexmath]] |
| === LaTeX Math Markup |
| |
| Math markup more complex than easily supported in straight asciidoctor |
| 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 KaTeX in-browser rendering script for HTML |
| outputs, or passed through asciidoctor-mathematical for PDF outputs. |
| |
| [NOTE] |
| .Note |
| ==== |
| There are font and style differences between LaTeX and asciidoctor math |
| markup which lead to minor visual inconsistencies. |
| We will try to make this better over time, but it is 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{cl} macro. |
| For example: |
| |
| * latexmath:[[0,1\]] |
| * latexmath:[\frac{1 - \frac{x}{2}}{x - 1}] |
| * latexmath:[\mathbf{c} = t \mathbf{c}_1 + (1-t) \mathbf{c}_2.] |
| |
| [source,asciidoc] |
| .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 asciidoctor macro parsing. |
| |
| _Block math_ is used for more complex equations. |
| This example uses the `aligned` environment to delimit the expression. |
| |
| [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} |
| +++++++++++++++++++ |
| |
| [source,asciidoc] |
| .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. |
| |
| Similarly, the asciidoctor-mathematical processor does not support |
| everything, though does have some support for AMSMath. |
| |
| Some workarounds we use are: |
| |
| .LaTeX math replacements for KaTeX compatibility |
| [width="70%",options="header",cols="20%,20%,60%"] |
| |==== |
| | Replace | With | Comments |
| | `++\begin{equation}++`, + |
| `++\end{equation}++` | _nothing_ | Unnecessary in blocks. Should not be used for inline. |
| | `\begin{align*}` | `++\begin{aligned}++` | |
| | `\end{align*}` | `++\end{aligned}++` | |
| | `++\operatorname{foo}++` | `++\mathbin{foo}++` | |
| | `{\rm A}` | `++\mathrm{A}++` | |
| | `\text{for }` | `\text{++for++}\` | Text ending in spaces is unpredictable - favour escaped spaces after text |
| |==== |
| |
| The KaTeX repository provides a |
| link:https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX[list of |
| currently supported LaTeX functionality]. |
| You can also use the link:https://khan.github.io/KaTeX/[live katex preview |
| tool] on the KaTeX website to double check support, without building the |
| whole specification. |
| |
| Note that we use a locally-cached copy of KaTeX which may lag the latest |
| published version on the website. |
| As of April 2021, we are using v0.11.1. |
| |
| See the mtex2MML repository for a |
| link:https://github.com/gjtorikian/mtex2MML/blob/master/SUPPORTED.md[list of |
| supported operations in the PDF build]. |
| In particular, `\mathop` is not supported properly, but most other standard |
| functionality is included. |
| |
| It is necessary to cross reference these two to make sure that support |
| exists before using anything, but almost all standard functionality is |
| supported for both. |
| ==== |
| |
| This example is among the most complex expressions in the Vulkan |
| specification: |
| |
| [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} |
| +++++++++++++++++++ |
| |
| [source,asciidoc] |
| .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} |
| +++++++++++++++++++ |
| ---- |
| |
| |
| [[writing-latexmath-in-table-cells]] |
| === LaTeX Math in Table Cells |
| |
| To use `[latexmath]` or `latexmath{cl}` constructs inside table cells, the |
| cell separator must be `a|` instead of just `|`: |
| |
| [source,asciidoc] |
| .Example Markup |
| ---- |
| .Advanced Blend Overlap Modes |
| [width="80%",options="header"] |
| |==== |
| | Overlap Mode | Weighting Equations |
| | ename:VK_BLEND_OVERLAP_UNCORRELATED_EXT a| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| \begin{aligned} |
| p_0(A_s,A_d) & = A_sA_d \\ |
| p_1(A_s,A_d) & = A_s(1-A_d) \\ |
| p_2(A_s,A_d) & = A_d(1-A_s) \\ |
| \end{aligned} |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |==== |
| ---- |
| |
| |
| [[writing-pNext-chain]] |
| == Describing Extending Structure Chains |
| |
| When describing an extending structure which is passed to an existing |
| command by including it in the pname:pNext chain of a structure parameter of |
| that command, introduce the structure description in this fashion: |
| |
| [source,asciidoc] |
| ---- |
| When *performing an operation described by the extending structure*, add |
| a slink:VkExtensionStructNameID structure to the pname:pNext chain of the |
| slink:VkBaseExtensionStructName structure passed to the |
| flink:vkBaseFunctionName command *saying what the extending structure |
| does*. |
| ---- |
| |
| When describing properties of a structure included in a pname:pNext chain, |
| refer to that structure as "`included in the pname:pNext chain`" rather than |
| `"present in`" or other similar terms, in this fashion: |
| |
| [source,asciidoc] |
| ---- |
| If the pname:pNext chain includes a slink:VkPhysicalDeviceFeatures2 |
| structure, then pname:pEnabledFeatures must: be `NULL` |
| ---- |
| |
| |
| [[writing-example]] |
| == Example Command, Structure, and Enumerant Descriptions |
| |
| The <<sample-command,next section>> is a sample based on the |
| <<vulkan-spec,Vulkan API Specification>>, and describes a command and |
| related structures and enumerated types 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. |
| |
| |
| [[sample-command]] |
| == Sample Command Description: Creating Command Pools |
| |
| [open,refpage='vkCreateCommandPool',desc='Create a new command pool object',type='protos'] |
| -- |
| To create a command pool, call: |
| |
| include::{generated}/api/protos/vkCreateCommandPool.adoc[] |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Begin the command description with an open block delimiting the contents as |
| a reference page. |
| The open block contains several required attribute values, as described for |
| <<writing-refpages, 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 `\{generated}/api/protos/` directory: |
| |
| // The 'subs=attributes+' and '{blank}--' are one way to allow the inner |
| // [source] block to show the correct two dashes. See |
| // https://discuss.asciidoctor.org/Another-markup-escaping-question-td5665.html |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| [open,refpage='vkCreateCommandPool',desc='Create a new command pool object',type='protos'] |
| {blank}-- |
| To create a command pool, call: |
| |
| \include::\{generated}/api/protos/vkCreateCommandPool.adoc[] |
| ---- |
| |
| Note that each autogenerated command, enumeration, flag, or structure |
| definition include file also defines a corresponding asciidoctor anchor |
| which is the base name of the file. |
| In this case, the anchor is named `vkCreateCommandPool`. |
| ==== |
| |
| * pname:device is the logical device that the command pool is created on. |
| * pname:pCreateInfo is a pointer to a slink:VkCommandPoolCreateInfo |
| structure specifying the state of the command pool object. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| * pname:pCommandPool is a pointer to a slink:VkCommandPool handle in which |
| the created pool is returned. |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Describe each command parameter in a separate bullet list item. |
| in the same order that parameters appear in the command. |
| |
| Each description must begin with the parameter name. |
| 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{cl} macro. |
| |
| Strive for compact notation, and in particular always try to use the |
| phrasing "`pname{cl}param _is_`" rather than wordier forms such as |
| "`pname{cl}param _specifies_`" or "`The pname{cl}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{cl}device is the logical |
| device`" rather than "`pname{cl}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. |
| ==== |
| |
| This is a general description of creating a command pool. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCreateCommandPool-queueFamilyIndex-01937]] |
| pname:pCreateInfo->queueFamilyIndex must: be the index of a queue family |
| available in the logical device pname:device |
| **** |
| |
| include::{generated}/validity/protos/vkCreateCommandPool.adoc[] |
| -- |
| |
| [NOTE] |
| .Guideline |
| ==== |
| If there is a general description of the command, add it following the |
| parameter descriptions: |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| This is a general description of creating a command pool. |
| ---- |
| |
| If there are _explicit_ valid usage statements for the command, add them in |
| their own valid usage block: |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| .Valid Usage |
| **** |
| * [[VUID-vkCreateCommandPool-queueFamilyIndex-01937]] |
| pname:pCreateInfo->queueFamilyIndex must: be the index of a queue family |
| available in the logical device pname:device |
| **** |
| ---- |
| |
| Although a valid usage ID is shown in the rendered example above, do not |
| specify the ID when initially writing the statement, as |
| <<sample-writing-explicit-vu, described below>>. |
| VUIDs are normally assigned immediately prior to publication. |
| |
| Some parameter and member validation language for commands and structures is |
| _implicit_ (autogenerated from `vk.xml`), and included from the |
| `\{generated}/validity/` directories. |
| All Vulkan command and structure language should include the autogenerated |
| file at the end of their descriptions. |
| It is harmless to include a nonexistent file, in the rare cases where no |
| implicit validity language exists. |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| \include::\{generated}/validity/protos/vkCreateCommandPool.adoc[] |
| {blank}-- |
| ---- |
| |
| Close the open block surrounding the command description after the implicit |
| validity include. |
| All content within the block will be extracted for the corresponding |
| reference page. |
| |
| Open blocks delimiting reference page content should not themselves contain |
| section headers, as asciidoctor cannot render such nested content correctly. |
| Reference pages should in general be relatively short, so this limitation is |
| not severe. |
| |
| Structures and enumerations first introduced as parameters of a command are |
| described next. |
| ==== |
| |
| [open,refpage='VkCommandPoolCreateInfo',desc='Structure specifying parameters of a newly created command pool',type='structs'] |
| -- |
| The sname:VkCommandPoolCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkCommandPoolCreateInfo.adoc[] |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Begin the structure description with an open block delimiting the contents |
| as a reference page, in the same fashion as described above for commands. |
| The open block contains several required attribute values, as described for |
| <<writing-refpages, automatic extraction into a reference page>>. |
| |
| Use a short, active paragraph to introduce the structure, usually just "`The |
| sname:VkStructureName structure is defined as:`". |
| |
| After the description, include the autogenerated definition for the |
| structure from the `\{generated}/api/structs/` directory: |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| [open,refpage='VkCommandPoolCreateInfo',desc='Structure specifying parameters of a newly created command pool',type='structs'] |
| {blank}-- |
| |
| The sname:VkCommandPoolCreateInfo structure is defined as: |
| |
| \include::\{generated}/api/structs/VkCommandPoolCreateInfo.adoc[] |
| ---- |
| ==== |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| + |
| -- |
| This demonstrates how to create a continuation paragraph in a member |
| description. |
| This paragraph is not present in the actual specification the example is |
| based on. |
| -- |
| * pname:flags is a bitmask of elink:VkCommandPoolCreateFlagBits indicating |
| usage behavior for the pool and command buffers allocated from it. |
| * pname:queueFamilyIndex designates a queue family as described in section |
| <<devsandqueues-queueprops,Queue Family Properties>>. |
| All command buffers allocated from this command pool must: be submitted |
| on queues from the same queue family. |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Each structure member is described in a separate bullet list item. |
| For structures with pname:sType and pname:pNext members, there is standard |
| boilerplate for their descriptions. |
| Descriptions of other members of the structure follow. |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| + |
| {blank}-- |
| This demonstrates how to create a continuation paragraph in a member |
| description. |
| This paragraph is not present in the actual specification the example is |
| based on. |
| {blank}-- |
| * pname:flags is a bitmask of elink:VkCommandPoolCreateFlagBits indicating |
| usage behavior for the pool and command buffers allocated from it. |
| * pname:queueFamilyIndex designates a queue family as described in section |
| <<devsandqueues-queueprops,Queue Family Properties>>. |
| All command buffers allocated from this command pool must: be submitted |
| on queues from the same queue family. |
| ---- |
| |
| These entries should be short and functional, without describing details of |
| e.g. new enumerant values, function of individual parameter settings, etc. |
| They can refer to other types using the appropriate *link: macros or to |
| related sections of the specification using asciidoctor xrefs. |
| |
| In rare cases, a member description will cover multiple paragraphs. |
| In these cases the normal list nesting and indentation guidelines cannot be |
| applied due to limitations of the asciidoctor parser. |
| It is usually best to append a continuation block following the first |
| paragraph of such a list item, as shown for pname:pNext above. |
| |
| Add general descriptions of the structure, if any, following the member |
| descriptions. |
| No general description is shown in this example. |
| ==== |
| |
| .Valid Usage |
| **** |
| ifdef::VK_VERSION_1_1[] |
| * [[VUID-VkCommandPoolCreateInfo-flags-02860]] |
| If the <<features-protectedMemory, pname:protectedMemory>> feature is |
| not enabled, the ename:VK_COMMAND_POOL_CREATE_PROTECTED_BIT bit of |
| pname:flags must: not be set |
| endif::VK_VERSION_1_1[] |
| **** |
| |
| include::{generated}/validity/structs/VkCommandPoolCreateInfo.adoc[] |
| -- |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Add explicit valid usage statements (if any) and the implicit autovalidity |
| include in the same fashion as described for commands above, then close the |
| open block. |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| .Valid Usage |
| **** |
| ifdef::VK_VERSION_1_1[] |
| * [[VUID-VkCommandPoolCreateInfo-flags-02860]] |
| If the <<features-protectedMemory, pname:protectedMemory>> feature is |
| not enabled, the ename:VK_COMMAND_POOL_CREATE_PROTECTED_BIT bit of |
| pname:flags must: not be set |
| endif::VK_VERSION_1_1[] |
| **** |
| |
| \include::\{generated}/validity/structs/VkCommandPoolCreateInfo.adoc[] |
| {blank}-- |
| ---- |
| ==== |
| |
| [open,refpage='VkCommandPoolCreateFlagBits',desc='Bitmask specifying usage behavior for a command pool',type='enums'] |
| -- |
| Bits which can: be set in slink:VkCommandPoolCreateInfo::pname:flags to |
| specify usage behavior for a command pool are: |
| |
| include::{generated}/api/enums/VkCommandPoolCreateFlagBits.adoc[] |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Begin an enumerated type description with an open block delimiting the |
| contents as a reference page, in the same fashion as described above for |
| commands and structures. |
| |
| Use boilerplate language similar to that above to introduce the type. |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| [open,refpage='VkCommandPoolCreateFlagBits',desc='Bitmask specifying usage behavior for a command pool',type='enums'] |
| {blank}-- |
| Bits which can: be set in slink:VkCommandPoolCreateInfo::pname:flags to |
| specify usage behavior for a command pool are: |
| |
| \include::\{generated}/api/enums/VkCommandPoolCreateFlagBits.adoc[] |
| ---- |
| ==== |
| |
| * ename:VK_COMMAND_POOL_CREATE_TRANSIENT_BIT specifies that command |
| buffers allocated from the pool will be short-lived, meaning that they |
| will be reset or freed in a relatively short timeframe. |
| This flag may: be used by the implementation to control memory |
| allocation behavior within the pool. |
| ifdef::VK_VERSION_1_1[] |
| * ename:VK_COMMAND_POOL_CREATE_PROTECTED_BIT specifies that command |
| buffers allocated from the pool are protected command buffers. |
| endif::VK_VERSION_1_1[] |
| -- |
| |
| [NOTE] |
| .Guideline |
| ==== |
| Each enumerant in the enumerated type is described in a separate bullet list |
| item. |
| Make sure to protect enumerants added to the type by extensions or future |
| core versions with asciidoctor conditionals. |
| Close the open block after all enumerants are described. |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| * ename:VK_COMMAND_POOL_CREATE_TRANSIENT_BIT specifies that command |
| buffers allocated from the pool will be short-lived, meaning that they |
| will be reset or freed in a relatively short timeframe. |
| This flag may: be used by the implementation to control memory |
| allocation behavior within the pool. |
| \ifdef::VK_VERSION_1_1[] |
| * ename:VK_COMMAND_POOL_CREATE_PROTECTED_BIT specifies that command |
| buffers allocated from the pool are protected command buffers. |
| \endif::VK_VERSION_1_1[] |
| {blank}-- |
| ---- |
| ==== |
| |
| |
| [[sample-writing-explicit-vu]] |
| == Writing Explicit Valid Usage Statements |
| |
| Explicit valid usage statements must be written at a point that all |
| information needed to evaluate them is known. |
| In particular, if validity of structure parameters depends on other |
| parameters of a command that structure is passed to, such valid usage |
| statements must be written for the command, rather than the structure. |
| |
| Each explicit valid usage statement should be a single, self-contained |
| assertion, possibly involving multiple subexpressions or parameters. |
| For example, instead of writing "`width, height, and depth must: all be |
| greater than zero`", write each condition as a separate statement. |
| In contrast, "`width {times} height must: be less than 1024`" is a single |
| assertion involving multiple parameters. |
| |
| Do not use "`unless`" to call out exceptions - always write valid usage |
| statements of the form "`if _A_ then _B_`". |
| This may result in harder to read statements in a few cases, but maintains |
| consistency. |
| In many cases, it may lead to a simpler VU statement, or splitting one large |
| VU into multiple new ones. |
| |
| A valid usage statement may used nested bullet lists or other asciidoc |
| markup. |
| |
| Be clear on the distinction between a "`valid pointer`" and a "`pointer to a |
| valid object`" when writing valid usage statements. |
| See the "`Valid Usage`" section of the Vulkan Specification, and |
| particularly the "`Valid Usage for Pointers`" section. |
| |
| When clauses in valid usage statements apply only when specific extensions |
| and/or core API versions are enabled at runtime, use appropriate asciidoctor |
| conditionals around such clauses. |
| |
| [NOTE] |
| ==== |
| Prior to specification update 1.3.255, there were stronger restrictions on |
| placement of asciidoctor conditionals that have been relaxed, allowing |
| writing such valid usage statements in a more natural manner and with less |
| duplication of language. |
| ==== |
| |
| Explicit valid usage statements must be assigned Valid Usage ID tags before |
| publication. |
| This process is described in the <<vuid, Valid Usage ID Tags>> appendix, but |
| is normally performed only when preparing to integrate functionality into |
| the Vulkan Specification prior to publication. |
| It is something authors of new functionality should be aware of, but are not |
| themselves responsible for. |
| For example, when writing the explicit |
| flink:vkCreateCommandPool::pname:queueFamilyIndex valid usage statement |
| shown above, the tag |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| [[VUID-vkCreateCommandPool-queueFamilyIndex-01937]] |
| ---- |
| |
| was inserted by a script, not the original author. |
| |
| [NOTE] |
| .Guideline |
| ==== |
| If the same set of valid usage statements are going to be common to multiple |
| commands or structures, these should be extracted into a separate file under |
| `chapters/commonvalidity/`. |
| The file name should be short but to the point (e.g. `draw_common.adoc`), |
| and then the file can be included in the relevant API features using |
| standard include syntax: |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| .Valid Usage |
| **** |
| \include::\{chapters}/commonvalidity/draw_common.adoc[] |
| \include::\{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-transformFeedback-02287]] |
| sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback |
| must: be enabled |
| **** |
| ---- |
| |
| Common VU includes should appear before individual VUs for consistency. |
| |
| The file itself should be structured with the comment `// Common Valid |
| Usage` used as a delimiter at the start and end of the file, with a comment |
| describing in more detail where these are included, and then the valid usage |
| statement bullets outside of a valid usage block. |
| For example: |
| |
| [source,asciidoc] |
| ---- |
| // Common Valid Usage |
| // Common to drawing commands that consume vertex binding state |
| * All vertex input bindings accessed via vertex input variables declared |
| in the vertex shader entry point's interface must: have valid buffers |
| bound |
| * For a given vertex buffer binding, any attribute data fetched must: be |
| entirely contained within the corresponding vertex buffer binding, as |
| described in <<fxvertex-input>> |
| // Common Valid Usage |
| ---- |
| |
| Finally, the original feature section needs to define the `:refpage:` |
| attribute to match the name of the feature, as this is used to correctly |
| generate links to expanded common valid usage statements in the built |
| specification. |
| |
| [source,asciidoc] |
| ---- |
| [open,refpage='vkCmdDrawIndirectByteCountEXT',desc='Draw primitives where the vertex count is derived from the counter byte value in the counter buffer',type='protos'] |
| -- |
| :refpage: vkCmdDrawIndirectByteCountEXT |
| ---- |
| |
| In general, this methodology should be preferred over any other method of |
| consolidation - e.g. calling out a block of common valid usage statements, |
| or referencing the valid usage statements of another command. |
| However, for cases where the boilerplate of setting this up creates more |
| text than a simple copy paste (e.g. only two commands consume a single |
| valid usage statement), the original VUs can be left intact. |
| ==== |
| |
| |
| [[writing-empty-enumerations]] |
| == Markup for Empty Enumerated Types |
| |
| Sometimes an enumerated type has all values defined by extensions, and each |
| enumerated value defined by the type will be surrounded by an asciidoctor |
| conditional for the corresponding extension. |
| When a specification is built without any of those extensions enabled, the |
| type should still be included, even though it is empty. |
| In this case, the enumerated value descriptions must be followed by one |
| additional conditional section which is only included when *none* of the |
| relevant extensions are enabled. |
| |
| For example, the relevant part of the |
| ename:VkDescriptorSetLayoutCreateFlagBits description, whose only value is |
| defined by an extension, will look like this: |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| \include::\{generated}/api/enums/VkDescriptorSetLayoutCreateFlagBits.adoc[] |
| |
| \ifdef::VK_KHR_push_descriptor[] |
| * ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR specifies |
| that descriptor sets must: not be allocated using this layout, and |
| descriptors are instead pushed by flink:vkCmdPushDescriptorSetKHR. |
| \endif::VK_KHR_push_descriptor[] |
| |
| \ifndef::VK_KHR_push_descriptor[] |
| [NOTE] |
| .Note |
| ==== |
| All bits for this type are defined by extensions, and none of those |
| extensions are enabled in this build of the specification. |
| ==== |
| \endif::VK_KHR_push_descriptor[] |
| ---- |
| |
| |
| [[writing-refpages]] |
| == Markup for Automatic Reference Page Extraction |
| |
| The Vulkan reference pages are (mostly) 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 an |
| asciidoctor `open` block surrounding markup describing that page, with |
| attributes used to specify properties of the reference page. |
| Additional heuristics and non-asciidoctor tags, described below, are used to |
| identify subsections of a reference page in some cases. |
| |
| In general the open block introduction will look like: |
| |
| [source,asciidoc] |
| ---- |
| [open,refpage='name',desc='short description',type='pagetype',alias='alias',anchor='anchor',xrefs='xrefs'] |
| -- |
| ---- |
| |
| Attributes which can be set on the block are: |
| |
| * *refpage* - the name of the reference page, e.g. the Vulkan interface |
| (command, structure, enumerant, handle, etc.) name. This attribute is |
| required. |
| * *desc* - short description / summary of the page, used in the page |
| title. |
| This attribute is required. |
| * *type* - type of the interface, which must match the directory name |
| following `api/` in the interface `include::` line within the block, and |
| must be one of `basetypes`, `defines`, `enums`, `flags`, `funcpointers`, |
| `handles`, `protos`, or `structs`; or the non-API block types `feature`, |
| `freeform`. or `spirv`. |
| This attribute is required. |
| * *alias* - list of comma-separated names of other API entities which this |
| refpage also describes. This is used when an API is promoted and the |
| refpage block describes both the old and promoted APIs. |
| This attribute is optional. |
| * *anchor* - anchor name at which this reference page is fully described |
| in the API specification document. |
| This attribute is optional except for the non-API block types, which do |
| not correspond to Vulkan APIs. |
| * *xrefs* - list of whitespace-separated names of other reference pages |
| which should be added to the `See Also` section of this page. |
| Most cross-references are automatically generated based on the immediate |
| dependency information in `vk.xml`, but in some cases, such as referring |
| between `*FlagBits` and `*Flags` types, this additional tagging is |
| useful. |
| This attribute is optional. |
| |
| Attributes of the open block must be written in this format, using single |
| quotes as delimiters (even though asciidoctor markup also allows double |
| quotes), and escape single quotes in e.g. the *desc* attribute value with |
| backquotes. |
| |
| After the open block is started, the following markup should be provided: |
| |
| * A single paragraph of text describing the definition of the interface. |
| This paragraph is optional, but strongly recommended. |
| * The `include` line for the interface, which must be consistent with the |
| page name and type in the open block attributes. |
| This paragraph is required. |
| * 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. |
| This list is required, unless the interface has nothing to describe, |
| such as an empty structure or enumeration, or a function with no |
| parameters. |
| * Paragraphs of text making up the `Description` section of the ref page. |
| This section is optional. |
| If it is necessary due to constraints of asciidoctor markup to have an |
| empty line in the bullet list section, add a `// refBody` comment |
| immediately following the bullet list and preceding this section: |
| + |
| [source,asciidoc] |
| ---- |
| // refBody |
| ---- |
| + |
| There are no examples of this usage in the Vulkan 1.2.192 Specification, |
| but it has been needed in the past and may again in the future. |
| + |
| * An explicit valid usage block. |
| This block is required if the interface has such valid usage |
| constraints. |
| * The `include` line for the implicit valid usage block. |
| This line is required for commands and structures, but not for |
| interfaces such as enumerated types, which do not have implicit valid |
| usage blocks. |
| * Finally, a two-dash asciidoctor delimiter closing the open block: |
| + |
| [source,asciidoc] |
| ---- |
| -- |
| ---- |
| |
| All elements specifying an interface name (open block `refpage` attributes, |
| interface `include` lines, and validity `include` lines) 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 - and the language will be structurally |
| incorrect, as well. |
| 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. |
| |
| Content that should only appear in reference pages, such as |
| developer-oriented guidelines for reference pages describing extensions, may |
| be conditionally included in the specification as follows: |
| |
| [source,asciidoc,subs=attributes+] |
| ---- |
| \ifdef::isrefpage[] |
| |
| === Refpage-Only Section |
| |
| *This section will appear only when generating an extension refpage, |
| but not in the specification extensions appendix.* |
| |
| \endif::isrefpage[] |
| ---- |