Make _SAT instructions compile correctly.
[mesa.git] / src / mesa / swrast / s_alpha.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 4.1
5 *
6 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file swrast/s_alpha.c
28 * \brief Functions to apply alpha test.
29 */
30
31 #include "glheader.h"
32 #include "context.h"
33 #include "colormac.h"
34 #include "macros.h"
35
36 #include "s_alpha.h"
37 #include "s_context.h"
38
39
40 /**
41 * \fn GLint _swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
42 * \brief Apply the alpha test to a span of pixels.
43 * \return
44 * - "0" = all pixels in the span failed the alpha test.
45 * - "1" = one or more pixels passed the alpha test.
46 */
47 GLint
48 _swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
49 {
50 const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
51 GLchan ref;
52 const GLuint n = span->end;
53 GLubyte *mask = span->array->mask;
54 GLuint i;
55
56 CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);
57
58 if (span->arrayMask & SPAN_RGBA) {
59 /* Use the array values */
60 switch (ctx->Color.AlphaFunc) {
61 case GL_LESS:
62 for (i = 0; i < n; i++)
63 mask[i] &= (rgba[i][ACOMP] < ref);
64 break;
65 case GL_LEQUAL:
66 for (i = 0; i < n; i++)
67 mask[i] &= (rgba[i][ACOMP] <= ref);
68 break;
69 case GL_GEQUAL:
70 for (i = 0; i < n; i++)
71 mask[i] &= (rgba[i][ACOMP] >= ref);
72 break;
73 case GL_GREATER:
74 for (i = 0; i < n; i++)
75 mask[i] &= (rgba[i][ACOMP] > ref);
76 break;
77 case GL_NOTEQUAL:
78 for (i = 0; i < n; i++)
79 mask[i] &= (rgba[i][ACOMP] != ref);
80 break;
81 case GL_EQUAL:
82 for (i = 0; i < n; i++)
83 mask[i] &= (rgba[i][ACOMP] == ref);
84 break;
85 case GL_ALWAYS:
86 /* do nothing */
87 return 1;
88 case GL_NEVER:
89 /* caller should check for zero! */
90 span->writeAll = GL_FALSE;
91 return 0;
92 default:
93 _mesa_problem( ctx, "Invalid alpha test in _swrast_alpha_test" );
94 return 0;
95 }
96 }
97 else {
98 /* Use the interpolation values */
99 #if CHAN_TYPE == GL_FLOAT
100 const GLfloat alphaStep = span->alphaStep;
101 GLfloat alpha = span->alpha;
102 ASSERT(span->interpMask & SPAN_RGBA);
103 switch (ctx->Color.AlphaFunc) {
104 case GL_LESS:
105 for (i = 0; i < n; i++) {
106 mask[i] &= (alpha < ref);
107 alpha += alphaStep;
108 }
109 break;
110 case GL_LEQUAL:
111 for (i = 0; i < n; i++) {
112 mask[i] &= (alpha <= ref);
113 alpha += alphaStep;
114 }
115 break;
116 case GL_GEQUAL:
117 for (i = 0; i < n; i++) {
118 mask[i] &= (alpha >= ref);
119 alpha += alphaStep;
120 }
121 break;
122 case GL_GREATER:
123 for (i = 0; i < n; i++) {
124 mask[i] &= (alpha > ref);
125 alpha += alphaStep;
126 }
127 break;
128 case GL_NOTEQUAL:
129 for (i = 0; i < n; i++) {
130 mask[i] &= (alpha != ref);
131 alpha += alphaStep;
132 }
133 break;
134 case GL_EQUAL:
135 for (i = 0; i < n; i++) {
136 mask[i] &= (alpha == ref);
137 alpha += alphaStep;
138 }
139 break;
140 case GL_ALWAYS:
141 /* do nothing */
142 return 1;
143 case GL_NEVER:
144 /* caller should check for zero! */
145 span->writeAll = GL_FALSE;
146 return 0;
147 default:
148 _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
149 return 0;
150 }
151 #else
152 /* 8 or 16-bit channel interpolation */
153 const GLfixed alphaStep = span->alphaStep;
154 GLfixed alpha = span->alpha;
155 ASSERT(span->interpMask & SPAN_RGBA);
156 switch (ctx->Color.AlphaFunc) {
157 case GL_LESS:
158 for (i = 0; i < n; i++) {
159 mask[i] &= (FixedToChan(alpha) < ref);
160 alpha += alphaStep;
161 }
162 break;
163 case GL_LEQUAL:
164 for (i = 0; i < n; i++) {
165 mask[i] &= (FixedToChan(alpha) <= ref);
166 alpha += alphaStep;
167 }
168 break;
169 case GL_GEQUAL:
170 for (i = 0; i < n; i++) {
171 mask[i] &= (FixedToChan(alpha) >= ref);
172 alpha += alphaStep;
173 }
174 break;
175 case GL_GREATER:
176 for (i = 0; i < n; i++) {
177 mask[i] &= (FixedToChan(alpha) > ref);
178 alpha += alphaStep;
179 }
180 break;
181 case GL_NOTEQUAL:
182 for (i = 0; i < n; i++) {
183 mask[i] &= (FixedToChan(alpha) != ref);
184 alpha += alphaStep;
185 }
186 break;
187 case GL_EQUAL:
188 for (i = 0; i < n; i++) {
189 mask[i] &= (FixedToChan(alpha) == ref);
190 alpha += alphaStep;
191 }
192 break;
193 case GL_ALWAYS:
194 /* do nothing */
195 return 1;
196 case GL_NEVER:
197 /* caller should check for zero! */
198 span->writeAll = GL_FALSE;
199 return 0;
200 default:
201 _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
202 return 0;
203 }
204 #endif /* CHAN_TYPE */
205 }
206
207 #if 0
208 /* XXXX This causes conformance failures!!!! */
209 while ((span->start <= span->end) &&
210 (mask[span->start] == 0))
211 span->start ++;
212
213 while ((span->end >= span->start) &&
214 (mask[span->end] == 0))
215 span->end --;
216 #endif
217
218 span->writeAll = GL_FALSE;
219
220 if (span->start >= span->end)
221 return 0;
222 else
223 return 1;
224 }