[Mesa-dev] [PATCH 09/21] etnaviv: compiler: setup registers from nir

Philipp Zabel p.zabel at pengutronix.de
Tue Jun 5 14:38:33 UTC 2018


From: Michael Tretter <m.tretter at pengutronix.de>

Add etna_compile_shader_nir, set up shader inputs and outputs,
and start emitting instructions for optimized NIR shaders.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 .../drivers/etnaviv/etnaviv_compiler.c        | 224 +++++++++++++++++-
 1 file changed, 212 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
index 4caf0504d24b..f87708d33f03 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
@@ -66,11 +66,15 @@
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
+#include <compiler/nir/nir.h>
+
 #include <fcntl.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include "nir/tgsi_to_nir.h"
+
 #define ETNA_MAX_INNER_TEMPS 2
 
 static const float sincos_const[2][4] = {
@@ -149,6 +153,9 @@ struct etna_compile {
 
    struct tgsi_shader_info info;
 
+   struct nir_shader *s;
+   nir_function_impl *impl;
+
    /* Register descriptions, per TGSI file, per register index */
    struct etna_compile_file file[TGSI_FILE_COUNT];
 
@@ -1897,6 +1904,188 @@ etna_compile_pass_generate_code(struct etna_compile *c)
    tgsi_parse_free(&ctx);
 }
 
+static void
+etna_setup_registers_from_nir(struct etna_compile *c, struct etna_shader_variant *v)
+{
+   assert(c->s);
+
+   /* Fragment shaders must not use t0 */
+   if (etna_shader_is_stage(c, MESA_SHADER_FRAGMENT))
+      c->next_free_native = 1;
+
+   foreach_list_typed(nir_register, nir_reg, node, &c->s->registers) {
+      struct etna_reg_desc *reg = &c->decl[c->total_decls++];
+
+      reg->native = alloc_new_native_reg(c);
+      reg->native.valid = 1;
+
+      DBG_F(ETNA_DBG_COMPILER_MSGS,
+            "temp: index=%d, id=%d",
+            nir_reg->index, reg->native.id);
+   }
+
+   if (etna_shader_is_stage(c, MESA_SHADER_VERTEX))
+      c->next_free_native++;
+}
+
+static void
+etna_setup_uniforms_from_nir(struct etna_compile *c, struct etna_shader_variant *v)
+{
+   assert(c->s);
+
+   int i = 0;
+
+   nir_foreach_variable(u, &c->s->uniforms) {
+      unsigned array_len = MAX2(glsl_get_length(u->type), 1);
+
+      for (i = 0; i < array_len; i++) {
+         struct etna_reg_desc *reg = &c->decl[c->total_decls++];
+         reg->active = 1;
+         reg->native.valid = 1;
+         reg->native.rgroup = INST_RGROUP_UNIFORM_0;
+         reg->native.id = i;
+
+         DBG_F(ETNA_DBG_COMPILER_MSGS,
+               "uniform: id=%d, group=%d",
+               reg->native.id, reg->native.rgroup);
+      }
+   }
+   c->imm_base = i * 4;
+}
+
+static void
+etna_setup_inputs_from_nir(struct etna_compile *c, struct etna_shader_variant *v)
+{
+   assert(c->s);
+
+   struct etna_shader_io_file *sf = &v->infile;
+
+   sf->num_reg = 0;
+
+   nir_foreach_variable(in, &c->s->inputs) {
+      unsigned array_len = MAX2(glsl_get_length(in->type), 1);
+      unsigned ncomp = glsl_get_components(in->type);
+      unsigned n = in->data.driver_location;
+      unsigned slot = in->data.location;
+
+      DBG_F(ETNA_DBG_COMPILER_MSGS,
+            "in: slot=%u, len=%ux%u, drvloc=%u",
+            slot, array_len, ncomp, n);
+
+      assert(sf->num_reg < ETNA_NUM_INPUTS);
+      /* XXX exclude inputs with special semantics such as gl_frontFacing */
+      sf->reg[sf->num_reg].reg = n;
+      /* FIXME: drop TGSI semantics */
+      if (etna_shader_is_stage(c, MESA_SHADER_FRAGMENT)) {
+         unsigned semantic_name, semantic_index;
+         varying_slot_to_tgsi_semantic(slot, &semantic_name, &semantic_index);
+         if (semantic_name != TGSI_SEMANTIC_POSITION) {
+            sf->reg[sf->num_reg].semantic.Name = semantic_name;
+            sf->reg[sf->num_reg].semantic.Index = semantic_index;
+            sf->reg[sf->num_reg].num_components = ncomp;
+            sf->num_reg++;
+         }
+      } else {
+         sf->reg[sf->num_reg].semantic.Name = TGSI_SEMANTIC_POSITION;
+         sf->reg[sf->num_reg].num_components = ncomp;
+         sf->num_reg++;
+      }
+   }
+
+   c->num_varyings = sf->num_reg;
+
+   /* XXX what is this */
+   if (etna_shader_is_stage(c, MESA_SHADER_FRAGMENT)) {
+      v->input_count_unk8 = 31;
+   } else if (etna_shader_is_stage(c, MESA_SHADER_VERTEX)) {
+      v->input_count_unk8 = (sf->num_reg + 19) / 16;
+   }
+}
+
+static void
+build_output_index(struct etna_shader_variant *sobj);
+
+static void
+etna_setup_outputs_from_nir(struct etna_compile *c, struct etna_shader_variant *v)
+{
+   assert(c->s);
+
+   struct etna_shader_io_file *sf = &v->outfile;
+   unsigned num_variables = 0;
+
+   sf->num_reg = 0;
+
+   nir_foreach_variable(out, &c->s->outputs) {
+      unsigned array_len = MAX2(glsl_get_length(out->type), 1);
+      unsigned ncomp = glsl_get_components(out->type);
+      unsigned n = out->data.driver_location;
+      unsigned slot = out->data.location;
+      unsigned semantic_name;
+      unsigned semantic_index;
+
+      DBG_F(ETNA_DBG_COMPILER_MSGS,
+            "out: slot=%u, len=%ux%u, drvloc=%u",
+            slot, array_len, ncomp, n);
+
+      num_variables++;
+
+      if (etna_shader_is_stage(c, MESA_SHADER_FRAGMENT)) {
+         switch (slot) {
+         case FRAG_RESULT_DEPTH:
+            v->ps_depth_out_reg = n;
+            break;
+         case FRAG_RESULT_COLOR:
+         case FRAG_RESULT_DATA0:
+            v->ps_color_out_reg = n;
+            break;
+         default:
+            assert(!"Only POSITION and COLOR/DATA0 output supported");
+         }
+      } else if (etna_shader_is_stage(c, MESA_SHADER_VERTEX)) {
+         switch (slot) {
+         case VARYING_SLOT_POS:
+            v->vs_pos_out_reg = n;
+            break;
+         case VARYING_SLOT_PSIZ:
+            v->vs_pointsize_out_reg = n;
+            break;
+         default:
+            /* FIXME drop TGSI semantics */
+            varying_slot_to_tgsi_semantic(slot, &semantic_name, &semantic_index);
+            sf->reg[sf->num_reg].semantic.Name = semantic_name;
+            sf->reg[sf->num_reg].semantic.Index = semantic_index;
+            sf->reg[sf->num_reg].reg = n;
+            sf->reg[sf->num_reg].num_components = ncomp;
+            /* FIXME update counters */
+            v->output_count_per_semantic[semantic_name] =
+               MAX2(semantic_index + 1,
+                    v->output_count_per_semantic[semantic_name]);
+            sf->num_reg++;
+            break;
+         }
+      }
+   }
+
+   if (etna_shader_is_stage(c, MESA_SHADER_VERTEX)) {
+      build_output_index(v);
+      v->vs_load_balancing = get_mystery_meat_load_balancing(c, num_variables);
+   }
+}
+
+static void
+etna_compile_shader_nir(struct etna_compile *c, struct etna_shader_variant *v)
+{
+   nir_function_impl *impl;
+
+   c->s = v->shader->nir;
+   c->total_decls = 0;
+
+   etna_setup_registers_from_nir(c, v);
+   etna_setup_uniforms_from_nir(c, v);
+   etna_setup_inputs_from_nir(c, v);
+   etna_setup_outputs_from_nir(c, v);
+}
+
 /* Look up register by semantic */
 static struct etna_reg_desc *
 find_decl_by_semantic(struct etna_compile *c, uint file, uint name, uint index)
@@ -2452,8 +2641,21 @@ etna_compile_shader(struct etna_shader_variant *v)
    c->specs = specs;
    c->key = &v->key;
 
-   etna_compile_shader_tgsi(c, v);
+   v->ps_color_out_reg = -1;
+   v->ps_depth_out_reg = -1;
+   v->vs_pos_out_reg = -1;
+   v->vs_pointsize_out_reg = -1;
 
+   if (v->shader->nir) {
+      etna_compile_shader_nir(c, v);
+   } else {
+      etna_compile_shader_tgsi(c, v);
+   }
+
+   /* FIXME v should not be modified before this check, because the check may
+    * fail the compilation leading to an inconsistent etna_shader_variant.
+    * etna_compile_shader_nir writes to v and violates this assumption.
+    */
    ret = etna_compile_check_limits(c);
    if (!ret)
       goto out;
@@ -2461,24 +2663,22 @@ etna_compile_shader(struct etna_shader_variant *v)
    etna_compile_fill_in_labels(c);
 
    /* fill in output structure */
-   v->processor = c->info.processor;
+   v->processor = v->shader->nir ? st_shader_stage_to_ptarget(v->shader->nir->info.stage) : c->info.processor;
    v->code_size = c->inst_ptr * 4;
    v->code = mem_dup(c->code, c->inst_ptr * 16);
    v->num_loops = c->num_loops;
    v->num_temps = c->next_free_native;
-   v->vs_pos_out_reg = -1;
-   v->vs_pointsize_out_reg = -1;
-   v->ps_color_out_reg = -1;
-   v->ps_depth_out_reg = -1;
    v->needs_icache = c->inst_ptr > c->specs->max_instructions;
    copy_uniform_state_to_shader(c, v);
 
-   if (c->info.processor == PIPE_SHADER_VERTEX) {
-      fill_in_vs_inputs(v, c);
-      fill_in_vs_outputs(v, c);
-   } else if (c->info.processor == PIPE_SHADER_FRAGMENT) {
-      fill_in_ps_inputs(v, c);
-      fill_in_ps_outputs(v, c);
+   if (!v->shader->nir) {
+      if (v->processor == PIPE_SHADER_VERTEX) {
+         fill_in_vs_inputs(v, c);
+         fill_in_vs_outputs(v, c);
+      } else if (v->processor == PIPE_SHADER_FRAGMENT) {
+         fill_in_ps_inputs(v, c);
+         fill_in_ps_outputs(v, c);
+      }
    }
 
 out:
-- 
2.17.1



More information about the mesa-dev mailing list