nir: Make nir_lower_clip_vs optionally work with variables.

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>
This commit is contained in:
Kenneth Graunke
2017-05-21 19:26:15 -07:00
parent d0f746b645
commit 5b682143da
5 changed files with 40 additions and 15 deletions

View 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);