Add more structure constructor tests.
[piglit/hramrach.git] / tests / glean / ttexswizzle.cpp
blobca56d9334a4e673737a12e0d9e8bae5db2adafb0
1 // BEGIN_COPYRIGHT -*- glean -*-
2 //
3 // Copyright (C) 2009 VMware, Inc. 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 VMWARE 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 // Test GL_EXT_texture_swizzle for all possible swizzle combinations
31 // both with fixed function and a fragment program.
32 // Brian Paul
33 // 28 Jan 2009
36 #define GL_GLEXT_PROTOTYPES
38 #include <cassert>
39 #include <cmath>
40 #include <cstring>
41 #include <stdlib.h>
42 #include "ttexswizzle.h"
43 #include "rand.h"
44 #include "timer.h"
45 #include "image.h"
48 namespace GLEAN {
50 static PFNGLPROGRAMSTRINGARBPROC glProgramStringARB_func = NULL;
51 static PFNGLBINDPROGRAMARBPROC glBindProgramARB_func = NULL;
52 static PFNGLGENPROGRAMSARBPROC glGenProgramsARB_func = NULL;
54 static const int TexSize = 16;
56 static const GLfloat vertexData[4][4] = {
57 // x, y, s, t
58 { -1.0, -1.0, 0.0, 0.0 },
59 { 1.0, -1.0, 1.0, 0.0 },
60 { 1.0, 1.0, 1.0, 1.0 },
61 { -1.0, 1.0, 0.0, 1.0 }
65 TexSwizzleResult::TexSwizzleResult()
67 pass = false;
71 void
72 TexSwizzleTest::RandomColor(GLubyte *color)
74 color[0] = rand.next() & 0xff;
75 color[1] = rand.next() & 0xff;
76 color[2] = rand.next() & 0xff;
77 color[3] = rand.next() & 0xff;
81 void
82 TexSwizzleTest::SetTextureColor(const GLubyte *color)
84 GLubyte texImage[TexSize][TexSize][4];
85 int i, j;
87 for (i = 0; i < TexSize; i++) {
88 for (j = 0; j < TexSize; j++) {
89 texImage[i][j][0] = color[0];
90 texImage[i][j][1] = color[1];
91 texImage[i][j][2] = color[2];
92 texImage[i][j][3] = color[3];
96 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexSize, TexSize, 0,
97 GL_RGBA, GL_UNSIGNED_BYTE, texImage);
101 GLubyte
102 TexSwizzleTest::Swizzle(const GLubyte *texColor, GLenum swizzle)
104 switch (swizzle) {
105 case GL_RED:
106 return texColor[0];
107 case GL_GREEN:
108 return texColor[1];
109 case GL_BLUE:
110 return texColor[2];
111 case GL_ALPHA:
112 return texColor[3];
113 case GL_ONE:
114 return 255;
115 case GL_ZERO:
116 return 0;
117 default:
118 assert(0);
123 void
124 TexSwizzleTest::ComputeExpectedColor(const GLubyte *texColor,
125 GLenum swizzleR,
126 GLenum swizzleG,
127 GLenum swizzleB,
128 GLenum swizzleA,
129 GLubyte *expectedColor)
131 expectedColor[0] = Swizzle(texColor, swizzleR);
132 expectedColor[1] = Swizzle(texColor, swizzleG);
133 expectedColor[2] = Swizzle(texColor, swizzleB);
134 expectedColor[3] = Swizzle(texColor, swizzleA);
138 const char *
139 TexSwizzleTest::SwizzleString(GLenum swizzle)
141 switch (swizzle) {
142 case GL_RED:
143 return "GL_RED";
144 case GL_GREEN:
145 return "GL_GREEN";
146 case GL_BLUE:
147 return "GL_BLUE";
148 case GL_ALPHA:
149 return "GL_ALPHA";
150 case GL_ZERO:
151 return "GL_ZERO";
152 case GL_ONE:
153 return "GL_ONE";
154 default:
155 assert(0);
156 return "???";
161 void
162 TexSwizzleTest::ReportFailure(GLenum swizzleR, GLenum swizzleG,
163 GLenum swizzleB, GLenum swizzleA,
164 const GLubyte *texColor,
165 const GLubyte *actual,
166 const GLubyte *expected)
168 char str[100];
170 env->log << name << ": Error: GL_EXT_texure_swizzle test failed\n";
171 env->log << "\tGL_TEXTURE_SWIZZLE_R_EXT = " << SwizzleString(swizzleR) << "\n";
172 env->log << "\tGL_TEXTURE_SWIZZLE_G_EXT = " << SwizzleString(swizzleG) << "\n";
173 env->log << "\tGL_TEXTURE_SWIZZLE_B_EXT = " << SwizzleString(swizzleB) << "\n";
174 env->log << "\tGL_TEXTURE_SWIZZLE_A_EXT = " << SwizzleString(swizzleA) << "\n";
175 if (glIsEnabled(GL_FRAGMENT_PROGRAM_ARB)) {
176 env->log << "\tGL_FRAGMENT_PROGRAM enabled\n";
178 sprintf(str, "%d, %d, %d, %d",
179 texColor[0], texColor[1], texColor[2], texColor[3]);
180 env->log << "\tTexture color: " << str << "\n";
181 sprintf(str, "%d, %d, %d, %d",
182 expected[0], expected[1], expected[2], expected[3]);
183 env->log << "\tExpected color: " << str << "\n";
184 sprintf(str, "%d, %d, %d, %d",
185 actual[0], actual[1], actual[2], actual[3]);
186 env->log << "\tRendered color: " << str << "\n";
190 // Test state setting/getting for texture swizzle.
191 bool
192 TexSwizzleTest::TestAPI(void)
194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R_EXT, GL_ONE);
195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G_EXT, GL_ZERO);
196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B_EXT, GL_RED);
197 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A_EXT, GL_BLUE);
199 if (glGetError() != GL_NO_ERROR) {
200 env->log << "\tSetting GL_TEXTURE_SWIZZLE_R/G/B/A generated an error.\n";
201 return false;
204 GLint val;
205 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R_EXT, &val);
206 if (val != GL_ONE) {
207 env->log << "\tQuery of GL_TEXTURE_SWIZZLE_R_EXT failed.\n";
208 return false;
210 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G_EXT, &val);
211 if (val != GL_ZERO) {
212 env->log << "\tQuery of GL_TEXTURE_SWIZZLE_G_EXT failed.\n";
213 return false;
215 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B_EXT, &val);
216 if (val != GL_RED) {
217 env->log << "\tQuery of GL_TEXTURE_SWIZZLE_B_EXT failed.\n";
218 return false;
220 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A_EXT, &val);
221 if (val != GL_BLUE) {
222 env->log << "\tQuery of GL_TEXTURE_SWIZZLE_A_EXT failed.\n";
223 return false;
226 // set all at once
227 const GLint swz[4] = { GL_BLUE, GL_GREEN, GL_ALPHA, GL_ZERO };
228 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA_EXT, swz);
229 if (glGetError() != GL_NO_ERROR) {
230 env->log << "\tSetting GL_TEXTURE_SWIZZLE_RGBA_EXT generated an error.\n";
231 return false;
234 GLint swzOut[4];
235 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA_EXT, swzOut);
236 if (swzOut[0] != swz[0] ||
237 swzOut[1] != swz[1] ||
238 swzOut[2] != swz[2] ||
239 swzOut[3] != swz[3]) {
240 env->log << "\tQuerying GL_TEXTURE_SWIZZLE_RGBA_EXT failed.\n";
241 return false;
244 return true;
248 // Loop over all possible combinations of texture swizzles,
249 // drawing with a texture and checking if the results are correct.
250 // return true/false for pass/fail
251 bool
252 TexSwizzleTest::TestSwizzles(void)
254 static const GLenum swizzles[6] = {
255 GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE
257 int ir, ig, ib, ia;
258 GLubyte texColor[4];
259 int err = 1; // XXX this should be computed from framebuffer depth
261 for (ir = 0; ir < 6; ir++) {
262 glTexParameteri(GL_TEXTURE_2D,
263 GL_TEXTURE_SWIZZLE_R_EXT,
264 swizzles[ir]);
265 for (ig = 0; ig < 6; ig++) {
266 glTexParameteri(GL_TEXTURE_2D,
267 GL_TEXTURE_SWIZZLE_G_EXT,
268 swizzles[ig]);
270 // Setup random texture color here (not in the innermost loop
271 // for _every_ iteration) just to speed things up a bit.
272 RandomColor(texColor);
273 SetTextureColor(texColor);
275 for (ib = 0; ib < 6; ib++) {
276 glTexParameteri(GL_TEXTURE_2D,
277 GL_TEXTURE_SWIZZLE_B_EXT,
278 swizzles[ib]);
279 for (ia = 0; ia < 6; ia++) {
280 glTexParameteri(GL_TEXTURE_2D,
281 GL_TEXTURE_SWIZZLE_A_EXT,
282 swizzles[ia]);
284 GLubyte expected[4];
285 ComputeExpectedColor(texColor,
286 swizzles[ir],
287 swizzles[ig],
288 swizzles[ib],
289 swizzles[ia],
290 expected);
292 // draw something and read back a pixel
293 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
294 GLubyte actual[4];
295 glReadPixels(windowSize / 2, windowSize / 2, 1, 1,
296 GL_RGBA, GL_UNSIGNED_BYTE, actual);
298 if (abs((int) actual[0] - (int) expected[0]) > err ||
299 abs((int) actual[1] - (int) expected[1]) > err ||
300 abs((int) actual[2] - (int) expected[2]) > err) {
302 ReportFailure(swizzles[ir],
303 swizzles[ig],
304 swizzles[ib],
305 swizzles[ia],
306 texColor, actual, expected);
308 return false;
315 return true;
319 // Same test as above, but using a fragment program instead of fixed-function.
320 bool
321 TexSwizzleTest::TestSwizzlesWithProgram(void)
323 const char *text =
324 "!!ARBfp1.0\n"
325 "TEX result.color, fragment.texcoord[0], texture[0], 2D; \n"
326 "END\n";
327 GLuint prog;
329 glGenProgramsARB_func(1, &prog);
330 glBindProgramARB_func(GL_FRAGMENT_PROGRAM_ARB, prog);
331 glProgramStringARB_func(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
332 strlen(text), (const GLubyte *) text);
334 assert(glGetError() == GL_NO_ERROR);
336 glEnable(GL_FRAGMENT_PROGRAM_ARB);
338 bool pass = TestSwizzles();
340 glDisable(GL_FRAGMENT_PROGRAM_ARB);
342 return pass;
346 void
347 TexSwizzleTest::Setup(void)
349 glProgramStringARB_func = (PFNGLPROGRAMSTRINGARBPROC) GLUtils::getProcAddress("glProgramStringARB");
350 assert(glProgramStringARB_func);
351 glBindProgramARB_func = (PFNGLBINDPROGRAMARBPROC) GLUtils::getProcAddress("glBindProgramARB");
352 assert(glBindProgramARB_func);
353 glGenProgramsARB_func = (PFNGLGENPROGRAMSARBPROC) GLUtils::getProcAddress("glGenProgramsARB");
354 assert(glGenProgramsARB_func);
356 // setup transformation
357 glViewport(0, 0, windowSize, windowSize);
358 glMatrixMode(GL_MODELVIEW);
359 glLoadIdentity();
360 glMatrixMode(GL_PROJECTION);
361 glLoadIdentity();
363 // setup vertex arrays (draw textured quad)
364 glVertexPointer(2, GL_FLOAT, 16, vertexData);
365 glTexCoordPointer(2, GL_FLOAT, 16, &vertexData[0][2]);
366 glEnable(GL_VERTEX_ARRAY);
367 glEnable(GL_TEXTURE_COORD_ARRAY);
369 // setup texture
370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
371 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
372 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
373 glEnable(GL_TEXTURE_2D);
377 void
378 TexSwizzleTest::runOne(TexSwizzleResult &r, Window &w)
380 (void) w; // silence warning
382 Setup();
384 r.pass = TestAPI();
386 if (r.pass) {
387 r.pass = TestSwizzles();
390 if (r.pass && GLUtils::haveExtension("GL_ARB_fragment_program")) {
391 r. pass = TestSwizzlesWithProgram();
396 void
397 TexSwizzleTest::logOne(TexSwizzleResult &r)
399 if (r.pass) {
400 logPassFail(r);
401 logConcise(r);
403 else {
404 env->log << name << " FAIL\n";
409 void
410 TexSwizzleTest::compareOne(TexSwizzleResult &oldR,
411 TexSwizzleResult &newR)
413 comparePassFail(oldR, newR);
417 void
418 TexSwizzleResult::putresults(ostream &s) const
420 if (pass) {
421 s << "PASS\n";
423 else {
424 s << "FAIL\n";
429 bool
430 TexSwizzleResult::getresults(istream &s)
432 char result[1000];
433 s >> result;
435 if (strcmp(result, "FAIL") == 0) {
436 pass = false;
438 else {
439 pass = true;
441 return s.good();
445 // The test object itself:
446 TexSwizzleTest texSwizzleTest("texSwizzle", "window, rgb",
447 "GL_EXT_texture_swizzle",
448 "Test the GL_EXT_texture_swizzle extension.\n");
452 } // namespace GLEAN