softpipe: expand quad pipeline to process >1 quad at a time
[mesa.git] / src / gallium / drivers / softpipe / sp_quad_alpha_test.c
index 7a42b08ef53f0895b8ae756dc3109698ba0bede1..3a282208b6b8a767a43c46fbef40cb41f934ab36 100644 (file)
@@ -4,82 +4,85 @@
  */
 
 #include "sp_context.h"
-#include "sp_headers.h"
 #include "sp_quad.h"
+#include "sp_quad_pipe.h"
 #include "pipe/p_defines.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
 
+#define ALPHATEST( FUNC, COMP )                                         \
+   static void                                                          \
+   alpha_test_quads_##FUNC( struct quad_stage *qs,                      \
+                           struct quad_header *quads[],                 \
+                           unsigned nr )                                \
+   {                                                                    \
+      const float ref = qs->softpipe->depth_stencil->alpha.ref_value;   \
+      const uint cbuf = 0; /* only output[0].alpha is tested */         \
+      unsigned pass_nr = 0;                                             \
+      unsigned i;                                                       \
+                                                                        \
+      for (i = 0; i < nr; i++) {                                        \
+         const float *aaaa = quads[i]->output.color[cbuf][3];           \
+         unsigned passMask = 0;                                         \
+                                                                        \
+         if (aaaa[0] COMP ref) passMask |= (1 << 0);                    \
+         if (aaaa[1] COMP ref) passMask |= (1 << 1);                    \
+         if (aaaa[2] COMP ref) passMask |= (1 << 2);                    \
+         if (aaaa[3] COMP ref) passMask |= (1 << 3);                    \
+                                                                        \
+         quads[i]->inout.mask &= passMask;                              \
+                                                                        \
+         if (quads[i]->inout.mask)                                      \
+            quads[pass_nr++] = quads[i];                                \
+      }                                                                 \
+                                                                        \
+      if (pass_nr)                                                      \
+         qs->next->run(qs->next, quads, pass_nr);                       \
+   }
+
+
+ALPHATEST( LESS,     < )
+ALPHATEST( EQUAL,    == )
+ALPHATEST( LEQUAL,   <= )
+ALPHATEST( GREATER,  > )
+ALPHATEST( NOTEQUAL, != )
+ALPHATEST( GEQUAL,   >= )
 
+
+/* XXX: Incorporate into shader using KILP.
+ */
 static void
-alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
+alpha_test_quad(struct quad_stage *qs, 
+                struct quad_header *quads[], 
+                unsigned nr)
 {
-   struct softpipe_context *softpipe = qs->softpipe;
-   const float ref = softpipe->depth_stencil->alpha.ref;
-   unsigned passMask = 0x0, j;
-   const uint cbuf = 0; /* only output[0].alpha is tested */
-   const float *aaaa = quad->outputs.color[cbuf][3];
-
-   switch (softpipe->depth_stencil->alpha.func) {
-   case PIPE_FUNC_NEVER:
-      quad->mask = 0x0;
-      break;
+   switch (qs->softpipe->depth_stencil->alpha.func) {
    case PIPE_FUNC_LESS:
-      /*
-       * If mask were an array [4] we could do this SIMD-style:
-       * passMask = (quad->outputs.color[0][3] <= vec4(ref));
-       */
-      for (j = 0; j < QUAD_SIZE; j++) {
-         if (aaaa[j] < ref) {
-            passMask |= (1 << j);
-         }
-      }
+      alpha_test_quads_LESS( qs, quads, nr );
       break;
    case PIPE_FUNC_EQUAL:
-      for (j = 0; j < QUAD_SIZE; j++) {
-         if (aaaa[j] == ref) {
-            passMask |= (1 << j);
-         }
-      }
+      alpha_test_quads_EQUAL( qs, quads, nr );
       break;
    case PIPE_FUNC_LEQUAL:
-      for (j = 0; j < QUAD_SIZE; j++) {
-         if (aaaa[j] <= ref) {
-            passMask |= (1 << j);
-         }
-      }
+      alpha_test_quads_LEQUAL( qs, quads, nr );
       break;
    case PIPE_FUNC_GREATER:
-      for (j = 0; j < QUAD_SIZE; j++) {
-         if (aaaa[j] > ref) {
-            passMask |= (1 << j);
-         }
-      }
+      alpha_test_quads_GREATER( qs, quads, nr );
       break;
    case PIPE_FUNC_NOTEQUAL:
-      for (j = 0; j < QUAD_SIZE; j++) {
-         if (aaaa[j] != ref) {
-            passMask |= (1 << j);
-         }
-      }
+      alpha_test_quads_NOTEQUAL( qs, quads, nr );
       break;
    case PIPE_FUNC_GEQUAL:
-      for (j = 0; j < QUAD_SIZE; j++) {
-         if (aaaa[j] >= ref) {
-            passMask |= (1 << j);
-         }
-      }
+      alpha_test_quads_GEQUAL( qs, quads, nr );
       break;
    case PIPE_FUNC_ALWAYS:
-      passMask = MASK_ALL;
+      assert(0); /* should be caught earlier */
+      qs->next->run(qs->next, quads, nr);
       break;
+   case PIPE_FUNC_NEVER:
    default:
-      assert(0);
+      assert(0); /* should be caught earlier */
+      return;
    }
-
-   quad->mask &= passMask;
-
-   if (quad->mask)
-      qs->next->run(qs->next, quad);
 }