From: Michael Tretter <m.tret...@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.tret...@pengutronix.de> Signed-off-by: Philipp Zabel <p.za...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev