Mesa (master): gallium: Clean up driver clear() interface.

Michel Dänzer daenzer at kemper.freedesktop.org
Sat Apr 4 17:02:21 UTC 2009


Module: Mesa
Branch: master
Commit: eb168e26aa63f11a47d70c4555cae30691a2cd57
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=eb168e26aa63f11a47d70c4555cae30691a2cd57

Author: Michel Dänzer <daenzer at vmware.com>
Date:   Sat Apr  4 19:01:51 2009 +0200

gallium: Clean up driver clear() interface.

Only allows clearing currently bound buffers, but colour and depth/stencil in
a single call.

---

 src/gallium/auxiliary/util/u_clear.h               |   60 +++++++
 src/gallium/auxiliary/util/u_pack_color.h          |   14 +-
 src/gallium/drivers/i915simple/i915_clear.c        |   13 +-
 src/gallium/drivers/i915simple/i915_context.h      |    4 +-
 src/gallium/drivers/nv10/nv10_clear.c              |    8 +-
 src/gallium/drivers/nv10/nv10_context.h            |    5 +-
 src/gallium/drivers/nv20/nv20_clear.c              |    8 +-
 src/gallium/drivers/nv20/nv20_context.h            |    4 +-
 src/gallium/drivers/nv30/nv30_clear.c              |    8 +-
 src/gallium/drivers/nv30/nv30_context.h            |    4 +-
 src/gallium/drivers/nv40/nv40_clear.c              |    8 +-
 src/gallium/drivers/nv40/nv40_context.h            |    4 +-
 src/gallium/drivers/nv50/nv50_context.h            |    4 +-
 src/gallium/drivers/softpipe/sp_clear.c            |   65 +++-----
 src/gallium/drivers/softpipe/sp_clear.h            |    4 +-
 src/gallium/drivers/trace/tr_context.c             |   21 ++-
 src/gallium/include/pipe/p_context.h               |   16 ++-
 src/gallium/include/pipe/p_defines.h               |    9 +
 src/gallium/state_trackers/g3dvl/vl_basic_csc.c    |    3 +-
 src/gallium/state_trackers/python/p_context.i      |   41 +----
 .../state_trackers/python/retrace/interpreter.py   |    4 +-
 src/gallium/state_trackers/python/samples/tri.py   |    8 +-
 .../tests/regress/vertex-shader/vertex-shader.py   |    7 +-
 .../state_trackers/python/tests/texture_render.py  |    7 +-
 .../state_trackers/python/tests/texture_sample.py  |    7 +-
 src/mesa/state_tracker/st_cb_clear.c               |  183 +++++++-------------
 26 files changed, 263 insertions(+), 256 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h
new file mode 100644
index 0000000..7c16b32
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_clear.h
@@ -0,0 +1,60 @@
+/**************************************************************************
+ * 
+ * Copyright 2009 VMware, Inc.  All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:
+ *    Michel Dänzer
+ */
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_pack_color.h"
+
+
+/**
+ * Clear the given buffers to the specified values.
+ * No masking, no scissor (clear entire buffer).
+ */
+static INLINE void
+util_clear(struct pipe_context *pipe,
+           struct pipe_framebuffer_state *framebuffer, unsigned buffers,
+           const float *rgba, double depth, unsigned stencil)
+{
+   if (buffers & PIPE_CLEAR_COLOR) {
+      struct pipe_surface *ps = framebuffer->cbufs[0];
+      unsigned color;
+
+      util_pack_color(rgba, ps->format, &color);
+      pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color);
+   }
+
+   if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+      struct pipe_surface *ps = framebuffer->zsbuf;
+
+      pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height,
+                         util_pack_z_stencil(ps->format, depth, stencil));
+   }
+}
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index e05d032..4ec7aee 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -448,17 +448,19 @@ util_pack_z(enum pipe_format format, double z)
 static INLINE uint
 util_pack_z_stencil(enum pipe_format format, double z, uint s)
 {
+   unsigned packed = util_pack_z(format, z);
+
    switch (format) {
    case PIPE_FORMAT_S8Z24_UNORM:
-      return util_pack_z(format, z) | s << 24;
+      packed |= s << 24;
+      break;
    case PIPE_FORMAT_Z24S8_UNORM:
-      return util_pack_z(format, z) | s;
+      packed |= s;
    default:
-      debug_print_format("gallium: unhandled format in util_pack_z_stencil()",
-                         format);
-      assert(0);
-      return 0;
+      break;
    }
+
+   return packed;
 }
 
 
diff --git a/src/gallium/drivers/i915simple/i915_clear.c b/src/gallium/drivers/i915simple/i915_clear.c
index cde69da..90530f2 100644
--- a/src/gallium/drivers/i915simple/i915_clear.c
+++ b/src/gallium/drivers/i915simple/i915_clear.c
@@ -25,23 +25,24 @@
  * 
  **************************************************************************/
 
-/* Author:
+/* Authors:
  *    Brian Paul
  */
 
 
-#include "pipe/p_defines.h"
+#include "util/u_clear.h"
 #include "i915_context.h"
 #include "i915_state.h"
 
 
 /**
- * Clear the given surface to the specified value.
+ * Clear the given buffers to the specified values.
  * No masking, no scissor (clear entire buffer).
  */
 void
-i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-	   unsigned clearValue)
+i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+	   double depth, unsigned stencil)
 {
-   pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
+   util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth,
+              stencil);
 }
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h
index 3cdabe4..b6983ba 100644
--- a/src/gallium/drivers/i915simple/i915_context.h
+++ b/src/gallium/drivers/i915simple/i915_context.h
@@ -314,8 +314,8 @@ void i915_emit_hardware_state(struct i915_context *i915 );
 /***********************************************************************
  * i915_clear.c: 
  */
-void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-		unsigned clearValue);
+void i915_clear( struct pipe_context *pipe, unsigned buffers, const float *rgba,
+                 double depth, unsigned stencil);
 
 
 /***********************************************************************
diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c
index be7e09c..a39a2b5 100644
--- a/src/gallium/drivers/nv10/nv10_clear.c
+++ b/src/gallium/drivers/nv10/nv10_clear.c
@@ -1,12 +1,14 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
+#include "util/u_clear.h"
 
 #include "nv10_context.h"
 
 void
-nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-	   unsigned clearValue)
+nv10_clear(struct pipe_context *pipe, unsigned buffers,
+           const float *rgba, double depth, unsigned stencil)
 {
-	pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
+	util_clear(pipe, nv10_context(pipe)->framebuffer, buffers, rgba, depth,
+		   stencil);
 }
diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h
index f3b56de..f1e003c 100644
--- a/src/gallium/drivers/nv10/nv10_context.h
+++ b/src/gallium/drivers/nv10/nv10_context.h
@@ -118,8 +118,9 @@ extern void nv10_init_surface_functions(struct nv10_context *nv10);
 extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen);
 
 /* nv10_clear.c */
-extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-		       unsigned clearValue);
+extern void nv10_clear(struct pipe_context *pipe, unsigned buffers,
+		       const float *rgba, double depth, unsigned stencil);
+
 
 /* nv10_draw.c */
 extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10);
diff --git a/src/gallium/drivers/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c
index 81b6f3e..2b4490f 100644
--- a/src/gallium/drivers/nv20/nv20_clear.c
+++ b/src/gallium/drivers/nv20/nv20_clear.c
@@ -1,12 +1,14 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
+#include "util/u_clear.h"
 
 #include "nv20_context.h"
 
 void
-nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-	   unsigned clearValue)
+nv20_clear(struct pipe_context *pipe, unsigned buffers,
+           const float *rgba, double depth, unsigned stencil)
 {
-	pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
+	util_clear(pipe, nv20_context(pipe)->framebuffer, buffers, rgba, depth,
+		   stencil);
 }
diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h
index 8ad926d..fc932f1 100644
--- a/src/gallium/drivers/nv20/nv20_context.h
+++ b/src/gallium/drivers/nv20/nv20_context.h
@@ -118,8 +118,8 @@ extern void nv20_init_surface_functions(struct nv20_context *nv20);
 extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen);
 
 /* nv20_clear.c */
-extern void nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-		       unsigned clearValue);
+extern void nv20_clear(struct pipe_context *pipe, unsigned buffers,
+		       const float *rgba, double depth, unsigned stencil);
 
 /* nv20_draw.c */
 extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20);
diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c
index 71f4135..c4ba926 100644
--- a/src/gallium/drivers/nv30/nv30_clear.c
+++ b/src/gallium/drivers/nv30/nv30_clear.c
@@ -1,12 +1,14 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
+#include "util/u_clear.h"
 
 #include "nv30_context.h"
 
 void
-nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-	   unsigned clearValue)
+nv30_clear(struct pipe_context *pipe, unsigned buffers,
+           const float *rgba, double depth, unsigned stencil)
 {
-	pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
+	util_clear(pipe, &nv30_context(pipe)->framebuffer, buffers, rgba, depth,
+		   stencil);
 }
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
index b933769..4229c0a 100644
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ b/src/gallium/drivers/nv30/nv30_context.h
@@ -206,7 +206,7 @@ extern boolean nv30_draw_elements(struct pipe_context *pipe,
 				  unsigned count);
 
 /* nv30_clear.c */
-extern void nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-		       unsigned clearValue);
+extern void nv30_clear(struct pipe_context *pipe, unsigned buffers,
+		       const float *rgba, double depth, unsigned stencil);
 
 #endif
diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c
index 2c4e8f0..ddf13ad 100644
--- a/src/gallium/drivers/nv40/nv40_clear.c
+++ b/src/gallium/drivers/nv40/nv40_clear.c
@@ -1,12 +1,14 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
+#include "util/u_clear.h"
 
 #include "nv40_context.h"
 
 void
-nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-	   unsigned clearValue)
+nv40_clear(struct pipe_context *pipe, unsigned buffers,
+           const float *rgba, double depth, unsigned stencil)
 {
-	pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
+	util_clear(pipe, &nv40_context(pipe)->framebuffer, buffers, rgba, depth,
+		   stencil);
 }
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index adcfbdd..97bc832 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -227,7 +227,7 @@ extern boolean nv40_draw_elements(struct pipe_context *pipe,
 				  unsigned count);
 
 /* nv40_clear.c */
-extern void nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-		       unsigned clearValue);
+extern void nv40_clear(struct pipe_context *pipe, unsigned buffers,
+		       const float *rgba, double depth, unsigned stencil);
 
 #endif
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 313e435..7b67a75 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -184,8 +184,8 @@ extern boolean nv50_draw_elements(struct pipe_context *pipe,
 extern void nv50_vbo_validate(struct nv50_context *nv50);
 
 /* nv50_clear.c */
-extern void nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-		       unsigned clearValue);
+extern void nv50_clear(struct pipe_context *pipe, unsigned buffers,
+		       const float *rgba, double depth, unsigned stencil);
 
 /* nv50_program.c */
 extern void nv50_vertprog_validate(struct nv50_context *nv50);
diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c
index a60c6c4..f72c6c6 100644
--- a/src/gallium/drivers/softpipe/sp_clear.c
+++ b/src/gallium/drivers/softpipe/sp_clear.c
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2009 VMware, Inc.  All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -27,6 +28,7 @@
 
 /* Author:
  *    Brian Paul
+ *    Michel Dänzer
  */
 
 
@@ -40,34 +42,15 @@
 
 
 /**
- * Convert packed pixel from one format to another.
- */
-static unsigned
-convert_color(enum pipe_format srcFormat, unsigned srcColor,
-              enum pipe_format dstFormat)
-{
-   ubyte r, g, b, a;
-   unsigned dstColor;
-
-   util_unpack_color_ub(srcFormat, &srcColor, &r, &g, &b, &a);
-   util_pack_color_ub(r, g, b, a, dstFormat, &dstColor);
-
-   return dstColor;
-}
-
-
-
-/**
- * Clear the given surface to the specified value.
+ * Clear the given buffers to the specified values.
  * No masking, no scissor (clear entire buffer).
- * Note: when clearing a color buffer, the clearValue is always
- * encoded as PIPE_FORMAT_A8R8G8B8_UNORM.
  */
 void
-softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-               unsigned clearValue)
+softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+               double depth, unsigned stencil)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
+   unsigned cv;
    uint i;
 
    if (softpipe->no_rast)
@@ -77,29 +60,29 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
    softpipe_update_derived(softpipe); /* not needed?? */
 #endif
 
-   if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) {
-      sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue);
-#if TILE_CLEAR_OPTIMIZATION
-      return;
-#endif
-   }
+   if (buffers & PIPE_CLEAR_COLOR) {
+      for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
+         struct pipe_surface *ps = softpipe->framebuffer.cbufs[i];
 
-   for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
-      if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) {
-         unsigned cv;
-         if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) {
-            cv = convert_color(PIPE_FORMAT_A8R8G8B8_UNORM, clearValue,
-                               ps->format);
-         }
-         else {
-            cv = clearValue;
-         }
+         util_pack_color(rgba, ps->format, &cv);
          sp_tile_cache_clear(softpipe->cbuf_cache[i], cv);
+
+#if !TILE_CLEAR_OPTIMIZATION
+         /* non-cached surface */
+         pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv);
+#endif
       }
    }
 
+   if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+      struct pipe_surface *ps = softpipe->framebuffer.zsbuf;
+
+      cv = util_pack_z_stencil(ps->format, depth, stencil);
+      sp_tile_cache_clear(softpipe->zsbuf_cache, cv);
+
 #if !TILE_CLEAR_OPTIMIZATION
-   /* non-cached surface */
-   pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
+      /* non-cached surface */
+      pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv);
 #endif
+      }
 }
diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h
index a8ed1c4..2e45067 100644
--- a/src/gallium/drivers/softpipe/sp_clear.h
+++ b/src/gallium/drivers/softpipe/sp_clear.h
@@ -36,8 +36,8 @@
 struct pipe_context;
 
 extern void
-softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-               unsigned clearValue);
+softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+               double depth, unsigned stencil);
 
 
 #endif /* SP_CLEAR_H */
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index b69ed2c..6e86a5d 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -973,21 +973,26 @@ trace_context_surface_fill(struct pipe_context *_pipe,
 
 static INLINE void
 trace_context_clear(struct pipe_context *_pipe,
-                    struct pipe_surface *surface,
-                    unsigned clearValue)
+                    unsigned surfaces,
+                    const float *rgba,
+                    double depth,
+                    unsigned stencil)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
 
-   surface = trace_surface_unwrap(tr_ctx, surface);
-
    trace_dump_call_begin("pipe_context", "clear");
 
    trace_dump_arg(ptr, pipe);
-   trace_dump_arg(ptr, surface);
-   trace_dump_arg(uint, clearValue);
-
-   pipe->clear(pipe, surface, clearValue);;
+   trace_dump_arg(uint, surfaces);
+   trace_dump_arg(float, rgba[0]);
+   trace_dump_arg(float, rgba[1]);
+   trace_dump_arg(float, rgba[2]);
+   trace_dump_arg(float, rgba[3]);
+   trace_dump_arg(float, depth);
+   trace_dump_arg(uint, stencil);
+
+   pipe->clear(pipe, surfaces, rgba, depth, stencil);
 
    trace_dump_call_end();
 }
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 2452bf3..29095dc 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -205,12 +205,20 @@ struct pipe_context {
 			unsigned dstx, unsigned dsty,
 			unsigned width, unsigned height,
 			unsigned value);
-
-   void (*clear)(struct pipe_context *pipe, 
-		 struct pipe_surface *ps,
-		 unsigned clearValue);
    /*@}*/
 
+   /**
+    * Clear the specified set of currently bound buffers to specified values.
+    *
+    * buffers is a bitfield of PIPE_CLEAR_* values.
+    *
+    * rgba is a pointer to an array of one float for each of r, g, b, a.
+    */
+   void (*clear)(struct pipe_context *pipe,
+                 unsigned buffers,
+		 const float *rgba,
+                 double depth,
+		 unsigned stencil);
 
    /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */
    void (*flush)( struct pipe_context *pipe,
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 8e4f253..81defa4 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -186,6 +186,15 @@ enum pipe_texture_target {
 
 
 /**
+ * Clear buffer bits
+ */
+/** All color buffers currently bound */
+#define PIPE_CLEAR_COLOR        (1 << 0)
+/** Depth/stencil combined */
+#define PIPE_CLEAR_DEPTHSTENCIL (1 << 1)
+
+
+/**
  * Transfer object usage flags
  */
 enum pipe_transfer_usage {
diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
index b61b49a..16d4f1e 100644
--- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
+++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
@@ -98,7 +98,8 @@ static int vlResizeFrameBuffer
 	);
 
 	/* Clear to black, in case video doesn't fill the entire window */
-	pipe->clear(pipe, basic_csc->framebuffer.cbufs[0], 0);
+	pipe->set_framebuffer_state(pipe, &basic_csc->framebuffer);
+	pipe->clear(pipe, PIPE_CLEAR_COLOR, 0, 0.0f, 0);
 
 	return 0;
 }
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index a0bf063..9a3003a 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -308,45 +308,10 @@ error1:
       pipe_surface_reference(&_dst, NULL);
    }
 
-   void surface_clear(struct st_surface *surface, unsigned value = 0) 
+   void clear(unsigned buffers, const float *rgba, double depth = 0.0f,
+              unsigned stencil = 0)
    {
-      unsigned i;
-      struct pipe_surface *_surface = NULL;
- 
-      if(!surface)
-          SWIG_exception(SWIG_TypeError, "surface must not be null");
-  
-      for(i = 0; i < $self->framebuffer.nr_cbufs; ++i) {
-         struct pipe_surface *cbuf = $self->framebuffer.cbufs[i];
-         if(cbuf) {
-            if(cbuf->texture == surface->texture &&
-               cbuf->face == surface->face &&
-               cbuf->level == surface->level &&
-               cbuf->zslice == surface->zslice) {                  
-               _surface = cbuf;
-               break;
-            }
-         }
-      }
-
-      if(!_surface) {
-         struct pipe_surface *zsbuf = $self->framebuffer.zsbuf;
-         if(zsbuf) {
-            if(zsbuf->texture == surface->texture &&
-               zsbuf->face == surface->face &&
-               zsbuf->level == surface->level &&
-               zsbuf->zslice == surface->zslice) {                  
-               _surface = zsbuf;
-            }
-         }
-      }
-
-      if(!_surface)
-         SWIG_exception(SWIG_ValueError, "surface not bound");
-      
-      $self->pipe->clear($self->pipe, _surface, value);
-   fail:
-      return;
+      $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil);
    }
 
 };
diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py
index 510adcc..d020993 100755
--- a/src/gallium/state_trackers/python/retrace/interpreter.py
+++ b/src/gallium/state_trackers/python/retrace/interpreter.py
@@ -531,8 +531,8 @@ class Context(Object):
             self.dirty = False
         return None
 
-    def clear(self, surface, value):
-        self.real.surface_clear(surface, value)
+    def clear(self, buffers, rgba, depth, stencil):
+        self.real.clear(buffers, rgba, depth, stencil)
         
     def _present(self):
         self.real.flush()
diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py
index 4c84d12..4b96598 100644
--- a/src/gallium/state_trackers/python/samples/tri.py
+++ b/src/gallium/state_trackers/python/samples/tri.py
@@ -150,8 +150,12 @@ def test(dev):
     fb.set_cbuf(0, cbuf)
     fb.set_zsbuf(zbuf)
     ctx.set_framebuffer(fb)
-    ctx.surface_clear(cbuf, 0x00000000)
-    ctx.surface_clear(zbuf, 0xffffffff)
+    rgba = FloatArray(4);
+    rgba[0] = 0.0
+    rgba[1] = 0.0
+    rgba[2] = 0.0
+    rgba[3] = 0.0
+    ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff)
     
     # vertex shader
     vs = Shader('''
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
index 434ac9b..472769f 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
@@ -122,7 +122,12 @@ def test(dev, name):
     fb.nr_cbufs = 1
     fb.set_cbuf(0, cbuf)
     ctx.set_framebuffer(fb)
-    ctx.surface_clear(cbuf, 0x80808080)
+    rgba = FloatArray(4);
+    rgba[0] = 0.5
+    rgba[1] = 0.5
+    rgba[2] = 0.5
+    rgba[3] = 0.5
+    ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0)
 
     # vertex shader
     vs = Shader(file('vert-' + name + '.sh', 'rt').read())
diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py
index 580bf65..0b76932 100755
--- a/src/gallium/state_trackers/python/tests/texture_render.py
+++ b/src/gallium/state_trackers/python/tests/texture_render.py
@@ -161,7 +161,12 @@ class TextureTest(TestCase):
         fb.nr_cbufs = 1
         fb.set_cbuf(0, dst_surface)
         ctx.set_framebuffer(fb)
-        ctx.surface_clear(dst_surface, 0x00000000)
+        rgba = FloatArray(4);
+        rgba[0] = 0.0
+        rgba[1] = 0.0
+        rgba[2] = 0.0
+        rgba[3] = 0.0
+        ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0)
         del fb
     
         # vertex shader
diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py
index f5f49f6..a382424 100755
--- a/src/gallium/state_trackers/python/tests/texture_sample.py
+++ b/src/gallium/state_trackers/python/tests/texture_sample.py
@@ -206,7 +206,12 @@ class TextureTest(TestCase):
         fb.nr_cbufs = 1
         fb.set_cbuf(0, cbuf)
         ctx.set_framebuffer(fb)
-        ctx.surface_clear(cbuf, 0x00000000)
+        rgba = FloatArray(4);
+        rgba[0] = 0.5
+        rgba[1] = 0.5
+        rgba[2] = 0.5
+        rgba[3] = 0.5
+        ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0)
         del fb
     
         # vertex shader
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index bec32db..5bdc6a1 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2009 VMware, Inc.  All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -29,6 +30,7 @@
   * Authors:
   *   Keith Whitwell <keith at tungstengraphics.com>
   *   Brian Paul
+  *   Michel Dänzer
   */
 
 #include "main/glheader.h"
@@ -373,101 +375,6 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
 
 
 
-static void
-clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
-{
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-
-   if (!strb->surface)
-      return;
-
-   if (check_clear_color_with_quad( ctx, rb )) {
-      /* masking or scissoring */
-      clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE);
-   }
-   else {
-      /* clear whole buffer w/out masking */
-      uint clearValue;
-      /* NOTE: we always pass the clear color as PIPE_FORMAT_A8R8G8B8_UNORM
-       * at this time!
-       */
-      util_pack_color(ctx->Color.ClearColor, PIPE_FORMAT_A8R8G8B8_UNORM, &clearValue);
-      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
-   }
-}
-
-
-static void
-clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
-{
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-
-   if (!strb->surface)
-      return;
-
-   if (check_clear_depth_with_quad(ctx, rb)) {
-      /* scissoring or we have a combined depth/stencil buffer */
-      clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_FALSE);
-   }
-   else {
-      /* simple clear of whole buffer */
-      uint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear);
-      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
-   }
-}
-
-
-static void
-clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
-{
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-
-   if (!strb->surface)
-      return;
-
-   if (check_clear_stencil_with_quad(ctx, rb)) {
-      /* masking or scissoring or combined depth/stencil buffer */
-      clear_with_quad(ctx, GL_FALSE, GL_FALSE, GL_TRUE);
-   }
-   else {
-      /* simple clear of whole buffer */
-      GLuint clearValue = ctx->Stencil.Clear;
-
-      switch (strb->surface->format) {
-      case PIPE_FORMAT_S8Z24_UNORM:
-         clearValue <<= 24;
-         break;
-      default:
-         ; /* no-op, stencil value is in least significant bits */
-      }  
-
-      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
-   }
-}
-
-
-static void
-clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
-{
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-
-   if (!strb->surface)
-      return;
-
-   if (check_clear_depth_stencil_with_quad(ctx, rb)) {
-      /* masking or scissoring */
-      clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE);
-   }
-   else {
-      /* clear whole buffer w/out masking */
-      GLuint clearValue = util_pack_z_stencil(strb->surface->format,
-                                              ctx->Depth.Clear,
-                                              ctx->Stencil.Clear);
-      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
-   }
-}
-
-
 void st_flush_clear( struct st_context *st )
 {
    /* Release vertex buffer to avoid synchronous rendering if we were
@@ -493,51 +400,89 @@ static void st_clear(GLcontext *ctx, GLbitfield mask)
       = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
    struct gl_renderbuffer *stencilRb
       = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
-   GLbitfield cmask = mask & BUFFER_BITS_COLOR;
+   GLbitfield quad_buffers = 0;
+   GLbitfield clear_buffers = 0;
+   GLuint i;
 
-   /* This makes sure the softpipe has the latest scissor, etc values */
+   /* This makes sure the pipe has the latest scissor, etc values */
    st_validate_state( st );
 
-   /*
-    * XXX TO-DO:
-    * If we're going to use clear_with_quad() for any reason, use it to
-    * clear as many other buffers as possible.
-    * As it is now, we sometimes call clear_with_quad() three times to clear
-    * color/depth/stencil individually...
-    */
+   if (mask & BUFFER_BITS_COLOR) {
+      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+         GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
 
-   if (cmask) {
-      GLuint b;
-      for (b = 0; cmask; b++) {
-         if (cmask & (1 << b)) {
+         if (mask & (1 << b)) {
             struct gl_renderbuffer *rb
                = ctx->DrawBuffer->Attachment[b].Renderbuffer;
+            struct st_renderbuffer *strb;
+
             assert(rb);
-            clear_color_buffer(ctx, rb);
-            cmask &= ~(1 << b); /* turn off bit */
+
+            strb = st_renderbuffer(rb);
+
+            if (!strb->surface)
+               continue;
+
+            if (check_clear_color_with_quad( ctx, rb ))
+               quad_buffers |= PIPE_CLEAR_COLOR;
+            else
+               clear_buffers |= PIPE_CLEAR_COLOR;
          }
-         assert(b < BUFFER_COUNT);
       }
    }
 
-   if (mask & BUFFER_BIT_ACCUM) {
-      st_clear_accum_buffer(ctx,
-                       ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
-   }
-
    if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
       /* clearing combined depth + stencil */
-      clear_depth_stencil_buffer(ctx, depthRb);
+      struct st_renderbuffer *strb = st_renderbuffer(depthRb);
+
+      if (strb->surface) {
+         if (check_clear_depth_stencil_with_quad(ctx, depthRb))
+            quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+         else
+            clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+      }
    }
    else {
       /* separate depth/stencil clears */
       if (mask & BUFFER_BIT_DEPTH) {
-         clear_depth_buffer(ctx, depthRb);
+         struct st_renderbuffer *strb = st_renderbuffer(depthRb);
+
+         if (strb->surface) {
+            if (check_clear_depth_with_quad(ctx, depthRb))
+               quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+            else
+               clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+         }
       }
       if (mask & BUFFER_BIT_STENCIL) {
-         clear_stencil_buffer(ctx, stencilRb);
+         struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
+
+         if (strb->surface) {
+            if (check_clear_stencil_with_quad(ctx, stencilRb))
+               quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+            else
+               clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+         }
       }
    }
+
+   /*
+    * If we're going to use clear_with_quad() for any reason, use it for
+    * everything possible.
+    */
+   if (quad_buffers) {
+      quad_buffers |= clear_buffers;
+      clear_with_quad(ctx,
+                      quad_buffers & PIPE_CLEAR_COLOR,
+                      mask & BUFFER_BIT_DEPTH,
+                      mask & BUFFER_BIT_STENCIL);
+   } else if (clear_buffers)
+      ctx->st->pipe->clear(ctx->st->pipe, clear_buffers, ctx->Color.ClearColor,
+                           ctx->Depth.Clear, ctx->Stencil.Clear);
+
+   if (mask & BUFFER_BIT_ACCUM)
+      st_clear_accum_buffer(ctx,
+                            ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
 }
 
 




More information about the mesa-commit mailing list