aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/softpipe/sp_quad_alpha_test.c')
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_alpha_test.c106
1 files changed, 55 insertions, 51 deletions
diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
index 0845bae0e68..3a282208b6b 100644
--- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
@@ -9,76 +9,80 @@
#include "pipe/p_defines.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_value;
- unsigned passMask = 0x0, j;
- const uint cbuf = 0; /* only output[0].alpha is tested */
- const float *aaaa = quad->output.color[cbuf][3];
-
- switch (softpipe->depth_stencil->alpha.func) {
- case PIPE_FUNC_NEVER:
- 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->inout.mask &= passMask;
-
- if (quad->inout.mask)
- qs->next->run(qs->next, quad);
}