ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / ext_texture_env_combine / combine.c
blobca7cb0a00ced7d8a8a223f0fc25ea1adb5d8d3fd
1 /*
2 * Copyright (C) 1999 Allen Akin All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the
15 * Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
18 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
20 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
28 /**
29 * @file combine.c: Test the GL_EXT_texture_env_combine extension
30 * Author: Brian Paul (brianp@valinux.com) September 2000
32 * GL_EXT_texture_env_dot3 extension test
33 * Author: Gareth Hughes (gareth@valinux.com) January 2001
35 * GL_ARB_texture_env_crossbar extension test
36 * Author: Brian Paul (brian@tungstengraphics.com) December 2002
38 * The challenge with testing this extension is dealing with combinatorial
39 * explosion. There are 16 state variables in this extension:
41 * GL_COMBINE_RGB_EXT which has 5 possible values
42 * GL_COMBINE_ALPHA_EXT which has 5 possible values
43 * GL_SOURCE0_RGB_EXT which has 4 possible values
44 * GL_SOURCE1_RGB_EXT which has 4 possible values
45 * GL_SOURCE2_RGB_EXT which has 4 possible values
46 * GL_SOURCE0_ALPHA_EXT which has 4 possible values
47 * GL_SOURCE1_ALPHA_EXT which has 4 possible values
48 * GL_SOURCE2_ALPHA_EXT which has 4 possible values
49 * GL_OPERAND0_RGB_EXT which has 4 possible values
50 * GL_OPERAND1_RGB_EXT which has 4 possible values
51 * GL_OPERAND2_RGB_EXT which has 2 possible values
52 * GL_OPERAND0_ALPHA_EXT which has 2 possible values
53 * GL_OPERAND1_ALPHA_EXT which has 2 possible values
54 * GL_OPERAND2_ALPHA_EXT which has 1 possible value
55 * GL_RGB_SCALE_EXT which has 3 possible values
56 * GL_ALPHA_SCALE which has 3 possible values
58 * The product of those values is 117,964,800. And that's just for one
59 * texture unit! If we wanted to fully exercise N texture units we'd
60 * need to run 117,964,800 ^ N tests! Ideally we'd also like to test
61 * with a number of different fragment, texenv and texture colors.
62 * Clearly we can't test everything.
64 * So, we've partitioned the combination space into subsets defined
65 * by the replace_params[], add_params[], interpolate_params[], etc arrays.
66 * For multitexture, we do an even more limited set of tests: testing
67 * all permutations of the 5 combine modes on all texture units.
69 * In the future we might look at programs that use the combine
70 * extension to see which mode combination are important to them and
71 * put them into this test.
74 #include "piglit-util-gl.h"
76 PIGLIT_GL_TEST_CONFIG_BEGIN
78 config.supports_gl_compat_version = 13;
79 config.window_visual = PIGLIT_GL_VISUAL_RGBA;
80 config.khr_no_error_support = PIGLIT_NO_ERRORS;
81 config.window_width = 2;
82 config.window_height = 2;
84 PIGLIT_GL_TEST_CONFIG_END
86 #define MAX_TEX_UNITS 8
88 #define COPY4(DST, SRC) \
89 { \
90 (DST)[0] = (SRC)[0]; \
91 (DST)[1] = (SRC)[1]; \
92 (DST)[2] = (SRC)[2]; \
93 (DST)[3] = (SRC)[3]; \
96 static bool have_dot3;
97 static bool have_crossbar;
98 static bool have_combine3;
99 static GLuint textures[MAX_TEX_UNITS];
100 static int test_stride = 1;
101 static int num_tex_units;
103 /* Our model of GL machine state */
104 static struct {
105 GLenum COMBINE_RGB[MAX_TEX_UNITS];
106 GLenum COMBINE_ALPHA[MAX_TEX_UNITS];
107 GLenum SOURCE0_RGB[MAX_TEX_UNITS];
108 GLenum SOURCE1_RGB[MAX_TEX_UNITS];
109 GLenum SOURCE2_RGB[MAX_TEX_UNITS];
110 GLenum SOURCE0_ALPHA[MAX_TEX_UNITS];
111 GLenum SOURCE1_ALPHA[MAX_TEX_UNITS];
112 GLenum SOURCE2_ALPHA[MAX_TEX_UNITS];
113 GLenum OPERAND0_RGB[MAX_TEX_UNITS];
114 GLenum OPERAND1_RGB[MAX_TEX_UNITS];
115 GLenum OPERAND2_RGB[MAX_TEX_UNITS];
116 GLenum OPERAND0_ALPHA[MAX_TEX_UNITS];
117 GLenum OPERAND1_ALPHA[MAX_TEX_UNITS];
118 GLenum OPERAND2_ALPHA[MAX_TEX_UNITS];
119 float RGB_SCALE[MAX_TEX_UNITS];
120 float ALPHA_SCALE[MAX_TEX_UNITS];
121 float frag_color[4]; /* fragment color */
122 float env_color[MAX_TEX_UNITS][4]; /* texture env color */
123 float tex_color[MAX_TEX_UNITS][4]; /* texture image color */
124 GLenum tex_format[MAX_TEX_UNITS]; /* texture base format */
125 } machine;
127 /* describes possible state combinations */
128 struct test_param {
129 GLenum target;
130 GLenum valid_values[6];
133 /* These objects define the space of tex-env combinations that we exercise.
134 * Each array element is { state-var, { list of possible values, 0 } }.
137 static const struct test_param replace_params[] = {
138 {GL_COMBINE_RGB_EXT, {GL_REPLACE, 0}},
139 {GL_COMBINE_ALPHA_EXT, {GL_REPLACE, 0}},
140 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
141 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
142 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
143 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
144 {GL_RGB_SCALE_EXT, {1, 2, 4, 0}},
145 {GL_ALPHA_SCALE, {1, 2, 4, 0}},
146 {0, {0, 0, 0, 0, 0}}
149 static const struct test_param add_params[] = {
150 {GL_COMBINE_RGB_EXT, {GL_ADD, 0}},
151 {GL_COMBINE_ALPHA_EXT, {GL_ADD, 0}},
152 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
153 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PREVIOUS_EXT, 0}},
154 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
155 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PREVIOUS_EXT, 0}},
156 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
157 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
158 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
159 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
160 {GL_RGB_SCALE_EXT, {1, 2, 4, 0}},
161 {GL_ALPHA_SCALE, {1, 2, 4, 0}},
162 {0, {0, 0, 0, 0, 0}}
165 static const struct test_param modulate_params[] = {
166 {GL_COMBINE_RGB_EXT, {GL_MODULATE, 0}},
167 {GL_COMBINE_ALPHA_EXT, {GL_MODULATE, 0}},
168 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
169 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
170 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
171 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
172 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
173 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
174 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
175 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
176 {GL_RGB_SCALE_EXT, {1, 2, 4, 0}},
177 {GL_ALPHA_SCALE, {1, 2, 4, 0}},
178 {0, {0, 0, 0, 0, 0}}
181 static const struct test_param add_signed_params[] = {
182 {GL_COMBINE_RGB_EXT, {GL_ADD_SIGNED_EXT, 0}},
183 {GL_COMBINE_ALPHA_EXT, {GL_ADD_SIGNED_EXT, 0}},
184 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
185 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
186 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
187 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
188 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
189 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
190 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
191 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
192 {GL_RGB_SCALE_EXT, {1, 2, 4, 0}},
193 {GL_ALPHA_SCALE, {1, 2, 4, 0}},
194 {0, {0, 0, 0, 0, 0}}
197 static const struct test_param interpolate_params[] = {
198 {GL_COMBINE_RGB_EXT, {GL_INTERPOLATE_EXT, 0}},
199 {GL_COMBINE_ALPHA_EXT, {GL_INTERPOLATE_EXT, 0}},
200 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
201 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
202 {GL_SOURCE2_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
203 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
204 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
205 {GL_SOURCE2_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
206 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
207 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
208 {GL_OPERAND2_RGB_EXT, {GL_SRC_ALPHA, 0}},
209 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
210 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
211 {GL_OPERAND2_ALPHA_EXT, {GL_SRC_ALPHA, 0}},
212 {GL_RGB_SCALE_EXT, {1, 4, 0}},
213 {GL_ALPHA_SCALE, {1, 2, 0}},
214 {0, {0, 0, 0, 0, 0}}
217 static const struct test_param dot3_rgb_params[] = {
218 {GL_COMBINE_RGB_EXT, {GL_DOT3_RGB_EXT, 0}},
219 {GL_COMBINE_ALPHA_EXT, {GL_MODULATE, 0}},
220 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
221 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
222 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
223 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
224 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
225 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
226 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
227 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
228 {GL_RGB_SCALE_EXT, {1, 2, 4, 0}},
229 {GL_ALPHA_SCALE, {1, 2, 4, 0}},
230 {0, {0, 0, 0, 0, 0}}
233 static const struct test_param dot3_rgba_params[] = {
234 {GL_COMBINE_RGB_EXT, {GL_DOT3_RGBA_EXT, 0}},
235 {GL_COMBINE_ALPHA_EXT, {GL_MODULATE, 0}},
236 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
237 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
238 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0}},
239 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
240 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
241 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
242 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
243 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
244 {GL_RGB_SCALE_EXT, {1, 2, 4, 0}},
245 {GL_ALPHA_SCALE, {1, 2, 4, 0}},
246 {0, {0, 0, 0, 0, 0}}
249 static const struct test_param modulate_add_params[] = {
250 {GL_COMBINE_RGB_EXT, {GL_MODULATE_ADD_ATI, 0}},
251 {GL_COMBINE_ALPHA_EXT, {GL_MODULATE_ADD_ATI, 0}},
252 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
253 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
254 {GL_SOURCE2_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
255 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
256 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
257 {GL_SOURCE2_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
258 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
259 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
260 {GL_OPERAND2_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
261 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
262 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
263 {GL_OPERAND2_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
264 {GL_RGB_SCALE_EXT, {1, 4, 0}},
265 {GL_ALPHA_SCALE, {1, 2, 0}},
266 {0, {0, 0, 0, 0, 0}}
269 static const struct test_param modulate_signed_add_params[] = {
270 {GL_COMBINE_RGB_EXT, {GL_MODULATE_SIGNED_ADD_ATI, 0}},
271 {GL_COMBINE_ALPHA_EXT, {GL_MODULATE_SIGNED_ADD_ATI, 0}},
272 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
273 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
274 {GL_SOURCE2_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
275 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
276 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
277 {GL_SOURCE2_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
278 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
279 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
280 {GL_OPERAND2_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
281 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
282 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
283 {GL_OPERAND2_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
284 {GL_RGB_SCALE_EXT, {1, 4, 0}},
285 {GL_ALPHA_SCALE, {1, 2, 0}},
286 {0, {0, 0, 0, 0, 0}}
289 static const struct test_param modulate_subtract_params[] = {
290 {GL_COMBINE_RGB_EXT, {GL_MODULATE_SUBTRACT_ATI, 0}},
291 {GL_COMBINE_ALPHA_EXT, {GL_MODULATE_SUBTRACT_ATI, 0}},
292 {GL_SOURCE0_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
293 {GL_SOURCE1_RGB_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
294 {GL_SOURCE2_RGB_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
295 {GL_SOURCE0_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
296 {GL_SOURCE1_ALPHA_EXT, {GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0}},
297 {GL_SOURCE2_ALPHA_EXT, {GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0}},
298 {GL_OPERAND0_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
299 {GL_OPERAND1_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
300 {GL_OPERAND2_RGB_EXT, {GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
301 {GL_OPERAND0_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
302 {GL_OPERAND1_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
303 {GL_OPERAND2_ALPHA_EXT, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0}},
304 {GL_RGB_SCALE_EXT, {1, 4, 0}},
305 {GL_ALPHA_SCALE, {1, 2, 0}},
306 {0, {0, 0, 0, 0, 0}}
309 static void
310 problem(const char *s)
312 fprintf(stderr, "Problem in combine(): %s\n", s);
313 assert(0);
316 /* Set machine parameters to default values. */
317 static void
318 reset_machine(void)
320 for (int u = 0; u < MAX_TEX_UNITS; u++) {
321 machine.COMBINE_RGB[u] = GL_MODULATE;
322 machine.COMBINE_ALPHA[u] = GL_MODULATE;
323 machine.SOURCE0_RGB[u] = GL_TEXTURE;
324 machine.SOURCE1_RGB[u] = GL_PREVIOUS_EXT;
325 machine.SOURCE2_RGB[u] = GL_CONSTANT_EXT;
326 machine.SOURCE0_ALPHA[u] = GL_TEXTURE;
327 machine.SOURCE1_ALPHA[u] = GL_PREVIOUS_EXT;
328 machine.SOURCE2_ALPHA[u] = GL_CONSTANT_EXT;
329 machine.OPERAND0_RGB[u] = GL_SRC_COLOR;
330 machine.OPERAND1_RGB[u] = GL_SRC_COLOR;
331 machine.OPERAND2_RGB[u] = GL_SRC_ALPHA;
332 machine.OPERAND0_ALPHA[u] = GL_SRC_ALPHA;
333 machine.OPERAND1_ALPHA[u] = GL_SRC_ALPHA;
334 machine.OPERAND2_ALPHA[u] = GL_SRC_ALPHA;
335 machine.RGB_SCALE[u] = 1.0;
336 machine.ALPHA_SCALE[u] = 1.0;
337 machine.tex_format[u] = GL_RGBA;
341 /* This computes the expected texcombine result for one texture unit. */
342 static void
343 compute_tex_combine(int tex_unit, const float prev_color[4], float result[4])
345 float term0[4], term1[4], term2[4], dot;
346 const float *color_src0, *color_src1, *color_src2;
347 const float *alpha_src0, *alpha_src1 = NULL, *alpha_src2 = NULL;
348 const float *frag_color = machine.frag_color;
349 const float *const_color = machine.env_color[tex_unit];
350 const float *tex_color = machine.tex_color[tex_unit];
351 int src_unit;
353 switch (machine.SOURCE0_RGB[tex_unit]) {
354 case GL_PRIMARY_COLOR_EXT:
355 color_src0 = frag_color;
356 break;
357 case GL_TEXTURE:
358 color_src0 = tex_color;
359 break;
360 case GL_CONSTANT_EXT:
361 color_src0 = const_color;
362 break;
363 case GL_PREVIOUS_EXT:
364 color_src0 = prev_color;
365 break;
366 case GL_TEXTURE0:
367 case GL_TEXTURE1:
368 case GL_TEXTURE2:
369 case GL_TEXTURE3:
370 case GL_TEXTURE4:
371 case GL_TEXTURE5:
372 case GL_TEXTURE6:
373 case GL_TEXTURE7:
374 /* GL_ARB_texture_env_crossbar */
375 src_unit = machine.SOURCE0_RGB[tex_unit] - GL_TEXTURE0;
376 color_src0 = machine.tex_color[src_unit];
377 break;
378 default:
379 problem("bad rgbSource0");
380 return;
383 switch (machine.SOURCE0_ALPHA[tex_unit]) {
384 case GL_PRIMARY_COLOR_EXT:
385 alpha_src0 = frag_color;
386 break;
387 case GL_TEXTURE:
388 alpha_src0 = tex_color;
389 break;
390 case GL_CONSTANT_EXT:
391 alpha_src0 = const_color;
392 break;
393 case GL_PREVIOUS_EXT:
394 alpha_src0 = prev_color;
395 break;
396 case GL_TEXTURE0:
397 case GL_TEXTURE1:
398 case GL_TEXTURE2:
399 case GL_TEXTURE3:
400 case GL_TEXTURE4:
401 case GL_TEXTURE5:
402 case GL_TEXTURE6:
403 case GL_TEXTURE7:
404 /* GL_ARB_texture_env_crossbar */
405 src_unit = machine.SOURCE0_ALPHA[tex_unit] - GL_TEXTURE0;
406 alpha_src0 = machine.tex_color[src_unit];
407 break;
408 default:
409 problem("bad alphaSource0");
410 return;
413 switch (machine.SOURCE1_RGB[tex_unit]) {
414 case GL_PRIMARY_COLOR_EXT:
415 color_src1 = frag_color;
416 break;
417 case GL_TEXTURE:
418 color_src1 = tex_color;
419 break;
420 case GL_CONSTANT_EXT:
421 color_src1 = const_color;
422 break;
423 case GL_PREVIOUS_EXT:
424 color_src1 = prev_color;
425 break;
426 case GL_TEXTURE0:
427 case GL_TEXTURE1:
428 case GL_TEXTURE2:
429 case GL_TEXTURE3:
430 case GL_TEXTURE4:
431 case GL_TEXTURE5:
432 case GL_TEXTURE6:
433 case GL_TEXTURE7:
434 /* GL_ARB_texture_env_crossbar */
435 src_unit = machine.SOURCE1_RGB[tex_unit] - GL_TEXTURE0;
436 color_src1 = machine.tex_color[src_unit];
437 break;
438 default:
439 problem("bad rgbSource1");
440 return;
443 switch (machine.SOURCE1_ALPHA[tex_unit]) {
444 case GL_PRIMARY_COLOR_EXT:
445 alpha_src1 = frag_color;
446 break;
447 case GL_TEXTURE:
448 alpha_src1 = tex_color;
449 break;
450 case GL_CONSTANT_EXT:
451 alpha_src1 = const_color;
452 break;
453 case GL_PREVIOUS_EXT:
454 alpha_src1 = prev_color;
455 break;
456 case GL_TEXTURE0:
457 case GL_TEXTURE1:
458 case GL_TEXTURE2:
459 case GL_TEXTURE3:
460 case GL_TEXTURE4:
461 case GL_TEXTURE5:
462 case GL_TEXTURE6:
463 case GL_TEXTURE7:
464 /* GL_ARB_texture_env_crossbar */
465 src_unit = machine.SOURCE1_ALPHA[tex_unit] - GL_TEXTURE0;
466 alpha_src1 = machine.tex_color[src_unit];
467 break;
468 default:
469 problem("bad alphaSource1");
470 return;
473 switch (machine.SOURCE2_RGB[tex_unit]) {
474 case GL_PRIMARY_COLOR_EXT:
475 color_src2 = frag_color;
476 break;
477 case GL_TEXTURE:
478 color_src2 = tex_color;
479 break;
480 case GL_CONSTANT_EXT:
481 color_src2 = const_color;
482 break;
483 case GL_PREVIOUS_EXT:
484 color_src2 = prev_color;
485 break;
486 case GL_TEXTURE0:
487 case GL_TEXTURE1:
488 case GL_TEXTURE2:
489 case GL_TEXTURE3:
490 case GL_TEXTURE4:
491 case GL_TEXTURE5:
492 case GL_TEXTURE6:
493 case GL_TEXTURE7:
494 /* GL_ARB_texture_env_crossbar */
495 src_unit = machine.SOURCE2_RGB[tex_unit] - GL_TEXTURE0;
496 color_src2 = machine.tex_color[src_unit];
497 break;
498 default:
499 problem("bad rgbSource2");
500 return;
503 switch (machine.SOURCE2_ALPHA[tex_unit]) {
504 case GL_PRIMARY_COLOR_EXT:
505 alpha_src2 = frag_color;
506 break;
507 case GL_TEXTURE:
508 alpha_src2 = tex_color;
509 break;
510 case GL_CONSTANT_EXT:
511 alpha_src2 = const_color;
512 break;
513 case GL_PREVIOUS_EXT:
514 alpha_src2 = prev_color;
515 break;
516 case GL_TEXTURE0:
517 case GL_TEXTURE1:
518 case GL_TEXTURE2:
519 case GL_TEXTURE3:
520 case GL_TEXTURE4:
521 case GL_TEXTURE5:
522 case GL_TEXTURE6:
523 case GL_TEXTURE7:
524 /* GL_ARB_texture_env_crossbar */
525 src_unit = machine.SOURCE2_ALPHA[tex_unit] - GL_TEXTURE0;
526 alpha_src2 = machine.tex_color[src_unit];
527 break;
528 default:
529 problem("bad alphaSource2");
530 return;
533 switch (machine.OPERAND0_RGB[tex_unit]) {
534 case GL_SRC_COLOR:
535 term0[0] = color_src0[0];
536 term0[1] = color_src0[1];
537 term0[2] = color_src0[2];
538 break;
539 case GL_ONE_MINUS_SRC_COLOR:
540 term0[0] = 1.0 - color_src0[0];
541 term0[1] = 1.0 - color_src0[1];
542 term0[2] = 1.0 - color_src0[2];
543 break;
544 case GL_SRC_ALPHA:
545 term0[0] = color_src0[3];
546 term0[1] = color_src0[3];
547 term0[2] = color_src0[3];
548 break;
549 case GL_ONE_MINUS_SRC_ALPHA:
550 term0[0] = 1.0 - color_src0[3];
551 term0[1] = 1.0 - color_src0[3];
552 term0[2] = 1.0 - color_src0[3];
553 break;
554 default:
555 problem("bad rgbOperand0");
556 return;
559 switch (machine.OPERAND0_ALPHA[tex_unit]) {
560 case GL_SRC_ALPHA:
561 term0[3] = alpha_src0[3];
562 break;
563 case GL_ONE_MINUS_SRC_ALPHA:
564 term0[3] = 1.0 - alpha_src0[3];
565 break;
566 default:
567 problem("bad alphaOperand0");
568 return;
571 switch (machine.OPERAND1_RGB[tex_unit]) {
572 case GL_SRC_COLOR:
573 term1[0] = color_src1[0];
574 term1[1] = color_src1[1];
575 term1[2] = color_src1[2];
576 break;
577 case GL_ONE_MINUS_SRC_COLOR:
578 term1[0] = 1.0 - color_src1[0];
579 term1[1] = 1.0 - color_src1[1];
580 term1[2] = 1.0 - color_src1[2];
581 break;
582 case GL_SRC_ALPHA:
583 term1[0] = color_src1[3];
584 term1[1] = color_src1[3];
585 term1[2] = color_src1[3];
586 break;
587 case GL_ONE_MINUS_SRC_ALPHA:
588 term1[0] = 1.0 - color_src1[3];
589 term1[1] = 1.0 - color_src1[3];
590 term1[2] = 1.0 - color_src1[3];
591 break;
592 default:
593 problem("bad rgbOperand1");
594 return;
597 switch (machine.OPERAND1_ALPHA[tex_unit]) {
598 case GL_SRC_ALPHA:
599 term1[3] = alpha_src1[3];
600 break;
601 case GL_ONE_MINUS_SRC_ALPHA:
602 term1[3] = 1.0 - alpha_src1[3];
603 break;
604 default:
605 problem("bad alphaOperand1");
606 return;
609 switch (machine.OPERAND2_RGB[tex_unit]) {
610 case GL_SRC_COLOR:
611 term2[0] = color_src2[0];
612 term2[1] = color_src2[1];
613 term2[2] = color_src2[2];
614 break;
615 case GL_ONE_MINUS_SRC_COLOR:
616 term2[0] = 1.0 - color_src2[0];
617 term2[1] = 1.0 - color_src2[1];
618 term2[2] = 1.0 - color_src2[2];
619 break;
620 case GL_SRC_ALPHA:
621 term2[0] = color_src2[3];
622 term2[1] = color_src2[3];
623 term2[2] = color_src2[3];
624 break;
625 case GL_ONE_MINUS_SRC_ALPHA:
626 term2[0] = 1.0 - color_src2[3];
627 term2[1] = 1.0 - color_src2[3];
628 term2[2] = 1.0 - color_src2[3];
629 break;
630 default:
631 problem("bad rgbOperand2");
632 return;
635 switch (machine.OPERAND2_ALPHA[tex_unit]) {
636 case GL_SRC_ALPHA:
637 term2[3] = alpha_src2[3];
638 break;
639 default:
640 problem("bad alphaOperand2");
641 return;
644 /* Final combine */
645 switch (machine.COMBINE_RGB[tex_unit]) {
646 case GL_REPLACE:
647 result[0] = term0[0];
648 result[1] = term0[1];
649 result[2] = term0[2];
650 break;
651 case GL_MODULATE:
652 result[0] = term0[0] * term1[0];
653 result[1] = term0[1] * term1[1];
654 result[2] = term0[2] * term1[2];
655 break;
656 case GL_ADD:
657 result[0] = term0[0] + term1[0];
658 result[1] = term0[1] + term1[1];
659 result[2] = term0[2] + term1[2];
660 break;
661 case GL_ADD_SIGNED_EXT:
662 result[0] = term0[0] + term1[0] - 0.5;
663 result[1] = term0[1] + term1[1] - 0.5;
664 result[2] = term0[2] + term1[2] - 0.5;
665 break;
666 case GL_INTERPOLATE_EXT:
667 result[0] = term0[0] * term2[0] + term1[0] * (1.0 - term2[0]);
668 result[1] = term0[1] * term2[1] + term1[1] * (1.0 - term2[1]);
669 result[2] = term0[2] * term2[2] + term1[2] * (1.0 - term2[2]);
670 break;
671 case GL_DOT3_RGB_EXT:
672 case GL_DOT3_RGBA_EXT:
673 dot = ((term0[0] - 0.5) * (term1[0] - 0.5) +
674 (term0[1] - 0.5) * (term1[1] - 0.5) +
675 (term0[2] - 0.5) * (term1[2] - 0.5));
676 result[0] = dot;
677 result[1] = dot;
678 result[2] = dot;
679 if (machine.COMBINE_RGB[tex_unit] == GL_DOT3_RGBA_EXT)
680 result[3] = dot;
681 break;
682 case GL_MODULATE_ADD_ATI:
683 result[0] = term0[0] * term2[0] + term1[0];
684 result[1] = term0[1] * term2[1] + term1[1];
685 result[2] = term0[2] * term2[2] + term1[2];
686 break;
687 case GL_MODULATE_SIGNED_ADD_ATI:
688 result[0] = term0[0] * term2[0] + term1[0] - 0.5;
689 result[1] = term0[1] * term2[1] + term1[1] - 0.5;
690 result[2] = term0[2] * term2[2] + term1[2] - 0.5;
691 break;
692 case GL_MODULATE_SUBTRACT_ATI:
693 result[0] = term0[0] * term2[0] - term1[0];
694 result[1] = term0[1] * term2[1] - term1[1];
695 result[2] = term0[2] * term2[2] - term1[2];
696 break;
697 default:
698 problem("bad rgbCombine");
699 return;
702 switch (machine.COMBINE_ALPHA[tex_unit]) {
703 case GL_REPLACE:
704 result[3] = term0[3];
705 break;
706 case GL_MODULATE:
707 result[3] = term0[3] * term1[3];
708 break;
709 case GL_ADD:
710 result[3] = term0[3] + term1[3];
711 break;
712 case GL_ADD_SIGNED_EXT:
713 result[3] = term0[3] + term1[3] - 0.5;
714 break;
715 case GL_INTERPOLATE_EXT:
716 result[3] = term0[3] * term2[3] + term1[3] * (1.0 - term2[3]);
717 break;
718 case GL_MODULATE_ADD_ATI:
719 result[3] = term0[3] * term2[3] + term1[3];
720 break;
721 case GL_MODULATE_SIGNED_ADD_ATI:
722 result[3] = term0[3] * term2[3] + term1[3] - 0.5;
723 break;
724 case GL_MODULATE_SUBTRACT_ATI:
725 result[3] = term0[3] * term2[3] - term1[3];
726 break;
727 default:
728 problem("bad alphaCombine");
729 return;
732 if (machine.COMBINE_RGB[tex_unit] == GL_DOT3_RGBA_EXT) {
733 result[3] = result[0];
736 /* scaling
737 * GH: Remove this crud when the ARB extension is done. It
738 * most likely won't have this scale factor restriction. */
739 switch (machine.COMBINE_RGB[tex_unit]) {
740 case GL_DOT3_RGB_EXT:
741 case GL_DOT3_RGBA_EXT:
742 result[0] *= 4.0;
743 result[1] *= 4.0;
744 result[2] *= 4.0;
745 break;
746 default:
747 result[0] *= machine.RGB_SCALE[tex_unit];
748 result[1] *= machine.RGB_SCALE[tex_unit];
749 result[2] *= machine.RGB_SCALE[tex_unit];
750 break;
752 switch (machine.COMBINE_RGB[tex_unit]) {
753 case GL_DOT3_RGBA_EXT:
754 result[3] *= 4.0;
755 break;
756 default:
757 result[3] *= machine.ALPHA_SCALE[tex_unit];
758 break;
761 /* final clamping */
762 result[0] = CLAMP(result[0], 0.0, 1.0);
763 result[1] = CLAMP(result[1], 0.0, 1.0);
764 result[2] = CLAMP(result[2], 0.0, 1.0);
765 result[3] = CLAMP(result[3], 0.0, 1.0);
768 /* Set the fragment, texenv (constant), and texture colors for all the
769 * machine's texture units. */
770 static void
771 setup_colors(void)
773 static const float frag_color[4] = {0.00, 0.25, 0.50, 0.75};
774 static const float env_colors[][4] = {{0.25, 0.50, 0.75, 1.00},
775 {0.50, 0.75, 1.00, 0.00},
776 {0.75, 1.00, 0.00, 0.25},
777 {1.00, 0.00, 0.25, 0.50}};
778 static const float tex_colors[][8] = {
779 {1.00, 0.00, 0.25, 0.50},
780 {0.75, 1.00, 0.00, 0.25},
781 {0.50, 0.75, 1.00, 0.00},
782 {0.25, 0.50, 0.75, 1.00},
783 /* extra colors that'll only be used for crossbar test */
784 {0.00, 0.00, 0.00, 0.00},
785 {0.25, 0.50, 0.50, 0.00},
786 {0.50, 0.25, 0.75, 0.25},
787 {0.75, 1.00, 0.25, 0.00}};
789 COPY4(machine.frag_color, frag_color);
790 glColor4fv(frag_color);
792 for (int u = 0; u < num_tex_units; u++) {
793 if (num_tex_units > 1)
794 glActiveTexture(GL_TEXTURE0 + u);
795 glBindTexture(GL_TEXTURE_2D, textures[u]);
796 glEnable(GL_TEXTURE_2D);
797 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
798 GL_NEAREST);
799 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
800 GL_NEAREST);
801 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
802 GL_COMBINE_EXT);
803 machine.env_color[u][0] = env_colors[u % 4][0];
804 machine.env_color[u][1] = env_colors[u % 4][1];
805 machine.env_color[u][2] = env_colors[u % 4][2];
806 machine.env_color[u][3] = env_colors[u % 4][3];
807 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
808 env_colors[u % 4]);
810 const float *tex_col = tex_colors[u % 8];
812 /* Setup texture color, according to texture format */
813 switch (machine.tex_format[u]) {
814 case GL_RGBA:
815 machine.tex_color[u][0] = tex_col[0];
816 machine.tex_color[u][1] = tex_col[1];
817 machine.tex_color[u][2] = tex_col[2];
818 machine.tex_color[u][3] = tex_col[3];
819 break;
820 case GL_RGB:
821 machine.tex_color[u][0] = tex_col[0];
822 machine.tex_color[u][1] = tex_col[1];
823 machine.tex_color[u][2] = tex_col[2];
824 machine.tex_color[u][3] = 1.0;
825 break;
826 case GL_ALPHA:
827 machine.tex_color[u][0] = 0.0;
828 machine.tex_color[u][1] = 0.0;
829 machine.tex_color[u][2] = 0.0;
830 machine.tex_color[u][3] = tex_col[3];
831 break;
832 case GL_LUMINANCE:
833 machine.tex_color[u][0] = tex_col[0];
834 machine.tex_color[u][1] = tex_col[0];
835 machine.tex_color[u][2] = tex_col[0];
836 machine.tex_color[u][3] = 1.0;
837 break;
838 case GL_LUMINANCE_ALPHA:
839 machine.tex_color[u][0] = tex_col[0];
840 machine.tex_color[u][1] = tex_col[0];
841 machine.tex_color[u][2] = tex_col[0];
842 machine.tex_color[u][3] = tex_col[3];
843 break;
844 case GL_INTENSITY:
845 machine.tex_color[u][0] = tex_col[0];
846 machine.tex_color[u][1] = tex_col[0];
847 machine.tex_color[u][2] = tex_col[0];
848 machine.tex_color[u][3] = tex_col[0];
849 break;
850 default:
851 problem("bad texture format");
852 return;
855 /* Make a 4x4 solid color texture */
856 float image[16][4];
857 for (int i = 0; i < 16; i++) {
858 image[i][0] = tex_colors[u % 8][0];
859 image[i][1] = tex_colors[u % 8][1];
860 image[i][2] = tex_colors[u % 8][2];
861 image[i][3] = tex_colors[u % 8][3];
863 glTexImage2D(GL_TEXTURE_2D, 0, machine.tex_format[u], 4, 4, 0,
864 GL_RGBA, GL_FLOAT, image);
868 /* Examine a set of test params and compute the number of possible
869 * state combinations. */
870 static int
871 count_test_combinations(const struct test_param test_params[])
873 int num_tests = 1;
874 for (int t = 0; test_params[t].target; t++) {
875 int values = 0;
876 for (int val = 0; test_params[t].valid_values[val]; val++) {
877 values++;
879 num_tests *= values;
881 return num_tests / test_stride;
884 /* Setup the actual GL state and our internal simulated GL state. */
885 static void
886 tex_env(int tex_unit, GLenum target, GLenum value)
888 if (num_tex_units > 1)
889 glActiveTexture(GL_TEXTURE0 + tex_unit);
891 glTexEnvi(GL_TEXTURE_ENV, target, value);
892 piglit_check_gl_error(GL_NO_ERROR);
894 switch (target) {
895 case GL_COMBINE_RGB_EXT:
896 machine.COMBINE_RGB[tex_unit] = value;
897 break;
898 case GL_COMBINE_ALPHA_EXT:
899 machine.COMBINE_ALPHA[tex_unit] = value;
900 break;
901 case GL_SOURCE0_RGB_EXT:
902 machine.SOURCE0_RGB[tex_unit] = value;
903 break;
904 case GL_SOURCE1_RGB_EXT:
905 machine.SOURCE1_RGB[tex_unit] = value;
906 break;
907 case GL_SOURCE2_RGB_EXT:
908 machine.SOURCE2_RGB[tex_unit] = value;
909 break;
910 case GL_SOURCE0_ALPHA_EXT:
911 machine.SOURCE0_ALPHA[tex_unit] = value;
912 break;
913 case GL_SOURCE1_ALPHA_EXT:
914 machine.SOURCE1_ALPHA[tex_unit] = value;
915 break;
916 case GL_SOURCE2_ALPHA_EXT:
917 machine.SOURCE2_ALPHA[tex_unit] = value;
918 break;
919 case GL_OPERAND0_RGB_EXT:
920 machine.OPERAND0_RGB[tex_unit] = value;
921 break;
922 case GL_OPERAND1_RGB_EXT:
923 machine.OPERAND1_RGB[tex_unit] = value;
924 break;
925 case GL_OPERAND2_RGB_EXT:
926 machine.OPERAND2_RGB[tex_unit] = value;
927 break;
928 case GL_OPERAND0_ALPHA_EXT:
929 machine.OPERAND0_ALPHA[tex_unit] = value;
930 break;
931 case GL_OPERAND1_ALPHA_EXT:
932 machine.OPERAND1_ALPHA[tex_unit] = value;
933 break;
934 case GL_OPERAND2_ALPHA_EXT:
935 machine.OPERAND2_ALPHA[tex_unit] = value;
936 break;
937 case GL_RGB_SCALE_EXT:
938 machine.RGB_SCALE[tex_unit] = value;
939 break;
940 case GL_ALPHA_SCALE:
941 machine.ALPHA_SCALE[tex_unit] = value;
942 break;
946 /* Make the glTexEnv calls to setup one particular set of test parameters
947 * from <test_params>.
948 * <test_num> must be between 0 and count_test_combinations(test_params)-1. */
949 static void
950 setup_test_env(int test_num, const struct test_param test_params[])
952 int divisor = 1;
953 for (int t = 0; test_params[t].target; t++) {
954 int num_values = 0;
955 for (int val = 0; test_params[t].valid_values[val]; val++) {
956 num_values++;
958 assert(num_values > 0);
959 int v = (test_num / divisor) % num_values;
960 GLenum target = test_params[t].target;
961 GLenum value = test_params[t].valid_values[v];
962 tex_env(0, target, value);
963 divisor *= num_values;
967 static void
968 print_test_env(int test_num, const struct test_param test_params[])
970 int divisor = 1;
971 for (int t = 0; test_params[t].target; t++) {
972 int num_values = 0;
973 for (int val = 0; test_params[t].valid_values[val]; val++) {
974 num_values++;
976 assert(num_values > 0);
977 int v = (test_num / divisor) % num_values;
978 GLenum target = test_params[t].target;
979 GLenum value = test_params[t].valid_values[v];
980 printf("%s %s\n", piglit_get_gl_enum_name(target),
981 piglit_get_gl_enum_name(value));
982 divisor *= num_values;
984 printf("\n");
987 #define RUN_SINGLE_TEXTURE_TEST(test) run_single_texture_test(test, #test)
989 /* Test texenv-combine with a single texture unit. */
990 static bool
991 run_single_texture_test(const struct test_param test_params[],
992 const char *test_name)
994 assert(num_tex_units == 1);
995 setup_colors();
997 const int num_tests = count_test_combinations(test_params);
999 for (int test = 0; test < num_tests; test += test_stride) {
1000 /* 0. Setup state */
1001 reset_machine();
1002 setup_test_env(test, test_params);
1004 /* 1. Render with OpenGL */
1005 glTexCoord2f(0, 0); /* use texcoord (0,0) for all vertices */
1006 piglit_draw_rect(-1, -1, 2, 2);
1008 /* 2. Compute expected result */
1009 float expected[4];
1010 expected[3] = -1.0f;
1011 compute_tex_combine(0, machine.frag_color, expected);
1013 /* 3. Compare rendered result to expected result */
1014 if (!piglit_probe_pixel_rgba(0, 0, expected)) {
1015 printf("Single Texture Test %s %d\n", test_name,
1016 test);
1017 print_test_env(test, test_params);
1018 return false;
1021 return true;
1024 /* For each texture unit, test each texenv-combine mode.
1025 * That's 5 ^ num_tex_units combinations.
1026 * Or 7 ^ num_tex_units if DOT3 combine mode is supported */
1027 static int
1028 count_multi_texture_test_combinations()
1030 int num_tests = 1;
1031 for (int i = 0; i < num_tex_units; i++)
1032 num_tests *= (have_dot3 ? 7 : 5);
1034 return num_tests / test_stride;
1037 /* Test texenv-combine with multiple texture units. */
1038 static bool
1039 run_multi_texture_test(void)
1041 static const GLenum combine_modes[10] = {
1042 GL_REPLACE,
1043 GL_ADD,
1044 GL_ADD_SIGNED_EXT,
1045 GL_MODULATE,
1046 GL_INTERPOLATE_EXT,
1047 GL_DOT3_RGB_EXT,
1048 GL_DOT3_RGBA_EXT,
1049 GL_MODULATE_ADD_ATI,
1050 GL_MODULATE_SIGNED_ADD_ATI,
1051 GL_MODULATE_SUBTRACT_ATI
1053 const int num_modes = have_dot3 ? (have_combine3 ? 10 : 7) : 5;
1055 /* four texture units is enough to test */
1056 if (num_tex_units > 4)
1057 num_tex_units = 4;
1059 const int num_tests = count_multi_texture_test_combinations();
1061 setup_colors();
1062 for (int test_num = 0; test_num < num_tests;
1063 test_num += test_stride) {
1064 /* 0. Set up texture units */
1065 reset_machine();
1066 int divisor = 1;
1067 for (int u = 0; u < num_tex_units; u++) {
1068 const int m = (test_num / divisor) % num_modes;
1069 const GLenum mode = combine_modes[m];
1071 /* Set GL_COMBINE_RGB_EXT and GL_COMBINE_ALPHA_EXT */
1072 tex_env(u, GL_COMBINE_RGB_EXT, mode);
1073 tex_env(u, GL_COMBINE_ALPHA_EXT,
1074 (mode == GL_DOT3_RGB_EXT ||
1075 mode == GL_DOT3_RGBA_EXT)
1076 ? GL_REPLACE
1077 : mode);
1078 tex_env(u, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
1079 tex_env(u, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
1080 tex_env(u, GL_SOURCE2_RGB_EXT, GL_TEXTURE);
1081 tex_env(u, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
1082 tex_env(u, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
1083 tex_env(u, GL_SOURCE2_ALPHA_EXT, GL_TEXTURE);
1084 tex_env(u, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
1085 tex_env(u, GL_OPERAND1_RGB_EXT,
1086 GL_ONE_MINUS_SRC_COLOR);
1087 tex_env(u, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
1088 tex_env(u, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
1089 tex_env(u, GL_OPERAND1_ALPHA_EXT,
1090 GL_ONE_MINUS_SRC_ALPHA);
1091 tex_env(u, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
1092 tex_env(u, GL_RGB_SCALE_EXT, 1);
1093 tex_env(u, GL_ALPHA_SCALE, 1);
1095 divisor *= num_modes;
1098 /* 1. Render with OpenGL */
1099 /* use texcoord (0,0) for all vertices */
1100 for (int u = 0; u < num_tex_units; u++)
1101 glMultiTexCoord2f(GL_TEXTURE0 + u, 0, 0);
1102 piglit_draw_rect(-1, -1, 2, 2);
1104 /* 2. Compute expected result */
1105 float prev_color[4];
1106 float expected[4] = {0};
1107 COPY4(prev_color, machine.frag_color);
1108 for (int u = 0; u < num_tex_units; u++) {
1109 compute_tex_combine(u, prev_color, expected);
1110 COPY4(prev_color, expected);
1113 /* 3. Compare rendered result to expected result */
1114 if (!piglit_probe_pixel_rgba(0, 0, expected)) {
1115 printf("Multi-texture test %d\n", test_num);
1116 return false;
1119 return true;
1122 /* We do a really short, simple test for GL_ARB_texture_env_crossbar since the
1123 * preceeding tests are pretty comprehensive and the crossbar feature is just
1124 * an incremental addition. Basically, if we have N texture units we run N
1125 * tests. For test [i] we set texture unit [i] to fetch the texture color
1126 * from unit [num_units - i - 1]. For units != i we use the constant color
1127 * (0,0,0,0). We use GL_ADD mode to compute the sum over all units. So
1128 * effectively, the result of texture combine is simply the incoming fragment
1129 * color plus unit [num_units - test - 1]'s texture color. */
1130 static bool
1131 run_crossbar_test()
1133 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num_tex_units);
1135 /* Set up constant texture state for all tests */
1136 setup_colors();
1137 reset_machine();
1138 for (int unit = 0; unit < num_tex_units; unit++) {
1139 tex_env(unit, GL_COMBINE_RGB_EXT, GL_ADD);
1140 tex_env(unit, GL_COMBINE_ALPHA_EXT, GL_ADD);
1141 tex_env(unit, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
1142 tex_env(unit, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
1143 /* SOURCE1_RGB/ALPHA is set below, per test */
1144 tex_env(unit, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
1145 tex_env(unit, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
1146 tex_env(unit, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
1147 tex_env(unit, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
1148 tex_env(unit, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
1149 tex_env(unit, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
1150 tex_env(unit, GL_RGB_SCALE_EXT, 1);
1151 tex_env(unit, GL_ALPHA_SCALE, 1);
1153 machine.env_color[unit][0] = 0.0;
1154 machine.env_color[unit][1] = 0.0;
1155 machine.env_color[unit][2] = 0.0;
1156 machine.env_color[unit][3] = 0.0;
1157 glActiveTexture(GL_TEXTURE0 + unit);
1158 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
1159 machine.env_color[unit]);
1162 for (int test = 0; test < num_tex_units; test++) {
1163 /* 1. Set up texture state */
1164 for (int unit = 0; unit < num_tex_units; unit++) {
1165 if (unit == test) {
1166 const int revUnit = num_tex_units - unit - 1;
1167 tex_env(unit, GL_SOURCE1_RGB_EXT,
1168 GL_TEXTURE0 + revUnit);
1169 tex_env(unit, GL_SOURCE1_ALPHA_EXT,
1170 GL_TEXTURE0 + revUnit);
1171 } else {
1172 tex_env(unit, GL_SOURCE1_RGB_EXT,
1173 GL_CONSTANT_EXT);
1174 tex_env(unit, GL_SOURCE1_ALPHA_EXT,
1175 GL_CONSTANT_EXT);
1179 /* 2. Render with OpenGL */
1180 /* texcoord (0,) for all vertices is OK */
1181 for (int unit = 0; unit < num_tex_units; unit++)
1182 glMultiTexCoord2f(GL_TEXTURE0 + unit, 0, 0);
1183 piglit_draw_rect(-1, -1, 2, 2);
1185 /* 3. Compute expected result */
1186 float prev_color[4];
1187 float expected[4];
1188 COPY4(prev_color, machine.frag_color);
1189 for (int unit = 0; unit < num_tex_units; unit++) {
1190 compute_tex_combine(unit, prev_color, expected);
1191 COPY4(prev_color, expected);
1194 /* 4. Compare rendered result to expected result */
1195 if (!piglit_probe_pixel_rgba(0, 0, expected)) {
1196 printf("Texture crossbar test %d\n", test);
1197 return false;
1200 return true;
1203 enum piglit_result
1204 piglit_display(void)
1206 bool pass = true;
1207 float old_tolerance[4];
1209 /* Do single texture unit tests first. */
1210 if (pass)
1211 pass = RUN_SINGLE_TEXTURE_TEST(replace_params);
1212 if (pass)
1213 pass = RUN_SINGLE_TEXTURE_TEST(add_params);
1214 if (pass)
1215 pass = RUN_SINGLE_TEXTURE_TEST(add_signed_params);
1216 if (pass)
1217 pass = RUN_SINGLE_TEXTURE_TEST(modulate_params);
1218 if (pass)
1219 pass = RUN_SINGLE_TEXTURE_TEST(interpolate_params);
1220 /* Some implementations have precision problems with the dot3
1221 * instruction. */
1222 for (int i = 0; i < 4; ++i) {
1223 old_tolerance[i] = piglit_tolerance[i];
1224 piglit_tolerance[i] = MAX2(0.02, piglit_tolerance[i]);
1226 if (pass && have_dot3)
1227 pass = RUN_SINGLE_TEXTURE_TEST(dot3_rgb_params);
1228 if (pass && have_dot3)
1229 pass = RUN_SINGLE_TEXTURE_TEST(dot3_rgba_params);
1230 for (int i = 0; i < 4; ++i)
1231 piglit_tolerance[i] = old_tolerance[i];
1232 if (pass && have_combine3)
1233 pass = RUN_SINGLE_TEXTURE_TEST(modulate_add_params);
1234 if (pass && have_combine3)
1235 pass = RUN_SINGLE_TEXTURE_TEST(modulate_signed_add_params);
1236 if (pass && have_combine3)
1237 pass = RUN_SINGLE_TEXTURE_TEST(modulate_subtract_params);
1239 /* Now do some multi-texture tests */
1240 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num_tex_units);
1241 if (pass && num_tex_units > 1) {
1242 pass = run_multi_texture_test();
1245 /* Do crossbar tests */
1246 if (pass && have_crossbar) {
1247 pass = run_crossbar_test();
1250 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
1253 void
1254 piglit_init(int argc, char **argv)
1256 piglit_require_extension("GL_EXT_texture_env_combine");
1258 /* Test the availability of the DOT3 extenstion */
1259 have_dot3 = piglit_is_extension_supported("GL_EXT_texture_env_dot3");
1261 have_crossbar =
1262 piglit_is_extension_supported("GL_ARB_texture_env_crossbar");
1264 have_combine3 =
1265 piglit_is_extension_supported("GL_ATI_texture_env_combine3");
1267 /* Allocate our textures */
1268 glGenTextures(MAX_TEX_UNITS, textures);
1270 reset_machine();
1271 num_tex_units = 1;
1273 for (int i = 1; i < argc; i++)
1274 if (!strcmp(argv[i], "--quick"))
1275 test_stride = 67; /* a prime number */