Mesa (main): docs/freedreno: Rewrite the section on array access.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jun 3 03:28:07 UTC 2021
Module: Mesa
Branch: main
Commit: 3b19545966b771cf44a32f186351eacbcf30e89b
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=3b19545966b771cf44a32f186351eacbcf30e89b
Author: Emma Anholt <emma at anholt.net>
Date: Wed Jun 2 13:12:41 2021 -0700
docs/freedreno: Rewrite the section on array access.
We don't use collect/split for array access these days, instead use
ir3_array structs that the ir3_register can point to.
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11147>
---
docs/drivers/freedreno/ir3-notes.rst | 87 ++++++++++++------------------------
1 file changed, 29 insertions(+), 58 deletions(-)
diff --git a/docs/drivers/freedreno/ir3-notes.rst b/docs/drivers/freedreno/ir3-notes.rst
index 91c1fe4c8cc..0d859813d5f 100644
--- a/docs/drivers/freedreno/ir3-notes.rst
+++ b/docs/drivers/freedreno/ir3-notes.rst
@@ -292,81 +292,52 @@ results in:
The scheduling pass has some smarts to schedule things such that only a single ``a0.x`` value is used at any one time.
-To implement variable arrays, values are stored in consecutive scalar registers. This has some overlap with `register groups`_, in that ``collect`` and ``split`` are used to help group things for the `register assignment`_ pass.
-
-To use a variable array as a src register, a slight variation of what is done for const array src. The instruction src is a `collect` instruction that groups all the array members:
+To implement variable arrays, the NIR registers are stored as an ``ir3_array``,
+which will be register allocated to consecutive hardware registers. The array
+access uses the id field in the ``ir3_register`` to map to the array being
+accessed, and the offset field for the fixed offset within the array. A NIR
+indirect register read such as:
::
- mova a0.x, hr1.y
- sub r1.y, r2.x, r3.x
- add r0.x, r1.y, r<a0.x + 2>
+ decl_reg vec2 32 r0[2]
+ ...
+ vec2 32 ssa_19 = mov r0[0 + ssa_9]
-results in:
-.. graphviz::
+results in:
- digraph {
- a0 [label="r0.z"];
- a1 [label="r0.w"];
- a2 [label="r1.x"];
- a3 [label="r1.y"];
- sub;
- collect;
- mova;
- add;
- add -> sub;
- add -> collect [label="off=2"];
- add -> mova;
- collect -> a0;
- collect -> a1;
- collect -> a2;
- collect -> a3;
- }
+::
-TODO better describe how actual deref offset is derived, i.e. based on array base register.
+ 0000:0000:001: shl.b hssa_19, hssa_17, himm[0.000000,1,0x1]
+ 0000:0000:002: mov.s16s16 hr61.x, hssa_19
+ 0000:0000:002: mov.u32u32 ssa_21, arr[id=1, offset=0, size=4, ssa_12], address=_[0000:0000:002: mov.s16s16]
+ 0000:0000:002: mov.u32u32 ssa_22, arr[id=1, offset=1, size=4, ssa_12], address=_[0000:0000:002: mov.s16s16]
-To do an indirect write to a variable array, a ``split`` is used. Say the array was assigned to registers ``r0.z`` through ``r1.y`` (hence the constant offset of 2):
- Note that only cat1 (mov) can do indirect write.
+Array writes write to the array in ``instr->regs[0]->array.id``. A NIR indirect
+register write such as:
::
- mova a0.x, hr1.y
- min r2.x, r2.x, c0.x
- mov r<a0.x + 2>, r2.x
- mul r0.x, r0.z, c0.z
-
-
-In this case, the ``mov`` instruction does not write all elements of the array (compared to usage of ``split`` for ``sam`` instructions in grouping_). But the ``mov`` instruction does need an additional dependency (via ``collect``) on instructions that last wrote the array element members, to ensure that they get scheduled before the ``mov`` in scheduling_ stage (which also serves to group the array elements for the `register assignment`_ stage).
+ decl_reg vec2 32 r0[2]
+ ...
+ r0[0 + ssa_12] = mov ssa_13
-.. graphviz::
+results in:
- digraph {
- a0 [label="r0.z"];
- a1 [label="r0.w"];
- a2 [label="r1.x"];
- a3 [label="r1.y"];
- min;
- mova;
- mov;
- mul;
- split [label="split\noff=0"];
- mul -> split;
- split -> mov;
- collect;
- collect -> a0;
- collect -> a1;
- collect -> a2;
- collect -> a3;
- mov -> min;
- mov -> mova;
- mov -> collect;
- }
+::
-Note that there would in fact be ``split`` nodes generated for each array element (although only the reachable ones will be scheduled, etc).
+ 0000:0000:001: shl.b hssa_29, hssa_27, himm[0.000000,1,0x1]
+ 0000:0000:002: mov.s16s16 hr61.x, hssa_29
+ 0000:0000:001: mov.u32u32 arr[id=1, offset=0, size=4, ssa_17], c2.y, address=_[0000:0000:002: mov.s16s16]
+ 0000:0000:004: mov.u32u32 arr[id=1, offset=1, size=4, ssa_31], c2.z, address=_[0000:0000:002: mov.s16s16]
+Note that only cat1 (mov) can do indirect write, and thus NIR register stores
+may need to introduce an extra mov.
+ir3 array accesses in the DAG get serialized by the ``instr->barrier_class`` and
+containing ``IR3_BARRIER_ARRAY_W`` or ``IR3_BARRIER_ARRAY_R``.
Shader Passes
-------------
More information about the mesa-commit
mailing list