diff options
author | marha <marha@users.sourceforge.net> | 2011-08-01 09:13:47 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-08-01 09:13:47 +0200 |
commit | 6730a76afc49a80573b2e582085086c2956fe96d (patch) | |
tree | 1478eb4f497670caeb2af983eadc4aee20f48b68 /mesalib/src/glsl | |
parent | a69cff9373daf6b7afc97fb975ceb4fc0d6864f7 (diff) | |
parent | f87ad0cdc41af88f134475ab50b0d604004d9cdc (diff) | |
download | vcxsrv-6730a76afc49a80573b2e582085086c2956fe96d.tar.gz vcxsrv-6730a76afc49a80573b2e582085086c2956fe96d.tar.bz2 vcxsrv-6730a76afc49a80573b2e582085086c2956fe96d.zip |
Merge remote-tracking branch 'origin/released'
Conflicts:
mesalib/src/glsl/ast_function.cpp
mesalib/src/glsl/glsl_types.cpp
mesalib/src/mesa/main/teximage.c
mesalib/src/mesa/main/texparam.c
xorg-server/config/udev.c
xorg-server/configure.ac
xorg-server/dix/main.c
xorg-server/hw/dmx/dmxinit.c
xorg-server/hw/kdrive/src/kdrive.c
xorg-server/hw/xfree86/common/xf86Config.c
xorg-server/hw/xfree86/common/xf86Configure.c
xorg-server/hw/xfree86/common/xf86Helper.c
xorg-server/hw/xfree86/common/xf86Init.c
xorg-server/hw/xfree86/common/xf86Option.c
xorg-server/hw/xfree86/common/xf86Priv.h
xorg-server/hw/xfree86/common/xf86Xinput.c
xorg-server/hw/xnest/Init.c
xorg-server/hw/xquartz/darwin.c
xorg-server/hw/xwin/InitOutput.c
xorg-server/hw/xwin/winerror.c
xorg-server/hw/xwin/xlaunch/config.cc
xorg-server/hw/xwin/xlaunch/config.h
xorg-server/hw/xwin/xlaunch/main.cc
xorg-server/hw/xwin/xlaunch/resources/dialog.rc
xorg-server/hw/xwin/xlaunch/resources/resources.h
xorg-server/hw/xwin/xlaunch/resources/resources.rc
xorg-server/hw/xwin/xlaunch/resources/strings.rc
xorg-server/hw/xwin/xlaunch/window/util.cc
xorg-server/hw/xwin/xlaunch/window/util.h
xorg-server/hw/xwin/xlaunch/window/wizard.h
xorg-server/include/os.h
xorg-server/os/log.c
xorg-server/xkeyboard-config/symbols/lv
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/ast_function.cpp | 12 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_types.cpp | 16 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_types.h | 35 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_function.cpp | 140 |
4 files changed, 113 insertions, 90 deletions
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index fad069135..463db9499 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -442,13 +442,21 @@ process_array_constructor(exec_list *instructions, ir_rvalue *ir = (ir_rvalue *) n;
ir_rvalue *result = ir;
- /* Apply implicit conversions (not the scalar constructor rules!) */
+ /* Apply implicit conversions (not the scalar constructor rules!). See
+ * the spec quote above. */
if (constructor_type->element_type()->is_float()) {
const glsl_type *desired_type =
glsl_type::get_instance(GLSL_TYPE_FLOAT,
ir->type->vector_elements,
ir->type->matrix_columns);
- result = convert_component(ir, desired_type);
+ if (result->type->can_implicitly_convert_to(desired_type)) {
+ /* 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);
+ }
}
if (result->type != constructor_type->element_type()) {
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 978e9a398..758fcf756 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -523,3 +523,19 @@ glsl_type::component_slots() const return 0;
}
}
+
+bool
+glsl_type::can_implicitly_convert_to(const glsl_type *desired) const
+{
+ if (this == desired)
+ return true;
+
+ /* There is no conversion among matrix types. */
+ if (this->matrix_columns > 1 || desired->matrix_columns > 1)
+ return false;
+
+ /* int and uint can be converted to float. */
+ return desired->is_float()
+ && this->is_integer()
+ && this->vector_elements == desired->vector_elements;
+}
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index 87f57e7c7..048696693 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -224,6 +224,41 @@ struct glsl_type { */ unsigned component_slots() const; + /** + * \brief Can this type be implicitly converted to another? + * + * \return True if the types are identical or if this type can be converted + * to \c desired according to Section 4.1.10 of the GLSL spec. + * + * \verbatim + * From page 25 (31 of the pdf) of the GLSL 1.50 spec, Section 4.1.10 + * Implicit Conversions: + * + * In some situations, an expression and its type will be implicitly + * converted to a different type. The following table shows all allowed + * implicit conversions: + * + * Type of expression | Can be implicitly converted to + * -------------------------------------------------- + * int float + * uint + * + * ivec2 vec2 + * uvec2 + * + * ivec3 vec3 + * uvec3 + * + * ivec4 vec4 + * uvec4 + * + * There are no implicit array or structure conversions. For example, + * an array of int cannot be implicitly converted to an array of float. + * There are no implicit conversions between signed and unsigned + * integers. + * \endverbatim + */ + bool can_implicitly_convert_to(const glsl_type *desired) const; /** * Query whether or not a type is a scalar (non-vector and non-matrix). diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index 0f2f1a0ee..6cfc32cc2 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -24,73 +24,36 @@ #include "glsl_types.h" #include "ir.h" -int -type_compare(const glsl_type *a, const glsl_type *b) -{ - /* If the types are the same, they trivially match. - */ - if (a == b) - return 0; - - switch (a->base_type) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: - case GLSL_TYPE_BOOL: - /* There is no implicit conversion to or from integer types or bool. - */ - if ((a->is_integer() != b->is_integer()) - || (a->is_boolean() != b->is_boolean())) - return -1; - - /* FALLTHROUGH */ - - case GLSL_TYPE_FLOAT: - if ((a->vector_elements != b->vector_elements) - || (a->matrix_columns != b->matrix_columns)) - return -1; - - return 1; - - case GLSL_TYPE_SAMPLER: - case GLSL_TYPE_STRUCT: - /* Samplers and structures must match exactly. - */ - return -1; - - case GLSL_TYPE_ARRAY: - if ((b->base_type != GLSL_TYPE_ARRAY) - || (a->length != b->length)) - return -1; - - /* From GLSL 1.50 spec, page 27 (page 33 of the PDF): - * "There are no implicit array or structure conversions." - * - * If the comparison of the array element types detects that a conversion - * would be required, the array types do not match. - */ - return (type_compare(a->fields.array, b->fields.array) == 0) ? 0 : -1; - - case GLSL_TYPE_VOID: - case GLSL_TYPE_ERROR: - default: - /* These are all error conditions. It is invalid for a parameter to - * a function to be declared as error, void, or a function. - */ - return -1; - } - - /* This point should be unreachable. - */ - assert(0); -} - +typedef enum { + PARAMETER_LIST_NO_MATCH, + PARAMETER_LIST_EXACT_MATCH, + PARAMETER_LIST_INEXACT_MATCH, /*< Match requires implicit conversion. */ +} parameter_list_match_t; + +/** + * \brief Check if two parameter lists match. + * + * \param list_a Parameters of the function definition. + * \param list_b Actual parameters passed to the function. + * \see matching_signature() + */ -static int +/** + * \brief Check if two parameter lists match. + * + * \param list_a Parameters of the function definition. + * \param list_b Actual parameters passed to the function. + * \see matching_signature() + */ +static parameter_list_match_t parameter_lists_match(const exec_list *list_a, const exec_list *list_b) { const exec_node *node_a = list_a->head; const exec_node *node_b = list_b->head; - int total_score = 0; + + /* This is set to true if there is an inexact match requiring an implicit + * conversion. */ + bool inexact_match = false; for (/* empty */ ; !node_a->is_tail_sentinel() @@ -100,18 +63,17 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) * do not match. */ if (node_b->is_tail_sentinel()) - return -1; + return PARAMETER_LIST_NO_MATCH; const ir_variable *const param = (ir_variable *) node_a; const ir_instruction *const actual = (ir_instruction *) node_b; - /* Determine whether or not the types match. If the types are an - * exact match, the match score is zero. If the types don't match - * but the actual parameter can be coerced to the type of the declared - * parameter, the match score is one. - */ - int score; + if (param->type == actual->type) + continue; + + /* Try to find an implicit conversion from actual to param. */ + inexact_match = true; switch ((enum ir_variable_mode)(param->mode)) { case ir_var_auto: case ir_var_uniform: @@ -121,15 +83,17 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) * as uniform. */ assert(0); - return -1; + return PARAMETER_LIST_NO_MATCH; case ir_var_const_in: case ir_var_in: - score = type_compare(param->type, actual->type); + if (!actual->type->can_implicitly_convert_to(param->type)) + return PARAMETER_LIST_NO_MATCH; break; case ir_var_out: - score = type_compare(actual->type, param->type); + if (!param->type->can_implicitly_convert_to(actual->type)) + return PARAMETER_LIST_NO_MATCH; break; case ir_var_inout: @@ -137,17 +101,12 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) * there is int -> float but no float -> int), inout parameters must * be exact matches. */ - score = (type_compare(actual->type, param->type) == 0) ? 0 : -1; - break; + return PARAMETER_LIST_NO_MATCH; default: assert(false); + return PARAMETER_LIST_NO_MATCH; } - - if (score < 0) - return -1; - - total_score += score; } /* If all of the parameters from the other parameter list have been @@ -155,9 +114,12 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) * match. */ if (!node_b->is_tail_sentinel()) - return -1; + return PARAMETER_LIST_NO_MATCH; - return total_score; + if (inexact_match) + return PARAMETER_LIST_INEXACT_MATCH; + else + return PARAMETER_LIST_EXACT_MATCH; } @@ -181,18 +143,20 @@ ir_function::matching_signature(const exec_list *actual_parameters) ir_function_signature *const sig = (ir_function_signature *) iter.get(); - const int score = parameter_lists_match(& sig->parameters, - actual_parameters); - - /* If we found an exact match, simply return it */ - if (score == 0) + switch (parameter_lists_match(& sig->parameters, actual_parameters)) { + case PARAMETER_LIST_EXACT_MATCH: return sig; - - if (score > 0) { + case PARAMETER_LIST_INEXACT_MATCH: if (match == NULL) match = sig; else multiple_inexact_matches = true; + continue; + case PARAMETER_LIST_NO_MATCH: + continue; + default: + assert(false); + return NULL; } } |