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=90da1013ec89cbe66fabfeea058f725583e831ae;hpb=f3958f1644391ed5f6d14373ac74d4978d8598b7;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 90da1013ec8..0507c4d2317 100644 --- a/src/compiler/nir/nir_lower_two_sided_color.c +++ b/src/compiler/nir/nir_lower_two_sided_color.c @@ -32,10 +32,12 @@ typedef struct { nir_builder b; nir_shader *shader; + bool face_sysval; struct { nir_variable *front; /* COLn */ nir_variable *back; /* BFCn */ } colors[MAX_COLORS]; + nir_variable *face; int colors_count; } lower_2side_state; @@ -46,22 +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; } @@ -84,17 +101,8 @@ load_input(nir_builder *b, nir_variable *in) static int setup_inputs(lower_2side_state *state) { - int maxloc = -1; - /* find color 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 after last existing input: - */ - maxloc = MAX2(maxloc, loc); - + nir_foreach_shader_in_variable(var, state->shader) { switch (var->data.location) { case VARYING_SLOT_COL0: case VARYING_SLOT_COL1: @@ -119,10 +127,13 @@ setup_inputs(lower_2side_state *state) slot = VARYING_SLOT_BFC1; state->colors[i].back = create_input( - state->shader, ++maxloc, slot, + state->shader, slot, state->colors[i].front->data.interpolation); } + if (!state->face_sysval) + state->face = create_face_input(state->shader); + return 0; } @@ -138,18 +149,28 @@ nir_lower_two_sided_color_block(nir_block *block, 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; @@ -158,9 +179,23 @@ nir_lower_two_sided_color_block(nir_block *block, * bcsel(load_system_value(FACE), load_input(COLn), load_input(BFCn)) */ b->cursor = nir_before_instr(&intr->instr); - nir_ssa_def *face = nir_load_front_face(b); - nir_ssa_def *front = load_input(b, state->colors[idx].front); - nir_ssa_def *back = load_input(b, state->colors[idx].back); + /* 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); @@ -187,13 +222,14 @@ nir_lower_two_sided_color_impl(nir_function_impl *impl, } 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)