Merge commit 'origin/gallium-master-merge'
[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_headers.h"
8 #include "sp_quad.h"
9 #include "pipe/p_defines.h"
10 #include "util/u_memory.h"
11
12
13 static void
14 alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
15 {
16 struct softpipe_context *softpipe = qs->softpipe;
17 const float ref = softpipe->depth_stencil->alpha.ref_value;
18 unsigned passMask = 0x0, j;
19 const uint cbuf = 0; /* only output[0].alpha is tested */
20 const float *aaaa = quad->output.color[cbuf][3];
21
22 switch (softpipe->depth_stencil->alpha.func) {
23 case PIPE_FUNC_NEVER:
24 break;
25 case PIPE_FUNC_LESS:
26 /*
27 * If mask were an array [4] we could do this SIMD-style:
28 * passMask = (quad->outputs.color[0][3] <= vec4(ref));
29 */
30 for (j = 0; j < QUAD_SIZE; j++) {
31 if (aaaa[j] < ref) {
32 passMask |= (1 << j);
33 }
34 }
35 break;
36 case PIPE_FUNC_EQUAL:
37 for (j = 0; j < QUAD_SIZE; j++) {
38 if (aaaa[j] == ref) {
39 passMask |= (1 << j);
40 }
41 }
42 break;
43 case PIPE_FUNC_LEQUAL:
44 for (j = 0; j < QUAD_SIZE; j++) {
45 if (aaaa[j] <= ref) {
46 passMask |= (1 << j);
47 }
48 }
49 break;
50 case PIPE_FUNC_GREATER:
51 for (j = 0; j < QUAD_SIZE; j++) {
52 if (aaaa[j] > ref) {
53 passMask |= (1 << j);
54 }
55 }
56 break;
57 case PIPE_FUNC_NOTEQUAL:
58 for (j = 0; j < QUAD_SIZE; j++) {
59 if (aaaa[j] != ref) {
60 passMask |= (1 << j);
61 }
62 }
63 break;
64 case PIPE_FUNC_GEQUAL:
65 for (j = 0; j < QUAD_SIZE; j++) {
66 if (aaaa[j] >= ref) {
67 passMask |= (1 << j);
68 }
69 }
70 break;
71 case PIPE_FUNC_ALWAYS:
72 passMask = MASK_ALL;
73 break;
74 default:
75 assert(0);
76 }
77
78 quad->inout.mask &= passMask;
79
80 if (quad->inout.mask)
81 qs->next->run(qs->next, quad);
82 }
83
84
85 static void alpha_test_begin(struct quad_stage *qs)
86 {
87 qs->next->begin(qs->next);
88 }
89
90
91 static void alpha_test_destroy(struct quad_stage *qs)
92 {
93 FREE( qs );
94 }
95
96
97 struct quad_stage *
98 sp_quad_alpha_test_stage( struct softpipe_context *softpipe )
99 {
100 struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
101
102 stage->softpipe = softpipe;
103 stage->begin = alpha_test_begin;
104 stage->run = alpha_test_quad;
105 stage->destroy = alpha_test_destroy;
106
107 return stage;
108 }