[Mesa-dev] [PATCH 01/11] gallium/ttn: Convert to using VARYING_SLOT_* / FRAG_RESULT_*.

Rob Clark robdclark at gmail.com
Sun Sep 13 08:51:48 PDT 2015


From: Eric Anholt <eric at anholt.net>

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

Signed-off-by: Rob Clark <robclark at freedesktop.org>
---
 src/gallium/auxiliary/nir/tgsi_to_nir.c            | 181 +++++++++++++++++++--
 src/gallium/auxiliary/nir/tgsi_to_nir.h            |   6 +
 .../drivers/freedreno/ir3/ir3_compiler_nir.c       |  61 ++++---
 src/gallium/drivers/vc4/vc4_nir_lower_blend.c      |   5 +-
 src/gallium/drivers/vc4/vc4_nir_lower_io.c         |  12 +-
 src/gallium/drivers/vc4/vc4_program.c              |  19 ++-
 6 files changed, 237 insertions(+), 47 deletions(-)

diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c
index cccc560..cf43ef2 100644
--- a/src/gallium/auxiliary/nir/tgsi_to_nir.c
+++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c
@@ -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;
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.h b/src/gallium/auxiliary/nir/tgsi_to_nir.h
index 687348a..1a185a8 100644
--- a/src/gallium/auxiliary/nir/tgsi_to_nir.h
+++ b/src/gallium/auxiliary/nir/tgsi_to_nir.h
@@ -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);
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
index 5a069fb..db930d4 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
@@ -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));
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
index 808cbea..3210ac8 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
@@ -400,7 +400,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;
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_io.c b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
index b632370..408a25f 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_io.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
@@ -72,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);
@@ -142,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 &&
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index e002983..7d59a2f 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -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;
 
-- 
2.4.3



More information about the mesa-dev mailing list