Vulkan-Docs/doc/specs/vulkan/style/writing.txt

740 lines
24 KiB
Plaintext

// Copyright (c) 2015-2017 Khronos Group. This work is licensed under a
// Creative Commons Attribution 4.0 International License; see
// http://creativecommons.org/licenses/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 http://blog.oxforddictionaries.com/2011/06/oxford-comma/
=== 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 ambigious 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`" http://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 asciidoc 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.`"
=== 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
|====
[[writing-compound-words]]
=== 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 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 |
| 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
3+h| 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
// 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-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, 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-latexmath]]
== 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 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`.
.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} + {onehalf}#
| +++[eq]#{onequarter} + {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} + 1#
| +++[eq]#{lceil}log~2~(max(pname:width, pname:height)){rceil} + 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~ + (1-t) **P**~2~#
| +++[eq]#**P** = t **P**~1~ + (1-t) **P**~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 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 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{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 asciidoc 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've had to make are:
.LaTeX math replacements for KaTeX compatibility
[width="70%",options="header",cols="20%,20%,60%"]
|====
| Replace | With | Comments
| `\begin{equation}` | _nothing_ | Unnecessary in blocks. Should not be used for inline.
| `\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
|====
See https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX for a list
of currently supported LaTeX functionality in KaTeX.
You can also use the live katex preview tool on the KaTeX website to double
check support, without building the whole spec:
https://khan.github.io/KaTeX/
See https://github.com/gjtorikian/mtex2MML/blob/master/SUPPORTED.md for the
list of supported operations in the PDF build.
\mathop in particular is not supported properly by the PDF build, 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-pNext-chain]]
== Describing Extension Structure Chains
When describing an extension structure which is passed to an existing
command by placing 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 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*.
----
[[writing-example]]
== An Example Command Description
The <<sample-command,next section>> is a sample based on the
<<vulkan-spec,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.
[[sample-command]]
== Sample Command Description: Creating Command Pools
// refBegin vkCreateCommandPool Create a new command pool object
To create a command pool, call:
include::../api/protos/vkCreateCommandPool.txt[]
[NOTE]
.Guideline
====
Begin the command description with a comment delimiting the language 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 `../protos/` directory:
[source,asciidoc]
----
// 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`.
====
* pname:device is the logical device that the command pool is created on.
* pname:pCreateInfo points to an instance of the
slink:VkCommandPoolCreateInfo structure containing information used to
create the command pool.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
* pname: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{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.
====
include::../validity/protos/vkCreateCommandPool.txt[]
[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 fname:vkCreateCommandPool used as an example here has no such explicit
language, but the sname:VkCommandPoolCreateInfo used below does have
explicit language.
[source,asciidoc]
----
\include::../validity/protos/vkCreateCommandPool.txt[]
----
Structures and enumerations first used as parameters of a command are
described next.
====
// refBegin VkCommandPoolCreateInfo - Structure specifying parameters of a newly created command pool
The sname:VkCommandPoolCreateInfo structure is defined as:
include::../api/structs/VkCommandPoolCreateInfo.txt[]
[NOTE]
.Guideline
====
Begin the structure description with a `refBegin` comment delimiting the
language for <<writing-refpages,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
sname:VkStructureName structure is defined as:`".
After the description, include the autogenerated definition for the
structure from the `../structs/` directory:
[source,asciidoc]
----
// refBegin VkCommandPoolCreateInfo - Structure specifying parameters of
a newly created command pool
The sname:VkCommandPoolCreateInfo structure is defined as:
\include::../api/structs/VkCommandPoolCreateInfo.txt[]
----
====
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:flags is a combination of bitmask flags indicating usage behavior
for the pool and command buffers allocated from it.
Possible values 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.
* pname: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 stext:Vk*CreateInfo structures in particular, there is standard
boilerplate for the pname:sType and pname:pNext members, followed by the
members specific to the structure.
[source,asciidoc]
----
* 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:
[source,asciidoc]
----
* 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
****
* pname:queueFamilyIndex must: be the index of a queue family available in
the calling command's pname:device parameter
****
include::../validity/structs/VkCommandPoolCreateInfo.txt[]
[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:
[source,asciidoc]
----
.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[]
----
Each explicit Valid Usage statement should be a single 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.
====
[[writing-refpages]]
== 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:
+
--
[source,asciidoc]
----
// 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 section^1^, add a `refBody` comment
immediately following the bullet list and preceding this section:
+
--
[source,asciidoc]
----
// 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:
+
--
[source,asciidoc]
----
// refEnd name [seeAlsoNames]*
----
--
1::
The only example of such markup in the 1.0.28 Vulkan Specification
source is the stext: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.