Mesa (master): glsl: Add method glsl_type::can_implicitly_convert_to()

2011-07-30 Thread Chad Versace
Module: Mesa
Branch: master
Commit: 200e4972c1579e8dfaa6f11eee2a7e54baad4852
URL:
http://cgit.freedesktop.org/mesa/mesa/commit/?id=200e4972c1579e8dfaa6f11eee2a7e54baad4852

Author: Chad Versace c...@chad-versace.us
Date:   Wed Jul 27 12:21:27 2011 -0700

glsl: Add method glsl_type::can_implicitly_convert_to()

This method checks if a source type is identical to or can be implicitly
converted to a target type according to the GLSL 1.20 spec, Section 4.1.10
Implicit Conversions.

The following commits use the method for a bugfix:
glsl: Fix implicit conversions in non-constructor function calls
glsl: Fix implicit conversions in array constructors

Note: This is a candidate for the 7.10 and 7.11 branches.
Reviewed-by: Kenneth Graunke kenn...@whitecape.org
Signed-off-by: Chad Versace c...@chad-versace.us

---

 src/glsl/glsl_types.cpp |   16 
 src/glsl/glsl_types.h   |   35 +++
 2 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index a5e21bb..c94aec0 100644
--- a/src/glsl/glsl_types.cpp
+++ b/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/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index 87f57e7..0486966 100644
--- a/src/glsl/glsl_types.h
+++ b/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
+*
+* ivec2vec2
+* uvec2
+*
+* ivec3vec3
+* uvec3
+*
+* ivec4vec4
+* 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).

___
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit


Mesa (master): glsl: Remove ir_function.cpp:type_compare()

2011-07-30 Thread Chad Versace
Module: Mesa
Branch: master
Commit: 6efe1a849586e46028c1eb763175904166ec7076
URL:
http://cgit.freedesktop.org/mesa/mesa/commit/?id=6efe1a849586e46028c1eb763175904166ec7076

Author: Chad Versace c...@chad-versace.us
Date:   Wed Jul 27 12:32:10 2011 -0700

glsl: Remove ir_function.cpp:type_compare()

The function is no longer used and has been replaced by
glsl_type::can_implicitly_convert_to().

Note: This is a candidate for the 7.10 and 7.11 branches.
Reviewed-by: Kenneth Graunke kenn...@whitecape.org
Signed-off-by: Chad Versace c...@chad-versace.us

---

 src/glsl/ir_function.cpp |   61 --
 1 files changed, 0 insertions(+), 61 deletions(-)

diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index eca0079..dd63e30 100644
--- a/src/glsl/ir_function.cpp
+++ b/src/glsl/ir_function.cpp
@@ -24,67 +24,6 @@
 #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);
-}
-
-
 /**
  * \brief Check if two parameter lists match.
  *

___
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit


Mesa (master): glsl: Fix implicit conversions in non-constructor function calls

2011-07-30 Thread Chad Versace
Module: Mesa
Branch: master
Commit: 8b3627fd7b52723102f070957d87f98073e92d7c
URL:
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8b3627fd7b52723102f070957d87f98073e92d7c

Author: Chad Versace c...@chad-versace.us
Date:   Wed Jul 27 12:31:10 2011 -0700

glsl: Fix implicit conversions in non-constructor function calls

Context
---
In ast_function_expression::hir(), parameter_lists_match() checks if the
function call's actual parameter list matches the signature's parameter
list, where the match may require implicit conversion of some arguments.
To check if an implicit conversion exists between individual arguments,
type_compare() is used.

Problems

type_compare() allowed the following illegal implicit conversions:
bool - float
bvecN - vecN

int - uint
ivecN - uvecN

uint - int
uvecN - ivecN

Change
--
type_compare() is buggy, so replace it with 
glsl_type::can_be_implicitly_converted_to().
This comprises a rewrite of parameter_lists_match().

Fixes piglit:spec/glsl-1.20/compiler/built-in-functions/outerProduct-bvec*.vert

Note: This is a candidate for the 7.10 and 7.11 branches.
Reviewed-by: Kenneth Graunke kenn...@whitecape.org
Signed-off-by: Chad Versace c...@chad-versace.us

---

 src/glsl/ir_function.cpp |   46 +-
 1 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index 0f2f1a0..eca0079 100644
--- a/src/glsl/ir_function.cpp
+++ b/src/glsl/ir_function.cpp
@@ -85,12 +85,25 @@ type_compare(const glsl_type *a, const glsl_type *b)
 }
 
 
+/**
+ * \brief Check if two parameter lists match.
+ *
+ * \param list_a Parameters of the function definition.
+ * \param list_b Actual parameters passed to the function.
+ * \return If an exact match, return 0.
+ * If an inexact match requiring implicit conversion, return 1.
+ * If not a match, return -1.
+ * \see matching_signature()
+ */
 static int
 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()
@@ -106,12 +119,11 @@ parameter_lists_match(const exec_list *list_a, const 
exec_list *list_b)
   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:
@@ -125,11 +137,13 @@ parameter_lists_match(const exec_list *list_a, const 
exec_list *list_b)
 
   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 -1;
 break;
 
   case ir_var_out:
-score = type_compare(actual-type, param-type);
+if (!param-type-can_implicitly_convert_to(actual-type))
+   return -1;
 break;
 
   case ir_var_inout:
@@ -137,17 +151,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 -1;
 
   default:
 assert(false);
-  }
-
-  if (score  0)
 return -1;
-
-  total_score += score;
+  }
}
 
/* If all of the parameters from the other parameter list have been
@@ -157,7 +166,10 @@ parameter_lists_match(const exec_list *list_a, const 
exec_list *list_b)
if (!node_b-is_tail_sentinel())
   return -1;
 
-   return total_score;
+   if (inexact_match)
+  return 1;
+   else
+  return 0;
 }
 
 

___
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit


Mesa (master): glsl: Fix conversions in array constructors

2011-07-30 Thread Chad Versace
Module: Mesa
Branch: master
Commit: a5ab9398e34287ed8cbb010d0758790e6692530c
URL:
http://cgit.freedesktop.org/mesa/mesa/commit/?id=a5ab9398e34287ed8cbb010d0758790e6692530c

Author: Chad Versace c...@chad-versace.us
Date:   Wed Jul 27 13:00:02 2011 -0700

glsl: Fix conversions in array constructors

Array constructors obey narrower conversion rules than other constructors
[1] --- they use the implicit conversion rules [2] instead of the scalar
constructor conversions [3].  But process_array_constructor() was
incorrectly applying the broader rules.

[1] GLSL 1.50 spec, Section 5.4.4 Array Constructors, page 52 (58 of pdf)
[2] GLSL 1.50 spec, Section 4.1.10 Implicit Conversions, page 25 (31 of pdf)
[3] GLSL 1.50 spec, Section 5.4.1 Conversion, page 48 (54 of pdf)

To fix this, first check (with glsl_type::can_be_implicitly_converted_to)
if an implicit conversion is legal before performing the conversion.

Fixes:
piglit:spec/glsl-1.20/compiler/structure-and-array-operations/array-ctor-implicit-conversion-bool-float.vert
piglit:spec/glsl-1.20/compiler/structure-and-array-operations/array-ctor-implicit-conversion-bvec*-vec*.vert

Note: This is a candidate for the 7.10 and 7.11 branches.
Reviewed-by: Kenneth Graunke kenn...@whitecape.org
Signed-off-by: Chad Versace c...@chad-versace.us

---

 src/glsl/ast_function.cpp |   12 ++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index bdb73f4..8bcf48d 100644
--- a/src/glsl/ast_function.cpp
+++ b/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()) {

___
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit


Mesa (master): glsl: Clarify ir_function::matching_sigature()

2011-07-30 Thread Chad Versace
Module: Mesa
Branch: master
Commit: 5081d31a0ed753e7e23c5ed51f572d38aef66bfe
URL:
http://cgit.freedesktop.org/mesa/mesa/commit/?id=5081d31a0ed753e7e23c5ed51f572d38aef66bfe

Author: Chad Versace c...@chad-versace.us
Date:   Wed Jul 27 12:37:51 2011 -0700

glsl: Clarify ir_function::matching_sigature()

The function used a variable named 'score', which was an outright lie.
A signature matches or it doesn't; there is no fuzzy scoring.

Change the return type of parameter_lists_match() to an enum, and
let ir_function::matching_sigature() switch on that enum.

Reviewed-by: Kenneth Graunke kenn...@whitecape.org
Signed-off-by: Chad Versace c...@chad-versace.us

---

 src/glsl/ir_function.cpp |   53 -
 1 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index dd63e30..6cfc32c 100644
--- a/src/glsl/ir_function.cpp
+++ b/src/glsl/ir_function.cpp
@@ -24,17 +24,28 @@
 #include glsl_types.h
 #include ir.h
 
+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.
- * \return If an exact match, return 0.
- * If an inexact match requiring implicit conversion, return 1.
- * If not a match, return -1.
  * \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;
@@ -52,7 +63,7 @@ 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;
@@ -72,17 +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:
 if (!actual-type-can_implicitly_convert_to(param-type))
-   return -1;
+   return PARAMETER_LIST_NO_MATCH;
 break;
 
   case ir_var_out:
 if (!param-type-can_implicitly_convert_to(actual-type))
-   return -1;
+   return PARAMETER_LIST_NO_MATCH;
 break;
 
   case ir_var_inout:
@@ -90,11 +101,11 @@ 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.
  */
-return -1;
+return PARAMETER_LIST_NO_MATCH;
 
   default:
 assert(false);
-return -1;
+return PARAMETER_LIST_NO_MATCH;
   }
}
 
@@ -103,12 +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;
 
if (inexact_match)
-  return 1;
+  return PARAMETER_LIST_INEXACT_MATCH;
else
-  return 0;
+  return PARAMETER_LIST_EXACT_MATCH;
 }
 
 
@@ -132,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;
   }
}
 

___
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit