Fix 'make check' in src/mapi/glapi/tests when builddir != srcdir
[mesa.git] / src / glsl / linker.cpp
index d8f655c39397b4cbe905afc111ed734e7a5c381c..1366077f7846ca14a6cef6e9d839174e41f1d8d6 100644 (file)
@@ -557,29 +557,6 @@ validate_geometry_shader_executable(struct gl_shader_program *prog,
 }
 
 
-/**
- * Generate a string describing the mode of a variable
- */
-static const char *
-mode_string(const ir_variable *var)
-{
-   switch (var->mode) {
-   case ir_var_auto:
-      return (var->read_only) ? "global constant" : "global variable";
-
-   case ir_var_uniform:    return "uniform";
-   case ir_var_shader_in:  return "shader input";
-   case ir_var_shader_out: return "shader output";
-
-   case ir_var_const_in:
-   case ir_var_temporary:
-   default:
-      assert(!"Should not get here.");
-      return "invalid variable";
-   }
-}
-
-
 /**
  * Perform validation of global variables used across multiple shaders
  */
@@ -674,6 +651,14 @@ cross_validate_globals(struct gl_shader_program *prog,
                existing->explicit_binding = true;
             }
 
+            if (var->type->contains_atomic() &&
+                var->atomic.offset != existing->atomic.offset) {
+               linker_error(prog, "offset specifications for %s "
+                            "`%s' have differing values\n",
+                            mode_string(var), var->name);
+               return;
+            }
+
            /* Validate layout qualifiers for gl_FragDepth.
             *
             * From the AMD/ARB_conservative_depth specs:
@@ -1108,7 +1093,7 @@ private:
     */
    static void fixup_type(const glsl_type **type, unsigned max_array_access)
    {
-      if ((*type)->is_array() && (*type)->length == 0) {
+      if ((*type)->is_unsized_array()) {
          *type = glsl_type::get_array_instance((*type)->fields.array,
                                                max_array_access + 1);
          assert(*type != NULL);
@@ -1123,7 +1108,7 @@ private:
    {
       for (unsigned i = 0; i < type->length; i++) {
          const glsl_type *elem_type = type->fields.structure[i].type;
-         if (elem_type->is_array() && elem_type->length == 0)
+         if (elem_type->is_unsized_array())
             return true;
       }
       return false;
@@ -1508,8 +1493,12 @@ update_array_sizes(struct gl_shader_program *prog)
         /* GL_ARB_uniform_buffer_object says that std140 uniforms
          * will not be eliminated.  Since we always do std140, just
          * don't resize arrays in UBOs.
+          *
+          * Atomic counters are supposed to get deterministic
+          * locations assigned based on the declaration ordering and
+          * sizes, array compaction would mess that up.
          */
-        if (var->is_in_uniform_block())
+        if (var->is_in_uniform_block() || var->type->contains_atomic())
            continue;
 
         unsigned int size = var->max_array_access;
@@ -2014,6 +2003,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       prog->UniformBlockStageIndex[i] = NULL;
    }
 
+   ralloc_free(prog->AtomicBuffers);
+   prog->AtomicBuffers = NULL;
+   prog->NumAtomicBuffers = 0;
+
    /* Separate the shaders into groups based on their type.
     */
    struct gl_shader **vert_shader_list;
@@ -2161,8 +2154,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       if (prog->_LinkedShaders[i] == NULL)
          continue;
 
-      validate_interstage_interface_blocks(prog, prog->_LinkedShaders[prev],
-                                           prog->_LinkedShaders[i]);
+      validate_interstage_inout_blocks(prog, prog->_LinkedShaders[prev],
+                                       prog->_LinkedShaders[i]);
       if (!prog->LinkStatus)
          goto done;
 
@@ -2175,6 +2168,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       prev = i;
    }
 
+   /* Cross-validate uniform blocks between shader stages */
+   validate_interstage_uniform_blocks(prog, prog->_LinkedShaders,
+                                      MESA_SHADER_TYPES);
+   if (!prog->LinkStatus)
+      goto done;
 
    for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
       if (prog->_LinkedShaders[i] != NULL)
@@ -2365,9 +2363,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 
    update_array_sizes(prog);
    link_assign_uniform_locations(prog);
+   link_assign_atomic_counter_resources(ctx, prog);
    store_fragdepth_layout(prog);
 
    check_resources(ctx, prog);
+   link_check_atomic_counter_resources(ctx, prog);
+
    if (!prog->LinkStatus)
       goto done;
 
@@ -2395,6 +2396,11 @@ done:
       if (prog->_LinkedShaders[i] == NULL)
         continue;
 
+      /* Do a final validation step to make sure that the IR wasn't
+       * invalidated by any modifications performed after intrastage linking.
+       */
+      validate_ir_tree(prog->_LinkedShaders[i]->ir);
+
       /* Retain any live IR, but trash the rest. */
       reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);