diff options
author | Jason Ekstrand <jason@jlekstrand.net> | 2021-06-18 08:16:18 -0500 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-06-21 16:46:59 +0000 |
commit | 73188c6954299d57c5b3eb30c514977895283b66 (patch) | |
tree | ebef2eb62749edc8f454b6afb5847e3fe39ecdc2 /docs/nir | |
parent | f00b5a30f5799b5072197ecb92bbcc16877109cd (diff) | |
download | mesa-73188c6954299d57c5b3eb30c514977895283b66.tar.gz mesa-73188c6954299d57c5b3eb30c514977895283b66.tar.bz2 mesa-73188c6954299d57c5b3eb30c514977895283b66.zip |
nir,docs: Add docs for NIR ALU instructions
About half or more of the text here is actually from Connor Abbot. I've
edited it a bit to bring it up-to-date and make a few things more clear.
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11438>
Diffstat (limited to 'docs/nir')
-rw-r--r-- | docs/nir/alu.rst | 69 | ||||
-rw-r--r-- | docs/nir/index.rst | 13 |
2 files changed, 82 insertions, 0 deletions
diff --git a/docs/nir/alu.rst b/docs/nir/alu.rst new file mode 100644 index 00000000000..315b99cf29e --- /dev/null +++ b/docs/nir/alu.rst @@ -0,0 +1,69 @@ +NIR ALU Instructions +==================== + +ALU instructions represent simple operations, such as addition, multiplication, +comparison, etc., that take a certain number of arguments and return a result +that only depends on the arguments. ALU instructions in NIR must be pure in +the sense that they have no side effect and that identical inputs yields an +identical output. A good rule of thumb is that only things which can be +constant folded should be ALU operations. If it can't be constant folded, then +it should probably be an intrinsic instead. + +Each ALU instruction has an opcode, which is a member of the :cpp:enum:`nir_op` +enum, that describes what it does as well as how many arguments it takes. +Associated with each opcode is an metadata structure, +:cpp:struct:`nir_op_info`, which shows how many arguments the opcode takes, +information about data types, and algebraic properties such as associativity +and commutivity. The info structure for each opcode may be accessed through +a global :cpp:var:`nir_op_infos` array that’s indexed by the opcode. + +ALU operations are typeless, meaning that they're only defined to convert +a certain bit-pattern input to another bit-pattern output. The only concrete +notion of types for a NIR SSA value or register is that each value has a number +of vector components and a bit-size. How that data is interpreted is entirely +controlled by the opcode. NIR doesn't have opcodes for ``intBitsToFloat()`` +and friends because they are implicit. + +Even though ALU operations are typeless, each opcode also has an "ALU type" +metadata for each of the sources and the destination which can be +floating-point, boolean, integer, or unsigned integer. The ALU type mainly +helps back-ends which want to handle all conversion instructions, for instance, +in a single switch case. They're also important when a back-end requests the +absolute value, negate, and saturate modifiers (not used by core NIR). In that +case, modifiers are interpreted with respect to the ALU type on the source or +destination of the instruction. In addition, if an operation takes a boolean +argument, then the argument may be assumed to be either ``0`` for false or +``~0`` (a.k.a ``-1``) for true even if it is not a 1-bit value. If an +operation’s result has a boolean type, then it may only produce only ``0`` or ``~0``. + +Most of the common ALU ops in NIR operate per-component, meaning that the +operation is defined by what it does on a single scalar value and, when +performed on vectors, it performs the same operation on each component. Things +like add, multiply, etc. fall into this category. Per-component operations +naturally scale to as many components as necessary. Non-per-component ALU ops +are things like :nir:alu-op:`vec4` or :nir:alu-op:`pack_64_2x32` where any +given component in the result value may be a combination of any component in +any source. These ops have a number of destination components and a number of +components required by each source which is fixed by the opcode. + +While most instruction types in NIR require vector sizes to perfectly match on +inputs and outputs, ALU instruction sources have an additional +:cpp:member:`nir_alu_src::swizzle` field which allows them to act on vectors +which are not the native vector size of the instruction. This is ideal for +hardware with a native data type of :c:expr:`vec4` but also means that ALU +instructions are often used (and required) for packing/unpacking vectors for +use in other instruction types like intrinsics or texture ops. + +.. doxygenstruct:: nir_op_info + :members: + +.. doxygenvariable:: nir_op_infos + +.. doxygenstruct:: nir_alu_instr + :members: + +.. doxygenstruct:: nir_alu_src + :members: + +.. doxygenstruct:: nir_alu_dest + :members: diff --git a/docs/nir/index.rst b/docs/nir/index.rst new file mode 100644 index 00000000000..630ba011885 --- /dev/null +++ b/docs/nir/index.rst @@ -0,0 +1,13 @@ +NIR Intermediate Representation (NIR) +===================================== + +The NIR Intermediate Representation (NIR) is the optimizing compiler stack that +sits at the core of most Mesa drivers' shader compilers. It consists of a set +of enums and data structures that make up the IR as well as a suite of helper +functions, optimization passes, and lowering passes for building a compiler +stack. + +.. toctree:: + :maxdepth: 2 + + alu |