diff options
Diffstat (limited to 'src/glsl/nir/docs/source/intro.rst')
-rw-r--r-- | src/glsl/nir/docs/source/intro.rst | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/glsl/nir/docs/source/intro.rst b/src/glsl/nir/docs/source/intro.rst new file mode 100644 index 0000000000..7c0f78c501 --- /dev/null +++ b/src/glsl/nir/docs/source/intro.rst @@ -0,0 +1,161 @@ +Introduction +============ + +What is NIR? +------------ + +NIR is an Intermediate Representation (IR) that's designed for the needs of +graphics drivers in Mesa. It sits between a frontend that translates another +language or IR such as GLSL IR or TGSI to NIR and the driver's own backend IR. +It includes several optimization passes, as well as some features that are +useful for making translating to the driver's own IR easier, although it is +*not* intended to replace the backend and as such doesn't support +backend-specific tasks such as scheduling, register allocation, etc. + +NIR was designed with several goals in mind: + +* To be backend-agnostic. There are some features, such as registers, that + require some level of backend involvement, but no core NIR optimization pass + depends on the semantics of these features. Instead, almost all interaction + besides simple operations such as addition and subtraction is described using + loads and stores to *variables* that are similar to variables in GLSL. +* To natively understand constructs, such as structured control flow, that are + common in GPU's but not elsewhere. +* To be compatible with the extensive body of literature around compiler + technology. NIR natively supports Single Static Assignment (SSA), which is + a prerequisite for many important optimizations, and all of its optimizations + assume SSA. Furthermore, NIR structures programs into *basic blocks*, which + is often assumed by compiler papers, and it supports several analyses such as + dominance analysis and liveness analysis that are often used by + optimizations. All of these things greatly reduce the hassle of translating + an idea described in a paper into code. + +One thing that NIR is *not* designed to be is a library for users outside of +Mesa. It's not possible to extend NIR at run-time to add additional +operations, although it's flexible enough that it's usually easy to do at +compile time. Furthermore, there is no stable API; it's expected that +producers and consumers will live in-tree so we can update them if we have to +make breaking changes. + +Organization +------------ + +NIR is written in C, although in a very object-oriented manner. Structures +and enums are typedef'ed: + +:: + + typedef struct nir_foo { + /* stuff */ + } nir_foo; + + typedef enum { + nir_enum_thing1, + nir_enum_thing2, + nir_enum_thing3, + } nir_enum; + +and inheritance is done through embedding structures. Upcasting is done +through inline functions defined by the NIR_DEFINE_CAST macro. For example, +here's how an animal structure inherited by cows, cats, and dogs would be +defined: + +:: + + typedef enum { + nir_animal_type_cow, + nir_animal_type_dog, + nir_animal_type_cat, + } nir_animal_type; + + typedef struct { + nir_animal_type type; + /* stuff */ + } nir_animal; + + typedef struct { + nir_animal animal; + } nir_cow; + + typedef struct { + nir_animal animal; + } nir_dog; + + typedef struct { + nir_animal animal; + } nir_cat; + + NIR_DEFINE_CAST(nir_animal_as_cow, nir_animal, nir_cow, animal) + NIR_DEFINE_CAST(nir_animal_as_dog, nir_animal, nir_dog, animal) + NIR_DEFINE_CAST(nir_animal_as_cat, nir_animal, nir_cat, animal) + +Datastructures +~~~~~~~~~~~~~~ + +The core IR consists of various structures defined in nir.h, as well as +functions for creating, destroying, and manipulating them. Currently, these +structures include: + +* ``nir_shader``: represents a linked or unlinked shader. This may contain one + or more functions as well as global registers and variables and other + whole-shader type information. Right now, a ``nir_shader`` usually only + contains one function called "main", but that may change. +* ``nir_function``: represents a GLSL-style overloaded function, for linking + purposes. It includes the name as well as a list of overloads. +* ``nir_function_overload``: represents a declaration or definition of a + function overload. If it's a declaration, then the ``impl`` field will be + NULL, and if it's a definition then ``impl`` will point to a + ``nir_function_impl``. +* ``nir_function_impl``: contains function-local stuff such as local + variables and registers. It's also the root of the *control flow tree*. +* ``nir_cf_node``: represents a node in the control flow tree. For more + information, see :doc:`Control Flow </control_flow>`. + + * ``nir_if`` + * ``nir_loop`` + * ``nir_block`` + +* ``nir_instr``: the base class for instructions in NIR. Each ``nir_block`` + has a list of ``nir_instr``'s. For more information, see :doc:`Instructions + </instructions>`. + + * ``nir_alu_instr`` + * ``nir_call_instr`` + * ``nir_jump_instr`` + * ``nir_tex_instr`` + * ``nir_intrinsic_instr`` + * ``nir_load_const_instr`` + * ``nir_ssa_undef_instr`` + * ``nir_phi_instr`` + * ``nir_parallel_copy_instr`` + +* ``nir_dest`` +* ``nir_src`` +* ``nir_ssa_def`` +* ``nir_register`` +* ``nir_variable`` +* ``nir_deref`` + * ``nir_deref_var`` + * ``nir_deref_struct`` + * ``nir_deref_array`` + +Printing +~~~~~~~~ + +NIR includes a function called ``nir_print_shader()`` for printing the +contents of a shader to a given ``FILE *``, which can be useful for +debugging. In addition, ``nir_print_instr()`` is exposed, which can be useful +for examining instructions in the debugger. + +Validation +~~~~~~~~~~ + +There are various bits of redundant information as well as various invariants +which must be satisfied in the IR. Often, passes will have bugs which result +in those invariants being broken or the information left incorrect, which may +only blow up much later when some other pass or analysis relies on that +information. To make debugging those sorts of problems much easier, NIR has a +validation pass, ``nir_validate_shader()``, which makes sure that the shader +is valid. It's a no-op on release builds, but when debugging it catches many +bugs at the source instead of much later. + |