From 8f1b2ea7a9e741c7f6d2b9ae919f4abe270164b6 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Thu, 12 Sep 2019 12:28:28 -0400 Subject: [PATCH] etnaviv: nir: use store_deref instead of store_output Allows some simplification. Signed-off-by: Jonathan Marek Reviewed-by: Christian Gmeiner --- .../drivers/etnaviv/etnaviv_compiler_nir.c | 104 ++++++++---------- .../etnaviv/etnaviv_compiler_nir_emit.h | 25 +++-- 2 files changed, 59 insertions(+), 70 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c index 2200bc45c8c..4f854954922 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c @@ -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 diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.h b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.h index 102836d085c..675bc59aff8 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.h +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.h @@ -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))); -- 2.30.2