From: Eric Anholt Date: Fri, 8 Nov 2019 20:30:02 +0000 (-0800) Subject: util: Make helper functions for pack/unpacking pixel rows. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c574cda3c6a3f880f99e4e22967fc82e34609942;p=mesa.git util: Make helper functions for pack/unpacking pixel rows. Almost all users of the unpack functions don't have strides to plug in (and many are only doing one pixel!), and this will help simplify them. Reviewed-by: Marek Olšák Part-of: --- diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 718411d8d1f..a146363ef49 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -591,12 +591,12 @@ util_clear_texture(struct pipe_context *pipe, if (util_format_has_depth(desc)) { clear |= PIPE_CLEAR_DEPTH; - desc->unpack_z_float(&depth, 0, data, 0, 1, 1); + util_format_unpack_z_float(tex->format, &depth, data, 1); } if (util_format_has_stencil(desc)) { clear |= PIPE_CLEAR_STENCIL; - desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1); + util_format_unpack_s_8uint(tex->format, &stencil, data, 1); } zstencil = util_pack64_z_stencil(tex->format, depth, stencil); @@ -606,12 +606,7 @@ util_clear_texture(struct pipe_context *pipe, box->width, box->height, box->depth); } else { union pipe_color_union color; - if (util_format_is_pure_uint(tex->format)) - desc->unpack_rgba_uint(color.ui, 0, data, 0, 1, 1); - else if (util_format_is_pure_sint(tex->format)) - desc->unpack_rgba_sint(color.i, 0, data, 0, 1, 1); - else - desc->unpack_rgba_float(color.f, 0, data, 0, 1, 1); + util_format_unpack_rgba(tex->format, color.ui, data, 1); util_clear_color_texture(pipe, tex, tex->format, &color, level, box->x, box->y, box->z, diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c index bc6fe1ded0f..94b68c8dcd8 100644 --- a/src/gallium/drivers/iris/iris_clear.c +++ b/src/gallium/drivers/iris/iris_clear.c @@ -702,10 +702,10 @@ iris_clear_texture(struct pipe_context *ctx, uint8_t stencil = 0; if (fmt_desc->unpack_z_float) - fmt_desc->unpack_z_float(&depth, 0, data, 0, 1, 1); + util_format_unpack_z_float(p_res->format, &depth, data, 1); if (fmt_desc->unpack_s_8uint) - fmt_desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1); + util_format_unpack_s_8uint(p_res->format, &stencil, data, 1); clear_depth_stencil(ice, p_res, level, box, true, true, true, depth, stencil); diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c index b083acfac3e..99ceef77403 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c @@ -41,15 +41,13 @@ nv30_emit_vtxattr(struct nv30_context *nv30, struct pipe_vertex_buffer *vb, const unsigned nc = util_format_get_nr_components(ve->src_format); struct nouveau_pushbuf *push = nv30->base.pushbuf; struct nv04_resource *res = nv04_resource(vb->buffer.resource); - const struct util_format_description *desc = - util_format_description(ve->src_format); const void *data; float v[4]; data = nouveau_resource_map_offset(&nv30->base, res, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_RD); - desc->unpack_rgba_float(v, 0, data, 0, 1, 1); + util_format_unpack_rgba_float(ve->src_format, v, data, 1); switch (nc) { case 4: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c index 7a2402d72ed..34c2633916b 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c @@ -475,11 +475,11 @@ nv50_clear_texture(struct pipe_context *pipe, if (util_format_has_depth(desc)) { clear |= PIPE_CLEAR_DEPTH; - desc->unpack_z_float(&depth, 0, data, 0, 1, 1); + util_format_unpack_z_float(res->format, &depth, data, 1); } if (util_format_has_stencil(desc)) { clear |= PIPE_CLEAR_STENCIL; - desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1); + util_format_unpack_s_8uint(res->format, &stencil, data, 1); } pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil, box->x, box->y, box->width, box->height, false); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c index 865d8b4359d..da4a0171ac6 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c @@ -149,15 +149,7 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, assert(vb->is_user_buffer); - if (desc->channel[0].pure_integer) { - if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) { - desc->unpack_rgba_sint((int32_t *)v, 0, data, 0, 1, 1); - } else { - desc->unpack_rgba_uint((uint32_t *)v, 0, data, 0, 1, 1); - } - } else { - desc->unpack_rgba_float(v, 0, data, 0, 1, 1); - } + util_format_unpack_rgba(ve->src_format, v, data, 1); switch (nc) { case 4: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index 6ed96509bf4..92bd7eb5b8e 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c @@ -184,17 +184,15 @@ nvc0_set_constant_vertex_attrib(struct nvc0_context *nvc0, const unsigned a) PUSH_SPACE(push, 6); BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 5); dst = &push->cur[1]; + util_format_unpack_rgba(ve->src_format, dst, src, 1); if (desc->channel[0].pure_integer) { if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) { mode = VTX_ATTR(a, 4, SINT, 32); - desc->unpack_rgba_sint(dst, 0, src, 0, 1, 1); } else { mode = VTX_ATTR(a, 4, UINT, 32); - desc->unpack_rgba_uint(dst, 0, src, 0, 1, 1); } } else { mode = VTX_ATTR(a, 4, FLOAT, 32); - desc->unpack_rgba_float(dst, 0, src, 0, 1, 1); } push->cur[0] = mode; push->cur += 5; diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 518e92d9fe7..ad94c9fb0f0 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -1635,11 +1635,11 @@ static void r600_clear_texture(struct pipe_context *pipe, /* Depth is always present. */ clear = PIPE_CLEAR_DEPTH; - desc->unpack_z_float(&depth, 0, data, 0, 1, 1); + util_format_unpack_z_float(tex->format, &depth, data, 1); if (rtex->surface.has_stencil) { clear |= PIPE_CLEAR_STENCIL; - desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1); + util_format_unpack_s_8uint(tex->format, &stencil, data, 1); } pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil, @@ -1648,13 +1648,7 @@ static void r600_clear_texture(struct pipe_context *pipe, } else { union pipe_color_union color; - /* pipe_color_union requires the full vec4 representation. */ - if (util_format_is_pure_uint(tex->format)) - desc->unpack_rgba_uint(color.ui, 0, data, 0, 1, 1); - else if (util_format_is_pure_sint(tex->format)) - desc->unpack_rgba_sint(color.i, 0, data, 0, 1, 1); - else - desc->unpack_rgba_float(color.f, 0, data, 0, 1, 1); + util_format_unpack_rgba(tex->format, color.ui, data, 1); if (screen->is_format_supported(screen, tex->format, tex->target, 0, 0, diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index c0aceea66c4..b1858fb42fe 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -752,11 +752,12 @@ static void si_clear_texture(struct pipe_context *pipe, /* Depth is always present. */ clear = PIPE_CLEAR_DEPTH; - desc->unpack_z_float(&depth, 0, data, 0, 1, 1); + util_format_unpack_z_float(tex->format, &depth, data, 1); if (stex->surface.has_stencil) { clear |= PIPE_CLEAR_STENCIL; - desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1); + util_format_unpack_s_8uint(tex->format, + &stencil, data, 1); } si_clear_depth_stencil(pipe, sf, clear, depth, stencil, @@ -765,13 +766,7 @@ static void si_clear_texture(struct pipe_context *pipe, } else { union pipe_color_union color; - /* pipe_color_union requires the full vec4 representation. */ - if (util_format_is_pure_uint(tex->format)) - desc->unpack_rgba_uint(color.ui, 0, data, 0, 1, 1); - else if (util_format_is_pure_sint(tex->format)) - desc->unpack_rgba_sint(color.i, 0, data, 0, 1, 1); - else - desc->unpack_rgba_float(color.f, 0, data, 0, 1, 1); + util_format_unpack_rgba(tex->format, color.ui, data, 1); if (screen->is_format_supported(screen, tex->format, tex->target, 0, 0, diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index 6aa74d5b69a..75507fc1752 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -309,8 +309,8 @@ svga_clear_texture(struct pipe_context *pipe, stencil = 0; } else { - desc->unpack_z_float(&depth, 0, data, 0, 1, 1); - desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1); + util_format_unpack_z_float(surface->format, &depth, data, 1); + util_format_unpack_s_8uint(surface->format, &stencil, data, 1); } if (util_format_has_depth(desc)) { @@ -367,18 +367,7 @@ svga_clear_texture(struct pipe_context *pipe, color.f[0] = color.f[1] = color.f[2] = color.f[3] = 0; } else { - if (util_format_is_pure_sint(surface->format)) { - /* signed integer */ - desc->unpack_rgba_sint(color.i, 0, data, 0, 1, 1); - } - else if (util_format_is_pure_uint(surface->format)) { - /* unsigned integer */ - desc->unpack_rgba_uint(color.ui, 0, data, 0, 1, 1); - } - else { - /* floating point */ - desc->unpack_rgba_float(color.f, 0, data, 0, 1, 1); - } + util_format_unpack_rgba(surface->format, color.ui, data, 1); } /* Setup render target view */ diff --git a/src/util/format/u_format.c b/src/util/format/u_format.c index d96874114ad..7af030108ad 100644 --- a/src/util/format/u_format.c +++ b/src/util/format/u_format.c @@ -717,13 +717,13 @@ util_format_translate(enum pipe_format dst_format, while (height--) { if (tmp_z) { - src_format_desc->unpack_z_float(tmp_z, 0, src_row, src_stride, width, 1); - dst_format_desc->pack_z_float(dst_row, dst_stride, tmp_z, 0, width, 1); + util_format_unpack_z_float(src_format, tmp_z, src_row, width); + util_format_pack_z_float(dst_format, dst_row, tmp_z, width); } if (tmp_s) { - src_format_desc->unpack_s_8uint(tmp_s, 0, src_row, src_stride, width, 1); - dst_format_desc->pack_s_8uint(dst_row, dst_stride, tmp_s, 0, width, 1); + util_format_unpack_s_8uint(src_format, tmp_s, src_row, width); + util_format_pack_s_8uint(dst_format, dst_row, tmp_s, width); } dst_row += dst_step; diff --git a/src/util/format/u_format.h b/src/util/format/u_format.h index 796373c3f67..1b6f0b88289 100644 --- a/src/util/format/u_format.h +++ b/src/util/format/u_format.h @@ -1439,6 +1439,106 @@ util_format_is_unorm8(const struct util_format_description *desc) return desc->is_unorm && desc->is_array && desc->channel[c].size == 8; } +static inline void +util_format_unpack_z_float(enum pipe_format format, float *dst, + const void *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + desc->unpack_z_float(dst, 0, (const uint8_t *)src, 0, w, 1); +} + +static inline void +util_format_unpack_z_32unorm(enum pipe_format format, uint32_t *dst, + const void *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + desc->unpack_z_32unorm(dst, 0, (const uint8_t *)src, 0, w, 1); +} + +static inline void +util_format_unpack_s_8uint(enum pipe_format format, uint8_t *dst, + const void *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + desc->unpack_s_8uint(dst, 0, (const uint8_t *)src, 0, w, 1); +} + +static inline void +util_format_unpack_rgba_float(enum pipe_format format, float *dst, + const void *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + desc->unpack_rgba_float(dst, 0, (const uint8_t *)src, 0, w, 1); +} + +/** + * Unpacks a row of color data to 32-bit RGBA, either integers for pure + * integer formats (sign-extended for signed data), or 32-bit floats. + */ +static inline void +util_format_unpack_rgba(enum pipe_format format, void *dst, + const void *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + if (util_format_is_pure_uint(format)) + desc->unpack_rgba_uint((uint32_t *)dst, 0, (const uint8_t *)src, 0, w, 1); + else if (util_format_is_pure_sint(format)) + desc->unpack_rgba_sint((int32_t *)dst, 0, (const uint8_t *)src, 0, w, 1); + else + desc->unpack_rgba_float((float *)dst, 0, (const uint8_t *)src, 0, w, 1); +} + +static inline void +util_format_pack_z_float(enum pipe_format format, void *dst, + const float *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + desc->pack_z_float((uint8_t *)dst, 0, src, 0, w, 1); +} + +static inline void +util_format_pack_z_32unorm(enum pipe_format format, void *dst, + const uint32_t *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + desc->pack_z_32unorm((uint8_t *)dst, 0, src, 0, w, 1); +} + +static inline void +util_format_pack_s_8uint(enum pipe_format format, void *dst, + const uint8_t *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + desc->pack_s_8uint((uint8_t *)dst, 0, src, 0, w, 1); +} + +/** + * Packs a row of color data from 32-bit RGBA, either integers for pure + * integer formats, or 32-bit floats. Values are clamped to the packed + * representation's range. + */ +static inline void +util_format_pack_rgba(enum pipe_format format, void *dst, + const void *src, unsigned w) +{ + const struct util_format_description *desc = util_format_description(format); + + if (util_format_is_pure_uint(format)) + desc->pack_rgba_uint((uint8_t *)dst, 0, (const uint32_t *)src, 0, w, 1); + else if (util_format_is_pure_sint(format)) + desc->pack_rgba_sint((uint8_t *)dst, 0, (const int32_t *)src, 0, w, 1); + else + desc->pack_rgba_float((uint8_t *)dst, 0, (const float *)src, 0, w, 1); +} + /* * Format access functions. */