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 <eocallag...@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 -- 2.5.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev