spirv_to_dxil: Handle clip/cull distance

Clip/cull only needs a little bit of lowering before nir_to_dxil can
handle it. Specifically, we just need to split apart arrays that
straddle the 4-component boundary of location, so that the signature
builder can handle it.

To do that cleanly, we need to add some lowering and optimization passes:
* nir_lower_clip_cull_distance_arrays: Merge clip/cull into a single array,
  which is similar to DXIL's requirements here.
* nir_lower_io_to_temporaries: Ensure that we only have one non-indirect write
  to the clip/cull output.
* nir_split_var_copies and nir_lower_var_copies: Ensure that each array entry
  has an independent write with a constant index
* Optimization loop: Make sure that there's no extra derefs in the way between
  deref_var for the output, deref_array for the component, and store_deref.
Then we can actually lower the clip/cull array cleanly.

Still to do is to sort the variables and add driver_location.

Reviewed-by: Bill Kristiansen <billkris@microsoft.com>
Reviewed-by: Michael Tang <tangm@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9846>
This commit is contained in:
Jesse Natalie 2021-03-25 18:27:22 -07:00 committed by Marge Bot
parent 39aa32b838
commit f447c69653
1 changed files with 26 additions and 0 deletions

View File

@ -23,6 +23,7 @@
#include "spirv_to_dxil.h"
#include "nir_to_dxil.h"
#include "dxil_nir.h"
#include "shader_enums.h"
#include "spirv/nir_spirv.h"
#include "util/blob.h"
@ -73,6 +74,31 @@ spirv_to_dxil(const uint32_t *words, size_t word_count,
exec_node_remove(&func->node);
}
assert(exec_list_length(&nir->functions) == 1);
NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
NIR_PASS_V(nir, nir_lower_io_to_temporaries, entrypoint->impl, true, true);
NIR_PASS_V(nir, nir_split_var_copies);
NIR_PASS_V(nir, nir_lower_var_copies);
{
bool progress;
do
{
progress = false;
NIR_PASS(progress, nir, nir_copy_prop);
NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
NIR_PASS(progress, nir, nir_opt_deref);
NIR_PASS(progress, nir, nir_opt_dce);
NIR_PASS(progress, nir, nir_opt_undef);
NIR_PASS(progress, nir, nir_opt_constant_folding);
NIR_PASS(progress, nir, nir_opt_cse);
NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
NIR_PASS(progress, nir, nir_opt_algebraic);
} while (progress);
}
NIR_PASS_V(nir, dxil_nir_split_clip_cull_distance);
struct nir_to_dxil_options opts = {0};
struct blob dxil_blob;