bool lower_io_variables;
/**
- * Lower color inputs to load_colorN that are kind of like system values
- * if lower_io_variables is also set. shader_info will contain
- * the interpolation settings. This is used by nir_lower_io_passes.
- */
- bool lower_fs_color_inputs;
-
- /**
* The masks of shader stages that support indirect indexing with
* load_input and store_output intrinsics. It's used when
* lower_io_variables is true. This is used by nir_lower_io_passes.
nir_lower_io_options);
bool nir_io_add_const_offset_to_base(nir_shader *nir, nir_variable_mode modes);
-
-void
-nir_lower_io_passes(nir_shader *nir);
-
+bool nir_lower_color_inputs(nir_shader *nir);
+void nir_lower_io_passes(nir_shader *nir);
bool nir_io_add_intrinsic_xfb_info(nir_shader *nir);
bool
return progress;
}
-static bool
+bool
nir_lower_color_inputs(nir_shader *nir)
{
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
- if (intrin->intrinsic != nir_intrinsic_load_deref)
+ if (intrin->intrinsic != nir_intrinsic_load_input &&
+ intrin->intrinsic != nir_intrinsic_load_interpolated_input)
continue;
- nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
- if (!nir_deref_mode_is(deref, nir_var_shader_in))
+ nir_io_semantics sem = nir_intrinsic_io_semantics(intrin);
+
+ if (sem.location != VARYING_SLOT_COL0 &&
+ sem.location != VARYING_SLOT_COL1)
continue;
+ /* Default to FLAT (for load_input) */
+ enum glsl_interp_mode interp = INTERP_MODE_FLAT;
+ bool sample = false;
+ bool centroid = false;
+
+ if (intrin->intrinsic == nir_intrinsic_load_interpolated_input) {
+ nir_intrinsic_instr *baryc =
+ nir_instr_as_intrinsic(intrin->src[0].ssa->parent_instr);
+
+ centroid =
+ baryc->intrinsic == nir_intrinsic_load_barycentric_centroid;
+ sample =
+ baryc->intrinsic == nir_intrinsic_load_barycentric_sample;
+ assert(centroid || sample ||
+ baryc->intrinsic == nir_intrinsic_load_barycentric_pixel);
+
+ interp = nir_intrinsic_interp_mode(baryc);
+ }
+
b.cursor = nir_before_instr(instr);
- nir_variable *var = nir_deref_instr_get_variable(deref);
- nir_ssa_def *def;
-
- if (var->data.location == VARYING_SLOT_COL0) {
- def = nir_load_color0(&b);
- nir->info.fs.color0_interp = var->data.interpolation;
- nir->info.fs.color0_sample = var->data.sample;
- nir->info.fs.color0_centroid = var->data.centroid;
- } else if (var->data.location == VARYING_SLOT_COL1) {
- def = nir_load_color1(&b);
- nir->info.fs.color1_interp = var->data.interpolation;
- nir->info.fs.color1_sample = var->data.sample;
- nir->info.fs.color1_centroid = var->data.centroid;
+ nir_ssa_def *load = NULL;
+
+ if (sem.location == VARYING_SLOT_COL0) {
+ load = nir_load_color0(&b);
+ nir->info.fs.color0_interp = interp;
+ nir->info.fs.color0_sample = sample;
+ nir->info.fs.color0_centroid = centroid;
} else {
- continue;
+ assert(sem.location == VARYING_SLOT_COL1);
+ load = nir_load_color1(&b);
+ nir->info.fs.color1_interp = interp;
+ nir->info.fs.color1_sample = sample;
+ nir->info.fs.color1_centroid = centroid;
}
- nir_ssa_def_rewrite_uses(&intrin->dest.ssa, def);
+ if (intrin->num_components != 4) {
+ unsigned start = nir_intrinsic_component(intrin);
+ unsigned count = intrin->num_components;
+ load = nir_channels(&b, load, BITFIELD_RANGE(start, count));
+ }
+
+ nir_ssa_def_rewrite_uses(&intrin->dest.ssa, load);
nir_instr_remove(instr);
progress = true;
}
NIR_PASS_V(nir, nir_lower_global_vars_to_local);
}
- if (nir->info.stage == MESA_SHADER_FRAGMENT &&
- nir->options->lower_fs_color_inputs)
- NIR_PASS_V(nir, nir_lower_color_inputs);
-
NIR_PASS_V(nir, nir_lower_io, nir_var_shader_out | nir_var_shader_in,
type_size_vec4, nir_lower_io_lower_64bit_to_32);