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

Jose Fonseca jfonseca at vmware.com
Fri Oct 7 16:54:34 PDT 2011



----- Original Message -----
> 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.

Essentially I was asking if there was an intersection of I/A/L formats and the pure integer APIs. And IIUC your reply, there is, in EXT_texture_integer.

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

True, there are no removals in compatability spec. But deprecation means a lot whenever the feature is optional.  Just look at all the recent changes to removed deprecated features.

Take EXT_texture_integer for example: if it's not part of the core or compatability profiles then we could choose not to implement it.

That said, I'm perfectly fine adding the formats, if they aren't used.  Just curious to see whether there was an use case or not.

Jose



More information about the mesa-dev mailing list