glsl: move array validation into its own function
authorTimothy Arceri <t_arceri@yahoo.com.au>
Sat, 21 Feb 2015 10:47:14 +0000 (21:47 +1100)
committerTimothy Arceri <t_arceri@yahoo.com.au>
Thu, 5 Mar 2015 20:26:41 +0000 (07:26 +1100)
V2: return true when var->type is unsized but max access is within valid range

Reviewed-by: Mark Janes <mark.a.janes@intel.com>
src/glsl/linker.cpp
src/glsl/linker.h

index e11b6fa9a2a6a4f943cd62a49db892a76e18c8dd..590f364d6c265fed3b026447d962e8e70fd8d1ed 100644 (file)
@@ -681,6 +681,45 @@ validate_geometry_shader_emissions(struct gl_context *ctx,
    }
 }
 
+bool
+validate_intrastage_arrays(struct gl_shader_program *prog,
+                           ir_variable *const var,
+                          ir_variable *const existing)
+{
+   /* Consider the types to be "the same" if both types are arrays
+    * of the same type and one of the arrays is implicitly sized.
+    * In addition, set the type of the linked variable to the
+    * explicitly sized array.
+    */
+   if (var->type->is_array() && existing->type->is_array() &&
+       (var->type->fields.array == existing->type->fields.array) &&
+       ((var->type->length == 0)|| (existing->type->length == 0))) {
+      if (var->type->length != 0) {
+         if (var->type->length <= existing->data.max_array_access) {
+            linker_error(prog, "%s `%s' declared as type "
+                         "`%s' but outermost dimension has an index"
+                         " of `%i'\n",
+                         mode_string(var),
+                         var->name, var->type->name,
+                         existing->data.max_array_access);
+         }
+         existing->type = var->type;
+         return true;
+      } else if (existing->type->length != 0) {
+         if(existing->type->length <= var->data.max_array_access) {
+            linker_error(prog, "%s `%s' declared as type "
+                         "`%s' but outermost dimension has an index"
+                         " of `%i'\n",
+                         mode_string(var),
+                         var->name, existing->type->name,
+                         var->data.max_array_access);
+         }
+         return true;
+      }
+   }
+   return false;
+}
+
 
 /**
  * Perform validation of global variables used across multiple shaders
@@ -720,50 +759,22 @@ cross_validate_globals(struct gl_shader_program *prog,
          */
         ir_variable *const existing = variables.get_variable(var->name);
         if (existing != NULL) {
+            /* Check if types match. Interface blocks have some special
+             * rules so we handle those elsewhere.
+             */
            if (var->type != existing->type) {
-              /* Consider the types to be "the same" if both types are arrays
-               * of the same type and one of the arrays is implicitly sized.
-               * In addition, set the type of the linked variable to the
-               * explicitly sized array.
-               */
-              if (var->type->is_array()
-                  && existing->type->is_array()
-                  && (var->type->fields.array == existing->type->fields.array)
-                  && ((var->type->length == 0)
-                      || (existing->type->length == 0))) {
-                 if (var->type->length != 0) {
-                     if (var->type->length <= existing->data.max_array_access) {
-                        linker_error(prog, "%s `%s' declared as type "
-                                     "`%s' but outermost dimension has an index"
-                                     " of `%i'\n",
-                                     mode_string(var),
-                                     var->name, var->type->name,
-                                     existing->data.max_array_access);
-                        return;
-                     }
-                    existing->type = var->type;
-                 } else if (existing->type->length != 0
-                             && existing->type->length <=
-                                var->data.max_array_access) {
+              if (!validate_intrastage_arrays(prog, var, existing)) {
+                  if (var->type->is_record() && existing->type->is_record()
+                      && existing->type->record_compare(var->type)) {
+                     existing->type = var->type;
+                  } else {
                      linker_error(prog, "%s `%s' declared as type "
-                                  "`%s' but outermost dimension has an index"
-                                  " of `%i'\n",
+                                  "`%s' and type `%s'\n",
                                   mode_string(var),
-                                  var->name, existing->type->name,
-                                  var->data.max_array_access);
+                                  var->name, var->type->name,
+                                  existing->type->name);
                      return;
                   }
-               } else if (var->type->is_record()
-                  && existing->type->is_record()
-                  && existing->type->record_compare(var->type)) {
-                 existing->type = var->type;
-              } else {
-                 linker_error(prog, "%s `%s' declared as type "
-                              "`%s' and type `%s'\n",
-                              mode_string(var),
-                              var->name, var->type->name,
-                              existing->type->name);
-                 return;
               }
            }
 
index be4da5e0aa2584209a001b8f231dba06236e36a2..ce3dc323297019db02165c465a47f0cc94b00c12 100644 (file)
@@ -61,6 +61,11 @@ link_uniform_blocks(void *mem_ctx,
                     unsigned num_shaders,
                     struct gl_uniform_block **blocks_ret);
 
+bool
+validate_intrastage_arrays(struct gl_shader_program *prog,
+                           ir_variable *const var,
+                           ir_variable *const existing);
+
 void
 validate_intrastage_interface_blocks(struct gl_shader_program *prog,
                                      const gl_shader **shader_list,