[Mesa-dev] [PATCH 4/8] glsl: Evaluate constant pack/unpack 4x8 expressions

Chad Versace chad.versace at linux.intel.com
Fri Jan 25 11:59:53 PST 2013


On 01/25/2013 11:38 AM, Chad Versace wrote:
> On 01/24/2013 07:47 PM, Matt Turner wrote:
>> That is, evaluate constant expressions for the following functions:
>>   packSnorm4x8, unpackSnorm4x8
>>   packUnorm4x8, unpackUnorm4x8
>> ---
>>  src/glsl/ir_constant_expression.cpp |  162 +++++++++++++++++++++++++++++++++++
>>  1 files changed, 162 insertions(+), 0 deletions(-)
>>
>> diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
>> index b34c6e8..4796f6f 100644
>> --- a/src/glsl/ir_constant_expression.cpp
>> +++ b/src/glsl/ir_constant_expression.cpp
>> @@ -76,12 +76,24 @@ bitcast_f2u(float f)
>>  }
>>  
>>  /**
>> + * Evaluate one component of a floating-point 4x8 unpacking function.
>> + */
>> +typedef uint8_t
>> +(*pack_1x8_func_t)(float);
>> +
>> +/**
>>   * Evaluate one component of a floating-point 2x16 unpacking function.
>>   */
>>  typedef uint16_t
>>  (*pack_1x16_func_t)(float);
>>  
>>  /**
>> + * Evaluate one component of a floating-point 4x8 unpacking function.
>> + */
>> +typedef float
>> +(*unpack_1x8_func_t)(uint8_t);
>> +
>> +/**
>>   * Evaluate one component of a floating-point 2x16 unpacking function.
>>   */
>>  typedef float
>> @@ -112,6 +124,32 @@ pack_2x16(pack_1x16_func_t pack_1x16,
>>  }
>>  
>>  /**
>> + * Evaluate a 4x8 floating-point packing function.
>> + */
>> +static uint32_t
>> +pack_4x8(pack_1x8_func_t pack_1x8,
>> +         float x, float y, float z, float w)
>> +{
>> +   /* From section 8.4 of the GLSL 4.30 spec:
>> +    *
>> +    *    packSnorm4x8
>> +    *    ------------
>> +    *    The first component of the vector will be written to the least
>> +    *    significant bits of the output; the last component will be written to
>> +    *    the most significant bits.
>> +    *
>> +    * The specifications for the other packing functions contain similar
>> +    * language.
>> +    */
>> +   uint32_t u = 0;
>> +   u |= ((uint32_t) pack_1x8(x) << 0);
>> +   u |= ((uint32_t) pack_1x8(y) << 8);
>> +   u |= ((uint32_t) pack_1x8(z) << 16);
>> +   u |= ((uint32_t) pack_1x8(w) << 24);
>> +   return u;
>> +}
>> +
>> +/**
>>   * Evaluate a 2x16 floating-point unpacking function.
>>   */
>>  static void
>> @@ -135,6 +173,48 @@ unpack_2x16(unpack_1x16_func_t unpack_1x16,
>>  }
>>  
>>  /**
>> + * Evaluate a 4x8 floating-point unpacking function.
>> + */
>> +static void
>> +unpack_4x8(unpack_1x8_func_t unpack_1x8, uint32_t u,
>> +           float *x, float *y, float *z, float *w)
>> +{
>> +    /* From section 8.4 of the GLSL 4.30 spec:
>> +     *
>> +     *    unpackSnorm4x8
>> +     *    --------------
>> +     *    The first component of the returned vector will be extracted from
>> +     *    the least significant bits of the input; the last component will be
>> +     *    extracted from the most significant bits.
>> +     *
>> +     * The specifications for the other unpacking functions contain similar
>> +     * language.
>> +     */
>> +   *x = unpack_1x8((uint8_t) (u & 0xff));
>> +   *y = unpack_1x8((uint8_t) (u >> 8));
>> +   *z = unpack_1x8((uint8_t) (u >> 16));
>> +   *w = unpack_1x8((uint8_t) (u >> 24));
>> +}
> 
> The bitmask (u & 0xff) confused me for a few moments, made me say "Why does Matt
> need a bitmask there?". But, then I realized that I did the same for unpack_2x16,
> and you likely just copied my pattern. Oh well. I'd prefer that unpack_2x16
> and unpack_4x8 follow a similar visual pattern rather than clean that up now,
> so I'm ok with that funny looking bitmask staying in this patch.
> 
>> +
>> +/**
>> + * Evaluate one component of packSnorm4x8.
>> + */
>> +static uint8_t
>> +pack_snorm_1x8(float x)
>> +{
>> +    /* From section 8.4 of the GLSL 4.30 spec:
>> +     *
>> +     *    packSnorm4x8
>> +     *    ------------
>> +     *    The conversion for component c of v to fixed point is done as
>> +     *    follows:
>> +     *
>> +     *      packSnorm4x8: round(clamp(c, -1, +1) * 127.0)
>> +     */
>> +   return (uint8_t) _mesa_round_to_even(CLAMP(x, -1.0f, +1.0f) * 127.0f);
>> +}
> 
> Conversion from a negative float to a uint, so an intermediate conversion to
> int8_t is needed here. Like Paul said. With that change, this is
> Reviewed-by: Chad Versace <chad.versace at linux.intel.com>
> 



More information about the mesa-dev mailing list