mesa/st: Fix iris regression with clip distances.
authorEmma Anholt <emma@anholt.net>
Tue, 18 May 2021 23:57:30 +0000 (16:57 -0700)
committerMarge Bot <eric+marge@anholt.net>
Mon, 24 May 2021 17:16:10 +0000 (17:16 +0000)
In general gallium shaders are all SSO and it's up to the driver to handle
lining up varying storage between stages at draw time.  However, there's a
NIR option "unify_interfaces" that iris uses which applies to non-SSO (as
indicated by nir->info.separate_shader) shaders and makes the inputs_read
and outputs_written match up at GLSL-to-NIR link time, and then iris then
avoids any lowering passes that would add new varyings.

By introducing info gathering after variant creation (because all I knew
was "gallium is always SSO"), I broke the unify_interfaces link-time setup
on iris.  Just skip that when the unify_interfaces flag is set, and add
some asserts to catch anyone trying to mix unify_interfaces with known
varying-adjusting lowering passes.

Closes: #4450
Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10876>

src/mesa/state_tracker/st_program.c

index 99c81b8..9f4040e 100644 (file)
@@ -774,11 +774,14 @@ st_create_common_variant(struct st_context *st,
 
       state.type = PIPE_SHADER_IR_NIR;
       state.ir.nir = get_nir_shader(st, stp);
+      const nir_shader_compiler_options *options = ((nir_shader *)state.ir.nir)->options;
+
       if (key->clamp_color) {
          NIR_PASS_V(state.ir.nir, nir_lower_clamp_color_outputs);
          finalize = true;
       }
       if (key->passthrough_edgeflags) {
+         assert(!options->unify_interfaces);
          NIR_PASS_V(state.ir.nir, nir_lower_passthrough_edgeflags);
          finalize = true;
       }
@@ -806,6 +809,7 @@ st_create_common_variant(struct st_context *st,
       }
 
       if (key->lower_ucp) {
+         assert(!options->unify_interfaces);
          lower_ucp(st, state.ir.nir, key->lower_ucp, params);
          finalize = true;
       }
@@ -823,9 +827,18 @@ st_create_common_variant(struct st_context *st,
          st_finalize_nir(st, &stp->Base, stp->shader_program, state.ir.nir,
                          true, false);
 
-         /* Some of the lowering above may have introduced new varyings */
-         nir_shader_gather_info(state.ir.nir,
-                                nir_shader_get_entrypoint(state.ir.nir));
+         /* Clip lowering and edgeflags may have introduced new varyings, so
+          * update the inputs_read/outputs_written. However, with
+          * unify_interfaces set (aka iris) the non-SSO varyings layout is
+          * decided at link time with outputs_written updated so the two line
+          * up.  A driver with this flag set may not use any of the lowering
+          * passes that would change the varyings, so skip to make sure we don't
+          * break its linkage.
+          */
+         if (!options->unify_interfaces) {
+            nir_shader_gather_info(state.ir.nir,
+                                   nir_shader_get_entrypoint(state.ir.nir));
+         }
       }
 
       if (key->is_draw_shader)