Allow dereference of vectors and matrices with []
authorIan Romanick <ian.d.romanick@intel.com>
Mon, 5 Apr 2010 20:16:00 +0000 (13:16 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 5 Apr 2010 20:16:00 +0000 (13:16 -0700)
This causes the following tests to pass:
     glslparsertest/glsl2/matrix-11.vert
     glslparsertest/glsl2/matrix-12.vert
     glslparsertest/shaders/CorrectParse2.vert
     glslparsertest/shaders/CorrectSwizzle2.frag

ast_to_hir.cpp

index f7a9ba8..c9f93cb 100644 (file)
@@ -1008,10 +1008,12 @@ ast_expression::hir(exec_list *instructions,
       if (error_emitted)
         break;
 
-      /* FINISHME: Handle vectors and matrices accessed with []. */
-      if (!array->type->is_array()) {
+      if (!array->type->is_array()
+         && !array->type->is_matrix()
+         && !array->type->is_vector()) {
         _mesa_glsl_error(& index_loc, state,
-                         "cannot dereference non-array");
+                         "cannot dereference non-array / non-matrix / "
+                         "non-vector");
         error_emitted = true;
       }
 
@@ -1033,6 +1035,16 @@ ast_expression::hir(exec_list *instructions,
       ir_constant *const const_index = op[1]->constant_expression_value();
       if (const_index != NULL) {
         const int idx = const_index->value.i[0];
+        const char *type_name;
+        unsigned bound = 0;
+
+        if (array->type->is_matrix()) {
+           type_name = "matrix";
+        } else if (array->type->is_vector()) {
+           type_name = "vector";
+        } else {
+           type_name = "array";
+        }
 
         /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
          *
@@ -1042,23 +1054,36 @@ ast_expression::hir(exec_list *instructions,
          *    declared size. It is also illegal to index an array with a
          *    negative constant expression."
          */
-        if ((array->type->array_size() > 0)
-            && (array->type->array_size() <= idx)) {
-           _mesa_glsl_error(& loc, state,
-                            "array index must be < %u",
-                            array->type->array_size());
-           error_emitted = true;
+        if (array->type->is_matrix()) {
+           if (array->type->row_type()->vector_elements <= idx) {
+              bound = array->type->row_type()->vector_elements;
+           }
+        } else if (array->type->is_vector()) {
+           if (array->type->vector_elements <= idx) {
+              bound = array->type->vector_elements;
+           }
+        } else {
+           if ((array->type->array_size() > 0)
+               && (array->type->array_size() <= idx)) {
+              bound = array->type->array_size();
+           }
         }
 
-        if (idx < 0) {
-           _mesa_glsl_error(& loc, state,
-                            "array index must be >= 0");
+        if (bound > 0) {
+           _mesa_glsl_error(& loc, state, "%s index must be < %u",
+                            type_name, bound);
+           error_emitted = true;
+        } else if (idx < 0) {
+           _mesa_glsl_error(& loc, state, "%s index must be >= 0",
+                            type_name);
            error_emitted = true;
         }
 
-        ir_variable *const v = array->as_variable();
-        if ((v != NULL) && (unsigned(idx) > v->max_array_access))
-           v->max_array_access = idx;
+        if (array->type->is_array()) {
+           ir_variable *const v = array->as_variable();
+           if ((v != NULL) && (unsigned(idx) > v->max_array_access))
+              v->max_array_access = idx;
+        }
       }
 
       if (error_emitted)