[Mesa-dev] [PATCH v3 10/12] vc4/nir: Use the new unified io intrinsics

Jason Ekstrand jason at jlekstrand.net
Tue Dec 8 13:46:27 PST 2015


---
 src/gallium/drivers/vc4/vc4_nir_lower_blend.c |  1 +
 src/gallium/drivers/vc4/vc4_nir_lower_io.c    | 38 ++++++++++++++++------
 src/gallium/drivers/vc4/vc4_program.c         | 47 +++++++++++++++++----------
 3 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
index 0672a92..5bd69fb 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
@@ -49,6 +49,7 @@ vc4_nir_get_dst_color(nir_builder *b)
                                            nir_intrinsic_load_input);
         load->num_components = 1;
         load->const_index[0] = VC4_NIR_TLB_COLOR_READ_INPUT;
+        load->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
         nir_ssa_dest_init(&load->instr, &load->dest, 1, NULL);
         nir_builder_instr_insert(b, &load->instr);
         return &load->dest.ssa;
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_io.c b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
index e3d018f..c3bafbf 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_io.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
@@ -179,6 +179,12 @@ vc4_nir_lower_vertex_attr(struct vc4_compile *c, nir_builder *b,
         /* All TGSI-to-NIR inputs are vec4. */
         assert(intr->num_components == 4);
 
+        /* We only accept direct outputs and TGSI only ever gives them to us
+         * with an offset value of 0.
+         */
+        assert(nir_src_as_const_value(intr->src[0]) &&
+               nir_src_as_const_value(intr->src[0])->u[0] == 0);
+
         /* Generate dword loads for the VPM values (Since these intrinsics may
          * be reordered, the actual reads will be generated at the top of the
          * shader by ntq_setup_inputs().
@@ -190,6 +196,7 @@ vc4_nir_lower_vertex_attr(struct vc4_compile *c, nir_builder *b,
                                                    nir_intrinsic_load_input);
                 intr_comp->num_components = 1;
                 intr_comp->const_index[0] = intr->const_index[0] * 4 + i;
+                intr_comp->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
                 nir_ssa_dest_init(&intr_comp->instr, &intr_comp->dest, 1, NULL);
                 nir_builder_instr_insert(b, &intr_comp->instr);
 
@@ -243,6 +250,12 @@ vc4_nir_lower_fs_input(struct vc4_compile *c, nir_builder *b,
         /* All TGSI-to-NIR inputs are vec4. */
         assert(intr->num_components == 4);
 
+        /* We only accept direct inputs and TGSI only ever gives them to us
+         * with an offset value of 0.
+         */
+        assert(nir_src_as_const_value(intr->src[0]) &&
+               nir_src_as_const_value(intr->src[0])->u[0] == 0);
+
         /* Generate scalar loads equivalent to the original VEC4. */
         nir_ssa_def *dests[4];
         for (unsigned i = 0; i < intr->num_components; i++) {
@@ -250,6 +263,8 @@ vc4_nir_lower_fs_input(struct vc4_compile *c, nir_builder *b,
                         nir_intrinsic_instr_create(c->s, nir_intrinsic_load_input);
                 intr_comp->num_components = 1;
                 intr_comp->const_index[0] = intr->const_index[0] * 4 + i;
+                intr_comp->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
+
                 nir_ssa_dest_init(&intr_comp->instr, &intr_comp->dest, 1, NULL);
                 nir_builder_instr_insert(b, &intr_comp->instr);
 
@@ -317,6 +332,12 @@ vc4_nir_lower_output(struct vc4_compile *c, nir_builder *b,
         /* All TGSI-to-NIR outputs are VEC4. */
         assert(intr->num_components == 4);
 
+        /* We only accept direct outputs and TGSI only ever gives them to us
+         * with an offset value of 0.
+         */
+        assert(nir_src_as_const_value(intr->src[1]) &&
+               nir_src_as_const_value(intr->src[1])->u[0] == 0);
+
         b->cursor = nir_before_instr(&intr->instr);
 
         for (unsigned i = 0; i < intr->num_components; i++) {
@@ -328,6 +349,7 @@ vc4_nir_lower_output(struct vc4_compile *c, nir_builder *b,
                 assert(intr->src[0].is_ssa);
                 intr_comp->src[0] =
                         nir_src_for_ssa(nir_channel(b, intr->src[0].ssa, i));
+                intr_comp->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
                 nir_builder_instr_insert(b, &intr_comp->instr);
         }
 
@@ -358,15 +380,12 @@ vc4_nir_lower_uniform(struct vc4_compile *c, nir_builder *b,
                 /* Convert the base offset to bytes and add the component */
                 intr_comp->const_index[0] = (intr->const_index[0] * 16 + i * 4);
 
-                if (intr->intrinsic == nir_intrinsic_load_uniform_indirect) {
-                        /* Convert the variable TGSI register index to a byte
-                         * offset.
-                         */
-                        intr_comp->src[0] =
-                                nir_src_for_ssa(nir_ishl(b,
-                                                         intr->src[0].ssa,
-                                                         nir_imm_int(b, 4)));
-                }
+                /* Convert the offset to bytes.  If it happens to be a
+                 * constant, constant-folding will clean up the shift for us.
+                 */
+                intr_comp->src[0] =
+                        nir_src_for_ssa(nir_ishl(b, intr->src[0].ssa,
+                                                 nir_imm_int(b, 4)));
 
                 dests[i] = &intr_comp->dest.ssa;
 
@@ -397,7 +416,6 @@ vc4_nir_lower_io_instr(struct vc4_compile *c, nir_builder *b,
                 break;
 
         case nir_intrinsic_load_uniform:
-        case nir_intrinsic_load_uniform_indirect:
         case nir_intrinsic_load_user_clip_plane:
                 vc4_nir_lower_uniform(c, b, intr);
                 break;
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 5ce1143..bdf89c5 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -1440,7 +1440,8 @@ static void
 ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
 {
         const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
-        int dword_offset;
+        nir_const_value *const_offset;
+        unsigned offset;
         struct qreg *dest = NULL;
 
         if (info->has_dest) {
@@ -1450,23 +1451,25 @@ ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
         switch (instr->intrinsic) {
         case nir_intrinsic_load_uniform:
                 assert(instr->num_components == 1);
-                /* The offset is in bytes, but we need dwords */
-                assert(instr->const_index[0] % 4 == 0);
-                dword_offset = instr->const_index[0] / 4;
-                if (dword_offset < VC4_NIR_STATE_UNIFORM_OFFSET) {
-                        *dest = qir_uniform(c, QUNIFORM_UNIFORM, dword_offset);
+                const_offset = nir_src_as_const_value(instr->src[0]);
+                if (const_offset) {
+                        offset = instr->const_index[0] + const_offset->u[0];
+                        assert(offset % 4 == 0);
+                        /* We need dwords */
+                        offset = offset / 4;
+                        if (offset < VC4_NIR_STATE_UNIFORM_OFFSET) {
+                                *dest = qir_uniform(c, QUNIFORM_UNIFORM,
+                                                    offset);
+                        } else {
+                                *dest = qir_uniform(c, offset -
+                                                    VC4_NIR_STATE_UNIFORM_OFFSET,
+                                                    0);
+                        }
                 } else {
-                        *dest = qir_uniform(c, dword_offset -
-                                            VC4_NIR_STATE_UNIFORM_OFFSET,
-                                            0);
+                        *dest = indirect_uniform_load(c, instr);
                 }
                 break;
 
-        case nir_intrinsic_load_uniform_indirect:
-                *dest = indirect_uniform_load(c, instr);
-
-                break;
-
         case nir_intrinsic_load_user_clip_plane:
                 *dest = qir_uniform(c, QUNIFORM_USER_CLIP_PLANE,
                                     instr->const_index[0]);
@@ -1478,18 +1481,26 @@ ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
 
         case nir_intrinsic_load_input:
                 assert(instr->num_components == 1);
+                const_offset = nir_src_as_const_value(instr->src[0]);
+                assert(const_offset && "vc4 doesn't support indirect inputs");
                 if (instr->const_index[0] == VC4_NIR_TLB_COLOR_READ_INPUT) {
+                        assert(const_offset->u[0] == 0);
                         *dest = qir_TLB_COLOR_READ(c);
                 } else {
-                        *dest = c->inputs[instr->const_index[0]];
+                        offset = instr->const_index[0] + const_offset->u[0];
+                        *dest = c->inputs[offset];
                 }
                 break;
 
         case nir_intrinsic_store_output:
                 assert(instr->num_components == 1);
-                c->outputs[instr->const_index[0]] =
-                        qir_MOV(c, ntq_get_src(c, instr->src[0], 0));
-                c->num_outputs = MAX2(c->num_outputs, instr->const_index[0] + 1);
+
+                const_offset = nir_src_as_const_value(instr->src[1]);
+                assert(const_offset && "vc4 doesn't support indirect outputs");
+                offset = instr->const_index[0] + const_offset->u[0];
+
+                c->outputs[offset] = qir_MOV(c, ntq_get_src(c, instr->src[0], 0));
+                c->num_outputs = MAX2(c->num_outputs, offset + 1);
                 break;
 
         case nir_intrinsic_discard:
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list