[Mesa-dev] [PATCH] glsl: Allow implicit int -> uint conversions for the % operator.

Ian Romanick idr at freedesktop.org
Thu Nov 12 14:48:34 PST 2015


On 11/12/2015 02:25 PM, Kenneth Graunke wrote:
> GLSL 4.00 and GL_ARB_gpu_shader5 introduced a new int -> uint implicit
> conversion rule and updated the rules for modulus to use them.  (In
> earlier languages, none of the implicit conversion rules did anything
> relevant, so there was no point in applying them.)
> 
> This allows expressions such as:
> 
>    int foo;
>    uint bar;
>    uint mod = foo % bar;
> 
> Cc: mesa-stable at lists.freedesktop.org
> Cc: idr at freedesktop.org
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
>  src/glsl/ast_to_hir.cpp | 36 +++++++++++++++++++++++++++---------
>  1 file changed, 27 insertions(+), 9 deletions(-)
> 
> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
> index 9d341e8..0ef6d46 100644
> --- a/src/glsl/ast_to_hir.cpp
> +++ b/src/glsl/ast_to_hir.cpp
> @@ -538,18 +538,19 @@ bit_logic_result_type(const struct glsl_type *type_a,
>  }
>  
>  static const struct glsl_type *
> -modulus_result_type(const struct glsl_type *type_a,
> -                    const struct glsl_type *type_b,
> +modulus_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
>                      struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
>  {
> +   const glsl_type *type_a = value_a->type;
> +   const glsl_type *type_b = value_b->type;
> +
>     if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) {
>        return glsl_type::error_type;
>     }
>  
> -   /* From GLSL 1.50 spec, page 56:
> +   /* From the GLSL 4.00 specification, page 64:

Since the pages change (even in spec updates), I'd like to change this
to the canonical "Section ... (blah blah) of the GLSL 4.00 specification
says:"

Other than that, this patch looks about how I would expect it to.

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

Do we have piglit tests for any of these?

>      *    "The operator modulus (%) operates on signed or unsigned integers or
> -    *    integer vectors. The operand types must both be signed or both be
> -    *    unsigned."
> +    *    integer vectors."
>      */
>     if (!type_a->is_integer()) {
>        _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer");
> @@ -559,11 +560,28 @@ modulus_result_type(const struct glsl_type *type_a,
>        _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer");
>        return glsl_type::error_type;
>     }
> -   if (type_a->base_type != type_b->base_type) {
> +
> +   /*    "If the fundamental types in the operands do not match, then the
> +    *    conversions from section 4.1.10 "Implicit Conversions" are applied
> +    *    to create matching types."
> +    *
> +    * Note that GLSL 4.00 (and GL_ARB_gpu_shader5) introduced implicit
> +    * int -> uint conversion rules.  Prior to that, there were no implicit
> +    * conversions.  So it's harmless to apply them universally - no implicit
> +    * conversions will exist.  If the types don't match, we'll receive false,
> +    * and raise an error, satisfying the GLSL 1.50 spec, page 56:
> +    *
> +    *    "The operand types must both be signed or unsigned."
> +    */
> +   if (!apply_implicit_conversion(type_a, value_b, state) &&
> +       !apply_implicit_conversion(type_b, value_a, state)) {
>        _mesa_glsl_error(loc, state,
> -                       "operands of %% must have the same base type");
> +                       "could not implicitly convert operands to "
> +                       "modulus (%%) operator");
>        return glsl_type::error_type;
>     }
> +   type_a = value_a->type;
> +   type_b = value_b->type;
>  
>     /*    "The operands cannot be vectors of differing size. If one operand is
>      *    a scalar and the other vector, then the scalar is applied component-
> @@ -1311,7 +1329,7 @@ ast_expression::do_hir(exec_list *instructions,
>        op[0] = this->subexpressions[0]->hir(instructions, state);
>        op[1] = this->subexpressions[1]->hir(instructions, state);
>  
> -      type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
> +      type = modulus_result_type(op[0], op[1], state, &loc);
>  
>        assert(operations[this->oper] == ir_binop_mod);
>  
> @@ -1558,7 +1576,7 @@ ast_expression::do_hir(exec_list *instructions,
>        op[0] = this->subexpressions[0]->hir(instructions, state);
>        op[1] = this->subexpressions[1]->hir(instructions, state);
>  
> -      type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
> +      type = modulus_result_type(op[0], op[1], state, &loc);
>  
>        assert(operations[this->oper] == ir_binop_mod);
>  
> 



More information about the mesa-dev mailing list