etnaviv: nir: use store_deref instead of store_output
Allows some simplification. Signed-off-by: Jonathan Marek <jonathan@marek.ca> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
parent
d92689c46f
commit
8f1b2ea7a9
|
@ -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
|
||||
|
|
|
@ -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)));
|
||||
|
|
Loading…
Reference in New Issue