egl/main: Stop using EGLNative types internally
[mesa.git] / src / glsl / link_functions.cpp
index c5398f5ff0416198361ccc5bdf60ffdaee691880..56f3f207ee8b2254a46865ec9e4b9d9cffd6e148 100644 (file)
@@ -34,6 +34,8 @@ find_matching_signature(const char *name, const exec_list *actual_parameters,
                        gl_shader **shader_list, unsigned num_shaders,
                        bool use_builtin);
 
+namespace {
+
 class call_link_visitor : public ir_hierarchical_visitor {
 public:
    call_link_visitor(gl_shader_program *prog, gl_shader *linked,
@@ -113,7 +115,7 @@ public:
       }
 
       ir_function_signature *linked_sig =
-        f->exact_matching_signature(&callee->parameters);
+        f->exact_matching_signature(NULL, &callee->parameters);
       if ((linked_sig == NULL)
          || ((linked_sig != NULL)
              && (linked_sig->is_builtin() != ir->use_builtin))) {
@@ -153,14 +155,17 @@ public:
 
       linked_sig->replace_parameters(&formal_parameters);
 
-      foreach_list_const(node, &sig->body) {
-        const ir_instruction *const original = (ir_instruction *) node;
+      if (sig->is_defined) {
+         foreach_list_const(node, &sig->body) {
+            const ir_instruction *const original = (ir_instruction *) node;
 
-        ir_instruction *copy = original->clone(linked, ht);
-        linked_sig->body.push_tail(copy);
+            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
@@ -196,8 +201,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);
                }
             }
          }
@@ -221,18 +227,32 @@ public:
            var = ir->var->clone(linked, NULL);
            linked->symbols->add_variable(var);
            linked->ir->push_head(var);
-        } else if (var->type->is_array()) {
-           /* It is possible to have a global array declared in multiple
-            * shaders without a size.  The array is implicitly sized by the
-            * maximal access to it in *any* shader.  Because of this, 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);
-
-           if (var->type->length == 0 && ir->var->type->length != 0)
-              var->type = ir->var->type;
+        } else {
+            if (var->type->is_array()) {
+               /* It is possible to have a global array declared in multiple
+                * shaders without a size.  The array is implicitly sized by
+                * the maximal access to it in *any* shader.  Because of this,
+                * we need to track the maximal access to the array as linking
+                * pulls more functions in that access the array.
+                */
+               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;
+            }
+            if (var->is_interface_instance()) {
+               /* Similarly, we need implicit sizes of arrays within interface
+                * blocks to be sized by the maximal access in *any* shader.
+                */
+               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]);
+               }
+            }
         }
 
         ir->var = var;
@@ -273,6 +293,7 @@ private:
    hash_table *locals;
 };
 
+} /* anonymous namespace */
 
 /**
  * Searches a list of shaders for a particular function definition
@@ -288,9 +309,11 @@ find_matching_signature(const char *name, const exec_list *actual_parameters,
       if (f == NULL)
         continue;
 
-      ir_function_signature *sig = f->matching_signature(actual_parameters);
+      ir_function_signature *sig =
+         f->matching_signature(NULL, actual_parameters);
 
-      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