summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndres Gomez <[email protected]>2016-08-02 16:20:59 +0300
committerAndres Gomez <[email protected]>2016-08-05 14:27:03 +0300
commitde60d549b9acd5f2f9337aec8c283150bc950c99 (patch)
tree84f8ef3fdb70e9b3197b77e81f958811075cc628 /src
parentaf796d756e9a507d5e055fb4cd03277386c5892a (diff)
glsl: Refactor implicit conversion into its own helper
v2: Refactor also the conversion to constant and replacement code (Timothy). Reviewed-by: Timothy Arceri <[email protected]> Signed-off-by: Andres Gomez <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/glsl/ast_function.cpp166
1 files changed, 86 insertions, 80 deletions
diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp
index 9dcec503605..e30c70c17f2 100644
--- a/src/compiler/glsl/ast_function.cpp
+++ b/src/compiler/glsl/ast_function.cpp
@@ -836,6 +836,62 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result;
}
+
+/**
+ * Perform automatic type and constant conversion of constructor parameters
+ *
+ * This implements the rules in the "Implicit Conversions" rules, not the
+ * "Conversion and Scalar Constructors".
+ *
+ * After attempting the implicit conversion, an attempt to convert into a
+ * constant valued expression is also done.
+ *
+ * The \c from \c ir_rvalue is converted "in place".
+ *
+ * \param from Operand that is being converted
+ * \param to Base type the operand will be converted to
+ * \param state GLSL compiler state
+ *
+ * \return
+ * If the attempt to convert into a constant expression succeeds, \c true is
+ * returned. Otherwise \c false is returned.
+ */
+static bool
+implicitly_convert_component(ir_rvalue * &from, const glsl_base_type to,
+ struct _mesa_glsl_parse_state *state)
+{
+ ir_rvalue *result = from;
+
+ if (to != from->type->base_type) {
+ const glsl_type *desired_type =
+ glsl_type::get_instance(to,
+ from->type->vector_elements,
+ from->type->matrix_columns);
+
+ if (from->type->can_implicitly_convert_to(desired_type, state)) {
+ /* Even though convert_component() implements the constructor
+ * conversion rules (not the implicit conversion rules), its safe
+ * to use it here because we already checked that the implicit
+ * conversion is legal.
+ */
+ result = convert_component(from, desired_type);
+ }
+ }
+
+ ir_rvalue *const constant = result->constant_expression_value();
+
+ if (constant != NULL)
+ result = constant;
+
+ if (from != result) {
+ from->replace_with(result);
+ from = result;
+ }
+
+ return constant != NULL;
+}
+
+
/**
* Dereference a specific component from a scalar, vector, or matrix
*/
@@ -918,53 +974,30 @@ process_vec_mat_constructor(exec_list *instructions,
/* Type cast each parameter and, if possible, fold constants. */
foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
- ir_rvalue *result = ir;
-
- /* Apply implicit conversions (not the scalar constructor rules!). See
- * the spec quote above. */
- if (constructor_type->base_type != result->type->base_type) {
- const glsl_type *desired_type =
- glsl_type::get_instance(constructor_type->base_type,
- ir->type->vector_elements,
- ir->type->matrix_columns);
- if (result->type->can_implicitly_convert_to(desired_type, state)) {
- /* Even though convert_component() implements the constructor
- * conversion rules (not the implicit conversion rules), its safe
- * to use it here because we already checked that the implicit
- * conversion is legal.
- */
- result = convert_component(ir, desired_type);
- }
- }
+ /* Apply implicit conversions (not the scalar constructor rules, see the
+ * spec quote above!) and attempt to convert the parameter to a constant
+ * valued expression. After doing so, track whether or not all the
+ * parameters to the constructor are trivially constant valued
+ * expressions.
+ */
+ all_parameters_are_constant &=
+ implicitly_convert_component(ir, constructor_type->base_type, state);
if (constructor_type->is_matrix()) {
- if (result->type != constructor_type->column_type()) {
+ if (ir->type != constructor_type->column_type()) {
_mesa_glsl_error(loc, state, "type error in matrix constructor: "
"expected: %s, found %s",
constructor_type->column_type()->name,
- result->type->name);
+ ir->type->name);
return ir_rvalue::error_value(ctx);
}
- } else if (result->type != constructor_type->get_scalar_type()) {
+ } else if (ir->type != constructor_type->get_scalar_type()) {
_mesa_glsl_error(loc, state, "type error in vector constructor: "
"expected: %s, found %s",
constructor_type->get_scalar_type()->name,
- result->type->name);
+ ir->type->name);
return ir_rvalue::error_value(ctx);
}
-
- /* Attempt to convert the parameter to a constant valued expression.
- * After doing so, track whether or not all the parameters to the
- * constructor are trivially constant valued expressions.
- */
- ir_rvalue *const constant = result->constant_expression_value();
-
- if (constant != NULL)
- result = constant;
- else
- all_parameters_are_constant = false;
-
- ir->replace_with(result);
}
if (all_parameters_are_constant)
@@ -1057,28 +1090,14 @@ process_array_constructor(exec_list *instructions,
/* Type cast each parameter and, if possible, fold constants. */
foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
- ir_rvalue *result = ir;
-
- const glsl_base_type element_base_type =
- constructor_type->fields.array->base_type;
-
- /* Apply implicit conversions (not the scalar constructor rules!). See
- * the spec quote above. */
- if (element_base_type != result->type->base_type) {
- const glsl_type *desired_type =
- glsl_type::get_instance(element_base_type,
- ir->type->vector_elements,
- ir->type->matrix_columns);
-
- if (result->type->can_implicitly_convert_to(desired_type, state)) {
- /* Even though convert_component() implements the constructor
- * conversion rules (not the implicit conversion rules), its safe
- * to use it here because we already checked that the implicit
- * conversion is legal.
- */
- result = convert_component(ir, desired_type);
- }
- }
+ /* Apply implicit conversions (not the scalar constructor rules, see the
+ * spec quote above!) and attempt to convert the parameter to a constant
+ * valued expression. After doing so, track whether or not all the
+ * parameters to the constructor are trivially constant valued
+ * expressions.
+ */
+ all_parameters_are_constant &=
+ implicitly_convert_component(ir, element_type->base_type, state);
if (constructor_type->fields.array->is_unsized_array()) {
/* As the inner parameters of the constructor are created without
@@ -1091,37 +1110,24 @@ process_array_constructor(exec_list *instructions,
* vec4[](vec4(0.0), vec4(1.0)));
*/
if (element_type->is_unsized_array()) {
- /* This is the first parameter so just get the type */
- element_type = result->type;
- } else if (element_type != result->type) {
+ /* This is the first parameter so just get the type */
+ element_type = ir->type;
+ } else if (element_type != ir->type) {
_mesa_glsl_error(loc, state, "type error in array constructor: "
"expected: %s, found %s",
element_type->name,
- result->type->name);
+ ir->type->name);
return ir_rvalue::error_value(ctx);
}
- } else if (result->type != constructor_type->fields.array) {
- _mesa_glsl_error(loc, state, "type error in array constructor: "
- "expected: %s, found %s",
- constructor_type->fields.array->name,
- result->type->name);
+ } else if (ir->type != constructor_type->fields.array) {
+ _mesa_glsl_error(loc, state, "type error in array constructor: "
+ "expected: %s, found %s",
+ constructor_type->fields.array->name,
+ ir->type->name);
return ir_rvalue::error_value(ctx);
} else {
- element_type = result->type;
+ element_type = ir->type;
}
-
- /* Attempt to convert the parameter to a constant valued expression.
- * After doing so, track whether or not all the parameters to the
- * constructor are trivially constant valued expressions.
- */
- ir_rvalue *const constant = result->constant_expression_value();
-
- if (constant != NULL)
- result = constant;
- else
- all_parameters_are_constant = false;
-
- ir->replace_with(result);
}
if (constructor_type->fields.array->is_unsized_array()) {