gallium/ttn: Convert to using VARYING_SLOT_* / FRAG_RESULT_*.
authorEric Anholt <eric@anholt.net>
Tue, 4 Aug 2015 21:28:02 +0000 (14:28 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 16 Sep 2015 19:03:53 +0000 (15:03 -0400)
This avoids exceeding the size of the .index bitfield since it got
truncated, and should make our NIR look more like the NIR that the rest of
the NIR developers are working on.

v2: split out vc4 updates, first patch uses varying_slot_to_tgsi_semantic()
    helper, and second patch does the actual conversion.
v3: add frag_result_to_tgsi_semantic() helper and don't try to map
    frag_results to semantic name/index as if they were varying_slot's
v4: use VERT_ATTRIB_ for VS inputs
v5: Fix vc4 build.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/auxiliary/nir/tgsi_to_nir.c
src/gallium/auxiliary/nir/tgsi_to_nir.h
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
src/gallium/drivers/vc4/vc4_nir_lower_blend.c
src/gallium/drivers/vc4/vc4_nir_lower_io.c
src/gallium/drivers/vc4/vc4_program.c

index cccc5606ccf3c7b8d4a5fd135c7b4e6f9ef23f2d..cf43ef2506f532cafd14663ffb1099e9f9589d43 100644 (file)
@@ -94,6 +94,128 @@ struct ttn_compile {
 #define ttn_channel(b, src, swiz) \
    nir_swizzle(b, src, SWIZ(swiz, swiz, swiz, swiz), 1, false)
 
+static gl_varying_slot
+tgsi_varying_semantic_to_slot(unsigned semantic, unsigned index)
+{
+   switch (semantic) {
+   case TGSI_SEMANTIC_POSITION:
+      return VARYING_SLOT_POS;
+   case TGSI_SEMANTIC_COLOR:
+      if (index == 0)
+         return VARYING_SLOT_COL0;
+      else
+         return VARYING_SLOT_COL1;
+   case TGSI_SEMANTIC_BCOLOR:
+      if (index == 0)
+         return VARYING_SLOT_BFC0;
+      else
+         return VARYING_SLOT_BFC1;
+   case TGSI_SEMANTIC_FOG:
+      return VARYING_SLOT_FOGC;
+   case TGSI_SEMANTIC_PSIZE:
+      return VARYING_SLOT_PSIZ;
+   case TGSI_SEMANTIC_GENERIC:
+      return VARYING_SLOT_VAR0 + index;
+   case TGSI_SEMANTIC_FACE:
+      return VARYING_SLOT_FACE;
+   case TGSI_SEMANTIC_EDGEFLAG:
+      return VARYING_SLOT_EDGE;
+   case TGSI_SEMANTIC_PRIMID:
+      return VARYING_SLOT_PRIMITIVE_ID;
+   case TGSI_SEMANTIC_CLIPDIST:
+      if (index == 0)
+         return VARYING_SLOT_CLIP_DIST0;
+      else
+         return VARYING_SLOT_CLIP_DIST1;
+   case TGSI_SEMANTIC_CLIPVERTEX:
+      return VARYING_SLOT_CLIP_VERTEX;
+   case TGSI_SEMANTIC_TEXCOORD:
+      return VARYING_SLOT_TEX0 + index;
+   case TGSI_SEMANTIC_PCOORD:
+      return VARYING_SLOT_PNTC;
+   case TGSI_SEMANTIC_VIEWPORT_INDEX:
+      return VARYING_SLOT_VIEWPORT;
+   case TGSI_SEMANTIC_LAYER:
+      return VARYING_SLOT_LAYER;
+   default:
+      fprintf(stderr, "Bad TGSI semantic: %d/%d\n", semantic, index);
+      abort();
+   }
+}
+
+/* Temporary helper to remap back to TGSI style semantic name/index
+ * values, for use in drivers that haven't been converted to using
+ * VARYING_SLOT_
+ */
+void
+varying_slot_to_tgsi_semantic(gl_varying_slot slot,
+                              unsigned *semantic_name, unsigned *semantic_index)
+{
+   static const unsigned map[][2] = {
+      [VARYING_SLOT_POS] = { TGSI_SEMANTIC_POSITION, 0 },
+      [VARYING_SLOT_COL0] = { TGSI_SEMANTIC_COLOR, 0 },
+      [VARYING_SLOT_COL1] = { TGSI_SEMANTIC_COLOR, 1 },
+      [VARYING_SLOT_BFC0] = { TGSI_SEMANTIC_BCOLOR, 0 },
+      [VARYING_SLOT_BFC1] = { TGSI_SEMANTIC_BCOLOR, 1 },
+      [VARYING_SLOT_FOGC] = { TGSI_SEMANTIC_FOG, 0 },
+      [VARYING_SLOT_PSIZ] = { TGSI_SEMANTIC_PSIZE, 0 },
+      [VARYING_SLOT_FACE] = { TGSI_SEMANTIC_FACE, 0 },
+      [VARYING_SLOT_EDGE] = { TGSI_SEMANTIC_EDGEFLAG, 0 },
+      [VARYING_SLOT_PRIMITIVE_ID] = { TGSI_SEMANTIC_PRIMID, 0 },
+      [VARYING_SLOT_CLIP_DIST0] = { TGSI_SEMANTIC_CLIPDIST, 0 },
+      [VARYING_SLOT_CLIP_DIST1] = { TGSI_SEMANTIC_CLIPDIST, 1 },
+      [VARYING_SLOT_CLIP_VERTEX] = { TGSI_SEMANTIC_CLIPVERTEX, 0 },
+      [VARYING_SLOT_PNTC] = { TGSI_SEMANTIC_PCOORD, 0 },
+      [VARYING_SLOT_VIEWPORT] = { TGSI_SEMANTIC_VIEWPORT_INDEX, 0 },
+      [VARYING_SLOT_LAYER] = { TGSI_SEMANTIC_LAYER, 0 },
+   };
+
+   if (slot >= VARYING_SLOT_VAR0) {
+      *semantic_name = TGSI_SEMANTIC_GENERIC;
+      *semantic_index = slot - VARYING_SLOT_VAR0;
+      return;
+   }
+
+   if (slot >= VARYING_SLOT_TEX0 && slot <= VARYING_SLOT_TEX7) {
+      *semantic_name = TGSI_SEMANTIC_TEXCOORD;
+      *semantic_index = slot - VARYING_SLOT_TEX0;
+      return;
+   }
+
+   if (slot >= ARRAY_SIZE(map)) {
+      fprintf(stderr, "Unknown varying slot %d\n", slot);
+      abort();
+   }
+
+   *semantic_name = map[slot][0];
+   *semantic_index = map[slot][1];
+}
+
+/* Temporary helper to remap back to TGSI style semantic name/index
+ * values, for use in drivers that haven't been converted to using
+ * FRAG_RESULT_
+ */
+void
+frag_result_to_tgsi_semantic(gl_frag_result slot,
+                             unsigned *semantic_name, unsigned *semantic_index)
+{
+   static const unsigned map[][2] = {
+      [FRAG_RESULT_DEPTH] = { TGSI_SEMANTIC_POSITION, 0 },
+      [FRAG_RESULT_COLOR] = { TGSI_SEMANTIC_COLOR, -1 },
+      [FRAG_RESULT_DATA0 + 0] = { TGSI_SEMANTIC_COLOR, 0 },
+      [FRAG_RESULT_DATA0 + 1] = { TGSI_SEMANTIC_COLOR, 1 },
+      [FRAG_RESULT_DATA0 + 2] = { TGSI_SEMANTIC_COLOR, 2 },
+      [FRAG_RESULT_DATA0 + 3] = { TGSI_SEMANTIC_COLOR, 3 },
+      [FRAG_RESULT_DATA0 + 4] = { TGSI_SEMANTIC_COLOR, 4 },
+      [FRAG_RESULT_DATA0 + 5] = { TGSI_SEMANTIC_COLOR, 5 },
+      [FRAG_RESULT_DATA0 + 6] = { TGSI_SEMANTIC_COLOR, 6 },
+      [FRAG_RESULT_DATA0 + 7] = { TGSI_SEMANTIC_COLOR, 7 },
+   };
+
+   *semantic_name = map[slot][0];
+   *semantic_index = map[slot][1];
+}
+
 static nir_ssa_def *
 ttn_src_for_dest(nir_builder *b, nir_alu_dest *dest)
 {
@@ -216,12 +338,15 @@ ttn_emit_declaration(struct ttn_compile *c)
             var->data.mode = nir_var_shader_in;
             var->name = ralloc_asprintf(var, "in_%d", idx);
 
-            /* We should probably translate to a VERT_ATTRIB_* or VARYING_SLOT_*
-             * instead, but nothing in NIR core is looking at the value
-             * currently, and this is less change to drivers.
-             */
-            var->data.location = decl->Semantic.Name;
-            var->data.index = decl->Semantic.Index;
+            if (c->scan->processor == TGSI_PROCESSOR_FRAGMENT) {
+               var->data.location =
+                  tgsi_varying_semantic_to_slot(decl->Semantic.Name,
+                                                decl->Semantic.Index);
+            } else {
+               assert(!decl->Declaration.Semantic);
+               var->data.location = VERT_ATTRIB_GENERIC0 + idx;
+            }
+            var->data.index = 0;
 
             /* We definitely need to translate the interpolation field, because
              * nir_print will decode it.
@@ -241,6 +366,8 @@ ttn_emit_declaration(struct ttn_compile *c)
             exec_list_push_tail(&b->shader->inputs, &var->node);
             break;
          case TGSI_FILE_OUTPUT: {
+            int semantic_name = decl->Semantic.Name;
+            int semantic_index = decl->Semantic.Index;
             /* Since we can't load from outputs in the IR, we make temporaries
              * for the outputs and emit stores to the real outputs at the end of
              * the shader.
@@ -252,14 +379,40 @@ ttn_emit_declaration(struct ttn_compile *c)
 
             var->data.mode = nir_var_shader_out;
             var->name = ralloc_asprintf(var, "out_%d", idx);
-
-            var->data.location = decl->Semantic.Name;
-            if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
-                decl->Semantic.Index == 0 &&
-                c->scan->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
-               var->data.index = -1;
-            else
-               var->data.index = decl->Semantic.Index;
+            var->data.index = 0;
+
+            if (c->scan->processor == TGSI_PROCESSOR_FRAGMENT) {
+               switch (semantic_name) {
+               case TGSI_SEMANTIC_COLOR: {
+                  /* TODO tgsi loses some information, so we cannot
+                   * actually differentiate here between DSB and MRT
+                   * at this point.  But so far no drivers using tgsi-
+                   * to-nir support dual source blend:
+                   */
+                  bool dual_src_blend = false;
+                  if (dual_src_blend && (semantic_index == 1)) {
+                     var->data.location = FRAG_RESULT_DATA0;
+                     var->data.index = 1;
+                  } else {
+                     if (c->scan->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
+                        var->data.location = FRAG_RESULT_COLOR;
+                     else
+                        var->data.location = FRAG_RESULT_DATA0 + semantic_index;
+                  }
+                  break;
+               }
+               case TGSI_SEMANTIC_POSITION:
+                  var->data.location = FRAG_RESULT_DEPTH;
+                  break;
+               default:
+                  fprintf(stderr, "Bad TGSI semantic: %d/%d\n",
+                          decl->Semantic.Name, decl->Semantic.Index);
+                  abort();
+               }
+            } else {
+               var->data.location =
+                  tgsi_varying_semantic_to_slot(semantic_name, semantic_index);
+            }
 
             if (is_array) {
                unsigned j;
index 687348a80efa86ea1910d88b055dcefe4400f572..1a185a8321901e7eb9d75d7bb5a22d7fdbc46ea6 100644 (file)
@@ -28,3 +28,9 @@ struct nir_shader_compiler_options *options;
 struct nir_shader *
 tgsi_to_nir(const void *tgsi_tokens,
             const struct nir_shader_compiler_options *options);
+void
+varying_slot_to_tgsi_semantic(gl_varying_slot slot,
+                              unsigned *semantic_name, unsigned *semantic_index);
+void
+frag_result_to_tgsi_semantic(gl_frag_result slot,
+                             unsigned *semantic_name, unsigned *semantic_index);
index 7ce1c976e9c554011bab981978dffc94dbee21d5..83a138515b578fe12738e48e1f9dafa0279722b6 100644 (file)
@@ -2133,17 +2133,12 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
        struct ir3_shader_variant *so = ctx->so;
        unsigned array_len = MAX2(glsl_get_length(in->type), 1);
        unsigned ncomp = glsl_get_components(in->type);
-       /* XXX: map loc slots to semantics */
-       unsigned semantic_name = in->data.location;
-       unsigned semantic_index = in->data.index;
        unsigned n = in->data.driver_location;
+       unsigned slot = in->data.location;
 
-       DBG("; in: %u:%u, len=%ux%u, loc=%u",
-                       semantic_name, semantic_index, array_len,
-                       ncomp, n);
+       DBG("; in: slot=%u, len=%ux%u, drvloc=%u",
+                       slot, array_len, ncomp, n);
 
-       so->inputs[n].semantic =
-                       ir3_semantic_name(semantic_name, semantic_index);
        so->inputs[n].compmask = (1 << ncomp) - 1;
        so->inputs[n].inloc = ctx->next_inloc;
        so->inputs[n].interpolate = 0;
@@ -2164,11 +2159,19 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
                break;
        }
 
-       for (int i = 0; i < ncomp; i++) {
-               struct ir3_instruction *instr = NULL;
-               unsigned idx = (n * 4) + i;
+       if (ctx->so->type == SHADER_FRAGMENT) {
+               unsigned semantic_name, semantic_index;
+
+               varying_slot_to_tgsi_semantic(slot,
+                               &semantic_name, &semantic_index);
+
+               so->inputs[n].semantic =
+                               ir3_semantic_name(semantic_name, semantic_index);
+
+               for (int i = 0; i < ncomp; i++) {
+                       struct ir3_instruction *instr = NULL;
+                       unsigned idx = (n * 4) + i;
 
-               if (ctx->so->type == SHADER_FRAGMENT) {
                        if (semantic_name == TGSI_SEMANTIC_POSITION) {
                                so->inputs[n].bary = false;
                                so->frag_coord = true;
@@ -2208,11 +2211,17 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
                                instr = create_frag_input(ctx,
                                                so->inputs[n].inloc + i - 8, use_ldlv);
                        }
-               } else {
-                       instr = create_input(ctx->block, idx);
-               }
 
-               ctx->ir->inputs[idx] = instr;
+                       ctx->ir->inputs[idx] = instr;
+               }
+       } else if (ctx->so->type == SHADER_VERTEX) {
+               so->inputs[n].semantic = 0;
+               for (int i = 0; i < ncomp; i++) {
+                       unsigned idx = (n * 4) + i;
+                       ctx->ir->inputs[idx] = create_input(ctx->block, idx);
+               }
+       } else {
+               compile_error(ctx, "unknown shader type: %d\n", ctx->so->type);
        }
 
        if (so->inputs[n].bary || (ctx->so->type == SHADER_VERTEX)) {
@@ -2227,17 +2236,18 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
        struct ir3_shader_variant *so = ctx->so;
        unsigned array_len = MAX2(glsl_get_length(out->type), 1);
        unsigned ncomp = glsl_get_components(out->type);
-       /* XXX: map loc slots to semantics */
-       unsigned semantic_name = out->data.location;
-       unsigned semantic_index = out->data.index;
+       unsigned semantic_name, semantic_index;
        unsigned n = out->data.driver_location;
+       unsigned slot = out->data.location;
        unsigned comp = 0;
 
-       DBG("; out: %u:%u, len=%ux%u, loc=%u",
-                       semantic_name, semantic_index, array_len,
-                       ncomp, n);
+       DBG("; out: slot=%u, len=%ux%u, drvloc=%u",
+                       slot, array_len, ncomp, n);
 
        if (ctx->so->type == SHADER_VERTEX) {
+               varying_slot_to_tgsi_semantic(slot,
+                               &semantic_name, &semantic_index);
+
                switch (semantic_name) {
                case TGSI_SEMANTIC_POSITION:
                        so->writes_pos = true;
@@ -2255,7 +2265,10 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
                        compile_error(ctx, "unknown VS semantic name: %s\n",
                                        tgsi_semantic_names[semantic_name]);
                }
-       } else {
+       } else if (ctx->so->type == SHADER_FRAGMENT) {
+               frag_result_to_tgsi_semantic(slot,
+                               &semantic_name, &semantic_index);
+
                switch (semantic_name) {
                case TGSI_SEMANTIC_POSITION:
                        comp = 2;  /* tgsi will write to .z component */
@@ -2271,6 +2284,8 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
                        compile_error(ctx, "unknown FS semantic name: %s\n",
                                        tgsi_semantic_names[semantic_name]);
                }
+       } else {
+               compile_error(ctx, "unknown shader type: %d\n", ctx->so->type);
        }
 
        compile_assert(ctx, n < ARRAY_SIZE(so->outputs));
index 808cbea8fde2adc7e01f8157ff63b672bebd9ac3..f8c3c5f65bfb7178f05d9e9ef236195928cfe9fc 100644 (file)
@@ -38,6 +38,7 @@
 #include "util/u_format.h"
 #include "vc4_qir.h"
 #include "glsl/nir/nir_builder.h"
+#include "nir/tgsi_to_nir.h"
 #include "vc4_context.h"
 
 /** Emits a load of the previous fragment color from the tile buffer. */
@@ -400,7 +401,10 @@ vc4_nir_lower_blend_block(nir_block *block, void *state)
                         }
                 }
                 assert(output_var);
-                unsigned semantic_name = output_var->data.location;
+                unsigned semantic_name, semantic_index;
+
+                varying_slot_to_tgsi_semantic(output_var->data.location,
+                                              &semantic_name, &semantic_index);
 
                 if (semantic_name != TGSI_SEMANTIC_COLOR)
                         continue;
index c401415fda7efca0410815b8e48cacca6a28b263..31ac64b0f7a8cb68c58575e02b8dc3fc7dc35304 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "vc4_qir.h"
+#include "nir/tgsi_to_nir.h"
 #include "tgsi/tgsi_info.h"
 #include "glsl/nir/nir_builder.h"
 
@@ -71,8 +72,11 @@ vc4_nir_lower_input(struct vc4_compile *c, nir_builder *b,
                 }
         }
         assert(input_var);
-        int semantic_name = input_var->data.location;
-        int semantic_index = input_var->data.index;
+        unsigned semantic_name, semantic_index;
+
+        varying_slot_to_tgsi_semantic(input_var->data.location,
+                                      &semantic_name, &semantic_index);
+
 
         /* All TGSI-to-NIR inputs are vec4. */
         assert(intr->num_components == 4);
@@ -141,7 +145,10 @@ vc4_nir_lower_output(struct vc4_compile *c, nir_builder *b,
                 }
         }
         assert(output_var);
-        unsigned semantic_name = output_var->data.location;
+        unsigned semantic_name, semantic_index;
+
+        varying_slot_to_tgsi_semantic(output_var->data.location,
+                                      &semantic_name, &semantic_index);
 
         if (c->stage == QSTAGE_COORD &&
             (semantic_name != TGSI_SEMANTIC_POSITION &&
index e002983fdbb4446922b3143007f9e5762d51c16b..7d59a2f070211bb43e7b00d3cbe3aa17b57c147b 100644 (file)
@@ -1412,11 +1412,12 @@ ntq_setup_inputs(struct vc4_compile *c)
         for (unsigned i = 0; i < num_entries; i++) {
                 nir_variable *var = vars[i];
                 unsigned array_len = MAX2(glsl_get_length(var->type), 1);
-                /* XXX: map loc slots to semantics */
-                unsigned semantic_name = var->data.location;
-                unsigned semantic_index = var->data.index;
+                unsigned semantic_name, semantic_index;
                 unsigned loc = var->data.driver_location;
 
+                varying_slot_to_tgsi_semantic(var->data.location,
+                                              &semantic_name, &semantic_index);
+
                 assert(array_len == 1);
                 (void)array_len;
                 resize_qreg_array(c, &c->inputs, &c->inputs_array_size,
@@ -1448,11 +1449,17 @@ ntq_setup_outputs(struct vc4_compile *c)
 {
         foreach_list_typed(nir_variable, var, node, &c->s->outputs) {
                 unsigned array_len = MAX2(glsl_get_length(var->type), 1);
-                /* XXX: map loc slots to semantics */
-                unsigned semantic_name = var->data.location;
-                unsigned semantic_index = var->data.index;
+                unsigned semantic_name, semantic_index;
                 unsigned loc = var->data.driver_location * 4;
 
+                if (c->stage == QSTAGE_FRAG) {
+                        frag_result_to_tgsi_semantic(var->data.location,
+                                                     &semantic_name, &semantic_index);
+                } else {
+                        varying_slot_to_tgsi_semantic(var->data.location,
+                                                      &semantic_name, &semantic_index);
+                }
+
                 assert(array_len == 1);
                 (void)array_len;