softpipe: expand quad pipeline to process >1 quad at a time
[mesa.git] / src / gallium / drivers / softpipe / sp_quad_alpha_test.c
1
2 /**
3 * quad alpha test
4 */
5
6 #include "sp_context.h"
7 #include "sp_quad.h"
8 #include "sp_quad_pipe.h"
9 #include "pipe/p_defines.h"
10 #include "util/u_memory.h"
11
12 #define ALPHATEST( FUNC, COMP ) \
13 static void \
14 alpha_test_quads_##FUNC( struct quad_stage *qs, \
15 struct quad_header *quads[], \
16 unsigned nr ) \
17 { \
18 const float ref = qs->softpipe->depth_stencil->alpha.ref_value; \
19 const uint cbuf = 0; /* only output[0].alpha is tested */ \
20 unsigned pass_nr = 0; \
21 unsigned i; \
22 \
23 for (i = 0; i < nr; i++) { \
24 const float *aaaa = quads[i]->output.color[cbuf][3]; \
25 unsigned passMask = 0; \
26 \
27 if (aaaa[0] COMP ref) passMask |= (1 << 0); \
28 if (aaaa[1] COMP ref) passMask |= (1 << 1); \
29 if (aaaa[2] COMP ref) passMask |= (1 << 2); \
30 if (aaaa[3] COMP ref) passMask |= (1 << 3); \
31 \
32 quads[i]->inout.mask &= passMask; \
33 \
34 if (quads[i]->inout.mask) \
35 quads[pass_nr++] = quads[i]; \
36 } \
37 \
38 if (pass_nr) \
39 qs->next->run(qs->next, quads, pass_nr); \
40 }
41
42
43 ALPHATEST( LESS, < )
44 ALPHATEST( EQUAL, == )
45 ALPHATEST( LEQUAL, <= )
46 ALPHATEST( GREATER, > )
47 ALPHATEST( NOTEQUAL, != )
48 ALPHATEST( GEQUAL, >= )
49
50
51 /* XXX: Incorporate into shader using KILP.
52 */
53 static void
54 alpha_test_quad(struct quad_stage *qs,
55 struct quad_header *quads[],
56 unsigned nr)
57 {
58 switch (qs->softpipe->depth_stencil->alpha.func) {
59 case PIPE_FUNC_LESS:
60 alpha_test_quads_LESS( qs, quads, nr );
61 break;
62 case PIPE_FUNC_EQUAL:
63 alpha_test_quads_EQUAL( qs, quads, nr );
64 break;
65 case PIPE_FUNC_LEQUAL:
66 alpha_test_quads_LEQUAL( qs, quads, nr );
67 break;
68 case PIPE_FUNC_GREATER:
69 alpha_test_quads_GREATER( qs, quads, nr );
70 break;
71 case PIPE_FUNC_NOTEQUAL:
72 alpha_test_quads_NOTEQUAL( qs, quads, nr );
73 break;
74 case PIPE_FUNC_GEQUAL:
75 alpha_test_quads_GEQUAL( qs, quads, nr );
76 break;
77 case PIPE_FUNC_ALWAYS:
78 assert(0); /* should be caught earlier */
79 qs->next->run(qs->next, quads, nr);
80 break;
81 case PIPE_FUNC_NEVER:
82 default:
83 assert(0); /* should be caught earlier */
84 return;
85 }
86 }
87
88
89 static void alpha_test_begin(struct quad_stage *qs)
90 {
91 qs->next->begin(qs->next);
92 }
93
94
95 static void alpha_test_destroy(struct quad_stage *qs)
96 {
97 FREE( qs );
98 }
99
100
101 struct quad_stage *
102 sp_quad_alpha_test_stage( struct softpipe_context *softpipe )
103 {
104 struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
105
106 stage->softpipe = softpipe;
107 stage->begin = alpha_test_begin;
108 stage->run = alpha_test_quad;
109 stage->destroy = alpha_test_destroy;
110
111 return stage;
112 }