[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