Begin hooking up stenciling.
authorBrian <brian.paul@tungstengraphics.com>
Tue, 10 Jul 2007 22:37:18 +0000 (16:37 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Tue, 10 Jul 2007 22:37:18 +0000 (16:37 -0600)
src/mesa/pipe/softpipe/sp_context.c
src/mesa/pipe/softpipe/sp_context.h
src/mesa/pipe/softpipe/sp_quad.c
src/mesa/pipe/softpipe/sp_quad.h
src/mesa/pipe/softpipe/sp_quad_stencil.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state.h
src/mesa/pipe/softpipe/sp_state_blend.c
src/mesa/sources

index 9becab4918d752d4faa80a43d6aed2a199e0daac..6afc0c1320f5fceb3eac2d657014b83d6130d35b 100644 (file)
@@ -65,20 +65,21 @@ struct pipe_context *softpipe_create( void )
    struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
 
    softpipe->pipe.destroy = softpipe_destroy;
-   softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
    softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state;
-   softpipe->pipe.set_blend_state = softpipe_set_blend_state;
    softpipe->pipe.set_blend_color = softpipe_set_blend_color;
+   softpipe->pipe.set_blend_state = softpipe_set_blend_state;
    softpipe->pipe.set_clip_state = softpipe_set_clip_state;
    softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state;
    softpipe->pipe.set_depth_state = softpipe_set_depth_test_state;
-   softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
-   softpipe->pipe.set_setup_state = softpipe_set_setup_state;
-   softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
+   softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
    softpipe->pipe.set_fs_state = softpipe_set_fs_state;
    softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
    softpipe->pipe.set_sampler_state = softpipe_set_sampler_state;
+   softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
+   softpipe->pipe.set_setup_state = softpipe_set_setup_state;
+   softpipe->pipe.set_stencil_state = softpipe_set_stencil_state;
    softpipe->pipe.set_texture_state = softpipe_set_texture_state;
+   softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
    softpipe->pipe.draw_vb = softpipe_draw_vb;
    softpipe->pipe.clear = softpipe_clear;
 
index c6046624a191bb84a4213811c672bac973fc0a63..2379a99b81f867c1e9702e9d9ffa3e992ac20454 100644 (file)
@@ -63,6 +63,7 @@ enum interp_mode {
 #define SP_NEW_DEPTH_TEST  0x200
 #define SP_NEW_SAMPLER     0x400
 #define SP_NEW_TEXTURE     0x800
+#define SP_NEW_STENCIL    0x1000
 
 
 struct softpipe_context {     
@@ -82,6 +83,7 @@ struct softpipe_context {
    struct pipe_scissor_state scissor;
    struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
    struct pipe_setup_state setup;
+   struct pipe_stencil_state stencil;
    struct pipe_texture_object *texture[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    GLuint dirty;
@@ -117,6 +119,7 @@ struct softpipe_context {
    struct {
       struct quad_stage *shade;
       struct quad_stage *alpha_test;
+      struct quad_stage *stencil_test;
       struct quad_stage *depth_test;
       struct quad_stage *blend;
       struct quad_stage *output;
index 63126a4da38bc89115e182bb82d969715aace256..31278f529d78c5d209219586054da6455ae7f21c 100644 (file)
@@ -16,7 +16,12 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
       sp->quad.first = sp->quad.blend;
    }
 
-   if (sp->depth_test.enabled) {
+   if (   sp->stencil.front_enabled
+       || sp->stencil.front_enabled) {
+      sp->quad.stencil_test->next = sp->quad.first;
+      sp->quad.first = sp->quad.stencil_test;
+   }
+   else if (sp->depth_test.enabled) {
       sp->quad.depth_test->next = sp->quad.first;
       sp->quad.first = sp->quad.depth_test;
    }
index 79f52721a3f3352ddd3b31081741a905dabe6023..c09905c2498d541088b6202afd22ec3638503992 100644 (file)
@@ -48,6 +48,7 @@ struct quad_stage {
 
 struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );
 struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe );
 struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe );
 struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe );
 struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe );
diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c
new file mode 100644 (file)
index 0000000..9f59d09
--- /dev/null
@@ -0,0 +1,134 @@
+
+/**
+ * \brief Quad stencil testing
+ */
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+#include "pipe/p_defines.h"
+
+
+static void
+stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf);
+   GLuint bzzzz[QUAD_SIZE];  /**< Z values fetched from depth buffer */
+   GLuint qzzzz[QUAD_SIZE];  /**< Z values from the quad */
+   GLuint zmask = 0;
+   GLuint j;
+   GLfloat scale;
+
+   assert(sps); /* shouldn't get here if there's no zbuffer */
+
+   /*
+    * To increase efficiency, we should probably have multiple versions
+    * of this function that are specifically for Z16, Z32 and FP Z buffers.
+    * Try to effectively do that with codegen...
+    */
+   if (sps->surface.format == PIPE_FORMAT_U_Z16)
+      scale = 65535.0;
+   else
+      assert(0);  /* XXX fix this someday */
+
+   /*
+    * Convert quad's float depth values to int depth values.
+    * If the Z buffer stores integer values, we _have_ to do the depth
+    * compares with integers (not floats).  Otherwise, the float->int->float
+    * conversion of Z values (which isn't an identity function) will cause
+    * Z-fighting errors.
+    */
+   for (j = 0; j < QUAD_SIZE; j++) {
+      qzzzz[j] = (GLuint) (quad->outputs.depth[j] * scale);
+   }
+
+   /* get zquad from zbuffer */
+   sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz);
+
+   switch (softpipe->depth_test.func) {
+   case PIPE_FUNC_NEVER:
+      /* zmask = 0 */
+      break;
+   case PIPE_FUNC_LESS:
+      /* Note this is pretty much a single sse or cell instruction.  
+       * Like this:  quad->mask &= (quad->outputs.depth < zzzz);
+       */
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] < bzzzz[j]) 
+           zmask |= 1 << j;
+      }
+      break;
+   case PIPE_FUNC_EQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] == bzzzz[j]) 
+           zmask |= 1 << j;
+      }
+      break;
+   case PIPE_FUNC_LEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] <= bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_GREATER:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] > bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_NOTEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] != bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_GEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] >= bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_ALWAYS:
+      zmask = MASK_ALL;
+      break;
+   default:
+      abort();
+   }
+
+   quad->mask &= zmask;
+
+   if (softpipe->depth_test.writemask) {
+      
+      /* This is also efficient with sse / spe instructions: 
+       */
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (quad->mask & (1 << j)) {
+           bzzzz[j] = qzzzz[j];
+        }
+      }
+
+      /* write updated zquad to zbuffer */
+      sps->write_quad_z(sps, quad->x0, quad->y0, bzzzz);
+   }
+
+   if (quad->mask)
+      qs->next->run(qs->next, quad);
+}
+
+
+
+
+struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = stencil_test_quad;
+
+   return stage;
+}
index 38a212b79ad98eb1858353c2fa24cb9bc4650696..71c1a2d9ba0b87a23f880547bd9123e5635f1d06 100644 (file)
@@ -56,8 +56,14 @@ void softpipe_set_clip_state( struct pipe_context *,
 void softpipe_set_depth_test_state( struct pipe_context *,
                                     const struct pipe_depth_state * );
 
-void softpipe_set_viewport_state( struct pipe_context *,
-                                  const struct pipe_viewport_state * );
+void softpipe_set_fs_state( struct pipe_context *,
+                          const struct pipe_fs_state * );
+
+void softpipe_set_polygon_stipple( struct pipe_context *,
+                                 const struct pipe_poly_stipple * );
+
+void softpipe_set_scissor_state( struct pipe_context *,
+                                 const struct pipe_scissor_state * );
 
 void softpipe_set_setup_state( struct pipe_context *,
                              const struct pipe_setup_state * );
@@ -66,18 +72,15 @@ void softpipe_set_sampler_state( struct pipe_context *,
                                  GLuint unit,
                                  const struct pipe_sampler_state * );
 
+void softpipe_set_stencil_state( struct pipe_context *,
+                                 const struct pipe_stencil_state * );
+
 void softpipe_set_texture_state( struct pipe_context *,
                                  GLuint unit,
                                  struct pipe_texture_object * );
 
-void softpipe_set_scissor_state( struct pipe_context *,
-                                 const struct pipe_scissor_state * );
-
-void softpipe_set_fs_state( struct pipe_context *,
-                          const struct pipe_fs_state * );
-
-void softpipe_set_polygon_stipple( struct pipe_context *,
-                                 const struct pipe_poly_stipple * );
+void softpipe_set_viewport_state( struct pipe_context *,
+                                  const struct pipe_viewport_state * );
 
 void softpipe_update_derived( struct softpipe_context *softpipe );
 
index ae8950e386e5176e1db494ac443014cd4bd8feac..8bc22b0efc04c8443cf97560c93e091d184d71ef 100644 (file)
@@ -80,3 +80,14 @@ softpipe_set_alpha_test_state(struct pipe_context *pipe,
    softpipe->dirty |= SP_NEW_ALPHA_TEST;
 }
 
+void
+softpipe_set_stencil_state(struct pipe_context *pipe,
+                           const struct pipe_stencil_state *stencil)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->stencil = *stencil;
+
+   softpipe->dirty |= SP_NEW_STENCIL;
+}
+
index 5bef7606d4f94b77e9851fa001cf2df5892dcef7..1ffac8df0ab3e2c09d7ac59762f74e45bd799c20 100644 (file)
@@ -163,6 +163,7 @@ SOFTPIPE_SOURCES = \
        pipe/softpipe/sp_quad_depth_test.c \
        pipe/softpipe/sp_quad_fs.c \
        pipe/softpipe/sp_quad_output.c \
+       pipe/softpipe/sp_quad_stencil.c \
        pipe/softpipe/sp_state_blend.c \
        pipe/softpipe/sp_state_clip.c \
        pipe/softpipe/sp_state_derived.c \