[Mesa-dev] [PATCH 3/5] gallium: add initial pure integer support (v2)
Jose Fonseca
jfonseca at vmware.com
Fri Oct 7 13:48:06 PDT 2011
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
Empty line missing here.
> PIPE_FORMAT_COUNT
> };
Jose
More information about the mesa-dev
mailing list