summaryrefslogtreecommitdiff
path: root/src/glsl/nir/docs/source/intro.rst
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl/nir/docs/source/intro.rst')
-rw-r--r--src/glsl/nir/docs/source/intro.rst161
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.
+