[Mesa-dev] [RFC 2/3] gallium: Move nv50 clear_texture impl down to util_surface

Roland Scheidegger sroland at vmware.com
Thu Dec 3 08:27:36 PST 2015


One problem with this is that clear_render_target and
clear_depth_stencil honor render condition, whereas clear_texture does
not. nv50 got it wrong, but I care a lot more when that wrongness is
moved to util. This could be fixed by making clear_render_target and
clear_depth_stencil optionally honor render condition (like blit does).
Though it seems a bit odd that everybody would implement this via util
and then clear_render_target/clear_depth_stencil, the whole reason
pipe->clear_texture exists in the first place is that you could clear
textures which you might not be able to render to (that is, couldn't use
clear_render_target/clear_depth_stencil), otherwise mesa/st should just
use util code directly and not bother with clear_texture...

Roland




Am 03.12.2015 um 10:44 schrieb Edward O'Callaghan:
> ARB_clear_texture is reasonably generic enough that it should
> be moved down to become part of the fallback mechanism of
> pipe->clear_texture.
> 
> Signed-off-by: Edward O'Callaghan <eocallaghan at alterapraxis.com>
> ---
>  src/gallium/auxiliary/util/u_surface.c          | 83 +++++++++++++++++++++++++
>  src/gallium/auxiliary/util/u_surface.h          |  6 ++
>  src/gallium/drivers/nouveau/nv50/nv50_surface.c | 67 +-------------------
>  3 files changed, 90 insertions(+), 66 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
> index 6aa44f9..e7ab175 100644
> --- a/src/gallium/auxiliary/util/u_surface.c
> +++ b/src/gallium/auxiliary/util/u_surface.c
> @@ -36,6 +36,7 @@
>  #include "pipe/p_screen.h"
>  #include "pipe/p_state.h"
>  
> +#include "util/u_math.h"
>  #include "util/u_format.h"
>  #include "util/u_inlines.h"
>  #include "util/u_rect.h"
> @@ -547,6 +548,88 @@ util_clear_depth_stencil(struct pipe_context *pipe,
>     }
>  }
>  
> +/**
> + * Fallback for pipe->clear_texture() function.
> + * clears a non-PIPE_BUFFER resource's specified level
> + * and bounding box with a clear value provided in that
> + * resource's native format.
> + *
> + * XXX sf->format = .. is problematic as hw need
> + * not nessarily support the format.
> + */
> +void
> +util_surface_clear_texture(struct pipe_context *pipe,
> +                           struct pipe_resource *res,
> +                           unsigned level,
> +                           const struct pipe_box *box,
> +                           const void *data)
> +{
> +   struct pipe_surface tmpl = {{0}}, *sf;
> +
> +   tmpl.format = res->format;
> +   tmpl.u.tex.first_layer = box->z;
> +   tmpl.u.tex.last_layer = box->z + box->depth - 1;
> +   tmpl.u.tex.level = level;
> +   sf = pipe->create_surface(pipe, res, &tmpl);
> +   if (!sf)
> +      return;
> +
> +   if (util_format_is_depth_or_stencil(res->format)) {
> +      float depth = 0;
> +      uint8_t stencil = 0;
> +      unsigned clear = 0;
> +      const struct util_format_description *desc =
> +         util_format_description(res->format);
> +
> +      if (util_format_has_depth(desc)) {
> +         clear |= PIPE_CLEAR_DEPTH;
> +         desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
> +      }
> +      if (util_format_has_stencil(desc)) {
> +         clear |= PIPE_CLEAR_STENCIL;
> +         desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
> +      }
> +      pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil,
> +                                box->x, box->y, box->width, box->height);
> +   } else {
> +      union pipe_color_union color;
> +
> +      switch (util_format_get_blocksizebits(res->format)) {
> +      case 128:
> +         sf->format = PIPE_FORMAT_R32G32B32A32_UINT;
> +         memcpy(&color.ui, data, 128 / 8);
> +         break;
> +      case 64:
> +         sf->format = PIPE_FORMAT_R32G32_UINT;
> +         memcpy(&color.ui, data, 64 / 8);
> +         memset(&color.ui[2], 0, 64 / 8);
> +         break;
> +      case 32:
> +         sf->format = PIPE_FORMAT_R32_UINT;
> +         memcpy(&color.ui, data, 32 / 8);
> +         memset(&color.ui[1], 0, 96 / 8);
> +         break;
> +      case 16:
> +         sf->format = PIPE_FORMAT_R16_UINT;
> +         color.ui[0] = util_cpu_to_le32(
> +            util_le16_to_cpu(*(unsigned short *)data));
> +         memset(&color.ui[1], 0, 96 / 8);
> +         break;
> +      case 8:
> +         sf->format = PIPE_FORMAT_R8_UINT;
> +         color.ui[0] = util_cpu_to_le32(*(unsigned char *)data);
> +         memset(&color.ui[1], 0, 96 / 8);
> +         break;
> +      default:
> +         assert(!"Unknown texel element size");
> +         return;
> +      }
> +
> +      pipe->clear_render_target(pipe, sf, &color,
> +                                box->x, box->y, box->width, box->height);
> +   }
> +   pipe->surface_destroy(pipe, sf);
> +}
>  
>  /* Return if the box is totally inside the resource.
>   */
> diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
> index bfd8f40..069a393 100644
> --- a/src/gallium/auxiliary/util/u_surface.h
> +++ b/src/gallium/auxiliary/util/u_surface.h
> @@ -97,6 +97,12 @@ util_clear_depth_stencil(struct pipe_context *pipe,
>                           unsigned stencil,
>                           unsigned dstx, unsigned dsty,
>                           unsigned width, unsigned height);
> +extern void
> +util_surface_clear_texture(struct pipe_context *pipe,
> +                           struct pipe_resource *res,
> +                           unsigned level,
> +                           const struct pipe_box *box,
> +                           const void *data);
>  
>  extern boolean
>  util_try_blit_via_copy_region(struct pipe_context *ctx,
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
> index 86be1b4..7980c9a 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
> @@ -27,7 +27,6 @@
>  #include "util/u_inlines.h"
>  #include "util/u_pack_color.h"
>  #include "util/u_format.h"
> -#include "util/u_math.h"
>  #include "util/u_surface.h"
>  
>  #include "tgsi/tgsi_ureg.h"
> @@ -446,71 +445,7 @@ nv50_clear_texture(struct pipe_context *pipe,
>                     const struct pipe_box *box,
>                     const void *data)
>  {
> -   struct pipe_surface tmpl = {{0}}, *sf;
> -
> -   tmpl.format = res->format;
> -   tmpl.u.tex.first_layer = box->z;
> -   tmpl.u.tex.last_layer = box->z + box->depth - 1;
> -   tmpl.u.tex.level = level;
> -   sf = pipe->create_surface(pipe, res, &tmpl);
> -   if (!sf)
> -      return;
> -
> -   if (util_format_is_depth_or_stencil(res->format)) {
> -      float depth = 0;
> -      uint8_t stencil = 0;
> -      unsigned clear = 0;
> -      const struct util_format_description *desc =
> -         util_format_description(res->format);
> -
> -      if (util_format_has_depth(desc)) {
> -         clear |= PIPE_CLEAR_DEPTH;
> -         desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
> -      }
> -      if (util_format_has_stencil(desc)) {
> -         clear |= PIPE_CLEAR_STENCIL;
> -         desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
> -      }
> -      pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil,
> -                                box->x, box->y, box->width, box->height);
> -   } else {
> -      union pipe_color_union color;
> -
> -      switch (util_format_get_blocksizebits(res->format)) {
> -      case 128:
> -         sf->format = PIPE_FORMAT_R32G32B32A32_UINT;
> -         memcpy(&color.ui, data, 128 / 8);
> -         break;
> -      case 64:
> -         sf->format = PIPE_FORMAT_R32G32_UINT;
> -         memcpy(&color.ui, data, 64 / 8);
> -         memset(&color.ui[2], 0, 64 / 8);
> -         break;
> -      case 32:
> -         sf->format = PIPE_FORMAT_R32_UINT;
> -         memcpy(&color.ui, data, 32 / 8);
> -         memset(&color.ui[1], 0, 96 / 8);
> -         break;
> -      case 16:
> -         sf->format = PIPE_FORMAT_R16_UINT;
> -         color.ui[0] = util_cpu_to_le32(
> -            util_le16_to_cpu(*(unsigned short *)data));
> -         memset(&color.ui[1], 0, 96 / 8);
> -         break;
> -      case 8:
> -         sf->format = PIPE_FORMAT_R8_UINT;
> -         color.ui[0] = util_cpu_to_le32(*(unsigned char *)data);
> -         memset(&color.ui[1], 0, 96 / 8);
> -         break;
> -      default:
> -         assert(!"Unknown texel element size");
> -         return;
> -      }
> -
> -      pipe->clear_render_target(pipe, sf, &color,
> -                                box->x, box->y, box->width, box->height);
> -   }
> -   pipe->surface_destroy(pipe, sf);
> +   util_surface_clear_texture(pipe, res, level, box, data);
>  }
>  
>  void
> 



More information about the mesa-dev mailing list