nir: Make nir_lower_clip_vs optionally work with variables.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 22 May 2017 02:26:15 +0000 (19:26 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 19 Nov 2018 22:33:16 +0000 (14:33 -0800)
The way nir_lower_clip_vs() works with store_output intrinsics makes a
ton of assumptions about the driver_location field.

In i965 and iris, I'd rather do this lowering early and work with
variables.  v3d may want to switch to that as well, and ir3 could too,
but I'm not sure exactly what would need updating.  For now, handle
both methods.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/broadcom/compiler/vir.c
src/compiler/nir/nir.h
src/compiler/nir/nir_lower_clip.c
src/gallium/drivers/freedreno/ir3/ir3_nir.c
src/gallium/drivers/vc4/vc4_program.c

index 9a671c6c97f90064ad28ead00d37d2f085fd7946..a52205b1a2a98c84b6769ceddaf245a6b3951fd9 100644 (file)
@@ -745,7 +745,8 @@ uint64_t *v3d_compile_vs(const struct v3d_compiler *compiler,
                 NIR_PASS_V(c->s, nir_lower_clamp_color_outputs);
 
         if (key->base.ucp_enables) {
-                NIR_PASS_V(c->s, nir_lower_clip_vs, key->base.ucp_enables);
+                NIR_PASS_V(c->s, nir_lower_clip_vs, key->base.ucp_enables,
+                           false);
                 NIR_PASS_V(c->s, nir_lower_io_to_scalar,
                            nir_var_shader_out);
         }
index 1dd605010f6d1d5330091bc531a086e539917b75..a292ec73e1edee78652a0ac07c78ab0e0c762635 100644 (file)
@@ -3014,7 +3014,7 @@ bool nir_lower_tex(nir_shader *shader,
 
 bool nir_lower_idiv(nir_shader *shader);
 
-bool nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables);
+bool nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars);
 bool nir_lower_clip_fs(nir_shader *shader, unsigned ucp_enables);
 bool nir_lower_clip_cull_distance_arrays(nir_shader *nir);
 
index 496c39e1b6d12afa7909fac3a75f4f9c434585f9..880d65c617bcef120cd40def526d3f320d2c1f14 100644 (file)
@@ -152,9 +152,12 @@ find_output(nir_shader *shader, unsigned drvloc)
 
 /* ucp_enables is bitmask of enabled ucps.  Actual ucp values are
  * passed in to shader via user_clip_plane system-values
+ *
+ * If use_vars is true, the pass will use variable loads and stores instead
+ * of working with store_output intrinsics.
  */
 bool
-nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables)
+nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars)
 {
    nir_function_impl *impl = nir_shader_get_entrypoint(shader);
    nir_ssa_def *clipdist[MAX_CLIP_PLANES];
@@ -196,17 +199,30 @@ nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables)
          /* if shader is already writing CLIPDIST, then
           * there should be no user-clip-planes to deal
           * with.
+          *
+          * We assume nir_remove_dead_variables has removed the clipdist
+          * variables if they're not written.
           */
          return false;
       }
    }
 
-   if (clipvertex)
-      cv = find_output(shader, clipvertex->data.driver_location);
-   else if (position)
-      cv = find_output(shader, position->data.driver_location);
-   else
-      return false;
+   if (use_vars) {
+      cv = nir_load_var(&b, clipvertex ? clipvertex : position);
+
+      if (clipvertex) {
+         exec_node_remove(&clipvertex->node);
+         clipvertex->data.mode = nir_var_global;
+         exec_list_push_tail(&shader->globals, &clipvertex->node);
+      }
+   } else {
+      if (clipvertex)
+         cv = find_output(shader, clipvertex->data.driver_location);
+      else if (position)
+         cv = find_output(shader, position->data.driver_location);
+      else
+         return false;
+   }
 
    /* insert CLIPDIST outputs: */
    if (ucp_enables & 0x0f)
@@ -228,10 +244,17 @@ nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables)
       }
    }
 
-   if (ucp_enables & 0x0f)
-      store_clipdist_output(&b, out[0], &clipdist[0]);
-   if (ucp_enables & 0xf0)
-      store_clipdist_output(&b, out[1], &clipdist[4]);
+   if (use_vars) {
+      if (ucp_enables & 0x0f)
+         nir_store_var(&b, out[0], nir_vec(&b, clipdist, 4), 0xf);
+      if (ucp_enables & 0xf0)
+         nir_store_var(&b, out[1], nir_vec(&b, &clipdist[4], 4), 0xf);
+   } else {
+      if (ucp_enables & 0x0f)
+         store_clipdist_output(&b, out[0], &clipdist[0]);
+      if (ucp_enables & 0xf0)
+         store_clipdist_output(&b, out[1], &clipdist[4]);
+   }
 
    nir_metadata_preserve(impl, nir_metadata_dominance);
 
index 63866ae4d0116af8ffcf871de7c21000f8f49983..7c2a8f83b62c1463aea812f23abeba0ea01ecc1a 100644 (file)
@@ -172,7 +172,7 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
 
        if (key) {
                if (s->info.stage == MESA_SHADER_VERTEX) {
-                       OPT_V(s, nir_lower_clip_vs, key->ucp_enables);
+                       OPT_V(s, nir_lower_clip_vs, key->ucp_enables, false);
                        if (key->vclamp_color)
                                OPT_V(s, nir_lower_clamp_color_outputs);
                } else if (s->info.stage == MESA_SHADER_FRAGMENT) {
index bc9bd76ae9503de9b401adb79f7ba050d11989e9..b98baca30cf8e0d4cb61fdd7816cc7a0b17e4773 100644 (file)
@@ -2363,7 +2363,8 @@ vc4_shader_ntq(struct vc4_context *vc4, enum qstage stage,
                 if (stage == QSTAGE_FRAG) {
                         NIR_PASS_V(c->s, nir_lower_clip_fs, c->key->ucp_enables);
                 } else {
-                        NIR_PASS_V(c->s, nir_lower_clip_vs, c->key->ucp_enables);
+                        NIR_PASS_V(c->s, nir_lower_clip_vs,
+                                  c->key->ucp_enables, false);
                         NIR_PASS_V(c->s, nir_lower_io_to_scalar,
                                    nir_var_shader_out);
                 }