Mesa (main): microsoft/compiler: use nir_shader_instructions_pass in dxil_nir_split_clip_cull_distance
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Aug 11 11:56:55 UTC 2021
Module: Mesa
Branch: main
Commit: b8de41902e354c81779e633fcdaa780dabba56a7
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b8de41902e354c81779e633fcdaa780dabba56a7
Author: Marcin Ślusarz <marcin.slusarz at intel.com>
Date: Tue Aug 10 13:30:56 2021 +0200
microsoft/compiler: use nir_shader_instructions_pass in dxil_nir_split_clip_cull_distance
No functional changes.
v2: fix build
Signed-off-by: Marcin Ślusarz <marcin.slusarz at intel.com>
Reviewed-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12324>
---
src/microsoft/compiler/dxil_nir.c | 165 ++++++++++++++++++++------------------
1 file changed, 86 insertions(+), 79 deletions(-)
diff --git a/src/microsoft/compiler/dxil_nir.c b/src/microsoft/compiler/dxil_nir.c
index e7ecaeabf48..0aae871ee39 100644
--- a/src/microsoft/compiler/dxil_nir.c
+++ b/src/microsoft/compiler/dxil_nir.c
@@ -1136,6 +1136,11 @@ dxil_nir_lower_upcast_phis(nir_shader *shader, unsigned min_bit_size)
return progress;
}
+struct dxil_nir_split_clip_cull_distance_params {
+ nir_variable *new_var;
+ nir_shader *shader;
+};
+
/* In GLSL and SPIR-V, clip and cull distance are arrays of floats (with a limit of 8).
* In DXIL, clip and cull distances are up to 2 float4s combined.
* Coming from GLSL, we can request this 2 float4 format, but coming from SPIR-V,
@@ -1144,96 +1149,98 @@ dxil_nir_lower_upcast_phis(nir_shader *shader, unsigned min_bit_size)
* To help emitting a valid input signature for this case, split the variables so that they
* match what we need to put in the signature (e.g. { float clip[4]; float clip1; float cull[3]; })
*/
-bool
-dxil_nir_split_clip_cull_distance(nir_shader *shader)
+static bool
+dxil_nir_split_clip_cull_distance_instr(nir_builder *b,
+ nir_instr *instr,
+ void *cb_data)
{
- nir_variable *new_var = NULL;
- nir_foreach_function(function, shader) {
- if (!function->impl)
- continue;
+ struct dxil_nir_split_clip_cull_distance_params *params = cb_data;
+ nir_variable *new_var = params->new_var;
- bool progress = false;
- nir_builder b;
- nir_builder_init(&b, function->impl);
- nir_foreach_block(block, function->impl) {
- nir_foreach_instr_safe(instr, block) {
- if (instr->type != nir_instr_type_deref)
- continue;
- nir_deref_instr *deref = nir_instr_as_deref(instr);
- nir_variable *var = nir_deref_instr_get_variable(deref);
- if (!var ||
- var->data.location < VARYING_SLOT_CLIP_DIST0 ||
- var->data.location > VARYING_SLOT_CULL_DIST1 ||
- !var->data.compact)
- continue;
+ if (instr->type != nir_instr_type_deref)
+ return false;
- /* The location should only be inside clip distance, because clip
- * and cull should've been merged by nir_lower_clip_cull_distance_arrays()
- */
- assert(var->data.location == VARYING_SLOT_CLIP_DIST0 ||
- var->data.location == VARYING_SLOT_CLIP_DIST1);
+ nir_deref_instr *deref = nir_instr_as_deref(instr);
+ nir_variable *var = nir_deref_instr_get_variable(deref);
+ if (!var ||
+ var->data.location < VARYING_SLOT_CLIP_DIST0 ||
+ var->data.location > VARYING_SLOT_CULL_DIST1 ||
+ !var->data.compact)
+ return false;
- /* The deref chain to the clip/cull variables should be simple, just the
- * var and an array with a constant index, otherwise more lowering/optimization
- * might be needed before this pass, e.g. copy prop, lower_io_to_temporaries,
- * split_var_copies, and/or lower_var_copies
- */
- assert(deref->deref_type == nir_deref_type_var ||
- deref->deref_type == nir_deref_type_array);
-
- b.cursor = nir_before_instr(instr);
- if (!new_var) {
- /* Update lengths for new and old vars */
- int old_length = glsl_array_size(var->type);
- int new_length = (old_length + var->data.location_frac) - 4;
- old_length -= new_length;
-
- /* The existing variable fits in the float4 */
- if (new_length <= 0)
- continue;
+ /* The location should only be inside clip distance, because clip
+ * and cull should've been merged by nir_lower_clip_cull_distance_arrays()
+ */
+ assert(var->data.location == VARYING_SLOT_CLIP_DIST0 ||
+ var->data.location == VARYING_SLOT_CLIP_DIST1);
- new_var = nir_variable_clone(var, shader);
- nir_shader_add_variable(shader, new_var);
- assert(glsl_get_base_type(glsl_get_array_element(var->type)) == GLSL_TYPE_FLOAT);
- var->type = glsl_array_type(glsl_float_type(), old_length, 0);
- new_var->type = glsl_array_type(glsl_float_type(), new_length, 0);
- new_var->data.location++;
- new_var->data.location_frac = 0;
- }
+ /* The deref chain to the clip/cull variables should be simple, just the
+ * var and an array with a constant index, otherwise more lowering/optimization
+ * might be needed before this pass, e.g. copy prop, lower_io_to_temporaries,
+ * split_var_copies, and/or lower_var_copies
+ */
+ assert(deref->deref_type == nir_deref_type_var ||
+ deref->deref_type == nir_deref_type_array);
- /* Update the type for derefs of the old var */
- if (deref->deref_type == nir_deref_type_var) {
- deref->type = var->type;
- continue;
- }
+ b->cursor = nir_before_instr(instr);
+ if (!new_var) {
+ /* Update lengths for new and old vars */
+ int old_length = glsl_array_size(var->type);
+ int new_length = (old_length + var->data.location_frac) - 4;
+ old_length -= new_length;
- nir_const_value *index = nir_src_as_const_value(deref->arr.index);
- assert(index);
+ /* The existing variable fits in the float4 */
+ if (new_length <= 0)
+ return false;
- /* Treat this array as a vector starting at the component index in location_frac,
- * so if location_frac is 1 and index is 0, then it's accessing the 'y' component
- * of the vector. If index + location_frac is >= 4, there's no component there,
- * so we need to add a new variable and adjust the index.
- */
- unsigned total_index = index->u32 + var->data.location_frac;
- if (total_index < 4)
- continue;
+ new_var = nir_variable_clone(var, params->shader);
+ nir_shader_add_variable(params->shader, new_var);
+ assert(glsl_get_base_type(glsl_get_array_element(var->type)) == GLSL_TYPE_FLOAT);
+ var->type = glsl_array_type(glsl_float_type(), old_length, 0);
+ new_var->type = glsl_array_type(glsl_float_type(), new_length, 0);
+ new_var->data.location++;
+ new_var->data.location_frac = 0;
+ params->new_var = new_var;
+ }
- nir_deref_instr *new_var_deref = nir_build_deref_var(&b, new_var);
- nir_deref_instr *new_array_deref = nir_build_deref_array(&b, new_var_deref, nir_imm_int(&b, total_index % 4));
- nir_ssa_def_rewrite_uses(&deref->dest.ssa, &new_array_deref->dest.ssa);
- progress = true;
- }
- }
- if (progress)
- nir_metadata_preserve(function->impl, nir_metadata_block_index |
- nir_metadata_dominance |
- nir_metadata_loop_analysis);
- else
- nir_metadata_preserve(function->impl, nir_metadata_all);
+ /* Update the type for derefs of the old var */
+ if (deref->deref_type == nir_deref_type_var) {
+ deref->type = var->type;
+ return false;
}
- return new_var != NULL;
+ nir_const_value *index = nir_src_as_const_value(deref->arr.index);
+ assert(index);
+
+ /* Treat this array as a vector starting at the component index in location_frac,
+ * so if location_frac is 1 and index is 0, then it's accessing the 'y' component
+ * of the vector. If index + location_frac is >= 4, there's no component there,
+ * so we need to add a new variable and adjust the index.
+ */
+ unsigned total_index = index->u32 + var->data.location_frac;
+ if (total_index < 4)
+ return false;
+
+ nir_deref_instr *new_var_deref = nir_build_deref_var(b, new_var);
+ nir_deref_instr *new_array_deref = nir_build_deref_array(b, new_var_deref, nir_imm_int(b, total_index % 4));
+ nir_ssa_def_rewrite_uses(&deref->dest.ssa, &new_array_deref->dest.ssa);
+ return true;
+}
+
+bool
+dxil_nir_split_clip_cull_distance(nir_shader *shader)
+{
+ struct dxil_nir_split_clip_cull_distance_params params = {
+ .new_var = NULL,
+ .shader = shader,
+ };
+ nir_shader_instructions_pass(shader,
+ dxil_nir_split_clip_cull_distance_instr,
+ nir_metadata_block_index |
+ nir_metadata_dominance |
+ nir_metadata_loop_analysis,
+ ¶ms);
+ return params.new_var != NULL;
}
bool
More information about the mesa-commit
mailing list