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
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the
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.
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) \
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 */
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 */
127 /* describes possible state combinations */
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}},
310 problem(const char *s
)
312 fprintf(stderr
, "Problem in combine(): %s\n", s
);
316 /* Set machine parameters to default values. */
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. */
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
];
353 switch (machine
.SOURCE0_RGB
[tex_unit
]) {
354 case GL_PRIMARY_COLOR_EXT
:
355 color_src0
= frag_color
;
358 color_src0
= tex_color
;
360 case GL_CONSTANT_EXT
:
361 color_src0
= const_color
;
363 case GL_PREVIOUS_EXT
:
364 color_src0
= prev_color
;
374 /* GL_ARB_texture_env_crossbar */
375 src_unit
= machine
.SOURCE0_RGB
[tex_unit
] - GL_TEXTURE0
;
376 color_src0
= machine
.tex_color
[src_unit
];
379 problem("bad rgbSource0");
383 switch (machine
.SOURCE0_ALPHA
[tex_unit
]) {
384 case GL_PRIMARY_COLOR_EXT
:
385 alpha_src0
= frag_color
;
388 alpha_src0
= tex_color
;
390 case GL_CONSTANT_EXT
:
391 alpha_src0
= const_color
;
393 case GL_PREVIOUS_EXT
:
394 alpha_src0
= prev_color
;
404 /* GL_ARB_texture_env_crossbar */
405 src_unit
= machine
.SOURCE0_ALPHA
[tex_unit
] - GL_TEXTURE0
;
406 alpha_src0
= machine
.tex_color
[src_unit
];
409 problem("bad alphaSource0");
413 switch (machine
.SOURCE1_RGB
[tex_unit
]) {
414 case GL_PRIMARY_COLOR_EXT
:
415 color_src1
= frag_color
;
418 color_src1
= tex_color
;
420 case GL_CONSTANT_EXT
:
421 color_src1
= const_color
;
423 case GL_PREVIOUS_EXT
:
424 color_src1
= prev_color
;
434 /* GL_ARB_texture_env_crossbar */
435 src_unit
= machine
.SOURCE1_RGB
[tex_unit
] - GL_TEXTURE0
;
436 color_src1
= machine
.tex_color
[src_unit
];
439 problem("bad rgbSource1");
443 switch (machine
.SOURCE1_ALPHA
[tex_unit
]) {
444 case GL_PRIMARY_COLOR_EXT
:
445 alpha_src1
= frag_color
;
448 alpha_src1
= tex_color
;
450 case GL_CONSTANT_EXT
:
451 alpha_src1
= const_color
;
453 case GL_PREVIOUS_EXT
:
454 alpha_src1
= prev_color
;
464 /* GL_ARB_texture_env_crossbar */
465 src_unit
= machine
.SOURCE1_ALPHA
[tex_unit
] - GL_TEXTURE0
;
466 alpha_src1
= machine
.tex_color
[src_unit
];
469 problem("bad alphaSource1");
473 switch (machine
.SOURCE2_RGB
[tex_unit
]) {
474 case GL_PRIMARY_COLOR_EXT
:
475 color_src2
= frag_color
;
478 color_src2
= tex_color
;
480 case GL_CONSTANT_EXT
:
481 color_src2
= const_color
;
483 case GL_PREVIOUS_EXT
:
484 color_src2
= prev_color
;
494 /* GL_ARB_texture_env_crossbar */
495 src_unit
= machine
.SOURCE2_RGB
[tex_unit
] - GL_TEXTURE0
;
496 color_src2
= machine
.tex_color
[src_unit
];
499 problem("bad rgbSource2");
503 switch (machine
.SOURCE2_ALPHA
[tex_unit
]) {
504 case GL_PRIMARY_COLOR_EXT
:
505 alpha_src2
= frag_color
;
508 alpha_src2
= tex_color
;
510 case GL_CONSTANT_EXT
:
511 alpha_src2
= const_color
;
513 case GL_PREVIOUS_EXT
:
514 alpha_src2
= prev_color
;
524 /* GL_ARB_texture_env_crossbar */
525 src_unit
= machine
.SOURCE2_ALPHA
[tex_unit
] - GL_TEXTURE0
;
526 alpha_src2
= machine
.tex_color
[src_unit
];
529 problem("bad alphaSource2");
533 switch (machine
.OPERAND0_RGB
[tex_unit
]) {
535 term0
[0] = color_src0
[0];
536 term0
[1] = color_src0
[1];
537 term0
[2] = color_src0
[2];
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];
545 term0
[0] = color_src0
[3];
546 term0
[1] = color_src0
[3];
547 term0
[2] = color_src0
[3];
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];
555 problem("bad rgbOperand0");
559 switch (machine
.OPERAND0_ALPHA
[tex_unit
]) {
561 term0
[3] = alpha_src0
[3];
563 case GL_ONE_MINUS_SRC_ALPHA
:
564 term0
[3] = 1.0 - alpha_src0
[3];
567 problem("bad alphaOperand0");
571 switch (machine
.OPERAND1_RGB
[tex_unit
]) {
573 term1
[0] = color_src1
[0];
574 term1
[1] = color_src1
[1];
575 term1
[2] = color_src1
[2];
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];
583 term1
[0] = color_src1
[3];
584 term1
[1] = color_src1
[3];
585 term1
[2] = color_src1
[3];
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];
593 problem("bad rgbOperand1");
597 switch (machine
.OPERAND1_ALPHA
[tex_unit
]) {
599 term1
[3] = alpha_src1
[3];
601 case GL_ONE_MINUS_SRC_ALPHA
:
602 term1
[3] = 1.0 - alpha_src1
[3];
605 problem("bad alphaOperand1");
609 switch (machine
.OPERAND2_RGB
[tex_unit
]) {
611 term2
[0] = color_src2
[0];
612 term2
[1] = color_src2
[1];
613 term2
[2] = color_src2
[2];
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];
621 term2
[0] = color_src2
[3];
622 term2
[1] = color_src2
[3];
623 term2
[2] = color_src2
[3];
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];
631 problem("bad rgbOperand2");
635 switch (machine
.OPERAND2_ALPHA
[tex_unit
]) {
637 term2
[3] = alpha_src2
[3];
640 problem("bad alphaOperand2");
645 switch (machine
.COMBINE_RGB
[tex_unit
]) {
647 result
[0] = term0
[0];
648 result
[1] = term0
[1];
649 result
[2] = term0
[2];
652 result
[0] = term0
[0] * term1
[0];
653 result
[1] = term0
[1] * term1
[1];
654 result
[2] = term0
[2] * term1
[2];
657 result
[0] = term0
[0] + term1
[0];
658 result
[1] = term0
[1] + term1
[1];
659 result
[2] = term0
[2] + term1
[2];
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;
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]);
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));
679 if (machine
.COMBINE_RGB
[tex_unit
] == GL_DOT3_RGBA_EXT
)
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];
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;
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];
698 problem("bad rgbCombine");
702 switch (machine
.COMBINE_ALPHA
[tex_unit
]) {
704 result
[3] = term0
[3];
707 result
[3] = term0
[3] * term1
[3];
710 result
[3] = term0
[3] + term1
[3];
712 case GL_ADD_SIGNED_EXT
:
713 result
[3] = term0
[3] + term1
[3] - 0.5;
715 case GL_INTERPOLATE_EXT
:
716 result
[3] = term0
[3] * term2
[3] + term1
[3] * (1.0 - term2
[3]);
718 case GL_MODULATE_ADD_ATI
:
719 result
[3] = term0
[3] * term2
[3] + term1
[3];
721 case GL_MODULATE_SIGNED_ADD_ATI
:
722 result
[3] = term0
[3] * term2
[3] + term1
[3] - 0.5;
724 case GL_MODULATE_SUBTRACT_ATI
:
725 result
[3] = term0
[3] * term2
[3] - term1
[3];
728 problem("bad alphaCombine");
732 if (machine
.COMBINE_RGB
[tex_unit
] == GL_DOT3_RGBA_EXT
) {
733 result
[3] = result
[0];
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
:
747 result
[0] *= machine
.RGB_SCALE
[tex_unit
];
748 result
[1] *= machine
.RGB_SCALE
[tex_unit
];
749 result
[2] *= machine
.RGB_SCALE
[tex_unit
];
752 switch (machine
.COMBINE_RGB
[tex_unit
]) {
753 case GL_DOT3_RGBA_EXT
:
757 result
[3] *= machine
.ALPHA_SCALE
[tex_unit
];
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. */
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
,
799 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
,
801 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
,
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
,
810 const float *tex_col
= tex_colors
[u
% 8];
812 /* Setup texture color, according to texture format */
813 switch (machine
.tex_format
[u
]) {
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];
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;
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];
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;
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];
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];
851 problem("bad texture format");
855 /* Make a 4x4 solid color texture */
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. */
871 count_test_combinations(const struct test_param test_params
[])
874 for (int t
= 0; test_params
[t
].target
; t
++) {
876 for (int val
= 0; test_params
[t
].valid_values
[val
]; val
++) {
881 return num_tests
/ test_stride
;
884 /* Setup the actual GL state and our internal simulated GL state. */
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
);
895 case GL_COMBINE_RGB_EXT
:
896 machine
.COMBINE_RGB
[tex_unit
] = value
;
898 case GL_COMBINE_ALPHA_EXT
:
899 machine
.COMBINE_ALPHA
[tex_unit
] = value
;
901 case GL_SOURCE0_RGB_EXT
:
902 machine
.SOURCE0_RGB
[tex_unit
] = value
;
904 case GL_SOURCE1_RGB_EXT
:
905 machine
.SOURCE1_RGB
[tex_unit
] = value
;
907 case GL_SOURCE2_RGB_EXT
:
908 machine
.SOURCE2_RGB
[tex_unit
] = value
;
910 case GL_SOURCE0_ALPHA_EXT
:
911 machine
.SOURCE0_ALPHA
[tex_unit
] = value
;
913 case GL_SOURCE1_ALPHA_EXT
:
914 machine
.SOURCE1_ALPHA
[tex_unit
] = value
;
916 case GL_SOURCE2_ALPHA_EXT
:
917 machine
.SOURCE2_ALPHA
[tex_unit
] = value
;
919 case GL_OPERAND0_RGB_EXT
:
920 machine
.OPERAND0_RGB
[tex_unit
] = value
;
922 case GL_OPERAND1_RGB_EXT
:
923 machine
.OPERAND1_RGB
[tex_unit
] = value
;
925 case GL_OPERAND2_RGB_EXT
:
926 machine
.OPERAND2_RGB
[tex_unit
] = value
;
928 case GL_OPERAND0_ALPHA_EXT
:
929 machine
.OPERAND0_ALPHA
[tex_unit
] = value
;
931 case GL_OPERAND1_ALPHA_EXT
:
932 machine
.OPERAND1_ALPHA
[tex_unit
] = value
;
934 case GL_OPERAND2_ALPHA_EXT
:
935 machine
.OPERAND2_ALPHA
[tex_unit
] = value
;
937 case GL_RGB_SCALE_EXT
:
938 machine
.RGB_SCALE
[tex_unit
] = value
;
941 machine
.ALPHA_SCALE
[tex_unit
] = value
;
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. */
950 setup_test_env(int test_num
, const struct test_param test_params
[])
953 for (int t
= 0; test_params
[t
].target
; t
++) {
955 for (int val
= 0; test_params
[t
].valid_values
[val
]; val
++) {
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
;
968 print_test_env(int test_num
, const struct test_param test_params
[])
971 for (int t
= 0; test_params
[t
].target
; t
++) {
973 for (int val
= 0; test_params
[t
].valid_values
[val
]; val
++) {
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
;
987 #define RUN_SINGLE_TEXTURE_TEST(test) run_single_texture_test(test, #test)
989 /* Test texenv-combine with a single texture unit. */
991 run_single_texture_test(const struct test_param test_params
[],
992 const char *test_name
)
994 assert(num_tex_units
== 1);
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 */
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 */
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
,
1017 print_test_env(test
, test_params
);
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 */
1028 count_multi_texture_test_combinations()
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. */
1039 run_multi_texture_test(void)
1041 static const GLenum combine_modes
[10] = {
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)
1059 const int num_tests
= count_multi_texture_test_combinations();
1062 for (int test_num
= 0; test_num
< num_tests
;
1063 test_num
+= test_stride
) {
1064 /* 0. Set up texture units */
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
)
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
);
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. */
1133 glGetIntegerv(GL_MAX_TEXTURE_UNITS
, &num_tex_units
);
1135 /* Set up constant texture state for all tests */
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
++) {
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
);
1172 tex_env(unit
, GL_SOURCE1_RGB_EXT
,
1174 tex_env(unit
, GL_SOURCE1_ALPHA_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];
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
);
1204 piglit_display(void)
1207 float old_tolerance
[4];
1209 /* Do single texture unit tests first. */
1211 pass
= RUN_SINGLE_TEXTURE_TEST(replace_params
);
1213 pass
= RUN_SINGLE_TEXTURE_TEST(add_params
);
1215 pass
= RUN_SINGLE_TEXTURE_TEST(add_signed_params
);
1217 pass
= RUN_SINGLE_TEXTURE_TEST(modulate_params
);
1219 pass
= RUN_SINGLE_TEXTURE_TEST(interpolate_params
);
1220 /* Some implementations have precision problems with the dot3
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
;
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");
1262 piglit_is_extension_supported("GL_ARB_texture_env_crossbar");
1265 piglit_is_extension_supported("GL_ATI_texture_env_combine3");
1267 /* Allocate our textures */
1268 glGenTextures(MAX_TEX_UNITS
, textures
);
1273 for (int i
= 1; i
< argc
; i
++)
1274 if (!strcmp(argv
[i
], "--quick"))
1275 test_stride
= 67; /* a prime number */