From: Marek Olšák Date: Tue, 30 Jul 2019 03:01:01 +0000 (-0400) Subject: radeonsi/nir: lower PS inputs before scanning the shader X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e77772017396423504a57d0e031eea99c93ccdd9;p=mesa.git radeonsi/nir: lower PS inputs before scanning the shader Lowering PS inputs can eliminate some of them, which messes up persp/linear barycentric coord usage info. Acked-by: Pierre-Eric Pelloux-Prayer --- diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 9a89be7932f..f94bd71cee4 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -773,6 +773,7 @@ void si_nir_scan_shader(const struct nir_shader *nir, struct tgsi_shader_info *info); void si_nir_scan_tess_ctrl(const struct nir_shader *nir, struct tgsi_tessctrl_info *out); +void si_nir_lower_ps_inputs(struct nir_shader *nir); void si_lower_nir(struct si_shader_selector *sel, unsigned wave_size); void si_nir_opts(struct nir_shader *nir); diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index 5ca4e178b86..f0a9e8f620b 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -85,14 +85,6 @@ static void gather_intrinsic_load_deref_input_info(const nir_shader *nir, } break; } - case MESA_SHADER_FRAGMENT: - if (var->data.location == VARYING_SLOT_COL0 || - var->data.location == VARYING_SLOT_COL1) { - unsigned index = var->data.location == VARYING_SLOT_COL1; - uint8_t mask = nir_ssa_def_components_read(&instr->dest.ssa); - info->colors_read |= mask << (index * 4); - } - break; default:; } } @@ -331,39 +323,54 @@ static void scan_instruction(const struct nir_shader *nir, info->writes_memory = true; info->num_memory_instructions++; /* we only care about stores */ break; + case nir_intrinsic_load_color0: + case nir_intrinsic_load_color1: { + unsigned index = intr->intrinsic == nir_intrinsic_load_color1; + uint8_t mask = nir_ssa_def_components_read(&intr->dest.ssa); + info->colors_read |= mask << (index * 4); + break; + } + case nir_intrinsic_load_barycentric_pixel: + case nir_intrinsic_load_barycentric_centroid: + case nir_intrinsic_load_barycentric_sample: + case nir_intrinsic_load_barycentric_at_offset: /* uses center */ + case nir_intrinsic_load_barycentric_at_sample: { /* uses center */ + unsigned mode = nir_intrinsic_interp_mode(intr); + + if (mode == INTERP_MODE_FLAT) + break; + + if (mode == INTERP_MODE_NOPERSPECTIVE) { + if (intr->intrinsic == nir_intrinsic_load_barycentric_sample) + info->uses_linear_sample = true; + else if (intr->intrinsic == nir_intrinsic_load_barycentric_centroid) + info->uses_linear_centroid = true; + else + info->uses_linear_center = true; + + if (intr->intrinsic == nir_intrinsic_load_barycentric_at_sample) + info->uses_linear_opcode_interp_sample = true; + } else { + if (intr->intrinsic == nir_intrinsic_load_barycentric_sample) + info->uses_persp_sample = true; + else if (intr->intrinsic == nir_intrinsic_load_barycentric_centroid) + info->uses_persp_centroid = true; + else + info->uses_persp_center = true; + + if (intr->intrinsic == nir_intrinsic_load_barycentric_at_sample) + info->uses_persp_opcode_interp_sample = true; + } + break; + } case nir_intrinsic_load_deref: { nir_variable *var = intrinsic_get_var(intr); nir_variable_mode mode = var->data.mode; - enum glsl_base_type base_type = - glsl_get_base_type(glsl_without_array(var->type)); if (mode == nir_var_shader_in) { + /* PS inputs use the interpolated load intrinsics. */ + assert(nir->info.stage != MESA_SHADER_FRAGMENT); gather_intrinsic_load_deref_input_info(nir, intr, var, info); - - switch (var->data.interpolation) { - case INTERP_MODE_NONE: - if (glsl_base_type_is_integer(base_type)) - break; - - /* fall-through */ - case INTERP_MODE_SMOOTH: - if (var->data.sample) - info->uses_persp_sample = true; - else if (var->data.centroid) - info->uses_persp_centroid = true; - else - info->uses_persp_center = true; - break; - - case INTERP_MODE_NOPERSPECTIVE: - if (var->data.sample) - info->uses_linear_sample = true; - else if (var->data.centroid) - info->uses_linear_centroid = true; - else - info->uses_linear_center = true; - break; - } } else if (mode == nir_var_shader_out) { gather_intrinsic_load_deref_output_info(nir, intr, var, info); } @@ -378,33 +385,9 @@ static void scan_instruction(const struct nir_shader *nir, } case nir_intrinsic_interp_deref_at_centroid: case nir_intrinsic_interp_deref_at_sample: - case nir_intrinsic_interp_deref_at_offset: { - enum glsl_interp_mode interp = intrinsic_get_var(intr)->data.interpolation; - switch (interp) { - case INTERP_MODE_SMOOTH: - case INTERP_MODE_NONE: - if (intr->intrinsic == nir_intrinsic_interp_deref_at_centroid) - info->uses_persp_opcode_interp_centroid = true; - else if (intr->intrinsic == nir_intrinsic_interp_deref_at_sample) - info->uses_persp_opcode_interp_sample = true; - else - info->uses_persp_opcode_interp_offset = true; - break; - case INTERP_MODE_NOPERSPECTIVE: - if (intr->intrinsic == nir_intrinsic_interp_deref_at_centroid) - info->uses_linear_opcode_interp_centroid = true; - else if (intr->intrinsic == nir_intrinsic_interp_deref_at_sample) - info->uses_linear_opcode_interp_sample = true; - else - info->uses_linear_opcode_interp_offset = true; - break; - case INTERP_MODE_FLAT: - break; - default: - unreachable("Unsupported interpoation type"); - } + case nir_intrinsic_interp_deref_at_offset: + unreachable("interp opcodes should have been lowered"); break; - } default: break; } @@ -968,6 +951,31 @@ si_nir_lower_color(nir_shader *nir) } } +void si_nir_lower_ps_inputs(struct nir_shader *nir) +{ + if (nir->info.stage != MESA_SHADER_FRAGMENT) + return; + + NIR_PASS_V(nir, nir_lower_io_to_temporaries, + nir_shader_get_entrypoint(nir), false, true); + + /* Since we're doing nir_lower_io_to_temporaries late, we need + * to lower all the copy_deref's introduced by + * lower_io_to_temporaries before calling nir_lower_io. + */ + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_lower_var_copies); + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + + si_nir_lower_color(nir); + NIR_PASS_V(nir, nir_lower_io, nir_var_shader_in, type_size_vec4, 0); + + /* This pass needs actual constants */ + NIR_PASS_V(nir, nir_opt_constant_folding); + NIR_PASS_V(nir, nir_io_add_const_offset_to_base, + nir_var_shader_in); +} + /** * Perform "lowering" operations on the NIR that are run once when the shader * selector is created. @@ -982,25 +990,6 @@ si_lower_nir(struct si_shader_selector* sel, unsigned wave_size) if (sel->nir->info.stage != MESA_SHADER_FRAGMENT) { nir_foreach_variable(variable, &sel->nir->inputs) variable->data.driver_location *= 4; - } else { - NIR_PASS_V(sel->nir, nir_lower_io_to_temporaries, - nir_shader_get_entrypoint(sel->nir), false, true); - - /* Since we're doing nir_lower_io_to_temporaries late, we need - * to lower all the copy_deref's introduced by - * lower_io_to_temporaries before calling nir_lower_io. - */ - NIR_PASS_V(sel->nir, nir_split_var_copies); - NIR_PASS_V(sel->nir, nir_lower_var_copies); - NIR_PASS_V(sel->nir, nir_lower_global_vars_to_local); - - si_nir_lower_color(sel->nir); - NIR_PASS_V(sel->nir, nir_lower_io, nir_var_shader_in, type_size_vec4, 0); - - /* This pass needs actual constants */ - NIR_PASS_V(sel->nir, nir_opt_constant_folding); - NIR_PASS_V(sel->nir, nir_io_add_const_offset_to_base, - nir_var_shader_in); } nir_foreach_variable(variable, &sel->nir->outputs) { diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 9e8e1db7a52..dbd918d58f1 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -2637,6 +2637,21 @@ static void *si_create_shader_selector(struct pipe_context *ctx, tgsi_scan_shader(state->tokens, &sel->info); tgsi_scan_tess_ctrl(state->tokens, &sel->info, &sel->tcs_info); + + /* Fixup for TGSI: Set which opcode uses which (i,j) pair. */ + if (sel->info.uses_persp_opcode_interp_centroid) + sel->info.uses_persp_centroid = true; + + if (sel->info.uses_linear_opcode_interp_centroid) + sel->info.uses_linear_centroid = true; + + if (sel->info.uses_persp_opcode_interp_offset || + sel->info.uses_persp_opcode_interp_sample) + sel->info.uses_persp_center = true; + + if (sel->info.uses_linear_opcode_interp_offset || + sel->info.uses_linear_opcode_interp_sample) + sel->info.uses_linear_center = true; } else { if (state->type == PIPE_SHADER_IR_TGSI) { sel->nir = tgsi_to_nir(state->tokens, ctx->screen); @@ -2645,6 +2660,7 @@ static void *si_create_shader_selector(struct pipe_context *ctx, sel->nir = state->ir.nir; } + si_nir_lower_ps_inputs(sel->nir); si_nir_opts(sel->nir); si_nir_scan_shader(sel->nir, &sel->info); si_nir_scan_tess_ctrl(sel->nir, &sel->tcs_info); @@ -2691,21 +2707,6 @@ static void *si_create_shader_selector(struct pipe_context *ctx, sel->pos_writes_edgeflag = true; } - /* Set which opcode uses which (i,j) pair. */ - if (sel->info.uses_persp_opcode_interp_centroid) - sel->info.uses_persp_centroid = true; - - if (sel->info.uses_linear_opcode_interp_centroid) - sel->info.uses_linear_centroid = true; - - if (sel->info.uses_persp_opcode_interp_offset || - sel->info.uses_persp_opcode_interp_sample) - sel->info.uses_persp_center = true; - - if (sel->info.uses_linear_opcode_interp_offset || - sel->info.uses_linear_opcode_interp_sample) - sel->info.uses_linear_center = true; - switch (sel->type) { case PIPE_SHADER_GEOMETRY: sel->gs_output_prim =