nir: copy intrinsic type when lowering load input/uniform and store output
[mesa.git] / src / compiler / nir / nir_lower_load_const_to_scalar.c
index b5df46413f1a03e13fe620aa02972ab937c19442..a65dcb06d0cad68dc18b390ed2d8a8650e616391 100644 (file)
  * same value was used in different vector contant loads.
  */
 
-static void
+static bool
 lower_load_const_instr_scalar(nir_load_const_instr *lower)
 {
    if (lower->def.num_components == 1)
-      return;
+      return false;
 
    nir_builder b;
    nir_builder_init(&b, nir_cf_node_get_function(&lower->instr.block->cf_node));
    b.cursor = nir_before_instr(&lower->instr);
 
    /* Emit the individual loads. */
-   nir_ssa_def *loads[4];
+   nir_ssa_def *loads[NIR_MAX_VEC_COMPONENTS];
    for (unsigned i = 0; i < lower->def.num_components; i++) {
-      nir_load_const_instr *load_comp = nir_load_const_instr_create(b.shader, 1);
-      load_comp->value.u32[0] = lower->value.u32[i];
+      nir_load_const_instr *load_comp =
+         nir_load_const_instr_create(b.shader, 1, lower->def.bit_size);
+      load_comp->value[0] = lower->value[i];
       nir_builder_instr_insert(&b, &load_comp->instr);
       loads[i] = &load_comp->def;
    }
@@ -60,30 +61,43 @@ lower_load_const_instr_scalar(nir_load_const_instr *lower)
    /* Replace the old load with a reference to our reconstructed vector. */
    nir_ssa_def_rewrite_uses(&lower->def, nir_src_for_ssa(vec));
    nir_instr_remove(&lower->instr);
+   return true;
 }
 
 static bool
-lower_load_const_to_scalar_block(nir_block *block, void *data)
+nir_lower_load_const_to_scalar_impl(nir_function_impl *impl)
 {
-   nir_foreach_instr_safe(block, instr) {
-      if (instr->type == nir_instr_type_load_const)
-         lower_load_const_instr_scalar(nir_instr_as_load_const(instr));
+   bool progress = false;
+
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         if (instr->type == nir_instr_type_load_const)
+            progress |=
+               lower_load_const_instr_scalar(nir_instr_as_load_const(instr));
+      }
    }
 
-   return true;
-}
+   if (progress) {
+      nir_metadata_preserve(impl, nir_metadata_block_index |
+                                  nir_metadata_dominance);
+   } else {
+#ifndef NDEBUG
+      impl->valid_metadata &= ~nir_metadata_not_properly_reset;
+#endif
+   }
 
-static void
-nir_lower_load_const_to_scalar_impl(nir_function_impl *impl)
-{
-   nir_foreach_block(impl, lower_load_const_to_scalar_block, NULL);
+   return progress;
 }
 
-void
+bool
 nir_lower_load_const_to_scalar(nir_shader *shader)
 {
-   nir_foreach_function(shader, function) {
+   bool progress = false;
+
+   nir_foreach_function(function, shader) {
       if (function->impl)
-         nir_lower_load_const_to_scalar_impl(function->impl);
+         progress |= nir_lower_load_const_to_scalar_impl(function->impl);
    }
+
+   return progress;
 }