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