glsl: Move generate_constructor_(matrix|vector) to ir_constant ctor.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 1 Sep 2010 22:31:06 +0000 (15:31 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 2 Sep 2010 01:57:50 +0000 (18:57 -0700)
src/glsl/ast_function.cpp
src/glsl/ir.cpp

index 0c9f8900384b19f5d0e377ee55d2cd3f397de1fb..f639b8a1badd246bf51ba462475ae05e19a86e13 100644 (file)
@@ -469,79 +469,6 @@ constant_record_constructor(const glsl_type *constructor_type,
 }
 
 
-/**
- * Generate data for a constant matrix constructor w/a single scalar parameter
- *
- * Matrix constructors in GLSL can be passed a single scalar of the
- * approriate type.  In these cases, the resulting matrix is the identity
- * matrix multipled by the specified scalar.  This function generates data for
- * that matrix.
- *
- * \param type         Type of the desired matrix.
- * \param initializer  Scalar value used to initialize the matrix diagonal.
- * \param data         Location to store the resulting matrix.
- */
-void
-generate_constructor_matrix(const glsl_type *type, ir_constant *initializer,
-                           ir_constant_data *data)
-{
-   assert(type->base_type == GLSL_TYPE_FLOAT);
-   assert(initializer->type->is_scalar());
-
-   for (unsigned i = 0; i < type->components(); i++)
-      data->f[i] = 0;
-
-   for (unsigned i = 0; i < type->matrix_columns; i++) {
-      /* The array offset of the ith row and column of the matrix. */
-      const unsigned idx = (i * type->vector_elements) + i;
-
-      data->f[idx] = initializer->value.f[0];
-   }
-}
-
-
-/**
- * Generate data for a constant vector constructor w/a single scalar parameter
- *
- * Vector constructors in GLSL can be passed a single scalar of the
- * approriate type.  In these cases, the resulting vector contains the specified
- * value in all components.  This function generates data for that vector.
- *
- * \param type         Type of the desired vector.
- * \param initializer  Scalar value used to initialize the vector.
- * \param data         Location to store the resulting vector data.
- */
-void
-generate_constructor_vector(const glsl_type *type, ir_constant *initializer,
-                           ir_constant_data *data)
-{
-   switch (type->base_type) {
-   case GLSL_TYPE_UINT:
-   case GLSL_TYPE_INT:
-      for (unsigned i = 0; i < type->components(); i++)
-        data->u[i] = initializer->value.u[0];
-
-      break;
-
-   case GLSL_TYPE_FLOAT:
-      for (unsigned i = 0; i < type->components(); i++)
-        data->f[i] = initializer->value.f[0];
-
-      break;
-
-   case GLSL_TYPE_BOOL:
-      for (unsigned i = 0; i < type->components(); i++)
-        data->b[i] = initializer->value.b[0];
-
-      break;
-
-   default:
-      assert(!"Should not get here.");
-      break;
-   }
-}
-
-
 /**
  * Determine if a list consists of a single scalar r-value
  */
@@ -1219,32 +1146,7 @@ ast_function_expression::hir(exec_list *instructions,
        * constant representing the complete collection of parameters.
        */
       if (all_parameters_are_constant) {
-        if (components_used >= type_components)
-           return new(ctx) ir_constant(constructor_type,
-                                       & actual_parameters);
-
-        /* The above case must handle all scalar constructors.
-         */
-        assert(constructor_type->is_vector()
-               || constructor_type->is_matrix());
-
-        /* Constructors with exactly one component are special for
-         * vectors and matrices.  For vectors it causes all elements of
-         * the vector to be filled with the value.  For matrices it
-         * causes the matrix to be filled with 0 and the diagonal to be
-         * filled with the value.
-         */
-        ir_constant_data data = { { 0 } };
-        ir_constant *const initializer =
-           (ir_constant *) actual_parameters.head;
-        if (constructor_type->is_matrix())
-           generate_constructor_matrix(constructor_type, initializer,
-                                       &data);
-        else
-           generate_constructor_vector(constructor_type, initializer,
-                                       &data);
-
-        return new(ctx) ir_constant(constructor_type, &data);
+        return new(ctx) ir_constant(constructor_type, &actual_parameters);
       } else if (constructor_type->is_scalar()) {
         return dereference_component((ir_rvalue *) actual_parameters.head,
                                      0);
index 5bd023f499e47e97a1f72200ed7089741e12d8d1..aee44a77c95424335dbf40b16fc6e456361ca22a 100644 (file)
@@ -415,6 +415,41 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
 
    ir_constant *value = (ir_constant *) (value_list->head);
 
+   /* Constructors with exactly one scalar argument are special for vectors
+    * and matrices.  For vectors, the scalar value is replicated to fill all
+    * the components.  For matrices, the scalar fills the components of the
+    * diagonal while the rest is filled with 0.
+    */
+   if (value->type->is_scalar() && value->next->is_tail_sentinel()) {
+      if (type->is_matrix()) {
+        /* Matrix - fill diagonal (rest is already set to 0) */
+        assert(type->base_type == GLSL_TYPE_FLOAT);
+        for (unsigned i = 0; i < type->matrix_columns; i++)
+           this->value.f[i * type->vector_elements + i] = value->value.f[0];
+      } else {
+        /* Vector or scalar - fill all components */
+        switch (type->base_type) {
+        case GLSL_TYPE_UINT:
+        case GLSL_TYPE_INT:
+           for (unsigned i = 0; i < type->components(); i++)
+              this->value.u[i] = value->value.u[0];
+           break;
+        case GLSL_TYPE_FLOAT:
+           for (unsigned i = 0; i < type->components(); i++)
+              this->value.f[i] = value->value.f[0];
+           break;
+        case GLSL_TYPE_BOOL:
+           for (unsigned i = 0; i < type->components(); i++)
+              this->value.b[i] = value->value.b[0];
+           break;
+        default:
+           assert(!"Should not get here.");
+           break;
+        }
+      }
+      return;
+   }
+
    /* Use each component from each entry in the value_list to initialize one
     * component of the constant being constructed.
     */