[Mesa-dev] [PATCH 3/5] gallium: add initial pure integer support (v2)

Marek Olšák maraeo at gmail.com
Fri Oct 7 15:11:12 PDT 2011


On Fri, Oct 7, 2011 at 10:48 PM, Jose Fonseca <jfonseca at vmware.com> wrote:
> Looks good overall. Comments inline.
>
> ----- Original Message -----
>> From: Dave Airlie <airlied at redhat.com>
>>
>> This add support for unsigned/signed integer types via adding a
>> 'pure' bit
>> in the format description table. It adds 4 new u_format get/put
>> hooks,
>> for get/put uint and get/put sint so that accessors can get native
>> access
>> to the integer bits. This is used to avoid precision loss via float
>> converting
>> paths.
>>
>> It doesn't add any float fetchers for these types at the moment, GL
>> doesn't
>> require float fetching from these types and I expect we'll introduce
>> a lot
>> of hidden bugs if we start allowing such conversions without an API
>> mandating
>> it.
>
> I'm Ok with this for the time being, but as I said when we discussed this, the ability of converting to/from floats is useful for debugging/visualization and to emulate unsupported formats.
>
>> It adds all formats from EXT_texture_integer and EXT_texture_rg.
>>
>> 0 regressions on llvmpipe here with this.
>>
>> (there is some more follow on code in my gallium-int-work branch,
>> bringing
>>  softpipe and mesa to a pretty integer clean state)
>>
>> v2: fixup python generator to get signed->unsigned and
>> unsigned->signed
>> fetches working.
>>
>> Signed-off-by: Dave Airlie <airlied at redhat.com>
>> ---
>>  src/gallium/auxiliary/util/u_format.c        |  139
>>  ++++++++++++++++++++++++++
>>  src/gallium/auxiliary/util/u_format.csv      |   61 +++++++++++
>>  src/gallium/auxiliary/util/u_format.h        |   66 ++++++++++++-
>>  src/gallium/auxiliary/util/u_format_pack.py  |   70 +++++++++++--
>>  src/gallium/auxiliary/util/u_format_parse.py |   18 +++-
>>  src/gallium/auxiliary/util/u_format_table.py |   23 ++++-
>>  src/gallium/auxiliary/util/u_tile.c          |  138
>>  +++++++++++++++++++++++++
>>  src/gallium/auxiliary/util/u_tile.h          |   39 +++++++
>>  src/gallium/drivers/llvmpipe/lp_tile_soa.py  |    2 +-
>>  src/gallium/include/pipe/p_format.h          |   59 +++++++++++
>>  10 files changed, 595 insertions(+), 20 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/util/u_format.c
>> b/src/gallium/auxiliary/util/u_format.c
>> index 9bf4258..045cf94 100644
>> --- a/src/gallium/auxiliary/util/u_format.c
>> +++ b/src/gallium/auxiliary/util/u_format.c
>> @@ -124,6 +124,62 @@ util_format_is_luminance(enum pipe_format
>> format)
>>     return FALSE;
>>  }
>>
>> +boolean
>> +util_format_is_pure_integer(enum pipe_format format)
>> +{
>> +   const struct util_format_description *desc =
>> util_format_description(format);
>> +   int i;
>> +   /* Find the first non-void channel. */
>> +   for (i = 0; i < 4; i++) {
>> +      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
>> +         break;
>> +      }
>> +   }
>> +
>> +   if (i == 4) {
>> +      return FALSE;
>> +   }
>> +
>> +   return desc->channel[i].pure_integer ? TRUE : FALSE;
>> +}
>> +
>> +boolean
>> +util_format_is_pure_sint(enum pipe_format format)
>> +{
>> +   const struct util_format_description *desc =
>> util_format_description(format);
>> +   int i;
>> +   /* Find the first non-void channel. */
>> +   for (i = 0; i < 4; i++) {
>> +      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
>> +         break;
>> +      }
>> +   }
>> +
>> +   if (i == 4) {
>> +      return FALSE;
>> +   }
>> +
>> +   return (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED &&
>> desc->channel[i].pure_integer) ? TRUE : FALSE;
>> +}
>> +
>> +boolean
>> +util_format_is_pure_uint(enum pipe_format format)
>> +{
>> +   const struct util_format_description *desc =
>> util_format_description(format);
>> +   int i;
>> +   /* Find the first non-void channel. */
>> +   for (i = 0; i < 4; i++) {
>> +      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
>> +         break;
>> +      }
>> +   }
>> +
>> +   if (i == 4) {
>> +      return FALSE;
>> +   }
>> +
>> +   return (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED &&
>> desc->channel[i].pure_integer) ? TRUE : FALSE;
>> +}
>
> Please refactor out the duplicated code in the above three functions into a common function.
>
>>  boolean
>>  util_format_is_luminance_alpha(enum pipe_format format)
>> @@ -262,6 +318,89 @@ util_format_write_4ub(enum pipe_format format,
>> const uint8_t *src, unsigned src_
>>     format_desc->pack_rgba_8unorm(dst_row, dst_stride, src_row,
>>     src_stride, w, h);
>>  }
>>
>> +void
>> +util_format_read_4ui(enum pipe_format format,
>> +                     unsigned *dst, unsigned dst_stride,
>> +                     const void *src, unsigned src_stride,
>> +                     unsigned x, unsigned y, unsigned w, unsigned h)
>> +{
>> +   const struct util_format_description *format_desc;
>> +   const uint8_t *src_row;
>> +   unsigned *dst_row;
>> +
>> +   format_desc = util_format_description(format);
>> +
>> +   assert(x % format_desc->block.width == 0);
>> +   assert(y % format_desc->block.height == 0);
>> +
>> +   src_row = (const uint8_t *)src + y*src_stride +
>> x*(format_desc->block.bits/8);
>> +   dst_row = dst;
>> +
>> +   format_desc->unpack_rgba_uint(dst_row, dst_stride, src_row,
>> src_stride, w, h);
>> +}
>> +
>> +void
>> +util_format_write_4ui(enum pipe_format format,
>> +                      const unsigned int *src, unsigned src_stride,
>> +                      void *dst, unsigned dst_stride,
>> +                      unsigned x, unsigned y, unsigned w, unsigned
>> h)
>> +{
>> +   const struct util_format_description *format_desc;
>> +   uint8_t *dst_row;
>> +   const unsigned *src_row;
>> +
>> +   format_desc = util_format_description(format);
>> +
>> +   assert(x % format_desc->block.width == 0);
>> +   assert(y % format_desc->block.height == 0);
>> +
>> +   dst_row = (uint8_t *)dst + y*dst_stride +
>> x*(format_desc->block.bits/8);
>> +   src_row = src;
>> +
>> +   format_desc->pack_rgba_uint(dst_row, dst_stride, src_row,
>> src_stride, w, h);
>> +}
>> +
>> +void
>> +util_format_read_4i(enum pipe_format format,
>> +                    int *dst, unsigned dst_stride,
>> +                    const void *src, unsigned src_stride,
>> +                    unsigned x, unsigned y, unsigned w, unsigned h)
>> +{
>> +   const struct util_format_description *format_desc;
>> +   const uint8_t *src_row;
>> +   int *dst_row;
>> +
>> +   format_desc = util_format_description(format);
>> +
>> +   assert(x % format_desc->block.width == 0);
>> +   assert(y % format_desc->block.height == 0);
>> +
>> +   src_row = (const uint8_t *)src + y*src_stride +
>> x*(format_desc->block.bits/8);
>> +   dst_row = dst;
>> +
>> +   format_desc->unpack_rgba_sint(dst_row, dst_stride, src_row,
>> src_stride, w, h);
>> +}
>> +
>> +void
>> +util_format_write_4i(enum pipe_format format,
>> +                      const int *src, unsigned src_stride,
>> +                      void *dst, unsigned dst_stride,
>> +                      unsigned x, unsigned y, unsigned w, unsigned
>> h)
>> +{
>> +   const struct util_format_description *format_desc;
>> +   uint8_t *dst_row;
>> +   const int *src_row;
>> +
>> +   format_desc = util_format_description(format);
>> +
>> +   assert(x % format_desc->block.width == 0);
>> +   assert(y % format_desc->block.height == 0);
>> +
>> +   dst_row = (uint8_t *)dst + y*dst_stride +
>> x*(format_desc->block.bits/8);
>> +   src_row = src;
>> +
>> +   format_desc->pack_rgba_sint(dst_row, dst_stride, src_row,
>> src_stride, w, h);
>> +}
>>
>>  boolean
>>  util_is_format_compatible(const struct util_format_description
>>  *src_desc,
>> diff --git a/src/gallium/auxiliary/util/u_format.csv
>> b/src/gallium/auxiliary/util/u_format.csv
>> index 621a46d..08aa0a4 100644
>> --- a/src/gallium/auxiliary/util/u_format.csv
>> +++ b/src/gallium/auxiliary/util/u_format.csv
>> @@ -42,6 +42,7 @@
>>  #     - 'h': fixed
>>  #     - 'f': FLOAT
>>  #   - optionally followed by 'n' if it is normalized
>> +#   - optionally followed by 'p' if it is pure
>>  #   - number of bits
>>  # - channel swizzle
>>  # - color space: rgb, yub, sz
>> @@ -278,3 +279,63 @@ PIPE_FORMAT_R10G10B10A2_SNORM       , plain, 1,
>> 1, sn10, sn10, sn10, sn2, xyzw,
>>  PIPE_FORMAT_B10G10R10A2_USCALED     , plain, 1, 1, u10, u10, u10,
>>  u2, zyxw, rgb
>>  PIPE_FORMAT_B10G10R10A2_SSCALED     , plain, 1, 1, s10, s10, s10,
>>  s2, zyxw, rgb
>>  PIPE_FORMAT_B10G10R10A2_SNORM       , plain, 1, 1, sn10, sn10, sn10,
>>  sn2, zyxw, rgb
>> +
>> +PIPE_FORMAT_R8_UINT                 , plain, 1, 1, up8, , , , x001,
>> rgb
>> +PIPE_FORMAT_R8G8_UINT               , plain, 1, 1, up8, up8, , ,
>> xy01, rgb
>> +PIPE_FORMAT_R8G8B8_UINT             , plain, 1, 1, up8, up8, up8, ,
>> xyz1, rgb
>> +PIPE_FORMAT_R8G8B8A8_UINT           , plain, 1, 1, up8, up8, up8,
>> up8, xyzw, rgb
>> +
>> +PIPE_FORMAT_R8_SINT                 , plain, 1, 1, sp8, , , , x001,
>> rgb
>> +PIPE_FORMAT_R8G8_SINT               , plain, 1, 1, sp8, sp8, , ,
>> xy01, rgb
>> +PIPE_FORMAT_R8G8B8_SINT             , plain, 1, 1, sp8, sp8, sp8, ,
>> xyz1, rgb
>> +PIPE_FORMAT_R8G8B8A8_SINT           , plain, 1, 1, sp8, sp8, sp8,
>> sp8, xyzw, rgb
>> +
>> +PIPE_FORMAT_R16_UINT                , plain, 1, 1, up16, , , , x001,
>> rgb
>> +PIPE_FORMAT_R16G16_UINT             , plain, 1, 1, up16, up16, , ,
>> xy01, rgb
>> +PIPE_FORMAT_R16G16B16_UINT          , plain, 1, 1, up16, up16, up16,
>> , xyz1, rgb
>> +PIPE_FORMAT_R16G16B16A16_UINT       , plain, 1, 1, up16, up16, up16,
>> up16, xyzw, rgb
>> +
>> +PIPE_FORMAT_R16_SINT                , plain, 1, 1, sp16, , , , x001,
>> rgb
>> +PIPE_FORMAT_R16G16_SINT             , plain, 1, 1, sp16, sp16, , ,
>> xy01, rgb
>> +PIPE_FORMAT_R16G16B16_SINT          , plain, 1, 1, sp16, sp16, sp16,
>> , xyz1, rgb
>> +PIPE_FORMAT_R16G16B16A16_SINT       , plain, 1, 1, sp16, sp16, sp16,
>> sp16, xyzw, rgb
>> +
>> +PIPE_FORMAT_R32_UINT                , plain, 1, 1, up32, , , , x001,
>> rgb
>> +PIPE_FORMAT_R32G32_UINT             , plain, 1, 1, up32, up32, , ,
>> xy01, rgb
>> +PIPE_FORMAT_R32G32B32_UINT          , plain, 1, 1, up32, up32, up32,
>> , xyz1, rgb
>> +PIPE_FORMAT_R32G32B32A32_UINT       , plain, 1, 1, up32, up32, up32,
>> up32, xyzw, rgb
>> +
>> +PIPE_FORMAT_R32_SINT                , plain, 1, 1, sp32, , , , x001,
>> rgb
>> +PIPE_FORMAT_R32G32_SINT             , plain, 1, 1, sp32, sp32, , ,
>> xy01, rgb
>> +PIPE_FORMAT_R32G32B32_SINT          , plain, 1, 1, sp32, sp32, sp32,
>> , xyz1, rgb
>> +PIPE_FORMAT_R32G32B32A32_SINT       , plain, 1, 1, sp32, sp32, sp32,
>> sp32, xyzw, rgb
>> +
>> +PIPE_FORMAT_A8_UINT                 , plain, 1, 1, up8, , , , 000x,
>> rgb
>> +PIPE_FORMAT_I8_UINT                 , plain, 1, 1, up8, , , , xxxx,
>> rgb
>> +PIPE_FORMAT_L8_UINT                 , plain, 1, 1, up8, , , , xxx1,
>> rgb
>> +PIPE_FORMAT_L8A8_UINT               , plain, 1, 1, up8, up8, , ,
>> xxxy, rgb
>> +
>> +PIPE_FORMAT_A8_SINT                 , plain, 1, 1, sp8, , , , 000x,
>> rgb
>> +PIPE_FORMAT_I8_SINT                 , plain, 1, 1, sp8, , , , xxxx,
>> rgb
>> +PIPE_FORMAT_L8_SINT                 , plain, 1, 1, sp8, , , , xxx1,
>> rgb
>> +PIPE_FORMAT_L8A8_SINT               , plain, 1, 1, sp8, sp8, , ,
>> xxxy, rgb
>> +
>> +PIPE_FORMAT_A16_UINT                , plain, 1, 1, up16, , , , 000x,
>> rgb
>> +PIPE_FORMAT_I16_UINT                , plain, 1, 1, up16, , , , xxxx,
>> rgb
>> +PIPE_FORMAT_L16_UINT                , plain, 1, 1, up16, , , , xxx1,
>> rgb
>> +PIPE_FORMAT_L16A16_UINT             , plain, 1, 1, up16, up16, , ,
>> xxxy, rgb
>> +
>> +PIPE_FORMAT_A16_SINT                , plain, 1, 1, sp16, , , , 000x,
>> rgb
>> +PIPE_FORMAT_I16_SINT                , plain, 1, 1, sp16, , , , xxxx,
>> rgb
>> +PIPE_FORMAT_L16_SINT                , plain, 1, 1, sp16, , , , xxx1,
>> rgb
>> +PIPE_FORMAT_L16A16_SINT             , plain, 1, 1, sp16, sp16, , ,
>> xxxy, rgb
>> +
>> +PIPE_FORMAT_A32_UINT                , plain, 1, 1, up32, , , , 000x,
>> rgb
>> +PIPE_FORMAT_I32_UINT                , plain, 1, 1, up32, , , , xxxx,
>> rgb
>> +PIPE_FORMAT_L32_UINT                , plain, 1, 1, up32, , , , xxx1,
>> rgb
>> +PIPE_FORMAT_L32A32_UINT             , plain, 1, 1, up32, up32, , ,
>> xxxy, rgb
>> +
>> +PIPE_FORMAT_A32_SINT                , plain, 1, 1, sp32, , , , 000x,
>> rgb
>> +PIPE_FORMAT_I32_SINT                , plain, 1, 1, sp32, , , , xxxx,
>> rgb
>> +PIPE_FORMAT_L32_SINT                , plain, 1, 1, sp32, , , , xxx1,
>> rgb
>> +PIPE_FORMAT_L32A32_SINT             , plain, 1, 1, sp32, sp32, , ,
>> xxxy, rgb
>> \ No newline at end of file
>> diff --git a/src/gallium/auxiliary/util/u_format.h
>> b/src/gallium/auxiliary/util/u_format.h
>> index 98528ea..4f5059a 100644
>> --- a/src/gallium/auxiliary/util/u_format.h
>> +++ b/src/gallium/auxiliary/util/u_format.h
>> @@ -120,8 +120,9 @@ enum util_format_colorspace {
>>
>>  struct util_format_channel_description
>>  {
>> -   unsigned type:6;        /**< UTIL_FORMAT_TYPE_x */
>> +   unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
>>     unsigned normalized:1;
>> +   unsigned pure_integer:1;
>>     unsigned size:9;        /**< bits per channel */
>>  };
>>
>> @@ -321,6 +322,37 @@ struct util_format_description
>>                        const uint8_t *src, unsigned src_stride,
>>                        unsigned width, unsigned height);
>>
>> +  /**
>> +    * Unpack pixel blocks to R32G32B32A32_UINT.
>> +    * Note: strides are in bytes.
>> +    *
>> +    * Only defined for INT formats.
>> +    */
>> +   void
>> +   (*unpack_rgba_uint)(unsigned *dst, unsigned dst_stride,
>> +                       const uint8_t *src, unsigned src_stride,
>> +                       unsigned width, unsigned height);
>> +
>> +   void
>> +   (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
>> +                     const unsigned *src, unsigned src_stride,
>> +                     unsigned width, unsigned height);
>> +
>> +  /**
>> +    * Unpack pixel blocks to R32G32B32A32_SINT.
>> +    * Note: strides are in bytes.
>> +    *
>> +    * Only defined for INT formats.
>> +    */
>> +   void
>> +   (*unpack_rgba_sint)(signed *dst, unsigned dst_stride,
>> +                       const uint8_t *src, unsigned src_stride,
>> +                       unsigned width, unsigned height);
>> +
>> +   void
>> +   (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
>> +                     const int *src, unsigned src_stride,
>> +                     unsigned width, unsigned height);
>>  };
>>
>>
>> @@ -511,6 +543,14 @@ util_format_is_luminance_alpha(enum pipe_format
>> format);
>>  boolean
>>  util_format_is_intensity(enum pipe_format format);
>>
>> +boolean
>> +util_format_is_pure_integer(enum pipe_format format);
>> +
>> +boolean
>> +util_format_is_pure_sint(enum pipe_format format);
>> +
>> +boolean
>> +util_format_is_pure_uint(enum pipe_format format);
>>
>>  /**
>>   * Whether the src format can be blitted to destation format with a
>>   simple
>> @@ -834,6 +874,30 @@ util_format_write_4ub(enum pipe_format format,
>>                        void *dst, unsigned dst_stride,
>>                        unsigned x, unsigned y, unsigned w, unsigned
>>                        h);
>>
>> +void
>> +util_format_read_4ui(enum pipe_format format,
>> +                     unsigned *dst, unsigned dst_stride,
>> +                     const void *src, unsigned src_stride,
>> +                     unsigned x, unsigned y, unsigned w, unsigned
>> h);
>> +
>> +void
>> +util_format_write_4ui(enum pipe_format format,
>> +                      const unsigned int *src, unsigned src_stride,
>> +                      void *dst, unsigned dst_stride,
>> +                      unsigned x, unsigned y, unsigned w, unsigned
>> h);
>> +
>> +void
>> +util_format_read_4i(enum pipe_format format,
>> +                    int *dst, unsigned dst_stride,
>> +                    const void *src, unsigned src_stride,
>> +                    unsigned x, unsigned y, unsigned w, unsigned h);
>> +
>> +void
>> +util_format_write_4i(enum pipe_format format,
>> +                     const int *src, unsigned src_stride,
>> +                     void *dst, unsigned dst_stride,
>> +                     unsigned x, unsigned y, unsigned w, unsigned
>> h);
>> +
>>  /*
>>   * Generic format conversion;
>>   */
>> diff --git a/src/gallium/auxiliary/util/u_format_pack.py
>> b/src/gallium/auxiliary/util/u_format_pack.py
>> index cc173f8..5cfbe32 100644
>> --- a/src/gallium/auxiliary/util/u_format_pack.py
>> +++ b/src/gallium/auxiliary/util/u_format_pack.py
>> @@ -126,6 +126,26 @@ def is_format_supported(format):
>>
>>      return True
>>
>> +def is_format_pure_unsigned(format):
>> +    for i in range(4):
>> +        channel = format.channels[i]
>> +        if channel.type not in (VOID, UNSIGNED):
>> +            return False
>> +        if channel.type == UNSIGNED and channel.pure == False:
>> +            return False
>> +
>> +    return True
>> +
>> +
>> +def is_format_pure_signed(format):
>> +    for i in range(4):
>> +        channel = format.channels[i]
>> +        if channel.type not in (VOID, SIGNED):
>> +            return False
>> +        if channel.type == SIGNED and channel.pure == False:
>> +            return False
>> +
>> +    return True
>>
>>  def native_type(format):
>>      '''Get the native appropriate for a format.'''
>> @@ -290,6 +310,7 @@ def conversion_expr(src_channel,
>>      src_type = src_channel.type
>>      src_size = src_channel.size
>>      src_norm = src_channel.norm
>> +    src_pure = src_channel.pure
>>
>>      # Promote half to float
>>      if src_type == FLOAT and src_size == 16:
>> @@ -653,18 +674,45 @@ def generate(formats):
>>              if is_format_supported(format):
>>                  generate_format_type(format)
>>
>> -            channel = Channel(FLOAT, False, 32)
>> -            native_type = 'float'
>> -            suffix = 'rgba_float'
>> +            if is_format_pure_unsigned(format):
>> +                native_type = 'unsigned'
>> +                suffix = 'unsigned'
>> +                channel = Channel(UNSIGNED, False, True, 32)
>> +
>> +                generate_format_unpack(format, channel, native_type,
>> suffix)
>> +                generate_format_pack(format, channel, native_type,
>> suffix)
>> +
>> +                channel = Channel(SIGNED, False, True, 32)
>> +                native_type = 'int'
>> +                suffix = 'signed'
>> +                generate_format_unpack(format, channel, native_type,
>> suffix)
>> +                generate_format_pack(format, channel, native_type,
>> suffix)
>> +            elif is_format_pure_signed(format):
>> +                native_type = 'int'
>> +                suffix = 'signed'
>> +                channel = Channel(SIGNED, False, True, 32)
>> +
>> +                generate_format_unpack(format, channel, native_type,
>> suffix)
>> +                generate_format_pack(format, channel, native_type,
>> suffix)
>> +
>> +                native_type = 'unsigned'
>> +                suffix = 'unsigned'
>> +                channel = Channel(UNSIGNED, False, True, 32)
>> +                generate_format_unpack(format, channel, native_type,
>> suffix)
>> +                generate_format_pack(format, channel, native_type,
>> suffix)
>> +            else:
>> +                channel = Channel(FLOAT, False, False, 32)
>> +                native_type = 'float'
>> +                suffix = 'rgba_float'
>>
>> -            generate_format_unpack(format, channel, native_type,
>> suffix)
>> -            generate_format_pack(format, channel, native_type,
>> suffix)
>> -            generate_format_fetch(format, channel, native_type,
>> suffix)
>> +                generate_format_unpack(format, channel, native_type,
>> suffix)
>> +                generate_format_pack(format, channel, native_type,
>> suffix)
>> +                generate_format_fetch(format, channel, native_type,
>> suffix)
>>
>> -            channel = Channel(UNSIGNED, True, 8)
>> -            native_type = 'uint8_t'
>> -            suffix = 'rgba_8unorm'
>> +                channel = Channel(UNSIGNED, True, False, 8)
>> +                native_type = 'uint8_t'
>> +                suffix = 'rgba_8unorm'
>>
>> -            generate_format_unpack(format, channel, native_type,
>> suffix)
>> -            generate_format_pack(format, channel, native_type,
>> suffix)
>> +                generate_format_unpack(format, channel, native_type,
>> suffix)
>> +                generate_format_pack(format, channel, native_type,
>> suffix)
>>
>> diff --git a/src/gallium/auxiliary/util/u_format_parse.py
>> b/src/gallium/auxiliary/util/u_format_parse.py
>> index ddb9f24..73a4bcb 100755
>> --- a/src/gallium/auxiliary/util/u_format_parse.py
>> +++ b/src/gallium/auxiliary/util/u_format_parse.py
>> @@ -52,9 +52,10 @@ VERY_LARGE = 99999999999999999999999
>>  class Channel:
>>      '''Describe the channel of a color channel.'''
>>
>> -    def __init__(self, type, norm, size, name = ''):
>> +    def __init__(self, type, norm, pure, size, name = ''):
>>          self.type = type
>>          self.norm = norm
>> +        self.pure = pure
>>          self.size = size
>>          self.sign = type in (SIGNED, FIXED, FLOAT)
>>          self.name = name
>> @@ -63,11 +64,13 @@ class Channel:
>>          s = str(self.type)
>>          if self.norm:
>>              s += 'n'
>> +        if self.pure:
>> +            s += 'p'
>>          s += str(self.size)
>>          return s
>>
>>      def __eq__(self, other):
>> -        return self.type == other.type and self.norm == other.norm
>> and self.size == other.size
>> +        return self.type == other.type and self.norm == other.norm
>> and self.pure == other.pure and self.size == other.size
>>
>>      def max(self):
>>          '''Maximum representable number.'''
>> @@ -158,6 +161,8 @@ class Format:
>>                      return True
>>                  if channel.norm != ref_channel.norm:
>>                      return True
>> +                if channel.pure != ref_channel.pure:
>> +                    return True
>>          return False
>>
>>      def is_pot(self):
>> @@ -274,15 +279,22 @@ def parse(filename):
>>                  type = _type_parse_map[field[0]]
>>                  if field[1] == 'n':
>>                      norm = True
>> +                    pure = False
>> +                    size = int(field[2:])
>> +                elif field[1] == 'p':
>> +                    pure = True
>> +                    norm = False
>>                      size = int(field[2:])
>>                  else:
>>                      norm = False
>> +                    pure = False
>>                      size = int(field[1:])
>>              else:
>>                  type = VOID
>>                  norm = False
>> +                pure = False
>>                  size = 0
>> -            channel = Channel(type, norm, size, names[i])
>> +            channel = Channel(type, norm, pure, size, names[i])
>>              channels.append(channel)
>>
>>          format = Format(name, layout, block_width, block_height,
>>          channels, swizzles, colorspace)
>> diff --git a/src/gallium/auxiliary/util/u_format_table.py
>> b/src/gallium/auxiliary/util/u_format_table.py
>> index 55e0f78..6c00b0d 100755
>> --- a/src/gallium/auxiliary/util/u_format_table.py
>> +++ b/src/gallium/auxiliary/util/u_format_table.py
>> @@ -113,7 +113,7 @@ def write_format_table(formats):
>>              else:
>>                  sep = ""
>>              if channel.size:
>> -                print "      {%s, %s, %u}%s\t/* %s = %s */" %
>> (type_map[channel.type], bool_map(channel.norm), channel.size, sep,
>> "xyzw"[i], channel.name)
>> +                print "      {%s, %s, %s, %u}%s\t/* %s = %s */" %
>> (type_map[channel.type], bool_map(channel.norm),
>> bool_map(channel.pure), channel.size, sep, "xyzw"[i], channel.name)
>>              else:
>>                  print "      {0, 0, 0}%s" % (sep,)
>>          print "   },"
>> @@ -131,7 +131,7 @@ def write_format_table(formats):
>>              print "      %s%s\t/* %s */" % (swizzle_map[swizzle],
>>              sep, comment)
>>          print "   },"
>>          print "   %s," % (colorspace_map(format.colorspace),)
>> -        if format.colorspace != ZS:
>> +        if format.colorspace != ZS and format.channels[0].pure ==
>> False:
>>              print "   &util_format_%s_unpack_rgba_8unorm," %
>>              format.short_name()
>>              print "   &util_format_%s_pack_rgba_8unorm," %
>>              format.short_name()
>>              if format.layout == 's3tc' or format.layout == 'rgtc':
>> @@ -160,10 +160,25 @@ def write_format_table(formats):
>>              print "   NULL, /* pack_z_float */"
>>          if format.colorspace == ZS and format.swizzles[1] !=
>>          SWIZZLE_NONE:
>>              print "   &util_format_%s_unpack_s_8uscaled," %
>>              format.short_name()
>> -            print "   &util_format_%s_pack_s_8uscaled" %
>> format.short_name()
>> +            print "   &util_format_%s_pack_s_8uscaled," %
>> format.short_name()
>>          else:
>>              print "   NULL, /* unpack_s_8uscaled */"
>> -            print "   NULL /* pack_s_8uscaled */"
>> +            print "   NULL, /* pack_s_8uscaled */"
>> +        if format.channels[0].pure == True and
>> format.channels[0].type == UNSIGNED:
>> +            print "   &util_format_%s_unpack_unsigned, /*
>> unpack_rgba_uint */" % format.short_name()
>> +            print "   &util_format_%s_pack_unsigned, /*
>> pack_rgba_uint */" % format.short_name()
>> +            print "   &util_format_%s_unpack_signed, /*
>> unpack_rgba_sint */" % format.short_name()
>> +            print "   &util_format_%s_pack_signed  /* pack_rgba_sint
>> */" % format.short_name()
>> +        elif format.channels[0].pure == True and
>> format.channels[0].type == SIGNED:
>> +            print "   &util_format_%s_unpack_unsigned, /*
>> unpack_rgba_uint */" % format.short_name()
>> +            print "   &util_format_%s_pack_unsigned, /*
>> pack_rgba_uint */" % format.short_name()
>> +            print "   &util_format_%s_unpack_signed, /*
>> unpack_rgba_sint */" % format.short_name()
>> +            print "   &util_format_%s_pack_signed  /* pack_rgba_sint
>> */" % format.short_name()
>> +        else:
>> +            print "   NULL, /* unpack_rgba_uint */"
>> +            print "   NULL, /* pack_rgba_uint */"
>> +            print "   NULL, /* unpack_rgba_sint */"
>> +            print "   NULL  /* pack_rgba_sint */"
>>          print "};"
>>          print
>>
>> diff --git a/src/gallium/auxiliary/util/u_tile.c
>> b/src/gallium/auxiliary/util/u_tile.c
>> index 23f12e5..6342bfb 100644
>> --- a/src/gallium/auxiliary/util/u_tile.c
>> +++ b/src/gallium/auxiliary/util/u_tile.c
>> @@ -389,6 +389,29 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
>>     }
>>  }
>>
>> +void
>> +pipe_tile_raw_to_unsigned(enum pipe_format format,
>> +                          void *src,
>> +                          uint w, uint h,
>> +                          unsigned *dst, unsigned dst_stride)
>> +{
>> +  util_format_read_4ui(format,
>> +                       dst, dst_stride * sizeof(float),
>> +                       src, util_format_get_stride(format, w),
>> +                       0, 0, w, h);
>> +}
>> +
>> +void
>> +pipe_tile_raw_to_signed(enum pipe_format format,
>> +                          void *src,
>> +                          uint w, uint h,
>> +                          int *dst, unsigned dst_stride)
>> +{
>> +  util_format_read_4i(format,
>> +                      dst, dst_stride * sizeof(float),
>> +                      src, util_format_get_stride(format, w),
>> +                      0, 0, w, h);
>> +}
>>
>>  void
>>  pipe_get_tile_rgba(struct pipe_context *pipe,
>> @@ -492,6 +515,61 @@ pipe_put_tile_rgba_format(struct pipe_context
>> *pipe,
>>     FREE(packed);
>>  }
>>
>> +void
>> +pipe_put_tile_i_format(struct pipe_context *pipe,
>> +                       struct pipe_transfer *pt,
>> +                       uint x, uint y, uint w, uint h,
>> +                       enum pipe_format format,
>> +                       const int *p)
>> +{
>> +   unsigned src_stride = w * 4;
>> +   void *packed;
>> +
>> +   if (u_clip_tile(x, y, &w, &h, &pt->box))
>> +      return;
>> +
>> +   packed = MALLOC(util_format_get_nblocks(format, w, h) *
>> util_format_get_blocksize(format));
>> +
>> +   if (!packed)
>> +      return;
>> +
>> +   util_format_write_4i(format,
>> +                        p, src_stride * sizeof(float),
>> +                        packed, util_format_get_stride(format, w),
>> +                        0, 0, w, h);
>> +
>> +   pipe_put_tile_raw(pipe, pt, x, y, w, h, packed, 0);
>> +
>> +   FREE(packed);
>> +}
>> +
>> +void
>> +pipe_put_tile_ui_format(struct pipe_context *pipe,
>> +                        struct pipe_transfer *pt,
>> +                        uint x, uint y, uint w, uint h,
>> +                        enum pipe_format format,
>> +                        const unsigned int *p)
>> +{
>> +   unsigned src_stride = w * 4;
>> +   void *packed;
>> +
>> +   if (u_clip_tile(x, y, &w, &h, &pt->box))
>> +      return;
>> +
>> +   packed = MALLOC(util_format_get_nblocks(format, w, h) *
>> util_format_get_blocksize(format));
>> +
>> +   if (!packed)
>> +      return;
>> +
>> +   util_format_write_4ui(format,
>> +                         p, src_stride * sizeof(float),
>> +                         packed, util_format_get_stride(format, w),
>> +                         0, 0, w, h);
>> +
>> +   pipe_put_tile_raw(pipe, pt, x, y, w, h, packed, 0);
>> +
>> +   FREE(packed);
>> +}
>>
>>  /**
>>   * Get a block of Z values, converted to 32-bit range.
>> @@ -688,3 +766,63 @@ pipe_put_tile_z(struct pipe_context *pipe,
>>  }
>>
>>
>> +void
>> +pipe_get_tile_ui_format(struct pipe_context *pipe,
>> +                        struct pipe_transfer *pt,
>> +                        uint x, uint y, uint w, uint h,
>> +                        enum pipe_format format,
>> +                        unsigned int *p)
>> +{
>> +   unsigned dst_stride = w * 4;
>> +   void *packed;
>> +
>> +   if (u_clip_tile(x, y, &w, &h, &pt->box)) {
>> +      return;
>> +   }
>> +
>> +   packed = MALLOC(util_format_get_nblocks(format, w, h) *
>> util_format_get_blocksize(format));
>> +   if (!packed) {
>> +      return;
>> +   }
>> +
>> +   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
>> +      assert((x & 1) == 0);
>> +   }
>> +
>> +   pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
>> +
>> +   pipe_tile_raw_to_unsigned(format, packed, w, h, p, dst_stride);
>> +
>> +   FREE(packed);
>> +}
>> +
>> +
>> +void
>> +pipe_get_tile_i_format(struct pipe_context *pipe,
>> +                       struct pipe_transfer *pt,
>> +                       uint x, uint y, uint w, uint h,
>> +                       enum pipe_format format,
>> +                       int *p)
>> +{
>> +   unsigned dst_stride = w * 4;
>> +   void *packed;
>> +
>> +   if (u_clip_tile(x, y, &w, &h, &pt->box)) {
>> +      return;
>> +   }
>> +
>> +   packed = MALLOC(util_format_get_nblocks(format, w, h) *
>> util_format_get_blocksize(format));
>> +   if (!packed) {
>> +      return;
>> +   }
>> +
>> +   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
>> +      assert((x & 1) == 0);
>> +   }
>> +
>> +   pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
>> +
>> +   pipe_tile_raw_to_signed(format, packed, w, h, p, dst_stride);
>> +
>> +   FREE(packed);
>> +}
>> diff --git a/src/gallium/auxiliary/util/u_tile.h
>> b/src/gallium/auxiliary/util/u_tile.h
>> index 0ba2743..926f169 100644
>> --- a/src/gallium/auxiliary/util/u_tile.h
>> +++ b/src/gallium/auxiliary/util/u_tile.h
>> @@ -118,6 +118,45 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
>>                        uint w, uint h,
>>                        float *dst, unsigned dst_stride);
>>
>> +void
>> +pipe_tile_raw_to_unsigned(enum pipe_format format,
>> +                          void *src,
>> +                          uint w, uint h,
>> +                          unsigned *dst, unsigned dst_stride);
>> +
>> +void
>> +pipe_tile_raw_to_signed(enum pipe_format format,
>> +                        void *src,
>> +                        uint w, uint h,
>> +                        int *dst, unsigned dst_stride);
>> +
>> +void
>> +pipe_get_tile_ui_format(struct pipe_context *pipe,
>> +                        struct pipe_transfer *pt,
>> +                        uint x, uint y, uint w, uint h,
>> +                        enum pipe_format format,
>> +                        unsigned int *p);
>> +
>> +void
>> +pipe_get_tile_i_format(struct pipe_context *pipe,
>> +                       struct pipe_transfer *pt,
>> +                       uint x, uint y, uint w, uint h,
>> +                       enum pipe_format format,
>> +                       int *p);
>> +
>> +void
>> +pipe_put_tile_ui_format(struct pipe_context *pipe,
>> +                        struct pipe_transfer *pt,
>> +                        uint x, uint y, uint w, uint h,
>> +                        enum pipe_format format,
>> +                        const unsigned *p);
>> +
>> +void
>> +pipe_put_tile_i_format(struct pipe_context *pipe,
>> +                       struct pipe_transfer *pt,
>> +                       uint x, uint y, uint w, uint h,
>> +                       enum pipe_format format,
>> +                       const int *p);
>>
>>  #ifdef __cplusplus
>>  }
>> diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py
>> b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
>> index a2795b6..706411c 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py
>> +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
>> @@ -612,7 +612,7 @@ def main():
>>
>>      generate_sse2()
>>
>> -    channel = Channel(UNSIGNED, True, 8)
>> +    channel = Channel(UNSIGNED, True, False, 8)
>>      native_type = 'uint8_t'
>>      suffix = '4ub'
>>
>> diff --git a/src/gallium/include/pipe/p_format.h
>> b/src/gallium/include/pipe/p_format.h
>> index 3d1c997..a5c9eb4 100644
>> --- a/src/gallium/include/pipe/p_format.h
>> +++ b/src/gallium/include/pipe/p_format.h
>> @@ -251,6 +251,65 @@ enum pipe_format {
>>     PIPE_FORMAT_B10G10R10A2_SSCALED     = 175,
>>     PIPE_FORMAT_B10G10R10A2_SNORM       = 176,
>>
>> +   PIPE_FORMAT_R8_UINT                 = 177,
>> +   PIPE_FORMAT_R8G8_UINT               = 178,
>> +   PIPE_FORMAT_R8G8B8_UINT             = 179,
>> +   PIPE_FORMAT_R8G8B8A8_UINT           = 180,
>> +
>> +   PIPE_FORMAT_R8_SINT                 = 181,
>> +   PIPE_FORMAT_R8G8_SINT               = 182,
>> +   PIPE_FORMAT_R8G8B8_SINT             = 183,
>> +   PIPE_FORMAT_R8G8B8A8_SINT           = 184,
>> +
>> +   PIPE_FORMAT_R16_UINT                = 185,
>> +   PIPE_FORMAT_R16G16_UINT             = 186,
>> +   PIPE_FORMAT_R16G16B16_UINT          = 187,
>> +   PIPE_FORMAT_R16G16B16A16_UINT       = 188,
>> +
>> +   PIPE_FORMAT_R16_SINT                = 189,
>> +   PIPE_FORMAT_R16G16_SINT             = 190,
>> +   PIPE_FORMAT_R16G16B16_SINT          = 191,
>> +   PIPE_FORMAT_R16G16B16A16_SINT       = 192,
>> +
>> +   PIPE_FORMAT_R32_UINT                = 193,
>> +   PIPE_FORMAT_R32G32_UINT             = 194,
>> +   PIPE_FORMAT_R32G32B32_UINT          = 195,
>> +   PIPE_FORMAT_R32G32B32A32_UINT       = 196,
>> +
>> +   PIPE_FORMAT_R32_SINT                = 197,
>> +   PIPE_FORMAT_R32G32_SINT             = 198,
>> +   PIPE_FORMAT_R32G32B32_SINT          = 199,
>> +   PIPE_FORMAT_R32G32B32A32_SINT       = 200,
>> +
>> +   PIPE_FORMAT_A8_UINT                 = 201,
>> +   PIPE_FORMAT_I8_UINT                 = 202,
>> +   PIPE_FORMAT_L8_UINT                 = 203,
>> +   PIPE_FORMAT_L8A8_UINT               = 204,
>> +
>> +   PIPE_FORMAT_A8_SINT                 = 205,
>> +   PIPE_FORMAT_I8_SINT                 = 206,
>> +   PIPE_FORMAT_L8_SINT                 = 207,
>> +   PIPE_FORMAT_L8A8_SINT               = 208,
>> +
>> +   PIPE_FORMAT_A16_UINT                = 209,
>> +   PIPE_FORMAT_I16_UINT                = 210,
>> +   PIPE_FORMAT_L16_UINT                = 211,
>> +   PIPE_FORMAT_L16A16_UINT             = 212,
>> +
>> +   PIPE_FORMAT_A16_SINT                = 213,
>> +   PIPE_FORMAT_I16_SINT                = 214,
>> +   PIPE_FORMAT_L16_SINT                = 215,
>> +   PIPE_FORMAT_L16A16_SINT             = 216,
>> +
>> +   PIPE_FORMAT_A32_UINT                = 217,
>> +   PIPE_FORMAT_I32_UINT                = 218,
>> +   PIPE_FORMAT_L32_UINT                = 219,
>> +   PIPE_FORMAT_L32A32_UINT             = 220,
>> +
>> +   PIPE_FORMAT_A32_SINT                = 221,
>> +   PIPE_FORMAT_I32_SINT                = 222,
>> +   PIPE_FORMAT_L32_SINT                = 223,
>> +   PIPE_FORMAT_L32A32_SINT             = 224,
>
> Are the pure versions of I/A/L really used anywhere? I thought these formats were being deprecated in GL 3.x

They have never been in GL 3.x. However, they are part of EXT_texture_integer.

Also, deprecation doesn't mean anything to us. A removal does. And
there are no removals in the GL Compatibility spec.

Marek


More information about the mesa-dev mailing list