1 /*
2  * Copyright 2012 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 /*
25  * file draw-pixels.c
26  *
27  * Test to verify functionality of glDrawPixels() with various pixel formats
28  * and data types
29  *
30  * author: Anuj Phogat
31  */
32 
33 #include "piglit-util-gl.h"
34 
35 /* Data conversions as used in mesa */
36 /** Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */
37 #define UBYTE_TO_FLOAT(u) ((float) u / 255.0F)
38 
39 /** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */
40 #define BYTE_TO_FLOAT(B)    ((B) == -128 ? -1.0F : (B) * (1.0F/127.0F))
41 
42 /** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */
43 #define USHORT_TO_FLOAT(S)  ((GLfloat) (S) * (1.0F / 65535.0F))
44 
45 /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
46 #define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
47 
48 /** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
49 #define UINT_TO_FLOAT(U)    ((GLfloat) ((U) * (1.0F / 4294967295.0)))
50 
51 /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
52 #define INT_TO_FLOAT(I)     ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0)))
53 
54 PIGLIT_GL_TEST_CONFIG_BEGIN
55 
56 	config.supports_gl_compat_version = 10;
57 
58 	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DEPTH | PIGLIT_GL_VISUAL_STENCIL;
59 
60 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
61 
62 PIGLIT_GL_TEST_CONFIG_END
63 
64 const GLuint idx0 = 0, idx1 = 1, idx2 = 2, idx3 = 3;
65 static GLfloat expected[100][4];
66 
67 /*As per OpenGL 3.0 specification integer formats are not allowed in
68  * glDrawPixels
69  */
70 static GLenum pixel_formats[] = {
71 	GL_RED,
72 	GL_GREEN,
73 	GL_BLUE,
74 	GL_ALPHA,
75 	GL_RG,
76 	GL_RGB,
77 	GL_BGR,
78 	GL_RGBA,
79 	GL_BGRA,
80 	GL_LUMINANCE,
81 	GL_LUMINANCE_ALPHA,
82 	GL_DEPTH_COMPONENT,
83 	GL_STENCIL_INDEX };
84 
85 static GLenum data_types[] = {
86 	GL_BYTE,
87 	GL_UNSIGNED_BYTE,
88 	GL_SHORT,
89 	GL_UNSIGNED_SHORT,
90 	GL_INT,
91 	GL_UNSIGNED_INT,
92 	GL_FLOAT,
93 	GL_UNSIGNED_BYTE_3_3_2,
94 	GL_UNSIGNED_BYTE_2_3_3_REV,
95 	GL_UNSIGNED_SHORT_5_6_5,
96 	GL_UNSIGNED_SHORT_5_6_5_REV,
97 	GL_UNSIGNED_SHORT_4_4_4_4,
98 	GL_UNSIGNED_SHORT_4_4_4_4_REV,
99 	GL_UNSIGNED_SHORT_5_5_5_1,
100 	GL_UNSIGNED_SHORT_1_5_5_5_REV,
101 	GL_UNSIGNED_INT_8_8_8_8,
102 	GL_UNSIGNED_INT_8_8_8_8_REV,
103 	GL_UNSIGNED_INT_10_10_10_2,
104 	GL_UNSIGNED_INT_2_10_10_10_REV };
105 
106 typedef struct p_ops {
107 	GLenum pname;
108 	GLint param;
109 } p_ops;
110 
111 static const p_ops pixel_ops[] = {
112 	{ GL_UNPACK_SWAP_BYTES,		0 },
113 	{ GL_UNPACK_SWAP_BYTES,		1 } };
114 
115 
Swap2Byte(void * value)116 void Swap2Byte(void *value)
117 {
118 	GLubyte *bytes = (GLubyte *) value;
119 	GLubyte tmp = bytes[0];
120 	bytes[0] = bytes[1];
121 	bytes[1] = tmp;
122 }
123 
Swap4Byte(void * value)124 void Swap4Byte(void *value)
125 {
126 	GLubyte *bytes = (GLubyte *) value;
127 	GLubyte tmp = bytes[0];
128 	bytes[0] = bytes[3];
129 	bytes[3] = tmp;
130 	tmp = bytes[1];
131 	bytes[1] = bytes[2];
132 	bytes[2] = tmp;
133 }
134 
is_format_type_mismatch(GLenum format,GLenum type)135 bool is_format_type_mismatch(GLenum format, GLenum type)
136 {
137 	if (((type == GL_UNSIGNED_BYTE_3_3_2 ||
138 	      type == GL_UNSIGNED_BYTE_2_3_3_REV ||
139 	      type == GL_UNSIGNED_SHORT_5_6_5 ||
140 	      type == GL_UNSIGNED_SHORT_5_6_5_REV) &&
141 	     (format != GL_RGB)) ||
142 
143 	    ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
144 	      type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
145 	      type == GL_UNSIGNED_SHORT_5_5_5_1 ||
146 	      type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
147 	      type == GL_UNSIGNED_INT_8_8_8_8 ||
148 	      type == GL_UNSIGNED_INT_8_8_8_8_REV ||
149 	      type == GL_UNSIGNED_INT_10_10_10_2 ||
150 	      type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
151 	     (format != GL_RGBA &&
152 	      format != GL_BGRA)))
153 		return true;
154 
155 	return false;
156 }
157 
158 static void *
allocPixels(GLenum format,GLenum type,GLuint components)159 allocPixels(GLenum format, GLenum type, GLuint components)
160 {
161 	GLint i, j;
162 	GLvoid *pixels;
163 	GLuint npixels = piglit_width * piglit_height;
164 
165 	switch(type) {
166 	case GL_BYTE:
167 		pixels = calloc(npixels * components, sizeof(GLbyte));
168 		for (i = 0; i < npixels; i++) {
169 			for (j = 0; j < components; j++)
170 				((GLbyte *)pixels)[i * components + j] = 50 + j * 4;
171 		}
172 		break;
173 
174 	case GL_UNSIGNED_BYTE:
175 		pixels = calloc(npixels * components, sizeof(GLubyte));
176 		for (i = 0; i < npixels; i++) {
177 			for (j = 0; j < components; j++)
178 				((GLubyte *)pixels)[i * components + j] = 100 + j * 4;
179 		}
180 		break;
181 
182 	case GL_UNSIGNED_BYTE_3_3_2:
183 	case GL_UNSIGNED_BYTE_2_3_3_REV:
184 		pixels = calloc(npixels, sizeof(GLubyte));
185 		for (i = 0; i < npixels; i++) {
186 			((GLubyte *)pixels)[i] = 0x99;
187 		}
188 		break;
189 
190 	case GL_SHORT:
191 		pixels = calloc(npixels * components, sizeof(GLshort));
192 		for (i = 0; i < npixels; i++) {
193 			for (j = 0; j < components; j++) {
194 				((GLshort *)pixels)[i * components + j] = 0x1234;
195 			}
196 		}
197 		break;
198 
199 	case GL_UNSIGNED_SHORT:
200 		pixels = calloc(npixels * components, sizeof(GLushort));
201 		for (i = 0; i < npixels; i++) {
202 			for (j = 0; j < components; j++) {
203 				((GLushort *)pixels)[i * components + j] = 0x4321;
204 			}
205 		}
206 		break;
207 
208 	case GL_UNSIGNED_SHORT_5_6_5:
209 	case GL_UNSIGNED_SHORT_5_6_5_REV:
210 	case GL_UNSIGNED_SHORT_4_4_4_4:
211 	case GL_UNSIGNED_SHORT_4_4_4_4_REV:
212 	case GL_UNSIGNED_SHORT_5_5_5_1:
213 	case GL_UNSIGNED_SHORT_1_5_5_5_REV:
214 		pixels = calloc(npixels, sizeof(GLushort));
215 		for (i = 0; i < npixels; i++)
216 			((GLushort *)pixels)[i] = 0x9b59;
217 		break;
218 
219 	case GL_INT:
220 		pixels = calloc(npixels * components, sizeof(GLint));
221 		for (i = 0; i < npixels; i++) {
222 			for (j = 0; j < components; j++) {
223 				((GLint *)pixels)[i * components + j] = 0x12345678;
224 			}
225 		}
226 		break;
227 
228 	case GL_UNSIGNED_INT:
229 		pixels = calloc(npixels * components, sizeof(GLuint));
230 		for (i = 0; i < npixels; i++) {
231 			for (j = 0; j < components; j++) {
232 				((GLuint *)pixels)[i * components + j] = 0x87654321;
233 			}
234 		}
235 		break;
236 
237 	case GL_UNSIGNED_INT_8_8_8_8:
238 	case GL_UNSIGNED_INT_8_8_8_8_REV:
239 	case GL_UNSIGNED_INT_10_10_10_2:
240 	case GL_UNSIGNED_INT_2_10_10_10_REV:
241 		pixels = calloc(npixels, sizeof(GLuint));
242 		for (i = 0; i < npixels; i++)
243 			((GLuint *)pixels)[i] = 0x1a4b5a4b;
244 		break;
245 
246 	case GL_FLOAT:
247 		pixels = calloc(npixels * components, sizeof(GLfloat));
248 		for (i = 0; i < npixels; i++) {
249 			for (j = 0; j < components; j++) {
250 				if (format == GL_STENCIL_INDEX)
251 					((GLfloat *)pixels)[i * components + j] =
252 					0x1020;
253 				else
254 					((GLfloat *)pixels)[i * components + j] =
255 					0.5 - j * 0.1;
256 			}
257 		}
258 		break;
259 
260 	default:
261 		assert(!"Unexpected data type");
262 		pixels = NULL;
263 		break;
264 	}
265 	return pixels;
266 }
267 
268 static void *
pixelsInit(GLenum format,GLenum type)269 pixelsInit(GLenum format, GLenum type)
270 {
271 	switch(format) {
272 	case GL_RED:
273 	case GL_GREEN:
274 	case GL_BLUE:
275 	case GL_ALPHA:
276 	case GL_LUMINANCE:
277 	case GL_DEPTH_COMPONENT:
278 	case GL_STENCIL_INDEX:
279 		return (allocPixels(format, type, 1));
280 	case GL_LUMINANCE_ALPHA:
281 	case GL_RG:
282 		return (allocPixels(format, type, 2));
283 	case GL_RGB:
284 	case GL_BGR:
285 		return (allocPixels(format, type, 3));
286 	case GL_RGBA:
287 	case GL_BGRA:
288 		return (allocPixels(format, type, 4));
289 	default:
290 		printf("format = %s not allowed in glDrawPixels()\n",
291 		       piglit_get_gl_enum_name(format));
292 		piglit_report_result(PIGLIT_FAIL);
293 	}
294 	return NULL;
295 }
296 
297 static float
typeToFloat(GLenum format,GLenum type,GLvoid * src,GLuint index,p_ops pixelops)298 typeToFloat(GLenum format, GLenum type, GLvoid *src,
299 	    GLuint index, p_ops pixelops)
300 {
301 	/* Scale factors */
302 	GLuint pi, pui, mask; GLushort pus; GLshort ps;
303 	GLfloat pf; GLint stencil_bits; GLbyte pb; GLubyte pub;
304 	const GLuint *uisrc; const GLushort *ussrc; const GLubyte *ubsrc;
305 	GLfloat rs = 1.0f, gs = 1.0f, bs = 1.0f, as = 1.0f;
306 
307 	GLboolean swap = (pixelops.pname == GL_UNPACK_SWAP_BYTES) ?
308 			 pixelops.param : false;
309 
310 	if (format == GL_STENCIL_INDEX) {
311 
312 		glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
313 		/* Clamp the return value to the size of stencil buffer */
314 		mask = 0xffffffff >> (sizeof(GLuint) *  8 - stencil_bits);
315 
316 		switch(type) {
317 		case GL_BYTE:
318 			pb = ((GLbyte *)src)[index];
319 			return pb & mask;
320 		case GL_UNSIGNED_BYTE:
321 			pub = ((GLubyte *)src)[index];
322 			return pub & mask;
323 		case GL_SHORT:
324 			ps = ((GLshort *)src)[index];
325 			if (swap)
326 				Swap2Byte(&ps);
327 			return ps & mask;
328 		case GL_UNSIGNED_SHORT:
329 			pus = ((GLushort *)src)[index];
330 			if (swap)
331 				Swap2Byte(&pus);
332 			return pus & mask;
333 		case GL_INT:
334 			pi = ((GLint *)src)[index];
335 			if (swap)
336 				Swap4Byte(&pi);
337 			return pi & mask;
338 		case GL_UNSIGNED_INT:
339 			pui = ((GLuint *)src)[index];
340 			if (swap)
341 				Swap4Byte(&pui);
342 			return pui & mask;
343 		case GL_FLOAT:
344 			pf = ((GLfloat *)src)[index];
345 			if (swap)
346 				Swap4Byte(&pf);
347 			return (GLfloat)((GLuint)pf & mask);
348 		default:
349 			printf("type = %s not allowed in glDrawPixels()\n",
350 			       piglit_get_gl_enum_name(type));
351 			piglit_report_result(PIGLIT_FAIL);
352 		}
353 	}
354 	else {
355 		switch(type) {
356 		case GL_BYTE:
357 			return BYTE_TO_FLOAT(((GLbyte *)src)[index]);
358 
359 		case GL_UNSIGNED_BYTE:
360 			return UBYTE_TO_FLOAT(((GLubyte *)src)[index]);
361 
362 		case GL_UNSIGNED_BYTE_3_3_2:
363 			ubsrc = (const GLubyte *) src;
364 			rs = 1.0F / 7.0F;
365 			gs = 1.0F / 7.0F;
366 			bs = 1.0F / 3.0F;
367 			pub = ubsrc[index];
368 			if (index == idx0)
369 				return (((pub >> 5)      ) * rs);
370 			else if (index == idx1)
371 				return (((pub >> 2) & 0x7) * gs);
372 			else if (index == idx2)
373 				return (((pub     ) & 0x3) * bs);
374 			else
375 				return 1.0F;
376 
377 		case GL_UNSIGNED_BYTE_2_3_3_REV:
378 			ubsrc = (const GLubyte *) src;
379 			rs = 1.0F / 7.0F;
380 			gs = 1.0F / 7.0F;
381 			bs = 1.0F / 3.0F;
382 			pub = ubsrc[index];
383 			if (index == idx0)
384 				return (((pub     ) & 0x7) * rs);
385 			else if (index == idx1)
386 				return (((pub >> 3) & 0x7) * gs);
387 			else if (index == idx2)
388 				return (((pub >> 6)      ) * bs);
389 			else
390 				return 1.0F;
391 
392 		case GL_SHORT:
393 			ps = ((GLshort *)src)[index];
394 			if (swap)
395 				Swap2Byte(&ps);
396 			return (SHORT_TO_FLOAT(ps));
397 
398 		case GL_UNSIGNED_SHORT:
399 			pus = ((GLushort *)src)[index];
400 			if (swap)
401 				Swap2Byte(&pus);
402 			return (USHORT_TO_FLOAT(pus));
403 
404 		case GL_UNSIGNED_SHORT_5_6_5:
405 			ussrc = (const GLushort *) src;
406 			rs = 1.0F / 31.0F;
407 			gs = 1.0F / 63.0F;
408 			bs = 1.0F / 31.0F;
409 			pus = ussrc[index];
410 			if (swap)
411 				Swap2Byte(&pus);
412 			if (index == idx0)
413 				return (((pus >> 11)       ) * rs);
414 			else if (index == idx1)
415 				return (((pus >>  5) & 0x3f) * gs);
416 			else if (index == idx2)
417 				return (((pus      ) & 0x1f) * bs);
418 			else
419 				return 1.0F;
420 
421 		case GL_UNSIGNED_SHORT_5_6_5_REV:
422 			ussrc = (const GLushort *) src;
423 			rs = 1.0F / 31.0F;
424 			gs = 1.0F / 63.0F;
425 			bs = 1.0F / 31.0F;
426 			pus = ussrc[index];
427 			if (swap)
428 				Swap2Byte(&pus);
429 			if (index == idx0)
430 				return (((pus      ) & 0x1f) * rs);
431 			else if (index == idx1)
432 				return (((pus >>  5) & 0x3f) * gs);
433 			else if (index == idx2)
434 				return (((pus >> 11)       ) * bs);
435 			else
436 				return 1.0F;
437 
438 		case GL_UNSIGNED_SHORT_4_4_4_4:
439 			ussrc = (const GLushort *) src;
440 			rs = gs = bs = as = 1.0F / 15.0F;
441 			pus = ussrc[index];
442 			if (swap)
443 				Swap2Byte(&pus);
444 			if (index == idx0)
445 				return (((pus >> 12)      ) * rs);
446 			else if (index == idx1)
447 				return (((pus >> 8) & 0xf ) * gs);
448 			else if (index == idx2)
449 				return (((pus >> 4) & 0xf ) * bs);
450 			else
451 				return (((pus     ) & 0xf ) * as);
452 
453 		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
454 			ussrc = (const GLushort *) src;
455 			rs = gs = bs = as = 1.0F / 15.0F;
456 			pus = ussrc[index];
457 			if (swap)
458 				Swap2Byte(&pus);
459 			if (index == idx0)
460 				return (((pus     ) & 0xf ) * rs);
461 			else if (index == idx1)
462 				return (((pus >> 4) & 0xf ) * gs);
463 			else if (index == idx2)
464 				return (((pus >> 8) & 0xf ) * bs);
465 			else
466 				return (((pus >> 12)      ) * as);
467 
468 		case GL_UNSIGNED_SHORT_5_5_5_1:
469 			ussrc = (const GLushort *) src;
470 			rs = gs = bs = 1.0F / 31.0F;
471 			pus = ussrc[index];
472 			if (swap)
473 				Swap2Byte(&pus);
474 			if (index == idx0)
475 				return (((pus >> 11)       ) * rs);
476 			else if (index == idx1)
477 				return (((pus >>  6) & 0x1f) * gs);
478 			else if (index == idx2)
479 				return (((pus >>  1) & 0x1f) * bs);
480 			else
481 				return (((pus      ) & 0x1)  * as);
482 
483 		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
484 			ussrc = (const GLushort *) src;
485 			rs = gs = bs = 1.0F / 31.0F;
486 			pus = ussrc[index];
487 			if (swap)
488 				Swap2Byte(&pus);
489 			if (index == idx0)
490 				return (((pus      ) & 0x1f) * rs);
491 			else if (index == idx1)
492 				return (((pus >>  5) & 0x1f) * gs);
493 			else if (index == idx2)
494 				return (((pus >> 10) & 0x1f) * bs);
495 			else
496 				return (((pus >> 15)       ) * as);
497 
498 		case GL_INT:
499 			pi = ((GLint *)src)[index];
500 			if (swap)
501 				Swap4Byte(&pi);
502 			return INT_TO_FLOAT(pi);
503 
504 		case GL_UNSIGNED_INT:
505 			pui = ((GLuint *)src)[index];
506 			if (swap)
507 				Swap4Byte(&pui);
508 			return UINT_TO_FLOAT(pui);
509 
510 		case GL_UNSIGNED_INT_8_8_8_8:
511 			uisrc = (const GLuint *) src;
512 			pui = uisrc[index];
513 			if (swap)
514 				Swap4Byte(&pui);
515 			if (index == idx0)
516 				return UBYTE_TO_FLOAT(((pui >> 24)       ));
517 			else if (index == idx1)
518 				return UBYTE_TO_FLOAT(((pui >> 16) & 0xff));
519 			else if (index == idx2)
520 				return UBYTE_TO_FLOAT(((pui >>  8) & 0xff));
521 			else
522 				return UBYTE_TO_FLOAT(((pui      ) & 0xff));
523 
524 		case GL_UNSIGNED_INT_8_8_8_8_REV:
525 			uisrc = (const GLuint *) src;
526 			pui = uisrc[index];
527 			if (swap)
528 				Swap4Byte(&pui);
529 			if (index == idx0)
530 				return UBYTE_TO_FLOAT(((pui      ) & 0xff));
531 			else if (index == idx1)
532 				return UBYTE_TO_FLOAT(((pui >>  8) & 0xff));
533 			else if (index == idx2)
534 				return UBYTE_TO_FLOAT(((pui >> 16) & 0xff));
535 			else
536 				return UBYTE_TO_FLOAT(((pui >> 24)       ));
537 
538 		case GL_UNSIGNED_INT_10_10_10_2:
539 			uisrc = (const GLuint *) src;
540 			pui = uisrc[index];
541 			rs = 1.0F / 1023.0F;
542 			gs = 1.0F / 1023.0F;
543 			bs = 1.0F / 1023.0F;
544 			as = 1.0F / 3.0F;
545 			if (swap)
546 				Swap4Byte(&pui);
547 			if (index == idx0)
548 				return (((pui >> 22)        ) * rs);
549 			else if (index == idx1)
550 				return (((pui >> 12) & 0x3ff) * gs);
551 			else if (index == idx2)
552 				return (((pui >>  2) & 0x3ff) * bs);
553 			else
554 				return (((pui      ) & 0x3  ) * as);
555 
556 		case GL_UNSIGNED_INT_2_10_10_10_REV:
557 			uisrc = (const GLuint *) src;
558 			pui = uisrc[index];
559 			rs = 1.0F / 1023.0F;
560 			gs = 1.0F / 1023.0F;
561 			bs = 1.0F / 1023.0F;
562 			as = 1.0F / 3.0F;
563 			if (swap)
564 				Swap4Byte(&pui);
565 			if (index == idx0)
566 				return (((pui      ) & 0x3ff) * rs);
567 			else if (index == idx1)
568 				return (((pui >> 10) & 0x3ff) * gs);
569 			else if (index == idx2)
570 				return (((pui >> 20) & 0x3ff) * bs);
571 			else
572 				return (((pui >> 30)        ) * as);
573 
574 		case GL_FLOAT:
575 			pf = ((GLfloat *)src)[index];
576 			if (swap)
577 				Swap4Byte(&pf);
578 			return pf;
579 		default:
580 			printf("type = %s not supported in glDrawPixels()\n",
581 			       piglit_get_gl_enum_name(format));
582 			piglit_report_result(PIGLIT_FAIL);
583 		}
584 	}
585 	return 0.0F;
586 }
587 
588 static float
clampColor(float f)589 clampColor(float f)
590 {
591 	return ((f > 1.0f) ? 1.0f : ((f < 0.0f ? 0.0f : f)));
592 }
593 
594 static void
computeExpected(GLenum format,GLenum type,GLuint index,p_ops pixelops,GLvoid * pixels)595 computeExpected(GLenum format, GLenum type, GLuint index,
596 		p_ops pixelops, GLvoid *pixels)
597 {
598 	int j = index;
599 	GLvoid * src = pixels;
600 	GLfloat fval;
601 
602 	switch(format) {
603 	case GL_RED:
604 		fval = typeToFloat(format, type, src, idx0, pixelops);
605 		expected[j][0] = clampColor(fval);
606 		expected[j][1] = 0.0;
607 		expected[j][2] = 0.0;
608 		expected[j][3] = 1.0;
609 		break;
610 	case GL_GREEN:
611 		fval = typeToFloat(format, type, src, idx0, pixelops);
612 		expected[j][0] = 0.0;
613 		expected[j][1] = clampColor(fval);
614 		expected[j][2] = 0.0;
615 		expected[j][3] = 1.0;
616 		break;
617 	case GL_BLUE:
618 		fval = typeToFloat(format, type, src, idx0, pixelops);
619 		expected[j][0] = 0.0;
620 		expected[j][1] = 0.0;
621 		expected[j][2] = clampColor(fval);
622 		expected[j][3] = 1.0;
623 		break;
624 
625 	case GL_ALPHA:
626 		fval = typeToFloat(format, type, src, idx0, pixelops);
627 		expected[j][0] = 0.0;
628 		expected[j][1] = 0.0;
629 		expected[j][2] = 0.0;
630 		expected[j][3] = clampColor(fval);
631 		break;
632 
633 	case GL_LUMINANCE:
634 		fval = typeToFloat(format, type, src, idx0, pixelops);
635 		expected[j][0] = clampColor(fval);
636 		expected[j][1] = clampColor(fval);
637 		expected[j][2] = clampColor(fval);
638 		expected[j][3] = 1.0;
639 		break;
640 
641 	case GL_LUMINANCE_ALPHA:
642 		fval = typeToFloat(format, type, src, idx0, pixelops);
643 		expected[j][0] = clampColor(fval);
644 		expected[j][1] = clampColor(fval);
645 		expected[j][2] = clampColor(fval);
646 		fval = typeToFloat(format, type, src, idx1, pixelops);
647 		expected[j][3] = clampColor(fval);
648 		break;
649 
650 	case GL_RG:
651 		fval = typeToFloat(format, type, src, idx0, pixelops);
652 		expected[j][0] = clampColor(fval);
653 		fval = typeToFloat(format, type, src, idx1, pixelops);
654 		expected[j][1] = clampColor(fval);
655 		expected[j][2] = 0.0;
656 		expected[j][3] = 1.0;
657 		break;
658 
659 	case GL_RGB:
660 		fval = typeToFloat(format, type, src, idx0, pixelops);
661 		expected[j][0] = clampColor(fval);
662 		fval = typeToFloat(format, type, src, idx1, pixelops);
663 		expected[j][1] = clampColor(fval);
664 		fval = typeToFloat(format, type, src, idx2, pixelops);
665 		expected[j][2] = clampColor(fval);
666 		expected[j][3] = 1.0;
667 		break;
668 
669 	case GL_BGR:
670 		fval = typeToFloat(format, type, src, idx2, pixelops);
671 		expected[j][0] = clampColor(fval);
672 		fval = typeToFloat(format, type, src, idx1, pixelops);
673 		expected[j][1] = clampColor(fval);
674 		fval = typeToFloat(format, type, src, idx0, pixelops);
675 		expected[j][2] = clampColor(fval);
676 		expected[j][3] = 1.0;
677 		break;
678 
679 	case GL_RGBA:
680 		fval = typeToFloat(format, type, src, idx0, pixelops);
681 		expected[j][0] = clampColor(fval);
682 		fval = typeToFloat(format, type, src, idx1, pixelops);
683 		expected[j][1] = clampColor(fval);
684 		fval = typeToFloat(format, type, src, idx2, pixelops);
685 		expected[j][2] = clampColor(fval);
686 		fval = typeToFloat(format, type, src, idx3, pixelops);
687 		expected[j][3] = clampColor(fval);
688 		break;
689 
690 	case GL_BGRA:
691 		fval = typeToFloat(format, type, src, idx2, pixelops);
692 		expected[j][0] = clampColor(fval);
693 		fval = typeToFloat(format, type, src, idx1, pixelops);
694 		expected[j][1] = clampColor(fval);
695 		fval = typeToFloat(format, type, src, idx0, pixelops);
696 		expected[j][2] = clampColor(fval);
697 		fval = typeToFloat(format, type, src, idx3, pixelops);
698 		expected[j][3] = clampColor(fval);
699 		break;
700 
701 	case GL_DEPTH_COMPONENT:
702 		fval = typeToFloat(format, type, src, idx0, pixelops);
703 		expected[j][0] = clampColor(fval);
704 		break;
705 
706 	case GL_STENCIL_INDEX:
707 		fval = typeToFloat(format, type, src, idx0, pixelops);
708 		expected[j][0] = fval;
709 		break;
710 	}
711 }
712 
713 static void
report_failure(GLenum format,GLenum type)714 report_failure(GLenum format, GLenum type)
715 {
716 	printf("  Failed with format %s, type %s\n",
717 	       piglit_get_gl_enum_name(format),
718 	       piglit_get_gl_enum_name(type));
719 }
720 
721 enum piglit_result
piglit_display(void)722 piglit_display(void)
723 {
724 	int i, j, k;
725 	GLenum format, type;
726 	GLvoid *pixels = NULL;
727 	bool pass = true, p;
728 	GLfloat black[4] = {0.0, 0.0, 0.0, 1.0};
729 	GLfloat red[4] = {1.0, 0.0, 0.0, 1.0};
730 
731 	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
732 
733 	for (i = 0; i < ARRAY_SIZE(data_types); i++) {
734 		for (k = 0; k < ARRAY_SIZE(pixel_ops); k++) {
735 			for (j = 0; j < ARRAY_SIZE(pixel_formats); j++) {
736 
737 				format = pixel_formats[j];
738 				type = data_types[i];
739 
740 				if (is_format_type_mismatch(format, type)) {
741 					if (piglit_khr_no_error)
742 						continue;
743 
744 					glDrawPixels(piglit_width, piglit_height,
745 						     format, type, pixels);
746 					/* Here GL_INVALID_OPERATION is an
747 					 * expected GL error
748 					 */
749 					pass = piglit_check_gl_error(
750 					       GL_INVALID_OPERATION)
751 					       && pass;
752 					continue;
753 				}
754 
755 				if (type == GL_UNSIGNED_BYTE_3_3_2 ||
756 				    type == GL_UNSIGNED_BYTE_2_3_3_REV)
757 					piglit_set_tolerance_for_bits(7, 7, 7, 7);
758 				else
759 					piglit_set_tolerance_for_bits(8, 8, 8, 8);
760 
761 				if (!piglit_automatic)
762 					printf("Format = %s, Type = %s,"
763 					       " Swap Bytes = %d\n",
764 					       piglit_get_gl_enum_name(format),
765 					       piglit_get_gl_enum_name(type),
766 					       pixel_ops[k].param);
767 
768 				pixels = pixelsInit(format, type);
769 				computeExpected(format, type, j, pixel_ops[k], pixels);
770 
771 				glClear(GL_COLOR_BUFFER_BIT);
772 				/* Enable/Disable byte swap while unpacking pixels */
773 				glPixelStorei(pixel_ops[k].pname, pixel_ops[k].param);
774 
775 				switch(format) {
776 
777 				case GL_RG:
778 					if (!piglit_is_extension_supported(
779 					   "GL_ARB_texture_rg")) {
780 						   if (!piglit_automatic)
781 							printf("GL_RG skipped\n");
782 						continue;
783 					}
784 
785 				case GL_RED:
786 				case GL_GREEN:
787 				case GL_BLUE:
788 				case GL_ALPHA:
789 				case GL_LUMINANCE:
790 				case GL_LUMINANCE_ALPHA:
791 				case GL_RGB:
792 				case GL_BGR:
793 				case GL_RGBA:
794 				case GL_BGRA:
795 					glDrawPixels(piglit_width, piglit_height,
796 						     format, type, pixels);
797 
798 					pass = piglit_check_gl_error(GL_NO_ERROR)
799 					       && pass;
800 					p = piglit_probe_rect_rgba(0, 0,
801 					       piglit_width, piglit_height,
802 					       expected[j]);
803 					if (!p) {
804 						report_failure(format, type);
805 						pass = GL_FALSE;
806 					}
807 					break;
808 
809 				case GL_DEPTH_COMPONENT:
810 					glEnable(GL_DEPTH_TEST);
811 					glClearDepth(0.0);
812 					glDepthFunc(GL_ALWAYS);
813 					glClear(GL_DEPTH_BUFFER_BIT);
814 					glDrawPixels(piglit_width, piglit_height,
815 						     format, type, pixels);
816 
817 					pass = piglit_check_gl_error(GL_NO_ERROR)
818 					       && pass;
819 					p = piglit_probe_rect_depth(0, 0,
820 					       piglit_width, piglit_height,
821 					       expected[j][0]);
822 					if (!p) {
823 						report_failure(format, type);
824 						pass = GL_FALSE;
825 					}
826 					glDisable(GL_DEPTH_TEST);
827 					break;
828 
829 				case GL_STENCIL_INDEX:
830 					glClearStencil(0.0);
831 					glClear(GL_STENCIL_BUFFER_BIT);
832 					glDrawPixels(piglit_width, piglit_height,
833 						     format, type, pixels);
834 
835 					pass = piglit_check_gl_error(GL_NO_ERROR)
836 					       && pass;
837 					/* Probe stencil buffer */
838 					p = piglit_probe_rect_stencil(0, 0,
839 								piglit_width,
840 								piglit_height,
841 								expected[j][0]);
842 					if (!p) {
843 						report_failure(format, type);
844 						pass = GL_FALSE;
845 					}
846 
847 					glEnable(GL_STENCIL_TEST);
848 					glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
849 					glStencilFunc(GL_EQUAL, 1, ~0);
850 					glColor4f(1.0, 0.0, 0.0, 1.0);
851 					piglit_draw_rect(0, 0, piglit_width,
852 							 piglit_height);
853 
854 					/* Probe color buffer. Color buffer will
855 					 * stay unaffected by piglit_draw_rect()
856 					 */
857 					p = piglit_probe_rect_rgba(0, 0,
858 					       piglit_width, piglit_height,
859 					       black);
860 					if (!p) {
861 						report_failure(format, type);
862 						pass = GL_FALSE;
863 					}
864 
865 					glStencilFunc(GL_EQUAL, expected[j][0], ~0);
866 					piglit_draw_rect(0, 0, piglit_width,
867 							 piglit_height);
868 					p = piglit_probe_rect_rgba(0, 0,
869 					       piglit_width, piglit_height,
870 					       red);
871 					if (!p) {
872 						report_failure(format, type);
873 						pass = GL_FALSE;
874 					}
875 
876 					glDisable(GL_STENCIL_TEST);
877 					break;
878 				}
879 				free(pixels);
880 				pixels = NULL;
881 
882 				if (!pass) {
883 					piglit_present_results();
884 				}
885 			}
886 		}
887 	}
888 	return (pass ? PIGLIT_PASS : PIGLIT_FAIL);
889 }
890 
891 void
piglit_init(int argc,char ** argv)892 piglit_init(int argc, char **argv)
893 {
894 	glClearColor(0.0, 0.0, 0.0, 1.0);
895 	piglit_ortho_projection(piglit_width, piglit_height, GL_TRUE);
896 }
897