On Fri, Apr 15, 2016 at 12:33 PM, Jakob Sinclair <[email protected]> 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 <[email protected]> > --- > 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 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
