Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> --- This isn't really for inclusion quite yet, but rather a demonstration. I'm pretty sure I've messed up at least some of the cases. It should all become more apparent once more piglit tests are available, testing more things.
[Among other things, I know I'm leaking the nv50_surface I create.] src/gallium/drivers/nouveau/nv50/nv50_surface.c | 78 +++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c index 6073deb..0302eda 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c @@ -27,6 +27,7 @@ #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" @@ -290,6 +291,12 @@ nv50_clear_render_target(struct pipe_context *pipe, BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2); + PUSH_DATA (push, width << 16); + PUSH_DATA (push, height << 16); + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, width << 16); + PUSH_DATA (push, height << 16); BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5); PUSH_DATAh(push, bo->offset + sf->offset); PUSH_DATA (push, bo->offset + sf->offset); @@ -393,6 +400,76 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, nv50->dirty |= NV50_NEW_FRAMEBUFFER; } +static void +nv50_clear_resource(struct pipe_context *pipe, + struct pipe_resource *res, + const struct pipe_box *box, + const void *data) +{ + struct nv50_miptree *mt = nv50_miptree(res); + struct nv50_surface *sf; + enum pipe_format dst_fmt; + union pipe_color_union color; + + assert(res->target != PIPE_BUFFER); + + switch (util_format_get_blocksizebits(res->format)) { + case 128: + dst_fmt = PIPE_FORMAT_R32G32B32A32_UINT; + memcpy(&color.ui, data, 128 / 8); + break; + case 64: + dst_fmt = PIPE_FORMAT_R32G32_UINT; + memcpy(&color.ui, data, 64 / 8); + memset(&color.ui[2], 0, 64 / 8); + break; + case 32: + dst_fmt = PIPE_FORMAT_R32_UINT; + memcpy(&color.ui, data, 32 / 8); + memset(&color.ui[1], 0, 96 / 8); + break; + case 16: + dst_fmt = 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: + dst_fmt = 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; + } + + sf = CALLOC_STRUCT(nv50_surface); + if (!sf) + return; + + pipe_reference_init(&sf->base.reference, 1); + pipe_resource_reference(&sf->base.texture, res); + + /* XXX check 3D textures vs *_ARRAY textures */ + /* XXX should I call nv50_miptree_surface_new? */ + sf->base.context = pipe; + sf->base.format = dst_fmt; + sf->base.writable = 1; + sf->base.u.tex.first_layer = box->z; + sf->base.u.tex.last_layer = box->z + box->depth; + sf->base.width = sf->width = res->width0 << mt->ms_x; + sf->base.height = sf->height = res->height0 << mt->ms_y; + sf->depth = MIN2(box->depth, MAX2(res->depth0, res->array_size)) - box->z; + if (mt->layout_3d) + sf->offset += nv50_mt_zslice_offset(mt, 0, box->z); + else + sf->offset += mt->layer_stride * box->z; + + nv50_clear_render_target(pipe, &sf->base, &color, + box->x, box->y, box->width, box->height); +} + void nv50_clear(struct pipe_context *pipe, unsigned buffers, const union pipe_color_union *color, @@ -1401,6 +1478,7 @@ nv50_init_surface_functions(struct nv50_context *nv50) pipe->resource_copy_region = nv50_resource_copy_region; pipe->blit = nv50_blit; pipe->flush_resource = nv50_flush_resource; + pipe->clear_resource = nv50_clear_resource; pipe->clear_render_target = nv50_clear_render_target; pipe->clear_depth_stencil = nv50_clear_depth_stencil; } -- 1.8.3.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev