[Mesa-dev] [PATCH 1/3] glsl: correctly handle conversions between int and uint
Bryan Cain
bryancain3 at gmail.com
Mon Apr 18 16:51:44 PDT 2011
This patch was revised several times before submitting, and even after
that I still wasn't sure that adding conversion operations was the right
solution. So I'm not really surprised that there are problems with this
one. :)
On 04/18/2011 06:36 PM, Ian Romanick wrote:
> On 04/17/2011 11:39 PM, Bryan Cain wrote:
> > From the GLSL 1.30 specification, section 4.1.10 ("Implicit
> Conversions"):
> > "There are no implicit conversions between signed and unsigned
> integers."
>
> > However, convert_component() was assuming that conversions between
> int and uint were implicit.
>
> The conversions applied in convert_component only apply to constructor
> parameters. As Ken mentions, in those cases we want
>
> Internally we treat signed and unsigned identically because the
> representation is the same. There's no way for an application to
> observe the difference between:
>
> ivec4 a = ivec4(5 , 6 , 7 , 8 );
> ivec4 b = ivec4(5 , 6 , 7 , 8u);
> ivec4 c = ivec4(5 , 6 , 7u, 8 );
> ivec4 d = ivec4(5 , 6 , 7u, 8u);
> ivec4 e = ivec4(5 , 6u, 7 , 8 );
> ivec4 f = ivec4(5 , 6u, 7 , 8u);
> ivec4 g = ivec4(5 , 6u, 7u, 8 );
> ivec4 h = ivec4(5 , 6u, 7u, 8u);
> // etc.
>
> The type checker ensures that operands to operations that could exhibit
> differing behavior (e.g., ir_bin_mul) have identical types. That code
> lives in arithmetic_result_type in ast_to_hir.cpp. There is similar
> code in match_function_by_name in ast_function.cpp.
>
> Do you have any specific test cases in mind that don't produce correct
> results with the existing code?
Yes, usages like this:
int var1 = 7;
uint var2 = uint(var1);
They were causing a type mismatch error in ast_to_hir.cpp because
convert_component() was treating the uint(int) constructor as a no-op.
>
> > ---
> > src/glsl/ast_function.cpp | 16 ++++++++++++----
> > src/glsl/ir.cpp | 8 ++++++++
> > src/glsl/ir.h | 2 ++
> > src/glsl/ir_constant_expression.cpp | 8 ++++++++
> > src/glsl/ir_validate.cpp | 8 ++++++++
> > 5 files changed, 38 insertions(+), 4 deletions(-)
>
> > diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
> > index e5cb873..cc3f032 100644
> > --- a/src/glsl/ast_function.cpp
> > +++ b/src/glsl/ast_function.cpp
> > @@ -267,17 +267,25 @@ convert_component(ir_rvalue *src, const
> glsl_type *desired_type)
> > assert(a <= GLSL_TYPE_BOOL);
> > assert(b <= GLSL_TYPE_BOOL);
>
> > - if ((a == b) || (src->type->is_integer() &&
> desired_type->is_integer()))
> > + if (a == b)
> > return src;
>
> > switch (a) {
> > case GLSL_TYPE_UINT:
> > case GLSL_TYPE_INT:
> > - if (b == GLSL_TYPE_FLOAT)
> > + switch(b) {
> > + case GLSL_TYPE_UINT:
> > + result = new(ctx) ir_expression(ir_unop_u2i, desired_type,
> src, NULL);
> > + break;
> > + case GLSL_TYPE_INT:
> > + result = new(ctx) ir_expression(ir_unop_i2u, desired_type,
> src, NULL);
> > + break;
> > + case GLSL_TYPE_FLOAT:
> > result = new(ctx) ir_expression(ir_unop_f2i, desired_type,
> src, NULL);
>
> With the other changes, leaving this as-is is kind of hinkey. Here the
> result base type will be GLSL_TYPE_INT, but the desired based type could
> be GLSL_TYPE_UINT.
Unless I'm missing something, that case is handled by the line "if (a ==
b)".
More information about the mesa-dev
mailing list