etnaviv: nir: use store_deref instead of store_output
authorJonathan Marek <jonathan@marek.ca>
Thu, 12 Sep 2019 16:28:28 +0000 (12:28 -0400)
committerJonathan Marek <jonathan@marek.ca>
Sat, 28 Sep 2019 04:34:43 +0000 (00:34 -0400)
Allows some simplification.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c
src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.h

index 2200bc45c8c4976f6ee8af2f0f11f93b5df263bb..4f854954922104737b2a503abc54e2802900989d 100644 (file)
@@ -49,9 +49,6 @@ struct etna_compile {
    const struct etna_specs *specs;
    struct etna_shader_variant *variant;
 
-   /* register assigned to each output, indexed by driver_location */
-   unsigned output_reg[ETNA_NUM_INPUTS];
-
    /* block # to instr index */
    unsigned *block_ptr;
 
@@ -75,18 +72,6 @@ struct etna_compile {
 static void
 etna_lower_io(nir_shader *shader, struct etna_shader_variant *v)
 {
-   bool rb_swap = shader->info.stage == MESA_SHADER_FRAGMENT && v->key.frag_rb_swap;
-
-   unsigned color_location = 0;
-   nir_foreach_variable(var, &shader->outputs) {
-      switch (var->data.location) {
-      case FRAG_RESULT_COLOR:
-      case FRAG_RESULT_DATA0:
-         color_location = var->data.driver_location;
-         break;
-      }
-   }
-
    nir_foreach_function(function, shader) {
       nir_builder b;
       nir_builder_init(&b, function->impl);
@@ -113,16 +98,24 @@ etna_lower_io(nir_shader *shader, struct etna_shader_variant *v)
                                                  nir_src_for_ssa(ssa),
                                                  ssa->parent_instr);
                } break;
-               case nir_intrinsic_store_output: {
-                  if (!rb_swap || nir_intrinsic_base(intr) != color_location)
+               case nir_intrinsic_store_deref: {
+                  if (shader->info.stage != MESA_SHADER_FRAGMENT || !v->key.frag_rb_swap)
                      break;
+
+                  nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
+                  assert(deref->deref_type == nir_deref_type_var);
+
+                  if (deref->var->data.location != FRAG_RESULT_COLOR &&
+                      deref->var->data.location != FRAG_RESULT_DATA0)
+                      break;
+
                   b.cursor = nir_before_instr(instr);
 
-                  nir_ssa_def *ssa = nir_mov(&b, intr->src[0].ssa);
+                  nir_ssa_def *ssa = nir_mov(&b, intr->src[1].ssa);
                   nir_alu_instr *alu = nir_instr_as_alu(ssa->parent_instr);
                   alu->src[0].swizzle[0] = 2;
                   alu->src[0].swizzle[2] = 0;
-                  nir_instr_rewrite_src(instr, &intr->src[0], nir_src_for_ssa(ssa));
+                  nir_instr_rewrite_src(instr, &intr->src[1], nir_src_for_ssa(ssa));
                } break;
                case nir_intrinsic_load_uniform: {
                   /* multiply by 16 and convert to int */
@@ -558,9 +551,39 @@ etna_emit_discard(struct etna_compile *c, struct etna_inst_src condition)
 }
 
 static void
-etna_emit_output(struct etna_compile *c, unsigned index, struct etna_inst_src src)
+etna_emit_output(struct etna_compile *c, nir_variable *var, struct etna_inst_src src)
 {
-   c->output_reg[index] = src.reg;
+   struct etna_shader_io_file *sf = &c->variant->outfile;
+
+   if (is_fs(c)) {
+      switch (var->data.location) {
+      case FRAG_RESULT_COLOR:
+      case FRAG_RESULT_DATA0: /* DATA0 is used by gallium shaders for color */
+         c->variant->ps_color_out_reg = src.reg;
+         break;
+      case FRAG_RESULT_DEPTH:
+         c->variant->ps_depth_out_reg = src.reg;
+         break;
+      default:
+         unreachable("Unsupported fs output");
+      }
+      return;
+   }
+
+   switch (var->data.location) {
+   case VARYING_SLOT_POS:
+      c->variant->vs_pos_out_reg = src.reg;
+      break;
+   case VARYING_SLOT_PSIZ:
+      c->variant->vs_pointsize_out_reg = src.reg;
+      break;
+   default:
+      sf->reg[sf->num_reg].reg = src.reg;
+      sf->reg[sf->num_reg].slot = var->data.location;
+      sf->reg[sf->num_reg].num_components = glsl_get_components(var->type);
+      sf->num_reg++;
+      break;
+   }
 }
 
 static void
@@ -715,7 +738,7 @@ etna_compile_shader_nir(struct etna_shader_variant *v)
       assert(sf->num_reg == count);
    }
 
-   NIR_PASS_V(s, nir_lower_io, nir_var_all, etna_glsl_type_size,
+   NIR_PASS_V(s, nir_lower_io, ~nir_var_shader_out, etna_glsl_type_size,
             (nir_lower_io_options)0);
 
    OPT_V(s, nir_lower_regs_to_ssa);
@@ -809,23 +832,7 @@ etna_compile_shader_nir(struct etna_shader_variant *v)
 
    if (s->info.stage == MESA_SHADER_FRAGMENT) {
       v->input_count_unk8 = 31; /* XXX what is this */
-
-      nir_foreach_variable(var, &s->outputs) {
-         unsigned reg = c->output_reg[var->data.driver_location];
-         switch (var->data.location) {
-         case FRAG_RESULT_COLOR:
-         case FRAG_RESULT_DATA0: /* DATA0 is used by gallium shaders for color */
-            v->ps_color_out_reg = reg;
-            break;
-         case FRAG_RESULT_DEPTH:
-            v->ps_depth_out_reg = reg;
-            break;
-         default:
-            compile_error(c, "Unsupported fs output %s\n", gl_frag_result_name(var->data.location));
-         }
-      }
       assert(v->ps_depth_out_reg <= 0);
-      v->outfile.num_reg = 0;
       ralloc_free(c->nir);
       FREE(c);
       return true;
@@ -833,27 +840,6 @@ etna_compile_shader_nir(struct etna_shader_variant *v)
 
    v->input_count_unk8 = DIV_ROUND_UP(v->infile.num_reg + 4, 16); /* XXX what is this */
 
-   sf = &v->outfile;
-   sf->num_reg = 0;
-   nir_foreach_variable(var, &s->outputs) {
-      unsigned native = c->output_reg[var->data.driver_location];
-
-      if (var->data.location == VARYING_SLOT_POS) {
-         v->vs_pos_out_reg = native;
-         continue;
-      }
-
-      if (var->data.location == VARYING_SLOT_PSIZ) {
-         v->vs_pointsize_out_reg = native;
-         continue;
-      }
-
-      sf->reg[sf->num_reg].reg = native;
-      sf->reg[sf->num_reg].slot = var->data.location;
-      sf->reg[sf->num_reg].num_components = glsl_get_components(var->type);
-      sf->num_reg++;
-   }
-
    /* fill in "mystery meat" load balancing value. This value determines how
     * work is scheduled between VS and PS
     * in the unified shader architecture. More precisely, it is determined from
index 102836d085c9d159698f69fce874736a95191372..675bc59aff8a4436880b13383fed4a48e11e3002 100644 (file)
@@ -580,7 +580,7 @@ dest_for_instr(nir_instr *instr)
       dest = &nir_instr_as_alu(instr)->dest.dest;
       break;
    case nir_instr_type_tex:
-      dest =&nir_instr_as_tex(instr)->dest;
+      dest = &nir_instr_as_tex(instr)->dest;
       break;
    case nir_instr_type_intrinsic: {
       nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
@@ -588,7 +588,9 @@ dest_for_instr(nir_instr *instr)
           intr->intrinsic == nir_intrinsic_load_input ||
           intr->intrinsic == nir_intrinsic_load_instance_id)
          dest = &intr->dest;
-   }
+   } break;
+   case nir_instr_type_deref:
+      return NULL;
    default:
       break;
    }
@@ -649,7 +651,7 @@ set_src_live(nir_src *src, void *void_state)
    if (src->is_ssa) {
       nir_instr *instr = src->ssa->parent_instr;
 
-      if (is_sysval(instr))
+      if (is_sysval(instr) || instr->type == nir_instr_type_deref)
          return true;
 
       switch (instr->type) {
@@ -784,7 +786,7 @@ live_defs(nir_function_impl *impl, struct live_def *defs, unsigned *live_map)
          /* output live till the end */
          if (instr->type == nir_instr_type_intrinsic) {
             nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
-            if (intr->intrinsic == nir_intrinsic_store_output)
+            if (intr->intrinsic == nir_intrinsic_store_deref)
                state.index = ~0u;
          }
 
@@ -928,11 +930,11 @@ ra_assign(struct state *state, nir_shader *shader)
          unsigned reg;
 
          switch (intr->intrinsic) {
-         case nir_intrinsic_store_output: {
+         case nir_intrinsic_store_deref: {
             /* don't want output to be swizzled
              * TODO: better would be to set the type to X/XY/XYZ/XYZW
              */
-            ra_set_node_class(g, live_map[src_index(impl, &intr->src[0])], REG_CLASS_VEC4);
+            ra_set_node_class(g, live_map[src_index(impl, &intr->src[1])], REG_CLASS_VEC4);
          } continue;
          case nir_intrinsic_load_input:
             reg = nir_intrinsic_base(intr) * NUM_REG_TYPES + (unsigned[]) {
@@ -1075,12 +1077,12 @@ static void
 emit_intrinsic(struct state *state, nir_intrinsic_instr * intr)
 {
    switch (intr->intrinsic) {
-   case nir_intrinsic_store_output:
-      emit(output, nir_intrinsic_base(intr), get_src(state, &intr->src[0]));
+   case nir_intrinsic_store_deref:
+      emit(output, nir_src_as_deref(intr->src[0])->var, get_src(state, &intr->src[1]));
       break;
    case nir_intrinsic_discard_if:
       emit(discard, get_src(state, &intr->src[0]));
-   break;
+      break;
    case nir_intrinsic_discard:
       emit(discard, SRC_DISABLE);
       break;
@@ -1119,6 +1121,7 @@ emit_instr(struct state *state, nir_instr * instr)
       assert(nir_instr_is_last(instr));
    case nir_instr_type_load_const:
    case nir_instr_type_ssa_undef:
+   case nir_instr_type_deref:
       break;
    default:
       assert(0);
@@ -1440,8 +1443,8 @@ emit_shader(nir_shader *shader, const struct emit_options *options,
          nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
 
          switch (intr->intrinsic) {
-         case nir_intrinsic_store_output: {
-            nir_src *src = &intr->src[0];
+         case nir_intrinsic_store_deref: {
+            nir_src *src = &intr->src[1];
             if (nir_src_is_const(*src) || is_sysval(src->ssa->parent_instr)) {
                b.cursor = nir_before_instr(instr);
                nir_instr_rewrite_src(instr, src, nir_src_for_ssa(nir_mov(&b, src->ssa)));