+ if (so->key.has_gs || so->key.tessellation) {
+ switch (so->shader->type) {
+ case MESA_SHADER_VERTEX:
+ NIR_PASS_V(s, ir3_nir_lower_to_explicit_output, so, so->key.tessellation);
+ progress = true;
+ break;
+ case MESA_SHADER_TESS_CTRL:
+ NIR_PASS_V(s, ir3_nir_lower_tess_ctrl, so, so->key.tessellation);
+ NIR_PASS_V(s, ir3_nir_lower_to_explicit_input);
+ progress = true;
+ break;
+ case MESA_SHADER_TESS_EVAL:
+ NIR_PASS_V(s, ir3_nir_lower_tess_eval, so->key.tessellation);
+ if (so->key.has_gs)
+ NIR_PASS_V(s, ir3_nir_lower_to_explicit_output, so, so->key.tessellation);
+ progress = true;
+ break;
+ case MESA_SHADER_GEOMETRY:
+ NIR_PASS_V(s, ir3_nir_lower_to_explicit_input);
+ progress = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (s->info.stage == MESA_SHADER_VERTEX) {
+ if (so->key.ucp_enables)
+ progress |= OPT(s, nir_lower_clip_vs, so->key.ucp_enables, false, false, NULL);
+ if (so->key.vclamp_color)
+ progress |= OPT(s, nir_lower_clamp_color_outputs);
+ } else if (s->info.stage == MESA_SHADER_FRAGMENT) {
+ if (so->key.ucp_enables)
+ progress |= OPT(s, nir_lower_clip_fs, so->key.ucp_enables, false);
+ if (so->key.fclamp_color)
+ progress |= OPT(s, nir_lower_clamp_color_outputs);
+ }
+ if (so->key.color_two_side) {
+ OPT_V(s, nir_lower_two_sided_color);
+ progress = true;
+ }
+
+ struct nir_lower_tex_options tex_options = { };
+
+ switch (so->shader->type) {
+ case MESA_SHADER_FRAGMENT:
+ tex_options.saturate_s = so->key.fsaturate_s;
+ tex_options.saturate_t = so->key.fsaturate_t;
+ tex_options.saturate_r = so->key.fsaturate_r;
+ break;
+ case MESA_SHADER_VERTEX:
+ tex_options.saturate_s = so->key.vsaturate_s;
+ tex_options.saturate_t = so->key.vsaturate_t;
+ tex_options.saturate_r = so->key.vsaturate_r;
+ break;
+ default:
+ /* TODO */
+ break;
+ }
+
+ if (tex_options.saturate_s || tex_options.saturate_t ||
+ tex_options.saturate_r) {
+ progress |= OPT(s, nir_lower_tex, &tex_options);
+ }
+
+ if (!so->binning_pass)
+ OPT_V(s, ir3_nir_analyze_ubo_ranges, so);
+
+ progress |= OPT(s, ir3_nir_lower_ubo_loads, so);
+
+ /* UBO offset lowering has to come after we've decided what will
+ * be left as load_ubo