[Mesa-dev] [RFC PATCH 4/4] nv50: provide a clear_resource implementation

Ilia Mirkin imirkin at alum.mit.edu
Thu Mar 6 22:41:18 PST 2014


Signed-off-by: Ilia Mirkin <imirkin at 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



More information about the mesa-dev mailing list