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

2011-10-07 Thread Dave Airlie
From: Dave Airlie airl...@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.

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 airl...@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;
+}
 
 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, 

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

2011-10-07 Thread Jose Fonseca
Looks good overall. Comments inline.

- Original Message -
 From: Dave Airlie airl...@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 airl...@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 

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

2011-10-07 Thread Marek Olšák
On Fri, Oct 7, 2011 at 10:48 PM, Jose Fonseca jfons...@vmware.com wrote:
 Looks good overall. Comments inline.

 - Original Message -
 From: Dave Airlie airl...@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 airl...@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,