X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_lower_two_sided_color.c;h=0507c4d2317a69c80a35aab74df45c761e4c1b19;hb=18e464cfc05cdae59af8d00f214a6477a72b8ac7;hp=ba3a4484f0f532e0eab2a2db9e71ef76c9b5f4f0;hpb=707e72f13bb78869ee95d3286980bf1709cba6cf;p=mesa.git diff --git a/src/compiler/nir/nir_lower_two_sided_color.c b/src/compiler/nir/nir_lower_two_sided_color.c index ba3a4484f0f..0507c4d2317 100644 --- a/src/compiler/nir/nir_lower_two_sided_color.c +++ b/src/compiler/nir/nir_lower_two_sided_color.c @@ -32,11 +32,12 @@ typedef struct { nir_builder b; nir_shader *shader; - nir_variable *face; + bool face_sysval; struct { nir_variable *front; /* COLn */ nir_variable *back; /* BFCn */ } colors[MAX_COLORS]; + nir_variable *face; int colors_count; } lower_2side_state; @@ -47,20 +48,37 @@ typedef struct { */ static nir_variable * -create_input(nir_shader *shader, unsigned drvloc, gl_varying_slot slot) +create_input(nir_shader *shader, gl_varying_slot slot, + enum glsl_interp_mode interpolation) { - nir_variable *var = rzalloc(shader, nir_variable); + nir_variable *var = nir_variable_create(shader, nir_var_shader_in, + glsl_vec4_type(), NULL); - var->data.driver_location = drvloc; - var->type = glsl_vec4_type(); - var->data.mode = nir_var_shader_in; - var->name = ralloc_asprintf(var, "in_%d", drvloc); + var->data.driver_location = shader->num_inputs++; + var->name = ralloc_asprintf(var, "in_%d", var->data.driver_location); var->data.index = 0; var->data.location = slot; + var->data.interpolation = interpolation; - exec_list_push_tail(&shader->inputs, &var->node); + return var; +} - shader->num_inputs++; /* TODO use type_size() */ +static nir_variable * +create_face_input(nir_shader *shader) +{ + nir_variable *var = + nir_find_variable_with_location(shader, nir_var_shader_in, + VARYING_SLOT_FACE); + + if (var == NULL) { + var = nir_variable_create(shader, nir_var_shader_in, + glsl_bool_type(), "gl_FrontFacing"); + + var->data.driver_location = shader->num_inputs++; + var->data.index = 0; + var->data.location = VARYING_SLOT_FACE; + var->data.interpolation = INTERP_MODE_FLAT; + } return var; } @@ -83,17 +101,8 @@ load_input(nir_builder *b, nir_variable *in) static int setup_inputs(lower_2side_state *state) { - int maxloc = -1; - - /* find color/face inputs: */ - nir_foreach_variable(var, &state->shader->inputs) { - int loc = var->data.driver_location; - - /* keep track of last used driver-location.. we'll be - * appending BCLr/FACE after last existing input: - */ - maxloc = MAX2(maxloc, loc); - + /* find color inputs: */ + nir_foreach_shader_in_variable(var, state->shader) { switch (var->data.location) { case VARYING_SLOT_COL0: case VARYING_SLOT_COL1: @@ -101,9 +110,6 @@ setup_inputs(lower_2side_state *state) state->colors[state->colors_count].front = var; state->colors_count++; break; - case VARYING_SLOT_FACE: - state->face = var; - break; } } @@ -111,12 +117,6 @@ setup_inputs(lower_2side_state *state) if (state->colors_count == 0) return -1; - /* if we don't already have one, insert a FACE input: */ - if (!state->face) { - state->face = create_input(state->shader, ++maxloc, VARYING_SLOT_FACE); - state->face->data.interpolation = INTERP_QUALIFIER_FLAT; - } - /* add required back-face color inputs: */ for (int i = 0; i < state->colors_count; i++) { gl_varying_slot slot; @@ -126,16 +126,21 @@ setup_inputs(lower_2side_state *state) else slot = VARYING_SLOT_BFC1; - state->colors[i].back = create_input(state->shader, ++maxloc, slot); + state->colors[i].back = create_input( + state->shader, slot, + state->colors[i].front->data.interpolation); } + if (!state->face_sysval) + state->face = create_face_input(state->shader); + return 0; } static bool -nir_lower_two_sided_color_block(nir_block *block, void *void_state) +nir_lower_two_sided_color_block(nir_block *block, + lower_2side_state *state) { - lower_2side_state *state = void_state; nir_builder *b = &state->b; nir_foreach_instr_safe(instr, block) { @@ -144,31 +149,54 @@ nir_lower_two_sided_color_block(nir_block *block, void *void_state) nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - if (intr->intrinsic != nir_intrinsic_load_input) - continue; - int idx; - for (idx = 0; idx < state->colors_count; idx++) { - unsigned drvloc = - state->colors[idx].front->data.driver_location; - if (nir_intrinsic_base(intr) == drvloc) { - assert(nir_src_as_const_value(intr->src[0])); - break; + if (intr->intrinsic == nir_intrinsic_load_input) { + for (idx = 0; idx < state->colors_count; idx++) { + unsigned drvloc = + state->colors[idx].front->data.driver_location; + if (nir_intrinsic_base(intr) == drvloc) { + assert(nir_src_is_const(intr->src[0])); + break; + } } - } + } else if (intr->intrinsic == nir_intrinsic_load_deref) { + nir_variable *var = nir_intrinsic_get_var(intr, 0); + if (var->data.mode != nir_var_shader_in) + continue; + + for (idx = 0; idx < state->colors_count; idx++) { + unsigned loc = state->colors[idx].front->data.location; + if (var->data.location == loc) + break; + } + } else + continue; if (idx == state->colors_count) continue; /* replace load_input(COLn) with - * bcsel(load_input(FACE), load_input(COLn), load_input(BFCn)) + * bcsel(load_system_value(FACE), load_input(COLn), load_input(BFCn)) */ b->cursor = nir_before_instr(&intr->instr); - nir_ssa_def *face = nir_channel(b, load_input(b, state->face), 0); - nir_ssa_def *front = load_input(b, state->colors[idx].front); - nir_ssa_def *back = load_input(b, state->colors[idx].back); - nir_ssa_def *cond = nir_flt(b, face, nir_imm_float(b, 0.0)); - nir_ssa_def *color = nir_bcsel(b, cond, back, front); + /* gl_FrontFace is a boolean but the intrinsic constructor creates + * 32-bit value by default. + */ + nir_ssa_def *face; + if (state->face_sysval) + face = nir_load_front_face(b, 1); + else + face = nir_load_var(b, state->face); + + nir_ssa_def *front, *back; + if (intr->intrinsic == nir_intrinsic_load_deref) { + front = nir_load_var(b, state->colors[idx].front); + back = nir_load_var(b, state->colors[idx].back); + } else { + front = load_input(b, state->colors[idx].front); + back = load_input(b, state->colors[idx].back); + } + nir_ssa_def *color = nir_bcsel(b, face, front, back); assert(intr->dest.is_ssa); nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(color)); @@ -185,26 +213,29 @@ nir_lower_two_sided_color_impl(nir_function_impl *impl, nir_builder_init(b, impl); - nir_foreach_block_call(impl, nir_lower_two_sided_color_block, state); + nir_foreach_block(block, impl) { + nir_lower_two_sided_color_block(block, state); + } nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance); } void -nir_lower_two_sided_color(nir_shader *shader) +nir_lower_two_sided_color(nir_shader *shader, bool face_sysval) { lower_2side_state state = { .shader = shader, + .face_sysval = face_sysval, }; - if (shader->stage != MESA_SHADER_FRAGMENT) + if (shader->info.stage != MESA_SHADER_FRAGMENT) return; if (setup_inputs(&state) != 0) return; - nir_foreach_function(shader, function) { + nir_foreach_function(function, shader) { if (function->impl) nir_lower_two_sided_color_impl(function->impl, &state); }