glsl: Add infrastructure for aggregate initializers.
authorMatt Turner <mattst88@gmail.com>
Sun, 30 Jun 2013 02:27:50 +0000 (19:27 -0700)
committerMatt Turner <mattst88@gmail.com>
Fri, 12 Jul 2013 03:58:59 +0000 (20:58 -0700)
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ast.h
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/glsl_parser_extras.cpp

index 8abea5225f03ea2d273b5107f6cdb2d464234b09..44e9f1874b5f357ed8a9a0b00712a3a09f53a74f 100644 (file)
@@ -189,7 +189,8 @@ enum ast_operators {
    ast_float_constant,
    ast_bool_constant,
 
-   ast_sequence
+   ast_sequence,
+   ast_aggregate
 };
 
 /**
@@ -292,6 +293,29 @@ private:
    bool cons;
 };
 
+/**
+ * C-style aggregate initialization class
+ *
+ * Represents C-style initializers of vectors, matrices, arrays, and
+ * structures. E.g., vec3 pos = {1.0, 0.0, -1.0} is equivalent to
+ * vec3 pos = vec3(1.0, 0.0, -1.0).
+ *
+ * Specified in GLSL 4.20 and GL_ARB_shading_language_420pack.
+ *
+ * \sa _mesa_ast_set_aggregate_type
+ */
+class ast_aggregate_initializer : public ast_expression {
+public:
+   ast_aggregate_initializer()
+      : ast_expression(ast_aggregate, NULL, NULL, NULL)
+   {
+      /* empty */
+   }
+
+   ast_type_specifier *constructor_type;
+   virtual ir_rvalue *hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state);
+};
 
 /**
  * Number of possible operators for an ast_expression
index 459a17a3dca72e5cc488783b8df994897ee5150f..39182639f33cb5fe9f99ffb0ef3d6df9d65106a9 100644 (file)
@@ -1699,3 +1699,33 @@ ast_function_expression::hir(exec_list *instructions,
 
    return ir_rvalue::error_value(ctx);
 }
+
+ir_rvalue *
+ast_aggregate_initializer::hir(exec_list *instructions,
+                               struct _mesa_glsl_parse_state *state)
+{
+   void *ctx = state;
+   YYLTYPE loc = this->get_location();
+   const char *name;
+   const glsl_type *const constructor_type =
+      this->constructor_type->glsl_type(&name, state);
+
+   if (!state->ARB_shading_language_420pack_enable) {
+      _mesa_glsl_error(&loc, state, "C-style initialization requires the "
+                       "GL_ARB_shading_language_420pack extension");
+      return ir_rvalue::error_value(ctx);
+   }
+
+   if (this->constructor_type->is_array) {
+      return process_array_constructor(instructions, constructor_type, &loc,
+                                       &this->expressions, state);
+   }
+
+   if (this->constructor_type->structure) {
+      return process_record_constructor(instructions, constructor_type, &loc,
+                                        &this->expressions, state);
+   }
+
+   return process_vec_mat_constructor(instructions, constructor_type, &loc,
+                                      &this->expressions, state);
+}
index 611a85dd8e1f9d8784acf8763c60cd53ea53bb17..c316127ff89c9e79c5795e3bc11dc3f30eef8d84 100644 (file)
@@ -1068,6 +1068,10 @@ ast_expression::hir(exec_list *instructions,
    loc = this->get_location();
 
    switch (this->oper) {
+   case ast_aggregate:
+         assert(!"ast_aggregate: Should never get here.");
+         break;
+
    case ast_assign: {
       op[0] = this->subexpressions[0]->hir(instructions, state);
       op[1] = this->subexpressions[1]->hir(instructions, state);
index aa5a435fa95c2ccea3b55d21116e51687818c041..602ec08328b06fb62983d3e3e3dd9c71f1b07f18 100644 (file)
@@ -862,6 +862,19 @@ ast_expression::print(void) const
       break;
    }
 
+   case ast_aggregate: {
+      printf("{ ");
+      foreach_list_const(n, & this->expressions) {
+        if (n != this->expressions.get_head())
+           printf(", ");
+
+        ast_node *ast = exec_node_data(ast_node, n, link);
+        ast->print();
+      }
+      printf("} ");
+      break;
+   }
+
    default:
       assert(0);
       break;