[Mesa-dev] [PATCH 1/4] gallium/radeon: add clear_texture function

Ilia Mirkin imirkin at alum.mit.edu
Fri Apr 15 17:00:33 UTC 2016


On Fri, Apr 15, 2016 at 12:33 PM, Jakob Sinclair
<sinclair.jakob at openmailbox.org> wrote:
> This patch adds the needed function for ARB_clear_texture.
> The function itself is mostly based on the nouveau implementation.
>
> Signed-off-by: Jakob Sinclair <sinclair.jakob at openmailbox.org>
> ---
>  src/gallium/drivers/radeon/r600_texture.c | 72 +++++++++++++++++++++++++++++++
>  1 file changed, 72 insertions(+)
>
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 72af534..ee77a37 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -1392,6 +1392,77 @@ static void r600_surface_destroy(struct pipe_context *pipe,
>         FREE(surface);
>  }
>
> +static void r600_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);

Oh, and another thing -- clear_render_target and clear_depth_stencil
are supposed to obey the render condition, while clear texture is not.
This is an issue on nouveau as well, which I solved by making
clear_render_target/clear_depth_stencil do the wrong thing (and
ignoring the render condition). However that's not a great generic
solution.

  -ilia


More information about the mesa-dev mailing list