diff options
author | dan sinclair <dsinclair@google.com> | 2019-09-19 09:46:27 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-19 09:46:27 -0400 |
commit | 47e354b0c2c813bdbec63085df40000efc811a23 (patch) | |
tree | 18b763e8106482713766e453ea58ef183e9e93b4 /docs | |
parent | 605c2e3c0ea7cab09c6cc3bc2a48030ba78d3a03 (diff) | |
download | spirv-tools-47e354b0c2c813bdbec63085df40000efc811a23.tar.gz |
Move docs into docs/ folder (#2872)
Diffstat (limited to 'docs')
-rw-r--r-- | docs/downloads.md | 14 | ||||
-rw-r--r-- | docs/projects.md | 82 | ||||
-rw-r--r-- | docs/syntax.md | 238 |
3 files changed, 334 insertions, 0 deletions
diff --git a/docs/downloads.md b/docs/downloads.md new file mode 100644 index 00000000..9c7d8567 --- /dev/null +++ b/docs/downloads.md @@ -0,0 +1,14 @@ +# Downloads +Download the latest builds. + +## Release +| Windows | Linux | MacOS | +| --- | --- | --- | +| [MSVC 2017](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_release.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_release.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html) | +| | [gcc](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_gcc_release.html) | | + +## Debug +| Windows | Linux | MacOS | +| --- | --- | --- | +| [MSVC 2017](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_debug.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_debug.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_debug.html) | +| | [gcc](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_gcc_debug.html) | | diff --git a/docs/projects.md b/docs/projects.md new file mode 100644 index 00000000..8f7f0bcd --- /dev/null +++ b/docs/projects.md @@ -0,0 +1,82 @@ +# Tracking SPIRV-Tools work with GitHub projects + +We are experimenting with using the [GitHub Project +feature](https://help.github.com/articles/tracking-the-progress-of-your-work-with-projects/) +to track progress toward large goals. + +For more on GitHub Projects in general, see: +* [Introductory blog post](https://github.com/blog/2256-a-whole-new-github-universe-announcing-new-tools-forums-and-features) +* [Introductory video](https://www.youtube.com/watch?v=C6MGKHkNtxU) + +The current SPIRV-Tools project list can be found at +[https://github.com/KhronosGroup/SPIRV-Tools/projects](https://github.com/KhronosGroup/SPIRV-Tools/projects) + +## How we use a Project + +A GitHub Project is a set of work with an overall purpose, and +consists of a collection of *Cards*. +Each card is either a *Note* or a regular GitHub *Issue.* +A Note can be converted to an Issue. + +In our projects, a card represents work, i.e. a change that can +be applied to the repository. +The work could be a feature, a bug to be fixed, documentation to be +updated, etc. + +A project and its cards are used as a [Kanban +board](https://en.wikipedia.org/wiki/Kanban_board), where cards progress +through a workflow starting with ideas through to implementation and completion. + +In our usage, a *project manager* is someone who organizes the work. +They manage the creation and movement of cards +through the project workflow: +* They create cards to capture ideas, or to decompose large ideas into smaller + ones. +* They determine if the work for a card has been completed. +* Normally they are the person (or persons) who can approve and merge a pull + request into the `master` branch. + +Our projects organize cards into the following columns: +* `Ideas`: Work which could be done, captured either as Cards or Notes. + * A card in this column could be marked as a [PLACEHOLDER](#placeholders). +* `Ready to start`: Issues which represent work we'd like to do, and which + are not blocked by other work. + * The issue should be narrow enough that it can usually be addressed by a + single pull request. + * We want these to be Issues (not Notes) so that someone can claim the work + by updating the Issue with their intent to do the work. + Once an Issue is claimed, the project manager moves the corresponding card + from `Ready to start` to `In progress`. +* `In progress`: Issues which were in `Ready to start` but which have been + claimed by someone. +* `Done`: Issues which have been resolved, by completing their work. + * The changes have been applied to the repository, typically by being pushed + into the `master` branch. + * Other kinds of work could update repository settings, for example. +* `Rejected ideas`: Work which has been considered, but which we don't want + implemented. + * We keep rejected ideas so they are not proposed again. This serves + as a form of institutional memory. + * We should record why an idea is rejected. For this reason, a rejected + idea is likely to be an Issue which has been closed. + +## Prioritization + +We are considering prioritizing cards in the `Ideas` and `Ready to start` +columns so that things that should be considered first float up to the top. + +Experience will tell us if we stick to that rule, and if it proves helpful. + +## Placeholders + +A *placeholder* is a Note or Issue that represents a possibly large amount +of work that can be broadly defined but which may not have been broken down +into small implementable pieces of work. + +Use a placeholder to capture a big idea, but without doing the upfront work +to consider all the details of how it should be implemented. +Over time, break off pieces of the placeholder into implementable Issues. +Move those Issues into the `Ready to start` column when they become unblocked. + +We delete the placeholder when all its work has been decomposed into +implementable cards. diff --git a/docs/syntax.md b/docs/syntax.md new file mode 100644 index 00000000..be3a5d5a --- /dev/null +++ b/docs/syntax.md @@ -0,0 +1,238 @@ +# SPIR-V Assembly language syntax + +## Overview + +The assembly attempts to adhere to the binary form from Section 3 of the SPIR-V +spec as closely as possible, with one exception aiming at improving the text's +readability. The `<result-id>` generated by an instruction is moved to the +beginning of that instruction and followed by an `=` sign. This allows us to +distinguish between variable definitions and uses and locate value definitions +more easily. + +Here is an example: + +``` + OpCapability Shader + OpMemoryModel Logical Simple + OpEntryPoint GLCompute %3 "main" + OpExecutionMode %3 LocalSize 64 64 1 +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%4 = OpLabel + OpReturn + OpFunctionEnd +``` + +A module is a sequence of instructions, separated by whitespace. +An instruction is an opcode name followed by operands, separated by +whitespace. Typically each instruction is presented on its own line, +but the assembler does not enforce this rule. + +The opcode names and expected operands are described in Section 3 of +the SPIR-V specification. An operand is one of: +* a literal integer: A decimal integer, or a hexadecimal integer. + A hexadecimal integer is indicated by a leading `0x` or `0X`. A hex + integer supplied for a signed integer value will be sign-extended. + For example, `0xffff` supplied as the literal for an `OpConstant` + on a signed 16-bit integer type will be interpreted as the value `-1`. +* a literal floating point number, in decimal or hexadecimal form. + See [below](#floats). +* a literal string. + * A literal string is everything following a double-quote `"` until the + following un-escaped double-quote. This includes special characters such + as newlines. + * A backslash `\` may be used to escape characters in the string. The `\` + may be used to escape a double-quote or a `\` but is simply ignored when + preceding any other character. +* a named enumerated value, specific to that operand position. For example, + the `OpMemoryModel` takes a named Addressing Model operand (e.g. `Logical` or + `Physical32`), and a named Memory Model operand (e.g. `Simple` or `OpenCL`). + Named enumerated values are only meaningful in specific positions, and will + otherwise generate an error. +* a mask expression, consisting of one or more mask enum names separated + by `|`. For example, the expression `NotNaN|NotInf|NSZ` denotes the mask + which is the combination of the `NotNaN`, `NotInf`, and `NSZ` flags. +* an injected immediate integer: `!<integer>`. See [below](#immediate). +* an ID, e.g. `%foo`. See [below](#id). +* the name of an extended instruction. For example, `sqrt` in an extended + instruction such as `%f = OpExtInst %f32 %OpenCLImport sqrt %arg` +* the name of an opcode for OpSpecConstantOp, but where the `Op` prefix + is removed. For example, the following indicates the use of an integer + addition in a specialization constant computation: + `%sum = OpSpecConstantOp %i32 IAdd %a %b` + +## ID Definitions & Usage +<a name="id"></a> + +An ID _definition_ pertains to the `<result-id>` of an instruction, and ID +_usage_ is a use of an ID as an input to an instruction. + +An ID in the assembly language begins with `%` and must be followed by a name +consisting of one or more letters, numbers or underscore characters. + +For every ID in the assembly program, the assembler generates a unique number +called the ID's internal number. Then each ID reference translates into its +internal number in the SPIR-V output. Internal numbers are unique within the +compilation unit: no two IDs in the same unit will share internal numbers. + +The disassembler generates IDs where the name is always a decimal number +greater than 0. + +So the example can be rewritten using more user-friendly names, as follows: +``` + OpCapability Shader + OpMemoryModel Logical Simple + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 64 64 1 + %void = OpTypeVoid +%fnMain = OpTypeFunction %void + %main = OpFunction %void None %fnMain +%lbMain = OpLabel + OpReturn + OpFunctionEnd +``` + +## Floating point literals +<a name="floats"></a> + +The assembler and disassembler support floating point literals in both +decimal and hexadecimal form. + +The syntax for a floating point literal is the same as floating point +constants in the C programming language, except: +* An optional leading minus (`-`) is part of the literal. +* An optional type specifier suffix is not allowed. +Infinity and NaN values are expressed in hexadecimal float literals +by using the maximum representable exponent for the bit width. + +For example, in 32-bit floating point, 8 bits are used for the exponent, and the +exponent bias is 127. So the maximum representable unbiased exponent is 128. +Therefore, we represent the infinities and some NaNs as follows: + +``` +%float32 = OpTypeFloat 32 +%inf = OpConstant %float32 0x1p+128 +%neginf = OpConstant %float32 -0x1p+128 +%aNaN = OpConstant %float32 0x1.8p+128 +%moreNaN = OpConstant %float32 -0x1.0002p+128 +``` +The assembler preserves all the bits of a NaN value. For example, the encoding +of `%aNaN` in the previous example is the same as the word with bits +`0x7fc00000`, and `%moreNaN` is encoded as `0xff800100`. + +The disassembler prints infinite, NaN, and subnormal values in hexadecimal form. +Zero and normal values are printed in decimal form with enough digits +to preserve all significand bits. + +## Arbitrary Integers +<a name="immediate"></a> + +When writing tests it can be useful to emit an invalid 32 bit word into the +binary stream at arbitrary positions within the assembly. To specify an +arbitrary word into the stream the prefix `!` is used, this takes the form +`!<integer>`. Here is an example. + +``` +OpCapability !0x0000FF00 +``` + +Any token in a valid assembly program may be replaced by `!<integer>` -- even +tokens that dictate how the rest of the instruction is parsed. Consider, for +example, the following assembly program: + +``` +%4 = OpConstant %1 123 456 789 OpExecutionMode %2 LocalSize 11 22 33 +OpExecutionMode %3 InputLines +``` + +The tokens `OpConstant`, `LocalSize`, and `InputLines` may be replaced by random +`!<integer>` values, and the assembler will still assemble an output binary with +three instructions. It will not necessarily be valid SPIR-V, but it will +faithfully reflect the input text. + +You may wonder how the assembler recognizes the instruction structure (including +instruction boundaries) in the text with certain crucial tokens replaced by +arbitrary integers. If, say, `OpConstant` becomes a `!<integer>` whose value +differs from the binary representation of `OpConstant` (remember that this +feature is intended for fine-grain control in SPIR-V testing), the assembler +generally has no idea what that value stands for. So how does it know there is +exactly one `<id>` and three number literals following in that instruction, +before the next one begins? And if `LocalSize` is replaced by an arbitrary +`!<integer>`, how does it know to take the next three tokens (instead of zero or +one, both of which are possible in the absence of certainty that `LocalSize` +provided)? The answer is a simple rule governing the parsing of instructions +with `!<integer>` in them: + +When a token in the assembly program is a `!<integer>`, that integer value is +emitted into the binary output, and parsing proceeds differently than before: +each subsequent token not recognized as an OpCode or a <result-id> is emitted +into the binary output without any checking; when a recognizable OpCode or a +<result-id> is eventually encountered, it begins a new instruction and parsing +returns to normal. (If a subsequent OpCode is never found, then this alternate +parsing mode handles all the remaining tokens in the program.) + +The assembler processes the tokens encountered in alternate parsing mode as +follows: + +* If the token is a number literal, since context may be lost, the number + is interpreted as a 32-bit value and output as a single word. In order to + specify multiple-word literals in alternate-parsing mode, further uses of + `!<integer>` tokens may be required. + All formats supported by `strtoul()` are accepted. +* If the token is a string literal, it outputs a sequence of words representing + the string as defined in the SPIR-V specification for Literal String. +* If the token is an ID, it outputs the ID's internal number. +* If the token is another `!<integer>`, it outputs that integer. +* Any other token causes the assembler to quit with an error. + +Note that this has some interesting consequences, including: + +* When an OpCode is replaced by `!<integer>`, the integer value should encode + the instruction's word count, as specified in the physical-layout section of + the SPIR-V specification. + +* Consecutive instructions may have their OpCode replaced by `!<integer>` and + still produce valid SPIR-V. For example, `!262187 %1 %2 "abc" !327739 %1 %3 6 + %2` will successfully assemble into SPIR-V declaring a constant and a + PrivateGlobal variable. + +* Enums (such as `DontInline` or `SubgroupMemory`, for instance) are not handled + by the alternate parsing mode. They must be replaced by `!<integer>` for + successful assembly. + +* The `<result-id>` on the left-hand side of an assignment cannot be a + `!<integer>`. The `<result-id>` can be still be manually controlled if desired + by expressing the entire instruction as `!<integer>` tokens for its opcode and + operands. + +* The `=` sign cannot be processed by the alternate parsing mode if the OpCode + following it is a `!<integer>`. + +* When replacing a named ID with `!<integer>`, it is possible to generate + unintentionally valid SPIR-V. If the integer provided happens to equal a + number generated for an existing named ID, it will result in a reference to + that named ID being output. This may be valid SPIR-V, contrary to the + presumed intention of the writer. + +## Notes + +* Some enumerants cannot be used by name, because the target instruction +in which they are meaningful take an ID reference instead of a literal value. +For example: + * Named enumerated value `CmdExecTime` from section 3.30 Kernel + Profiling Info is used in constructing a mask value supplied as + an ID for `OpCaptureEventProfilingInfo`. But no other instruction + has enough context to bring the enumerant names from section 3.30 + into scope. + * Similarly, the names in section 3.29 Kernel Enqueue Flags are used to + construct a value supplied as an ID to the Flags argument of + OpEnqueueKernel. + * Similarly for the names in section 3.25 Memory Semantics. + * Similarly for the names in section 3.27 Scope. +* Some enumerants cannot be used by name, because they only name values +returned by an instruction: + * Enumerants from 3.12 Image Channel Order name possible values returned + by the `OpImageQueryOrder` instruction. + * Enumerants from 3.13 Image Channel Data Type name possible values + returned by the `OpImageQueryFormat` instruction. |