Add more structure constructor tests.
[piglit/hramrach.git] / tests / glean / ttexcombine.cpp
blobd4a43c2e6c1893a0ca1fd632c9a80f7bc86b9add
1 // BEGIN_COPYRIGHT -*- glean -*-
2 //
3 // Copyright (C) 1999 Allen Akin All Rights Reserved.
4 //
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
12 // conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
16 // Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
26 //
27 // END_COPYRIGHT
30 // ttexcombine.cpp: Test the GL_EXT_texture_env_combine extension
31 // Author: Brian Paul (brianp@valinux.com) September 2000
33 // GL_EXT_texture_env_dot3 extension test
34 // Author: Gareth Hughes (gareth@valinux.com) January 2001
36 // GL_ARB_texture_env_crossbar extension test
37 // Author: Brian Paul (brian@tungstengraphics.com) December 2002
39 // The challenge with testing this extension is dealing with combinatorial
40 // explosion. There are 16 state variables in this extension:
42 // GL_COMBINE_RGB_EXT which has 5 possible values
43 // GL_COMBINE_ALPHA_EXT which has 5 possible values
44 // GL_SOURCE0_RGB_EXT which has 4 possible values
45 // GL_SOURCE1_RGB_EXT which has 4 possible values
46 // GL_SOURCE2_RGB_EXT which has 4 possible values
47 // GL_SOURCE0_ALPHA_EXT which has 4 possible values
48 // GL_SOURCE1_ALPHA_EXT which has 4 possible values
49 // GL_SOURCE2_ALPHA_EXT which has 4 possible values
50 // GL_OPERAND0_RGB_EXT which has 4 possible values
51 // GL_OPERAND1_RGB_EXT which has 4 possible values
52 // GL_OPERAND2_RGB_EXT which has 2 possible values
53 // GL_OPERAND0_ALPHA_EXT which has 2 possible values
54 // GL_OPERAND1_ALPHA_EXT which has 2 possible values
55 // GL_OPERAND2_ALPHA_EXT which has 1 possible value
56 // GL_RGB_SCALE_EXT which has 3 possible values
57 // GL_ALPHA_SCALE which has 3 possible values
59 // The product of those values is 117,964,800. And that's just for one
60 // texture unit! If we wanted to fully exercise N texture units we'd
61 // need to run 117,964,800 ^ N tests! Ideally we'd also like to test
62 // with a number of different fragment, texenv and texture colors.
63 // Clearly we can't test everything.
64 //
65 // So, we've partitioned the combination space into subsets defined
66 // by the ReplaceParams[], AddParams[], InterpolateParams[], etc arrays.
67 // For multitexture, we do an even more limited set of tests: testing
68 // all permutations of the 5 combine modes on all texture units.
70 // In the future we might look at programs that use the combine
71 // extension to see which mode combination are important to them and
72 // put them into this test.
75 #include "ttexcombine.h"
76 #include <cassert>
77 #include <stdio.h>
78 #include <cmath>
80 #define CLAMP(VAL, MIN, MAX) \
81 ((VAL) < (MIN) ? (MIN) : ((VAL) > (MAX) ? (MAX) : (VAL)))
83 #define COPY4(DST, SRC) \
84 { \
85 (DST)[0] = (SRC)[0]; \
86 (DST)[1] = (SRC)[1]; \
87 (DST)[2] = (SRC)[2]; \
88 (DST)[3] = (SRC)[3]; \
92 namespace GLEAN {
95 // These objects define the space of tex-env combinations that we exercise.
96 // Each array element is { state-var, { list of possible values, 0 } }.
99 TexCombineTest::test_param TexCombineTest::ReplaceParams[] = {
100 { GL_COMBINE_RGB_EXT, { GL_REPLACE, 0 } },
101 { GL_COMBINE_ALPHA_EXT, { GL_REPLACE, 0 } },
102 { GL_SOURCE0_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
103 { GL_SOURCE0_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
104 { GL_OPERAND0_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
105 { GL_OPERAND0_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
106 { GL_RGB_SCALE_EXT, { 1, 2, 4, 0 } },
107 { GL_ALPHA_SCALE, { 1, 2, 4, 0 } },
108 { 0, { 0, 0, 0, 0, 0 } }
111 TexCombineTest::test_param TexCombineTest::AddParams[] = {
112 { GL_COMBINE_RGB_EXT, { GL_ADD, 0 } },
113 { GL_COMBINE_ALPHA_EXT, { GL_ADD, 0 } },
114 { GL_SOURCE0_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
115 { GL_SOURCE1_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PREVIOUS_EXT, 0 } },
116 { GL_SOURCE0_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
117 { GL_SOURCE1_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PREVIOUS_EXT, 0 } },
118 { GL_OPERAND0_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
119 { GL_OPERAND1_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
120 { GL_OPERAND0_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
121 { GL_OPERAND1_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
122 { GL_RGB_SCALE_EXT, { 1, 2, 4, 0 } },
123 { GL_ALPHA_SCALE, { 1, 2, 4, 0 } },
124 { 0, { 0, 0, 0, 0, 0 } }
127 TexCombineTest::test_param TexCombineTest::ModulateParams[] = {
128 { GL_COMBINE_RGB_EXT, { GL_MODULATE, 0 } },
129 { GL_COMBINE_ALPHA_EXT, { GL_MODULATE, 0 } },
130 { GL_SOURCE0_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
131 { GL_SOURCE1_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
132 { GL_SOURCE0_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
133 { GL_SOURCE1_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
134 { GL_OPERAND0_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
135 { GL_OPERAND1_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
136 { GL_OPERAND0_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
137 { GL_OPERAND1_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
138 { GL_RGB_SCALE_EXT, { 1, 2, 4, 0 } },
139 { GL_ALPHA_SCALE, { 1, 2, 4, 0 } },
140 { 0, { 0, 0, 0, 0, 0 } }
143 TexCombineTest::test_param TexCombineTest::AddSignedParams[] = {
144 { GL_COMBINE_RGB_EXT, { GL_ADD_SIGNED_EXT, 0 } },
145 { GL_COMBINE_ALPHA_EXT, { GL_ADD_SIGNED_EXT, 0 } },
146 { GL_SOURCE0_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
147 { GL_SOURCE1_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
148 { GL_SOURCE0_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
149 { GL_SOURCE1_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
150 { GL_OPERAND0_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
151 { GL_OPERAND1_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
152 { GL_OPERAND0_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
153 { GL_OPERAND1_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
154 { GL_RGB_SCALE_EXT, { 1, 2, 4, 0 } },
155 { GL_ALPHA_SCALE, { 1, 2, 4, 0 } },
156 { 0, { 0, 0, 0, 0, 0 } }
159 TexCombineTest::test_param TexCombineTest::InterpolateParams[] = {
160 { GL_COMBINE_RGB_EXT, { GL_INTERPOLATE_EXT, 0 } },
161 { GL_COMBINE_ALPHA_EXT, { GL_INTERPOLATE_EXT, 0 } },
162 { GL_SOURCE0_RGB_EXT, { GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0 } },
163 { GL_SOURCE1_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
164 { GL_SOURCE2_RGB_EXT, { GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0 } },
165 { GL_SOURCE0_ALPHA_EXT, { GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0 } },
166 { GL_SOURCE1_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
167 { GL_SOURCE2_ALPHA_EXT, { GL_TEXTURE, GL_PRIMARY_COLOR_EXT, 0 } },
168 { GL_OPERAND0_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
169 { GL_OPERAND1_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
170 { GL_OPERAND2_RGB_EXT, { GL_SRC_ALPHA, 0 } },
171 { GL_OPERAND0_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
172 { GL_OPERAND1_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
173 { GL_OPERAND2_ALPHA_EXT, { GL_SRC_ALPHA, 0 } },
174 { GL_RGB_SCALE_EXT, { 1, 4, 0 } },
175 { GL_ALPHA_SCALE, { 1, 2, 0 } },
176 { 0, { 0, 0, 0, 0, 0 } }
179 TexCombineTest::test_param TexCombineTest::Dot3RGBParams[] = {
180 { GL_COMBINE_RGB_EXT, { GL_DOT3_RGB_EXT, 0 } },
181 { GL_COMBINE_ALPHA_EXT, { GL_MODULATE, 0 } },
182 { GL_SOURCE0_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
183 { GL_SOURCE1_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
184 { GL_SOURCE0_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
185 { GL_SOURCE1_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
186 { GL_OPERAND0_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
187 { GL_OPERAND1_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
188 { GL_OPERAND0_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
189 { GL_OPERAND1_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
190 { GL_RGB_SCALE_EXT, { 1, 2, 4, 0 } },
191 { GL_ALPHA_SCALE, { 1, 2, 4, 0 } },
192 { 0, { 0, 0, 0, 0, 0 } }
195 TexCombineTest::test_param TexCombineTest::Dot3RGBAParams[] = {
196 { GL_COMBINE_RGB_EXT, { GL_DOT3_RGBA_EXT, 0 } },
197 { GL_COMBINE_ALPHA_EXT, { GL_MODULATE, 0 } },
198 { GL_SOURCE0_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
199 { GL_SOURCE1_RGB_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
200 { GL_SOURCE0_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, 0 } },
201 { GL_SOURCE1_ALPHA_EXT, { GL_TEXTURE, GL_CONSTANT_EXT, GL_PRIMARY_COLOR_EXT, GL_PREVIOUS_EXT, 0 } },
202 { GL_OPERAND0_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
203 { GL_OPERAND1_RGB_EXT, { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
204 { GL_OPERAND0_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
205 { GL_OPERAND1_ALPHA_EXT, { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 0 } },
206 { GL_RGB_SCALE_EXT, { 1, 2, 4, 0 } },
207 { GL_ALPHA_SCALE, { 1, 2, 4, 0 } },
208 { 0, { 0, 0, 0, 0, 0 } }
212 static void
213 problem(const char *s) {
214 cerr << "Problem in combine():" << s << "\n";
219 // Set machine parameters to default values.
221 void
222 TexCombineTest::ResetMachine(glmachine &machine) {
223 for (int u = 0; u < MAX_TEX_UNITS; u++) {
224 machine.COMBINE_RGB[u] = GL_MODULATE;
225 machine.COMBINE_ALPHA[u] = GL_MODULATE;
226 machine.SOURCE0_RGB[u] = GL_TEXTURE;
227 machine.SOURCE1_RGB[u] = GL_PREVIOUS_EXT;
228 machine.SOURCE2_RGB[u] = GL_CONSTANT_EXT;
229 machine.SOURCE0_ALPHA[u] = GL_TEXTURE;
230 machine.SOURCE1_ALPHA[u] = GL_PREVIOUS_EXT;
231 machine.SOURCE2_ALPHA[u] = GL_CONSTANT_EXT;
232 machine.OPERAND0_RGB[u] = GL_SRC_COLOR;
233 machine.OPERAND1_RGB[u] = GL_SRC_COLOR;
234 machine.OPERAND2_RGB[u] = GL_SRC_ALPHA;
235 machine.OPERAND0_ALPHA[u] = GL_SRC_ALPHA;
236 machine.OPERAND1_ALPHA[u] = GL_SRC_ALPHA;
237 machine.OPERAND2_ALPHA[u] = GL_SRC_ALPHA;
238 machine.RGB_SCALE[u] = 1.0;
239 machine.ALPHA_SCALE[u] = 1.0;
240 machine.TexFormat[u] = GL_RGBA;
246 // This computes the expected texcombine result for one texture unit.
248 void
249 TexCombineTest::ComputeTexCombine(const glmachine &machine, int texUnit,
250 const GLfloat prevColor[4],
251 GLfloat result[4]) const {
252 GLfloat term0[4], term1[4], term2[4], dot;
253 const GLfloat *colorSrc0, *colorSrc1, *colorSrc2;
254 const GLfloat *alphaSrc0, *alphaSrc1 = NULL, *alphaSrc2 = NULL;
255 const GLfloat *fragColor = machine.FragColor;
256 const GLfloat *constColor = machine.EnvColor[texUnit];
257 const GLfloat *texColor = machine.TexColor[texUnit];
258 int srcUnit;
260 switch (machine.SOURCE0_RGB[texUnit]) {
261 case GL_PRIMARY_COLOR_EXT:
262 colorSrc0 = fragColor;
263 break;
264 case GL_TEXTURE:
265 colorSrc0 = texColor;
266 break;
267 case GL_CONSTANT_EXT:
268 colorSrc0 = constColor;
269 break;
270 case GL_PREVIOUS_EXT:
271 colorSrc0 = prevColor;
272 break;
273 case GL_TEXTURE0_ARB:
274 case GL_TEXTURE1_ARB:
275 case GL_TEXTURE2_ARB:
276 case GL_TEXTURE3_ARB:
277 case GL_TEXTURE4_ARB:
278 case GL_TEXTURE5_ARB:
279 case GL_TEXTURE6_ARB:
280 case GL_TEXTURE7_ARB:
281 /* GL_ARB_texture_env_crossbar */
282 srcUnit = machine.SOURCE0_RGB[texUnit] - GL_TEXTURE0_ARB;
283 colorSrc0 = machine.TexColor[srcUnit];
284 break;
285 default:
286 problem("bad rgbSource0");
287 return;
290 switch (machine.SOURCE0_ALPHA[texUnit]) {
291 case GL_PRIMARY_COLOR_EXT:
292 alphaSrc0 = fragColor;
293 break;
294 case GL_TEXTURE:
295 alphaSrc0 = texColor;
296 break;
297 case GL_CONSTANT_EXT:
298 alphaSrc0 = constColor;
299 break;
300 case GL_PREVIOUS_EXT:
301 alphaSrc0 = prevColor;
302 break;
303 case GL_TEXTURE0_ARB:
304 case GL_TEXTURE1_ARB:
305 case GL_TEXTURE2_ARB:
306 case GL_TEXTURE3_ARB:
307 case GL_TEXTURE4_ARB:
308 case GL_TEXTURE5_ARB:
309 case GL_TEXTURE6_ARB:
310 case GL_TEXTURE7_ARB:
311 /* GL_ARB_texture_env_crossbar */
312 srcUnit = machine.SOURCE0_ALPHA[texUnit] - GL_TEXTURE0_ARB;
313 alphaSrc0 = machine.TexColor[srcUnit];
314 break;
315 default:
316 problem("bad alphaSource0");
317 return;
320 switch (machine.SOURCE1_RGB[texUnit]) {
321 case GL_PRIMARY_COLOR_EXT:
322 colorSrc1 = fragColor;
323 break;
324 case GL_TEXTURE:
325 colorSrc1 = texColor;
326 break;
327 case GL_CONSTANT_EXT:
328 colorSrc1 = constColor;
329 break;
330 case GL_PREVIOUS_EXT:
331 colorSrc1 = prevColor;
332 break;
333 case GL_TEXTURE0_ARB:
334 case GL_TEXTURE1_ARB:
335 case GL_TEXTURE2_ARB:
336 case GL_TEXTURE3_ARB:
337 case GL_TEXTURE4_ARB:
338 case GL_TEXTURE5_ARB:
339 case GL_TEXTURE6_ARB:
340 case GL_TEXTURE7_ARB:
341 /* GL_ARB_texture_env_crossbar */
342 srcUnit = machine.SOURCE1_RGB[texUnit] - GL_TEXTURE0_ARB;
343 colorSrc1 = machine.TexColor[srcUnit];
344 break;
345 default:
346 problem("bad rgbSource1");
347 return;
350 switch (machine.SOURCE1_ALPHA[texUnit]) {
351 case GL_PRIMARY_COLOR_EXT:
352 alphaSrc1 = fragColor;
353 break;
354 case GL_TEXTURE:
355 alphaSrc1 = texColor;
356 break;
357 case GL_CONSTANT_EXT:
358 alphaSrc1 = constColor;
359 break;
360 case GL_PREVIOUS_EXT:
361 alphaSrc1 = prevColor;
362 break;
363 case GL_TEXTURE0_ARB:
364 case GL_TEXTURE1_ARB:
365 case GL_TEXTURE2_ARB:
366 case GL_TEXTURE3_ARB:
367 case GL_TEXTURE4_ARB:
368 case GL_TEXTURE5_ARB:
369 case GL_TEXTURE6_ARB:
370 case GL_TEXTURE7_ARB:
371 /* GL_ARB_texture_env_crossbar */
372 srcUnit = machine.SOURCE1_ALPHA[texUnit] - GL_TEXTURE0_ARB;
373 alphaSrc1 = machine.TexColor[srcUnit];
374 break;
375 default:
376 problem("bad alphaSource1");
377 return;
380 switch (machine.SOURCE2_RGB[texUnit]) {
381 case GL_PRIMARY_COLOR_EXT:
382 colorSrc2 = fragColor;
383 break;
384 case GL_TEXTURE:
385 colorSrc2 = texColor;
386 break;
387 case GL_CONSTANT_EXT:
388 colorSrc2 = constColor;
389 break;
390 case GL_PREVIOUS_EXT:
391 colorSrc2 = prevColor;
392 break;
393 case GL_TEXTURE0_ARB:
394 case GL_TEXTURE1_ARB:
395 case GL_TEXTURE2_ARB:
396 case GL_TEXTURE3_ARB:
397 case GL_TEXTURE4_ARB:
398 case GL_TEXTURE5_ARB:
399 case GL_TEXTURE6_ARB:
400 case GL_TEXTURE7_ARB:
401 /* GL_ARB_texture_env_crossbar */
402 srcUnit = machine.SOURCE2_RGB[texUnit] - GL_TEXTURE0_ARB;
403 colorSrc2 = machine.TexColor[srcUnit];
404 break;
405 default:
406 problem("bad rgbSource2");
407 return;
410 switch (machine.SOURCE2_ALPHA[texUnit]) {
411 case GL_PRIMARY_COLOR_EXT:
412 alphaSrc2 = fragColor;
413 break;
414 case GL_TEXTURE:
415 alphaSrc2 = texColor;
416 break;
417 case GL_CONSTANT_EXT:
418 alphaSrc2 = constColor;
419 break;
420 case GL_PREVIOUS_EXT:
421 alphaSrc2 = prevColor;
422 break;
423 case GL_TEXTURE0_ARB:
424 case GL_TEXTURE1_ARB:
425 case GL_TEXTURE2_ARB:
426 case GL_TEXTURE3_ARB:
427 case GL_TEXTURE4_ARB:
428 case GL_TEXTURE5_ARB:
429 case GL_TEXTURE6_ARB:
430 case GL_TEXTURE7_ARB:
431 /* GL_ARB_texture_env_crossbar */
432 srcUnit = machine.SOURCE2_ALPHA[texUnit] - GL_TEXTURE0_ARB;
433 alphaSrc2 = machine.TexColor[srcUnit];
434 break;
435 default:
436 problem("bad alphaSource2");
437 return;
440 switch (machine.OPERAND0_RGB[texUnit]) {
441 case GL_SRC_COLOR:
442 term0[0] = colorSrc0[0];
443 term0[1] = colorSrc0[1];
444 term0[2] = colorSrc0[2];
445 break;
446 case GL_ONE_MINUS_SRC_COLOR:
447 term0[0] = 1.0 - colorSrc0[0];
448 term0[1] = 1.0 - colorSrc0[1];
449 term0[2] = 1.0 - colorSrc0[2];
450 break;
451 case GL_SRC_ALPHA:
452 term0[0] = colorSrc0[3];
453 term0[1] = colorSrc0[3];
454 term0[2] = colorSrc0[3];
455 break;
456 case GL_ONE_MINUS_SRC_ALPHA:
457 term0[0] = 1.0 - colorSrc0[3];
458 term0[1] = 1.0 - colorSrc0[3];
459 term0[2] = 1.0 - colorSrc0[3];
460 break;
461 default:
462 problem("bad rgbOperand0");
463 return;
466 switch (machine.OPERAND0_ALPHA[texUnit]) {
467 case GL_SRC_ALPHA:
468 term0[3] = alphaSrc0[3];
469 break;
470 case GL_ONE_MINUS_SRC_ALPHA:
471 term0[3] = 1.0 - alphaSrc0[3];
472 break;
473 default:
474 problem("bad alphaOperand0");
475 return;
478 switch (machine.OPERAND1_RGB[texUnit]) {
479 case GL_SRC_COLOR:
480 term1[0] = colorSrc1[0];
481 term1[1] = colorSrc1[1];
482 term1[2] = colorSrc1[2];
483 break;
484 case GL_ONE_MINUS_SRC_COLOR:
485 term1[0] = 1.0 - colorSrc1[0];
486 term1[1] = 1.0 - colorSrc1[1];
487 term1[2] = 1.0 - colorSrc1[2];
488 break;
489 case GL_SRC_ALPHA:
490 term1[0] = colorSrc1[3];
491 term1[1] = colorSrc1[3];
492 term1[2] = colorSrc1[3];
493 break;
494 case GL_ONE_MINUS_SRC_ALPHA:
495 term1[0] = 1.0 - colorSrc1[3];
496 term1[1] = 1.0 - colorSrc1[3];
497 term1[2] = 1.0 - colorSrc1[3];
498 break;
499 default:
500 problem("bad rgbOperand1");
501 return;
504 switch (machine.OPERAND1_ALPHA[texUnit]) {
505 case GL_SRC_ALPHA:
506 term1[3] = alphaSrc1[3];
507 break;
508 case GL_ONE_MINUS_SRC_ALPHA:
509 term1[3] = 1.0 - alphaSrc1[3];
510 break;
511 default:
512 problem("bad alphaOperand1");
513 return;
516 switch (machine.OPERAND2_RGB[texUnit]) {
517 case GL_SRC_ALPHA:
518 term2[0] = colorSrc2[3];
519 term2[1] = colorSrc2[3];
520 term2[2] = colorSrc2[3];
521 break;
522 default:
523 problem("bad rgbOperand2");
524 return;
527 switch (machine.OPERAND2_ALPHA[texUnit]) {
528 case GL_SRC_ALPHA:
529 term2[3] = alphaSrc2[3];
530 break;
531 default:
532 problem("bad alphaOperand2");
533 return;
536 // Final combine
537 switch (machine.COMBINE_RGB[texUnit]) {
538 case GL_REPLACE:
539 result[0] = term0[0];
540 result[1] = term0[1];
541 result[2] = term0[2];
542 break;
543 case GL_MODULATE:
544 result[0] = term0[0] * term1[0];
545 result[1] = term0[1] * term1[1];
546 result[2] = term0[2] * term1[2];
547 break;
548 case GL_ADD:
549 result[0] = term0[0] + term1[0];
550 result[1] = term0[1] + term1[1];
551 result[2] = term0[2] + term1[2];
552 break;
553 case GL_ADD_SIGNED_EXT:
554 result[0] = term0[0] + term1[0] - 0.5;
555 result[1] = term0[1] + term1[1] - 0.5;
556 result[2] = term0[2] + term1[2] - 0.5;
557 break;
558 case GL_INTERPOLATE_EXT:
559 result[0] = term0[0] * term2[0] + term1[0] * (1.0 - term2[0]);
560 result[1] = term0[1] * term2[1] + term1[1] * (1.0 - term2[1]);
561 result[2] = term0[2] * term2[2] + term1[2] * (1.0 - term2[2]);
562 break;
563 case GL_DOT3_RGB_EXT:
564 case GL_DOT3_RGBA_EXT:
565 dot = ((term0[0] - 0.5) * (term1[0] - 0.5) +
566 (term0[1] - 0.5) * (term1[1] - 0.5) +
567 (term0[2] - 0.5) * (term1[2] - 0.5));
568 result[0] = dot;
569 result[1] = dot;
570 result[2] = dot;
571 if (machine.COMBINE_RGB[texUnit] == GL_DOT3_RGBA_EXT)
572 result[3] = dot;
573 break;
574 default:
575 problem("bad rgbCombine");
576 return;
579 switch (machine.COMBINE_ALPHA[texUnit]) {
580 case GL_REPLACE:
581 result[3] = term0[3];
582 break;
583 case GL_MODULATE:
584 result[3] = term0[3] * term1[3];
585 break;
586 case GL_ADD:
587 result[3] = term0[3] + term1[3];
588 break;
589 case GL_ADD_SIGNED_EXT:
590 result[3] = term0[3] + term1[3] - 0.5;
591 break;
592 case GL_INTERPOLATE_EXT:
593 result[3] = term0[3] * term2[3] + term1[3] * (1.0 - term2[3]);
594 break;
595 default:
596 problem("bad alphaCombine");
597 return;
600 if (machine.COMBINE_RGB[texUnit] == GL_DOT3_RGBA_EXT) {
601 result[3] = result[0];
605 // scaling
606 // GH: Remove this crud when the ARB extension is done. It
607 // most likely won't have this scale factor restriction.
608 switch (machine.COMBINE_RGB[texUnit]) {
609 case GL_DOT3_RGB_EXT:
610 case GL_DOT3_RGBA_EXT:
611 result[0] *= 4.0;
612 result[1] *= 4.0;
613 result[2] *= 4.0;
614 break;
615 default:
616 result[0] *= machine.RGB_SCALE[texUnit];
617 result[1] *= machine.RGB_SCALE[texUnit];
618 result[2] *= machine.RGB_SCALE[texUnit];
619 break;
621 switch (machine.COMBINE_RGB[texUnit]) {
622 case GL_DOT3_RGBA_EXT:
623 result[3] *= 4.0;
624 break;
625 default:
626 result[3] *= machine.ALPHA_SCALE[texUnit];
627 break;
630 // final clamping
631 result[0] = CLAMP(result[0], 0.0, 1.0);
632 result[1] = CLAMP(result[1], 0.0, 1.0);
633 result[2] = CLAMP(result[2], 0.0, 1.0);
634 result[3] = CLAMP(result[3], 0.0, 1.0);
639 // Return string for an enum value.
641 const char *
642 EnumString(GLenum pname)
644 static char s[100];
645 switch (pname) {
646 case GL_COMBINE_RGB_EXT:
647 return "GL_COMBINE_RGB_EXT";
648 case GL_COMBINE_ALPHA_EXT:
649 return "GL_COMBINE_ALPHA_EXT";
650 case GL_REPLACE:
651 return "GL_REPLACE";
652 case GL_MODULATE:
653 return "GL_MODULATE";
654 case GL_ADD:
655 return "GL_ADD";
656 case GL_ADD_SIGNED_EXT:
657 return "GL_ADD_SIGNED_EXT";
658 case GL_INTERPOLATE_EXT:
659 return "GL_INTERPOLATE_EXT";
660 case GL_DOT3_RGB_EXT:
661 return "GL_DOT3_RGB_EXT";
662 case GL_DOT3_RGBA_EXT:
663 return "GL_DOT3_RGBA_EXT";
664 case GL_TEXTURE:
665 return "GL_TEXTURE";
666 case GL_CONSTANT_EXT:
667 return "GL_CONSTANT_EXT";
668 case GL_PRIMARY_COLOR_EXT:
669 return "GL_PRIMARY_COLOR_EXT";
670 case GL_PREVIOUS_EXT:
671 return "GL_PREVIOUS_EXT";
672 case GL_SRC_COLOR:
673 return "GL_SRC_COLOR";
674 case GL_ONE_MINUS_SRC_COLOR:
675 return "GL_ONE_MINUS_SRC_COLOR";
676 case GL_SRC_ALPHA:
677 return "GL_SRC_ALPHA";
678 case GL_ONE_MINUS_SRC_ALPHA:
679 return "GL_ONE_MINUS_SRC_ALPHA";
680 case GL_TEXTURE0_ARB:
681 return "GL_TEXTURE0_ARB";
682 case GL_TEXTURE1_ARB:
683 return "GL_TEXTURE1_ARB";
684 case GL_TEXTURE2_ARB:
685 return "GL_TEXTURE2_ARB";
686 case GL_TEXTURE3_ARB:
687 return "GL_TEXTURE3_ARB";
688 case GL_TEXTURE4_ARB:
689 return "GL_TEXTURE4_ARB";
690 case GL_TEXTURE5_ARB:
691 return "GL_TEXTURE5_ARB";
692 case GL_TEXTURE6_ARB:
693 return "GL_TEXTURE6_ARB";
694 case GL_TEXTURE7_ARB:
695 return "GL_TEXTURE7_ARB";
696 default:
697 sprintf(s, "0x%04x", (unsigned int) pname);
698 return s;
704 // Print current values of all machine state vars.
705 // Used when reporting failures.
707 void
708 TexCombineTest::PrintMachineState(const glmachine &machine) const {
710 env->log << "\tCurrent combine state:\n";
711 env->log << "\tIncoming Fragment RGBA = "
712 << machine.FragColor[0] << ", "
713 << machine.FragColor[1] << ", "
714 << machine.FragColor[2] << ", "
715 << machine.FragColor[3] << "\n";
716 for (int u = 0; u < machine.NumTexUnits; u++) {
717 env->log << "\tTexture Unit " << u << ":\n";
718 env->log << "\t GL_COMBINE_RGB_EXT = "
719 << EnumString(machine.COMBINE_RGB[u]) << "\n";
720 env->log << "\t GL_COMBINE_ALPHA_EXT = "
721 << EnumString(machine.COMBINE_ALPHA[u]) << "\n";
722 env->log << "\t GL_SOURCE0_RGB_EXT = "
723 << EnumString(machine.SOURCE0_RGB[u]) << "\n";
724 env->log << "\t GL_SOURCE1_RGB_EXT = "
725 << EnumString(machine.SOURCE1_RGB[u]) << "\n";
726 env->log << "\t GL_SOURCE2_RGB_EXT = "
727 << EnumString(machine.SOURCE2_RGB[u]) << "\n";
728 env->log << "\t GL_SOURCE0_ALPHA_EXT = "
729 << EnumString(machine.SOURCE0_ALPHA[u]) << "\n";
730 env->log << "\t GL_SOURCE1_ALPHA_EXT = "
731 << EnumString(machine.SOURCE1_ALPHA[u]) << "\n";
732 env->log << "\t GL_SOURCE2_ALPHA_EXT = "
733 << EnumString(machine.SOURCE2_ALPHA[u]) << "\n";
734 env->log << "\t GL_OPERAND0_RGB_EXT = "
735 << EnumString(machine.OPERAND0_RGB[u]) << "\n";
736 env->log << "\t GL_OPERAND1_RGB_EXT = "
737 << EnumString(machine.OPERAND1_RGB[u]) << "\n";
738 env->log << "\t GL_OPERAND2_RGB_EXT = "
739 << EnumString(machine.OPERAND2_RGB[u]) << "\n";
740 env->log << "\t GL_OPERAND0_ALPHA_EXT = "
741 << EnumString(machine.OPERAND0_ALPHA[u]) << "\n";
742 env->log << "\t GL_OPERAND1_ALPHA_EXT = "
743 << EnumString(machine.OPERAND1_ALPHA[u]) << "\n";
744 env->log << "\t GL_OPERAND2_ALPHA_EXT = "
745 << EnumString(machine.OPERAND2_ALPHA[u]) << "\n";
746 env->log << "\t GL_RGB_SCALE_EXT = "
747 << machine.RGB_SCALE[u] << "\n";
748 env->log << "\t GL_ALPHA_SCALE = "
749 << machine.ALPHA_SCALE[u] << "\n";
750 env->log << "\t Tex Env RGBA = "
751 << machine.EnvColor[u][0] << ", "
752 << machine.EnvColor[u][1] << ", "
753 << machine.EnvColor[u][2] << ", "
754 << machine.EnvColor[u][3] << "\n";
755 switch (machine.TexFormat[u]) {
756 case GL_ALPHA:
757 env->log << "\t Texture ALPHA = "
758 << machine.TexColor[u][3] << "\n";
759 break;
760 case GL_LUMINANCE:
761 env->log << "\t Texture LUMINANCE = "
762 << machine.TexColor[u][0] << "\n";
763 break;
764 case GL_LUMINANCE_ALPHA:
765 env->log << "\t Texture RGBA = "
766 << machine.TexColor[u][0] << ", "
767 << machine.TexColor[u][3] << "\n";
768 break;
769 case GL_INTENSITY:
770 env->log << "\t Texture INTENSITY = "
771 << machine.TexColor[u][0] << "\n";
772 break;
773 case GL_RGB:
774 env->log << "\t Texture RGB = "
775 << machine.TexColor[u][0] << ", "
776 << machine.TexColor[u][1] << ", "
777 << machine.TexColor[u][2] << "\n";
778 break;
779 case GL_RGBA:
780 env->log << "\t Texture RGBA = "
781 << machine.TexColor[u][0] << ", "
782 << machine.TexColor[u][1] << ", "
783 << machine.TexColor[u][2] << ", "
784 << machine.TexColor[u][3] << "\n";
785 break;
793 // Check that the actual GL implementation's texture state matches what's
794 // in the given glean machine state. This is only used for debugging.
796 bool
797 TexCombineTest::VerifyMachineState(const glmachine &machine) const {
799 #define VERIFY(var, expected) \
800 glGetTexEnviv(GL_TEXTURE_ENV, var, &actual); \
801 if ((GLint) (expected) != (actual)) { \
802 cerr << "Expected " << var << " = " \
803 << EnumString(expected) \
804 << " but got " \
805 << EnumString(actual) \
806 << "\n"; \
807 return false; \
809 #define VERIFYF(var, expected) \
810 glGetTexEnvfv(GL_TEXTURE_ENV, var, &actualf); \
811 if ((expected) != (actualf)) { \
812 cerr << "Expected " << var << " = " \
813 << expected \
814 << " but got " \
815 << actualf \
816 << "\n"; \
817 return false; \
821 for (int u = 0; u < machine.NumTexUnits; u++) {
822 GLint actual;
823 GLfloat actualf;
824 VERIFY(GL_COMBINE_RGB_EXT, machine.COMBINE_RGB[u]);
825 VERIFY(GL_COMBINE_ALPHA_EXT, machine.COMBINE_ALPHA[u]);
826 VERIFY(GL_SOURCE0_RGB_EXT, machine.SOURCE0_RGB[u]);
827 VERIFY(GL_SOURCE1_RGB_EXT, machine.SOURCE1_RGB[u]);
828 VERIFY(GL_SOURCE2_RGB_EXT, machine.SOURCE2_RGB[u]);
829 VERIFY(GL_OPERAND0_RGB_EXT, machine.OPERAND0_RGB[u]);
830 VERIFY(GL_OPERAND1_RGB_EXT, machine.OPERAND1_RGB[u]);
831 VERIFY(GL_OPERAND2_RGB_EXT, machine.OPERAND2_RGB[u]);
832 VERIFYF(GL_RGB_SCALE_EXT, machine.RGB_SCALE[u]);
833 VERIFYF(GL_ALPHA_SCALE, machine.ALPHA_SCALE[u]);
836 return true; // state is AOK
841 // Print an error report.
843 void
844 TexCombineTest::ReportFailure(const glmachine &machine,
845 const GLfloat expected[4],
846 const GLfloat rendered[4],
847 BasicResult& r,
848 const char *where) {
850 env->log << name << ": FAIL "
851 << r.config->conciseDescription() << '\n'
852 << "\texpected "
853 << expected[0] << ", "
854 << expected[1] << ", "
855 << expected[2] << ", "
856 << expected[3] << ", got "
857 << rendered[0] << ", "
858 << rendered[1] << ", "
859 << rendered[2] << ", "
860 << rendered[3]
861 << " in " << where << "\n";
862 PrintMachineState(machine);
867 // Examine a set of test params and compute the number of possible
868 // state combinations.
871 TexCombineTest::CountTestCombinations(const test_param testParams[]) const {
873 int numTests = 1;
874 for (int t = 0; testParams[t].target; t++) {
875 int values = 0;
876 for (int val = 0; testParams[t].validValues[val]; val++) {
877 values++;
879 numTests *= values;
881 return numTests / testStride;
886 // Setup the actual GL state and our internal simulated GL state.
888 void
889 TexCombineTest::TexEnv(glmachine &machine, int texUnit,
890 GLenum target, GLenum value) {
892 if (machine.NumTexUnits > 1)
893 p_glActiveTextureARB(GL_TEXTURE0_ARB + texUnit);
895 glTexEnvi(GL_TEXTURE_ENV, target, value);
896 int err = glGetError();
897 if (err != GL_NO_ERROR)
898 printf("Problem: glTexEnvi() generated error 0x%x\n", err);
900 switch (target) {
901 case GL_COMBINE_RGB_EXT:
902 machine.COMBINE_RGB[texUnit] = value;
903 break;
904 case GL_COMBINE_ALPHA_EXT:
905 machine.COMBINE_ALPHA[texUnit] = value;
906 break;
907 case GL_SOURCE0_RGB_EXT:
908 machine.SOURCE0_RGB[texUnit] = value;
909 break;
910 case GL_SOURCE1_RGB_EXT:
911 machine.SOURCE1_RGB[texUnit] = value;
912 break;
913 case GL_SOURCE2_RGB_EXT:
914 machine.SOURCE2_RGB[texUnit] = value;
915 break;
916 case GL_SOURCE0_ALPHA_EXT:
917 machine.SOURCE0_ALPHA[texUnit] = value;
918 break;
919 case GL_SOURCE1_ALPHA_EXT:
920 machine.SOURCE1_ALPHA[texUnit] = value;
921 break;
922 case GL_SOURCE2_ALPHA_EXT:
923 machine.SOURCE2_ALPHA[texUnit] = value;
924 break;
925 case GL_OPERAND0_RGB_EXT:
926 machine.OPERAND0_RGB[texUnit] = value;
927 break;
928 case GL_OPERAND1_RGB_EXT:
929 machine.OPERAND1_RGB[texUnit] = value;
930 break;
931 case GL_OPERAND2_RGB_EXT:
932 machine.OPERAND2_RGB[texUnit] = value;
933 break;
934 case GL_OPERAND0_ALPHA_EXT:
935 machine.OPERAND0_ALPHA[texUnit] = value;
936 break;
937 case GL_OPERAND1_ALPHA_EXT:
938 machine.OPERAND1_ALPHA[texUnit] = value;
939 break;
940 case GL_OPERAND2_ALPHA_EXT:
941 machine.OPERAND2_ALPHA[texUnit] = value;
942 break;
943 case GL_RGB_SCALE_EXT:
944 machine.RGB_SCALE[texUnit] = value;
945 break;
946 case GL_ALPHA_SCALE:
947 machine.ALPHA_SCALE[texUnit] = value;
948 break;
954 // Make the glTexEnv calls to setup one particular set of test parameters
955 // from <testParams>.
956 // <testNum> must be between 0 and CountTestCombinations(testParams)-1.
958 void
959 TexCombineTest::SetupTestEnv(struct glmachine &machine, int texUnit,
960 int testNum, const struct test_param testParams[]) {
962 int divisor = 1;
963 for (int t = 0; testParams[t].target; t++) {
964 int numValues = 0;
965 for (int val = 0; testParams[t].validValues[val]; val++) {
966 numValues++;
968 int v = (testNum / divisor) % numValues;
969 GLenum target = testParams[t].target;
970 GLenum value = testParams[t].validValues[v];
971 TexEnv(machine, texUnit, target, value);
972 divisor *= numValues;
978 // Set the fragment, texenv (constant), and texture colors for all the
979 // machine's texture units.
981 void
982 TexCombineTest::SetupColors(glmachine &machine) {
984 static const GLfloat fragColor[4] = { 0.00, 0.25, 0.50, 0.75 };
985 static const GLfloat envColors[][4] = {
986 { 0.25, 0.50, 0.75, 1.00 },
987 { 0.50, 0.75, 1.00, 0.00 },
988 { 0.75, 1.00, 0.00, 0.25 },
989 { 1.00, 0.00, 0.25, 0.50 }
991 static const GLfloat texColors[][8] = {
992 { 1.00, 0.00, 0.25, 0.50 },
993 { 0.75, 1.00, 0.00, 0.25 },
994 { 0.50, 0.75, 1.00, 0.00 },
995 { 0.25, 0.50, 0.75, 1.00 },
996 // extra colors that'll only be used for crossbar test
997 { 0.00, 0.00, 0.00, 0.00 },
998 { 0.25, 0.50, 0.50, 0.00 },
999 { 0.50, 0.25, 0.75, 0.25 },
1000 { 0.75, 1.00, 0.25, 0.00 }
1003 COPY4(machine.FragColor, fragColor);
1004 glColor4fv(fragColor);
1006 for (int u = 0; u < machine.NumTexUnits; u++) {
1007 if (machine.NumTexUnits > 1)
1008 p_glActiveTextureARB(GL_TEXTURE0_ARB + u);
1009 glBindTexture(GL_TEXTURE_2D, mTextures[u]);
1010 glEnable(GL_TEXTURE_2D);
1011 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1012 GL_NEAREST);
1013 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1014 GL_NEAREST);
1015 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
1016 machine.EnvColor[u][0] = envColors[u % 4][0];
1017 machine.EnvColor[u][1] = envColors[u % 4][1];
1018 machine.EnvColor[u][2] = envColors[u % 4][2];
1019 machine.EnvColor[u][3] = envColors[u % 4][3];
1020 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
1021 envColors[u % 4]);
1023 const GLfloat *texCol = texColors[u % 8];
1025 // Setup texture color, according to texture format
1026 switch (machine.TexFormat[u]) {
1027 case GL_RGBA:
1028 machine.TexColor[u][0] = texCol[0];
1029 machine.TexColor[u][1] = texCol[1];
1030 machine.TexColor[u][2] = texCol[2];
1031 machine.TexColor[u][3] = texCol[3];
1032 break;
1033 case GL_RGB:
1034 machine.TexColor[u][0] = texCol[0];
1035 machine.TexColor[u][1] = texCol[1];
1036 machine.TexColor[u][2] = texCol[2];
1037 machine.TexColor[u][3] = 1.0;
1038 break;
1039 case GL_ALPHA:
1040 machine.TexColor[u][0] = 0.0;
1041 machine.TexColor[u][1] = 0.0;
1042 machine.TexColor[u][2] = 0.0;
1043 machine.TexColor[u][3] = texCol[3];
1044 break;
1045 case GL_LUMINANCE:
1046 machine.TexColor[u][0] = texCol[0];
1047 machine.TexColor[u][1] = texCol[0];
1048 machine.TexColor[u][2] = texCol[0];
1049 machine.TexColor[u][3] = 1.0;
1050 break;
1051 case GL_LUMINANCE_ALPHA:
1052 machine.TexColor[u][0] = texCol[0];
1053 machine.TexColor[u][1] = texCol[0];
1054 machine.TexColor[u][2] = texCol[0];
1055 machine.TexColor[u][3] = texCol[3];
1056 break;
1057 case GL_INTENSITY:
1058 machine.TexColor[u][0] = texCol[0];
1059 machine.TexColor[u][1] = texCol[0];
1060 machine.TexColor[u][2] = texCol[0];
1061 machine.TexColor[u][3] = texCol[0];
1062 break;
1063 default:
1064 problem("bad texture format");
1065 return;
1068 // Make a 4x4 solid color texture
1069 GLfloat image[16][4];
1070 int i;
1071 for (i = 0; i < 16; i++) {
1072 image[i][0] = texColors[u % 8][0];
1073 image[i][1] = texColors[u % 8][1];
1074 image[i][2] = texColors[u % 8][2];
1075 image[i][3] = texColors[u % 8][3];
1077 glTexImage2D(GL_TEXTURE_2D, 0, machine.TexFormat[u],
1078 4, 4, 0, GL_RGBA, GL_FLOAT, image);
1080 #if 0 // Debug
1081 GLfloat check[16][4];
1082 GLint r, g, b, a;
1083 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1084 GL_TEXTURE_RED_SIZE, &r);
1085 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1086 GL_TEXTURE_GREEN_SIZE, &g);
1087 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1088 GL_TEXTURE_BLUE_SIZE, &b);
1089 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1090 GL_TEXTURE_ALPHA_SIZE, &a);
1091 printf("Texture bits: %d %d %d %d\n", r, g, b, a);
1092 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT,
1093 check);
1094 for (i = 0;i < 16; i++) {
1095 printf("%2d: %4f %4f %4f %4f %4f %4f %4f %4f\n", i,
1096 image[i][0], image[i][1],
1097 image[i][2], image[i][3],
1098 check[i][0], check[i][1],
1099 check[i][2], check[i][3]);
1101 #endif
1107 // Test texenv-combine with a single texture unit.
1109 bool
1110 TexCombineTest::RunSingleTextureTest(glmachine &machine,
1111 const test_param testParams[], BasicResult &r, Window& w) {
1113 assert(machine.NumTexUnits == 1);
1114 SetupColors(machine);
1116 const int numTests = CountTestCombinations(testParams);
1117 //printf("Testing %d combinations\n", numTests);
1119 for (int test = 0; test < numTests; test += testStride) {
1120 // 0. Setup state
1121 ResetMachine(machine);
1122 SetupTestEnv(machine, 0, test, testParams);
1124 // 1. Render with OpenGL
1125 GLfloat renderedResult[4];
1126 glTexCoord2f(0, 0); // use texcoord (0,0) for all vertices
1127 glBegin(GL_POLYGON);
1128 glVertex2f(-1.0, -1.0);
1129 glVertex2f( 1.0, -1.0);
1130 glVertex2f( 1.0, 1.0);
1131 glVertex2f(-1.0, 1.0);
1132 glEnd();
1133 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, renderedResult);
1134 w.swap();
1136 // 2. Compute expected result
1137 GLfloat expected[4];
1138 ComputeTexCombine(machine, 0, machine.FragColor, expected);
1140 // 3. Compare rendered result to expected result
1141 const GLfloat dr = fabs(expected[0] - renderedResult[0]);
1142 const GLfloat dg = fabs(expected[1] - renderedResult[1]);
1143 const GLfloat db = fabs(expected[2] - renderedResult[2]);
1144 const GLfloat da = fabs(expected[3] - renderedResult[3]);
1145 if (dr > mTolerance[0] || dg > mTolerance[1] ||
1146 db > mTolerance[2] || da > mTolerance[3]) {
1147 ReportFailure(machine, expected, renderedResult, r,
1148 "Single Texture Test");
1149 #if 0 // Debug
1150 VerifyMachineState(machine);
1151 // For debugging, printing the state of the previous
1152 // test is useful to see what's changed when we've
1153 // failed a test but passed the previous one.
1154 printf("single-texture test %d failed\n", test);
1155 if (test > 0) {
1156 printf("prev test:\n");
1157 SetupTestEnv(machine, 0, test - 1, testParams);
1158 PrintMachineState(machine);
1160 #endif
1161 return false;
1163 #if 0 // Debug
1164 else {
1165 printf("PASSED test %d!\n", test);
1166 env->log << "\texpected "
1167 << expected[0] << ", "
1168 << expected[1] << ", "
1169 << expected[2] << ", "
1170 << expected[3] << ", got "
1171 << renderedResult[0] << ", "
1172 << renderedResult[1] << ", "
1173 << renderedResult[2] << ", "
1174 << renderedResult[3] << "\n";
1175 // PrintMachineState(machine);
1177 #endif
1179 return true;
1185 // For each texture unit, test each texenv-combine mode.
1186 // That's 5 ^ NumTexUnits combinations.
1187 // Or 7 ^ numTexUnits if DOT3 combine mode is supported
1190 TexCombineTest::CountMultiTextureTestCombinations(const glmachine &machine) const {
1192 int numTests = 1;
1193 int numUnits = machine.NumTexUnits > 4 ? 4 : machine.NumTexUnits;
1194 for (int i = 0; i < numUnits; i++)
1195 numTests *= (haveDot3 ? 7 : 5);
1197 return numTests / testStride;
1202 // Test texenv-combine with multiple texture units.
1204 bool
1205 TexCombineTest::RunMultiTextureTest(glmachine &machine, BasicResult &r,
1206 Window& w) {
1208 static const GLenum combineModes[7] = {
1209 GL_REPLACE,
1210 GL_ADD,
1211 GL_ADD_SIGNED_EXT,
1212 GL_MODULATE,
1213 GL_INTERPOLATE_EXT,
1214 GL_DOT3_RGB_EXT,
1215 GL_DOT3_RGBA_EXT
1217 static const int numModes = haveDot3 ? 7 : 5;
1219 // four texture units is enough to test
1220 if (machine.NumTexUnits > 4)
1221 machine.NumTexUnits = 4;
1223 const int numTests = CountMultiTextureTestCombinations(machine);
1224 //printf("Testing %d multitexture combinations\n", numTests);
1226 SetupColors(machine);
1227 for (int testNum = 0; testNum < numTests; testNum += testStride) {
1228 // 0. Set up texture units
1229 ResetMachine(machine);
1230 int divisor = 1;
1231 int u;
1232 for (u = 0; u < machine.NumTexUnits; u++) {
1233 const int m = (testNum / divisor) % numModes;
1234 const GLenum mode = combineModes[m];
1236 // Set GL_COMBINE_RGB_EXT and GL_COMBINE_ALPHA_EXT
1237 TexEnv(machine, u, GL_COMBINE_RGB_EXT, mode);
1238 TexEnv(machine, u, GL_COMBINE_ALPHA_EXT,
1239 (mode == GL_DOT3_RGB_EXT ||
1240 mode == GL_DOT3_RGBA_EXT) ? GL_REPLACE : mode);
1241 TexEnv(machine, u, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
1242 TexEnv(machine, u, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
1243 TexEnv(machine, u, GL_SOURCE2_RGB_EXT, GL_TEXTURE);
1244 TexEnv(machine, u, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
1245 TexEnv(machine, u, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
1246 TexEnv(machine, u, GL_SOURCE2_ALPHA_EXT, GL_TEXTURE);
1247 TexEnv(machine, u, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
1248 TexEnv(machine, u, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
1249 TexEnv(machine, u, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
1250 TexEnv(machine, u, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
1251 TexEnv(machine, u, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA);
1252 TexEnv(machine, u, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
1253 TexEnv(machine, u, GL_RGB_SCALE_EXT, 1);
1254 TexEnv(machine, u, GL_ALPHA_SCALE, 1);
1256 //printf("texenv%d = %s ", u, EnumString(mode));
1257 divisor *= numModes;
1259 //printf("\n");
1261 // 1. Render with OpenGL
1262 GLfloat renderedResult[4];
1263 // use texcoord (0,0) for all vertices
1264 for (int u = 0; u < machine.NumTexUnits; u++)
1265 p_glMultiTexCoord2fARB(GL_TEXTURE0_ARB + u, 0, 0);
1266 glBegin(GL_POLYGON);
1267 glVertex2f(-1.0, -1.0);
1268 glVertex2f( 1.0, -1.0);
1269 glVertex2f( 1.0, 1.0);
1270 glVertex2f(-1.0, 1.0);
1271 glEnd();
1272 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, renderedResult);
1273 w.swap();
1275 // 2. Compute expected result
1276 GLfloat prevColor[4];
1277 GLfloat expected[4];
1278 for (u = 0; u < machine.NumTexUnits; u++) {
1279 if (u == 0) {
1280 COPY4(prevColor, machine.FragColor);
1281 } else {
1282 COPY4(prevColor, expected);
1284 ComputeTexCombine(machine, u, prevColor, expected);
1287 // 3. Compare rendered result to expected result
1288 const GLfloat dr = fabs(expected[0] - renderedResult[0]);
1289 const GLfloat dg = fabs(expected[1] - renderedResult[1]);
1290 const GLfloat db = fabs(expected[2] - renderedResult[2]);
1291 const GLfloat da = fabs(expected[3] - renderedResult[3]);
1292 if (dr > mTolerance[0] || dg > mTolerance[1] ||
1293 db > mTolerance[2] || da > mTolerance[3]) {
1294 ReportFailure(machine, expected, renderedResult, r,
1295 "Multi-texture test");
1296 #if 0 // Debug
1297 printf("multitex test %d failed\n", testNum);
1298 if (testNum > 0) {
1299 printf("prev test:\n");
1300 SetupTestEnv(machine, 0, testNum - 1, testParams);
1301 PrintMachineState(machine);
1303 #endif
1305 return false;
1308 return true;
1313 TexCombineTest::CountCrossbarCombinations() const
1315 GLint numUnits;
1316 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &numUnits);
1317 return numUnits;
1321 bool
1322 TexCombineTest::RunCrossbarTest(glmachine &machine, BasicResult &r, Window& w) {
1323 // We do a really short, simple test for GL_ARB_texture_env_crossbar
1324 // since the preceeding tests are pretty comprehensive and the
1325 // crossbar feature is just an incremental addition.
1326 // Basically, if we have N texture units we run N tests.
1327 // For test [i] we set texture unit [i] to fetch the texture color
1328 // from unit [numUnits - i - 1]. For units != i we use the constant
1329 // color (0,0,0,0). We use GL_ADD mode to compute the sum over all units.
1330 // So effectively, the result of texture combine is simply the incoming
1331 // fragment color plus unit [numUnits - test - 1]'s texture color.
1333 int unit;
1335 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint *) &Machine.NumTexUnits);
1337 // Set up constant texture state for all tests
1338 ResetMachine(machine);
1339 SetupColors(machine);
1340 for (unit = 0; unit < machine.NumTexUnits; unit++) {
1341 TexEnv(machine, unit, GL_COMBINE_RGB_EXT, GL_ADD);
1342 TexEnv(machine, unit, GL_COMBINE_ALPHA_EXT, GL_ADD);
1343 TexEnv(machine, unit, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
1344 TexEnv(machine, unit, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
1345 // SOURCE1_RGB/ALPHA is set below, per test
1346 TexEnv(machine, unit, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
1347 TexEnv(machine, unit, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
1348 TexEnv(machine, unit, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
1349 TexEnv(machine, unit, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
1350 TexEnv(machine, unit, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
1351 TexEnv(machine, unit, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
1352 TexEnv(machine, unit, GL_RGB_SCALE_EXT, 1);
1353 TexEnv(machine, unit, GL_ALPHA_SCALE, 1);
1355 machine.EnvColor[unit][0] = 0.0F;
1356 machine.EnvColor[unit][1] = 0.0F;
1357 machine.EnvColor[unit][2] = 0.0F;
1358 machine.EnvColor[unit][3] = 0.0F;
1359 p_glActiveTextureARB(GL_TEXTURE0_ARB + unit);
1360 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
1361 machine.EnvColor[unit]);
1364 for (int test = 0; test < machine.NumTexUnits; test++) {
1365 // 1. Set up texture state
1366 for (unit = 0; unit < machine.NumTexUnits; unit++) {
1367 if (unit == test) {
1368 const int revUnit = machine.NumTexUnits - unit - 1;
1369 TexEnv(machine, unit, GL_SOURCE1_RGB_EXT,
1370 GL_TEXTURE0_ARB + revUnit);
1371 TexEnv(machine, unit, GL_SOURCE1_ALPHA_EXT,
1372 GL_TEXTURE0_ARB + revUnit);
1374 else {
1375 TexEnv(machine, unit, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT);
1376 TexEnv(machine, unit, GL_SOURCE1_ALPHA_EXT, GL_CONSTANT_EXT);
1380 // 2. Render with OpenGL
1381 GLfloat renderedResult[4];
1382 // texcoord (0,) for all vertices is OK
1383 for (unit = 0; unit < machine.NumTexUnits; unit++)
1384 p_glMultiTexCoord2fARB(GL_TEXTURE0_ARB + unit, 0, 0);
1385 glColor4fv(machine.FragColor);
1386 glBegin(GL_POLYGON);
1387 glVertex2f(-1.0, -1.0);
1388 glVertex2f( 1.0, -1.0);
1389 glVertex2f( 1.0, 1.0);
1390 glVertex2f(-1.0, 1.0);
1391 glEnd();
1392 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, renderedResult);
1393 w.swap();
1395 // 3. Compute expected result
1396 GLfloat prevColor[4];
1397 GLfloat expected[4];
1398 for (unit = 0; unit < machine.NumTexUnits; unit++) {
1399 if (unit == 0) {
1400 COPY4(prevColor, machine.FragColor);
1401 } else {
1402 COPY4(prevColor, expected);
1404 ComputeTexCombine(machine, unit, prevColor, expected);
1407 // 4. Compare rendered result to expected result
1408 const GLfloat dr = fabs(expected[0] - renderedResult[0]);
1409 const GLfloat dg = fabs(expected[1] - renderedResult[1]);
1410 const GLfloat db = fabs(expected[2] - renderedResult[2]);
1411 const GLfloat da = fabs(expected[3] - renderedResult[3]);
1412 if (dr > mTolerance[0] || dg > mTolerance[1] ||
1413 db > mTolerance[2] || da > mTolerance[3]) {
1414 ReportFailure(machine, expected, renderedResult, r,
1415 "Texture crossbar test");
1416 #if 0 // Debug
1417 printf("crossbar test %d failed\n", testNum);
1418 PrintMachineState(machine);
1419 #endif
1420 return false;
1423 return true;
1426 ///////////////////////////////////////////////////////////////////////////////
1427 // runOne: Run a single test case
1428 ///////////////////////////////////////////////////////////////////////////////
1430 // XXX should we run a number of individual tests instead?
1431 void
1432 TexCombineTest::runOne(BasicResult& r, Window& w) {
1433 // Grab pointers to the extension functions. It's safe to use
1434 // these without testing them because we already know that we
1435 // won't be invoked except on contexts that support the
1436 // extension.
1437 p_glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)
1438 (GLUtils::getProcAddress("glActiveTextureARB"));
1439 p_glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)
1440 (GLUtils::getProcAddress("glMultiTexCoord2fARB"));
1442 // Test the availability of the DOT3 extenstion
1443 haveDot3 = GLUtils::haveExtensions("GL_EXT_texture_env_dot3");
1445 haveCrossbar = GLUtils::haveExtensions("GL_ARB_texture_env_crossbar")
1446 && GLUtils::haveExtensions("GL_ARB_texture_env_combine");
1448 // compute RGB error tolerance
1450 GLint rBits, gBits, bBits, aBits;
1451 GLint rTexBits, gTexBits, bTexBits, aTexBits;
1452 GLfloat texImage[4][4][4];
1453 // Make dummy texture image
1454 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0,
1455 GL_RGBA, GL_FLOAT, texImage);
1456 glGetIntegerv(GL_RED_BITS, &rBits);
1457 glGetIntegerv(GL_GREEN_BITS, &gBits);
1458 glGetIntegerv(GL_BLUE_BITS, &bBits);
1459 glGetIntegerv(GL_ALPHA_BITS, &aBits);
1460 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1461 GL_TEXTURE_RED_SIZE, &rTexBits);
1462 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1463 GL_TEXTURE_GREEN_SIZE, &gTexBits);
1464 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1465 GL_TEXTURE_BLUE_SIZE, &bTexBits);
1466 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
1467 GL_TEXTURE_ALPHA_SIZE, &aTexBits);
1468 // find smaller of frame buffer and texture bits
1469 rBits = (rBits < rTexBits) ? rBits : rTexBits;
1470 gBits = (gBits < gTexBits) ? gBits : gTexBits;
1471 bBits = (bBits < bTexBits) ? bBits : bTexBits;
1472 aBits = (aBits < aTexBits) ? aBits : aTexBits;
1473 // tolerance is 3 bits of error
1474 mTolerance[0] = 8.0 / (1 << rBits);
1475 mTolerance[1] = 8.0 / (1 << gBits);
1476 mTolerance[2] = 8.0 / (1 << bBits);
1477 if (aBits == 0)
1478 mTolerance[3] = 1.0;
1479 else
1480 mTolerance[3] = 8.0 / (1 << aBits);
1482 printf("Tolerance: %g %g %g %g\n",
1483 mTolerance[0], mTolerance[1],
1484 mTolerance[2], mTolerance[3]);
1488 // Allocate our textures
1489 glGenTextures(MAX_TEX_UNITS, mTextures);
1491 // We'll only render a 4-pixel polygon
1492 glViewport(0, 0, 2, 2);
1494 ResetMachine(Machine);
1495 Machine.NumTexUnits = 1;
1497 // If quick mode, run fewer tests
1498 if (env->options.quick)
1499 testStride = 11; // a prime number
1500 else
1501 testStride = 1;
1503 // Do single texture unit tests first.
1504 bool passed = RunSingleTextureTest(Machine, ReplaceParams, r, w);
1505 if (passed)
1506 passed = RunSingleTextureTest(Machine, AddParams, r, w);
1507 if (passed)
1508 passed = RunSingleTextureTest(Machine, AddSignedParams, r, w);
1509 if (passed)
1510 passed = RunSingleTextureTest(Machine, ModulateParams, r, w);
1511 if (passed)
1512 passed = RunSingleTextureTest(Machine, InterpolateParams, r, w);
1513 if (passed && haveDot3)
1514 passed = RunSingleTextureTest(Machine, Dot3RGBParams, r, w);
1515 if (passed && haveDot3)
1516 passed = RunSingleTextureTest(Machine, Dot3RGBAParams, r, w);
1518 // Now do some multi-texture tests
1519 if (passed) {
1520 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,
1521 (GLint *) &Machine.NumTexUnits);
1522 if (Machine.NumTexUnits > 1) {
1523 passed = RunMultiTextureTest(Machine, r, w);
1527 // Do crossbar tests
1528 if (passed && haveCrossbar) {
1529 passed = RunCrossbarTest(Machine, r, w);
1532 r.pass = passed;
1534 // Delete our textures
1535 glDeleteTextures(MAX_TEX_UNITS, mTextures);
1537 } // TexCombineTest::runOne
1539 void
1540 TexCombineTest::logOne(BasicResult& r) {
1541 if (r.pass) {
1542 logPassFail(r);
1543 logConcise(r);
1544 env->log << "\tTested "
1545 << CountTestCombinations(ReplaceParams)
1546 << " GL_REPLACE combinations\n";
1547 env->log << "\tTested "
1548 << CountTestCombinations(AddParams)
1549 << " GL_ADD combinations\n";
1550 env->log << "\tTested "
1551 << CountTestCombinations(AddSignedParams)
1552 << " GL_ADD_SIGNED_EXT combinations\n";
1553 env->log << "\tTested "
1554 << CountTestCombinations(ModulateParams)
1555 << " GL_MODULATE combinations\n";
1556 env->log << "\tTested "
1557 << CountTestCombinations(InterpolateParams)
1558 << " GL_INTERPOLATE_EXT combinations\n";
1559 if (haveDot3) {
1560 env->log << "\tTested "
1561 << CountTestCombinations(Dot3RGBParams)
1562 << " GL_DOT3_RGB_EXT combinations\n";
1563 env->log << "\tTested "
1564 << CountTestCombinations(Dot3RGBAParams)
1565 << " GL_DOT3_RGBA_EXT combinations\n";
1567 env->log << "\tTested "
1568 << CountMultiTextureTestCombinations(Machine)
1569 << " multitexture combinations\n";
1570 if (haveCrossbar) {
1571 env->log << "\tTested "
1572 << CountCrossbarCombinations()
1573 << " crossbar combinations\n";
1576 } // TexCombineTest::logOne
1579 ///////////////////////////////////////////////////////////////////////////////
1580 // The test object itself:
1581 ///////////////////////////////////////////////////////////////////////////////
1582 TexCombineTest texCombTest("texCombine", "window, rgb",
1584 "GL_EXT_texture_env_combine verification test.\n"
1585 "We only test a subset of all possible texture env combinations\n"
1586 "because there's simply too many to exhaustively test them all.\n");
1589 } // namespace GLEAN