[Mesa-dev] [RFC 2/3] gallium: Move nv50 clear_texture impl down to util_surface

Edward O'Callaghan eocallaghan at alterapraxis.com
Thu Dec 3 01:44:17 PST 2015


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 <eocallaghan at 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



More information about the mesa-dev mailing list