nir: Add a basic metadata management system
[mesa.git] / src / glsl / link_functions.cpp
index fd80099980266fa7d48fcfbe93f9faeed3d96795..537f4dc77ac7532c50bf48b0ebd34cfb2ec02a3b 100644 (file)
@@ -145,8 +145,7 @@ public:
       struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash,
                                              hash_table_pointer_compare);
       exec_list formal_parameters;
-      foreach_list_const(node, &sig->parameters) {
-        const ir_instruction *const original = (ir_instruction *) node;
+      foreach_in_list(const ir_instruction, original, &sig->parameters) {
         assert(const_cast<ir_instruction *>(original)->as_variable());
 
         ir_instruction *copy = original->clone(linked, ht);
@@ -155,14 +154,17 @@ public:
 
       linked_sig->replace_parameters(&formal_parameters);
 
-      foreach_list_const(node, &sig->body) {
-        const ir_instruction *const original = (ir_instruction *) node;
+      linked_sig->is_intrinsic = sig->is_intrinsic;
 
-        ir_instruction *copy = original->clone(linked, ht);
-        linked_sig->body.push_tail(copy);
+      if (sig->is_defined) {
+         foreach_in_list(const ir_instruction, original, &sig->body) {
+            ir_instruction *copy = original->clone(linked, ht);
+            linked_sig->body.push_tail(copy);
+         }
+
+         linked_sig->is_defined = true;
       }
 
-      linked_sig->is_defined = true;
       hash_table_dtor(ht);
 
       /* Patch references inside the function to things outside the function
@@ -198,8 +200,9 @@ public:
             if (formal_param->type->is_array()) {
                ir_dereference_variable *deref = actual_param->as_dereference_variable();
                if (deref && deref->var && deref->var->type->is_array()) {
-                  deref->var->max_array_access =
-                     MAX2(formal_param->max_array_access, deref->var->max_array_access);
+                  deref->var->data.max_array_access =
+                     MAX2(formal_param->data.max_array_access,
+                         deref->var->data.max_array_access);
                }
             }
          }
@@ -231,8 +234,9 @@ public:
                 * we need to track the maximal access to the array as linking
                 * pulls more functions in that access the array.
                 */
-               var->max_array_access =
-                  MAX2(var->max_array_access, ir->var->max_array_access);
+               var->data.max_array_access =
+                  MAX2(var->data.max_array_access,
+                       ir->var->data.max_array_access);
 
                if (var->type->length == 0 && ir->var->type->length != 0)
                   var->type = ir->var->type;
@@ -241,11 +245,19 @@ public:
                /* Similarly, we need implicit sizes of arrays within interface
                 * blocks to be sized by the maximal access in *any* shader.
                 */
+               unsigned *const linked_max_ifc_array_access =
+                  var->get_max_ifc_array_access();
+               unsigned *const ir_max_ifc_array_access =
+                  ir->var->get_max_ifc_array_access();
+
+               assert(linked_max_ifc_array_access != NULL);
+               assert(ir_max_ifc_array_access != NULL);
+
                for (unsigned i = 0; i < var->get_interface_type()->length;
                     i++) {
-                  var->max_ifc_array_access[i] =
-                     MAX2(var->max_ifc_array_access[i],
-                          ir->var->max_ifc_array_access[i]);
+                  linked_max_ifc_array_access[i] =
+                     MAX2(linked_max_ifc_array_access[i],
+                          ir_max_ifc_array_access[i]);
                }
             }
         }
@@ -305,9 +317,10 @@ find_matching_signature(const char *name, const exec_list *actual_parameters,
         continue;
 
       ir_function_signature *sig =
-         f->matching_signature(NULL, actual_parameters);
+         f->matching_signature(NULL, actual_parameters, use_builtin);
 
-      if ((sig == NULL) || !sig->is_defined)
+      if ((sig == NULL) ||
+          (!sig->is_defined && !sig->is_intrinsic))
         continue;
 
       /* If this function expects to bind to a built-in function and the