ttn: Use nir_load_front_face instead of the TGSI-style input.
authorEric Anholt <eric@anholt.net>
Thu, 4 Aug 2016 20:20:31 +0000 (13:20 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 19 Aug 2016 20:11:36 +0000 (13:11 -0700)
This reduces the diff between GLSL-to-NIR and TGSI-to-NIR, and gives NIR
more optimization to work on.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/gallium/auxiliary/nir/tgsi_to_nir.c
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
src/gallium/drivers/vc4/vc4_nir_lower_io.c

index 3d80ef06f13dd84b6f2db72904e7bc20103e0ec8..906c6436faf92ad3676bdc2907647bb3a42bb78b 100644 (file)
@@ -339,9 +339,14 @@ ttn_emit_declaration(struct ttn_compile *c)
             var->name = ralloc_asprintf(var, "in_%d", idx);
 
             if (c->scan->processor == PIPE_SHADER_FRAGMENT) {
-               var->data.location =
-                  tgsi_varying_semantic_to_slot(decl->Semantic.Name,
-                                                decl->Semantic.Index);
+               if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) {
+                  var->data.location = SYSTEM_VALUE_FRONT_FACE;
+                  var->data.mode = nir_var_system_value;
+               } else {
+                  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;
@@ -593,6 +598,25 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
 
       switch (file) {
       case TGSI_FILE_INPUT:
+         /* Special case: Turn the frontface varying into a load of the
+          * frontface intrinsic plus math, and appending the silly floats.
+          */
+         if (c->scan->processor == PIPE_SHADER_FRAGMENT &&
+             c->scan->input_semantic_name[index] == TGSI_SEMANTIC_FACE) {
+            nir_ssa_def *tgsi_frontface[4] = {
+               nir_bcsel(&c->build,
+                         nir_load_system_value(&c->build,
+                                               nir_intrinsic_load_front_face, 0),
+                         nir_imm_float(&c->build, 1.0),
+                         nir_imm_float(&c->build, -1.0)),
+               nir_imm_float(&c->build, 0.0),
+               nir_imm_float(&c->build, 0.0),
+               nir_imm_float(&c->build, 1.0),
+            };
+
+            return nir_src_for_ssa(nir_vec(&c->build, tgsi_frontface, 4));
+         }
+
          op = nir_intrinsic_load_input;
          assert(!dim);
          break;
index 63235663ffe36063ad554779b25252580cbbe872..22f5525c6aa55ed8072438195d5754991d0f15d3 100644 (file)
@@ -571,48 +571,6 @@ create_frag_coord(struct ir3_compile *ctx, unsigned comp)
        }
 }
 
-/* NOTE: this creates the "TGSI" style fragface (ie. input slot
- * VARYING_SLOT_FACE).  For NIR style nir_intrinsic_load_front_face
- * we can just use the value from hw directly (since it is boolean)
- */
-static struct ir3_instruction *
-create_frag_face(struct ir3_compile *ctx, unsigned comp)
-{
-       struct ir3_block *block = ctx->block;
-       struct ir3_instruction *instr;
-
-       switch (comp) {
-       case 0: /* .x */
-               compile_assert(ctx, !ctx->frag_face);
-
-               ctx->frag_face = create_input(block, 0);
-               ctx->frag_face->regs[0]->flags |= IR3_REG_HALF;
-
-               /* for faceness, we always get -1 or 0 (int).. but TGSI expects
-                * positive vs negative float.. and piglit further seems to
-                * expect -1.0 or 1.0:
-                *
-                *    mul.s tmp, hr0.x, 2
-                *    add.s tmp, tmp, 1
-                *    mov.s32f32, dst, tmp
-                *
-                */
-               instr = ir3_MUL_S(block, ctx->frag_face, 0,
-                               create_immed(block, 2), 0);
-               instr = ir3_ADD_S(block, instr, 0,
-                               create_immed(block, 1), 0);
-               instr = ir3_COV(block, instr, TYPE_S32, TYPE_F32);
-
-               return instr;
-       case 1: /* .y */
-       case 2: /* .z */
-               return create_immed(block, fui(0.0));
-       default:
-       case 3: /* .w */
-               return create_immed(block, fui(1.0));
-       }
-}
-
 static struct ir3_instruction *
 create_driver_param(struct ir3_compile *ctx, enum ir3_driver_param dp)
 {
@@ -2053,10 +2011,6 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
                                so->inputs[n].slot = VARYING_SLOT_VAR8;
                                so->inputs[n].bary = true;
                                instr = create_frag_input(ctx, false);
-                       } else if (slot == VARYING_SLOT_FACE) {
-                               so->inputs[n].bary = false;
-                               so->frag_face = true;
-                               instr = create_frag_face(ctx, i);
                        } else {
                                bool use_ldlv = false;
 
index 2b4ad9c5ea6dddd08e0caa02a37a04981fe1009c..e55f77cd38fd02e76fd5bc378863c8ad14306f2c 100644 (file)
@@ -273,20 +273,7 @@ vc4_nir_lower_fs_input(struct vc4_compile *c, nir_builder *b,
                 dests[i] = &intr_comp->dest.ssa;
         }
 
-        if (input_var->data.location == VARYING_SLOT_FACE) {
-                /* TGSI-to-NIR's front face.  Convert to using the system
-                 * value boolean instead.
-                 */
-                nir_ssa_def *face =
-                        nir_load_system_value(b,
-                                              nir_intrinsic_load_front_face,
-                                              0);
-                dests[0] = nir_bcsel(b, face, nir_imm_float(b, 1.0),
-                                     nir_imm_float(b, -1.0));
-                dests[1] = nir_imm_float(b, 0.0);
-                dests[2] = nir_imm_float(b, 0.0);
-                dests[3] = nir_imm_float(b, 1.0);
-        } else if (input_var->data.location >= VARYING_SLOT_VAR0) {
+        if (input_var->data.location >= VARYING_SLOT_VAR0) {
                 if (c->fs_key->point_sprite_mask &
                     (1 << (input_var->data.location -
                            VARYING_SLOT_VAR0))) {