1 /* BEGIN_COPYRIGHT -*- glean -*-
2  *
3  * Copyright (C) 2007, 2014  Intel Corporation
4  * Copyright (C) 1999  Allen Akin  All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
20  * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
21  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22  * PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
24  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  *
28  * END_COPYRIGHT
29  */
30 
31 /** @file pbo.c
32  *
33  * Test OpenGL Extension GL_ARB_pixel_buffer_object
34  *
35  * Authors:
36  * Shuang He <shuang.he@intel.com>
37  * Adapted to Piglit by Laura Ekstrand <laura@jlekstrand.net>, November 2014.
38  */
39 
40 #include "piglit-util-gl.h"
41 
42 #define WINSIZE 100
43 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
44 
45 PIGLIT_GL_TEST_CONFIG_BEGIN
46 
47 	config.supports_gl_compat_version = 10;
48 
49 	config.window_visual = PIGLIT_GL_VISUAL_RGBA |
50 		PIGLIT_GL_VISUAL_DOUBLE;
51 
52 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
53 
54 PIGLIT_GL_TEST_CONFIG_END
55 
56 void
piglit_init(int argc,char ** argv)57 piglit_init(int argc, char **argv)
58 {
59 	piglit_require_extension("GL_ARB_pixel_buffer_object");
60 
61 	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
62 }
63 
64 static void
report_failure(const char * msg,const int line)65 report_failure(const char *msg, const int line)
66 {
67 	printf("FAILURE: %s (at pbo.c: %d)\n", msg, line);
68 }
69 
70 #define REPORT_FAILURE(MSG) report_failure(MSG, __LINE__)
71 
72 #define TEXSIZE 64
73 
74 enum piglit_result
test_sanity(void * null)75 test_sanity(void *null)
76 {
77 	GLuint pbs[1];
78 	GLuint pb_binding;
79 
80 	glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING_ARB,
81 		      (GLint *) & pb_binding);
82 	if (pb_binding != 0) {
83 		REPORT_FAILURE("Failed to bind unpack pixel buffer object");
84 		return PIGLIT_FAIL;
85 	}
86 
87 	glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING_ARB,
88 		      (GLint *) & pb_binding);
89 	if (pb_binding != 0) {
90 		REPORT_FAILURE("Failed to bind pack pixel buffer object");
91 		return PIGLIT_FAIL;
92 	}
93 
94 	glGenBuffersARB(1, pbs);
95 
96 	if (glIsBufferARB(pbs[0]) != GL_FALSE) {
97 		REPORT_FAILURE("glIsBufferARB failed");
98 		return PIGLIT_FAIL;
99 	}
100 
101 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbs[0]);
102 	glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING_ARB,
103 		      (GLint *) & pb_binding);
104 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
105 	if (pb_binding != pbs[0]) {
106 		REPORT_FAILURE("Failed to bind unpack pixel buffer object");
107 		return PIGLIT_FAIL;
108 	}
109 
110 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbs[0]);
111 	glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING_ARB,
112 		      (GLint *) & pb_binding);
113 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
114 	if (pb_binding != pbs[0]) {
115 		REPORT_FAILURE("Failed to bind unpack pixel buffer object");
116 		return PIGLIT_FAIL;
117 	}
118 
119 	glDeleteBuffersARB(1, pbs);
120 
121 	if (glIsBufferARB(pbs[0]) == GL_TRUE) {
122 		REPORT_FAILURE("glIsBufferARB failed");
123 		return PIGLIT_FAIL;
124 	}
125 
126 	return PIGLIT_PASS;
127 }
128 
129 enum piglit_result
test_draw_pixels(void * null)130 test_draw_pixels(void *null)
131 {
132 	int use_unpack;
133 	int use_pack;
134 	GLuint pb_pack[1];
135 	GLuint pb_unpack[1];
136 	GLubyte buf[WINSIZE * WINSIZE * 4];
137 	GLubyte t[TEXSIZE * TEXSIZE * 4];
138 	int i, j;
139 	GLubyte * pbo_pack_mem = NULL;
140 	GLubyte black[4] = { 0, 0, 0, 255 };
141 	bool pass = true;
142 	GLubyte expected[WINSIZE * WINSIZE * 4];
143 
144 	glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
145 	glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
146 
147 	for (use_unpack = 0; use_unpack < 2; use_unpack++) {
148 		for (use_pack = 0; use_pack < 2; use_pack++) {
149 			GLubyte *pbo_mem = NULL;
150 			glClearColor(0.0, 0.0, 0.0, 1.0);
151 			glClear(GL_COLOR_BUFFER_BIT);
152 			if (use_unpack) {
153 				glGenBuffersARB(1, pb_unpack);
154 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
155 						pb_unpack[0]);
156 				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
157 						TEXSIZE * TEXSIZE * 4 *
158 						sizeof(GLubyte), NULL,
159 						GL_STREAM_DRAW);
160 			}
161 			if (use_unpack) {
162 				pbo_mem = (GLubyte *) glMapBufferARB(
163 						GL_PIXEL_UNPACK_BUFFER_ARB,
164 						GL_WRITE_ONLY);
165 			}
166 			else {
167 				pbo_mem = t;
168 			}
169 
170 			/* Fill the buffer */
171 			for (i = 0; i < TEXSIZE; i++)
172 				for (j = 0; j < TEXSIZE; j++) {
173 					int idx = 4 * (i * TEXSIZE + j);
174 					pbo_mem[idx + 0] = i % 256;
175 					pbo_mem[idx + 1] = i % 256;
176 					pbo_mem[idx + 2] = i % 256;
177 					pbo_mem[idx + 3] = 0;
178 				}
179 
180 			if (use_unpack) {
181 				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
182 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
183 						0);
184 			}
185 
186 			/* Draw the buffer */
187 			if (use_unpack) {
188 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
189 						pb_unpack[0]);
190 				glDrawPixels(TEXSIZE, TEXSIZE, GL_BGRA,
191 					     GL_UNSIGNED_BYTE, NULL);
192 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
193 						0);
194 			}
195 			else {
196 				glDrawPixels(TEXSIZE, TEXSIZE, GL_BGRA,
197 					     GL_UNSIGNED_BYTE, pbo_mem);
198 			}
199 
200 			if (!piglit_automatic)
201 				piglit_present_results();
202 
203 			/* Check the result */
204 			if (use_pack) {
205 				glGenBuffersARB(1, pb_pack);
206 				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
207 						pb_pack[0]);
208 				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
209 						WINSIZE * WINSIZE * 4 *
210 						sizeof(GL_UNSIGNED_BYTE),
211 						NULL, GL_STREAM_DRAW);
212 				glReadPixels(0, 0, WINSIZE, WINSIZE,
213 					     GL_BGRA, GL_UNSIGNED_BYTE, NULL);
214 				pbo_pack_mem = (GLubyte *) glMapBufferARB(
215 						GL_PIXEL_PACK_BUFFER_ARB,
216 						GL_READ_ONLY);
217 			}
218 			else {
219 				pbo_pack_mem = buf;
220 				glReadPixels(0, 0, WINSIZE, WINSIZE,
221 					     GL_BGRA,
222 					     GL_UNSIGNED_BYTE, pbo_pack_mem);
223 			}
224 
225 			/* Make expected. */
226 			for (j = 0; j < WINSIZE; j++) {
227 				for (i = 0; i < WINSIZE; i++) {
228 					int idx = (j * WINSIZE + i) * 4;
229 					if (i < TEXSIZE && j < TEXSIZE) {
230 						expected[idx + 0] = j % 256;
231 						expected[idx + 1] = j % 256;
232 						expected[idx + 2] = j % 256;
233 						expected[idx + 3] = 0;
234 					}
235 					else {
236 						expected[idx + 0] = black[0];
237 						expected[idx + 1] = black[1];
238 						expected[idx + 2] = black[2];
239 						expected[idx + 3] = black[3];
240 					}
241 				}
242 			}
243 
244 			pass &= piglit_compare_images_ubyte(0, 0, WINSIZE,
245 							    WINSIZE,
246 							    expected,
247 							    pbo_pack_mem);
248 
249 			if (use_pack) {
250 				glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
251 				glDeleteBuffersARB(1, pb_pack);
252 			}
253 
254 			if (use_unpack) {
255 				glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
256 				glDeleteBuffersARB(1, pb_unpack);
257 			}
258 
259 		}
260 	}
261 
262 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
263 }
264 
265 
266 enum piglit_result
test_pixel_map(void * null)267 test_pixel_map(void *null)
268 {
269 	int use_unpack;
270 	int use_pack;
271 	GLuint pb_pack[1];
272 	GLuint pb_unpack[1];
273 	int i;
274 	int size;
275 	int max;
276 	GLushort *pbo_mem;
277 
278 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
279 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
280 
281 	glGetIntegerv(GL_MAX_PIXEL_MAP_TABLE, &max);
282 
283 	for (use_pack = 0; use_pack < 2; use_pack++) {
284 		for (use_unpack = 0; use_unpack < 2;
285 		   use_unpack++) {
286 			glClearColor(0.0, 0.0, 0.0, 1.0);
287 			glClear(GL_COLOR_BUFFER_BIT);
288 			if (use_unpack) {
289 				glGenBuffersARB(1, pb_unpack);
290 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
291 						pb_unpack[0]);
292 				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
293 						max * sizeof(GLushort), NULL,
294 						GL_STREAM_DRAW);
295 			}
296 			pbo_mem = NULL;
297 			if (use_unpack) {
298 				pbo_mem = (GLushort *) glMapBufferARB(
299 						GL_PIXEL_UNPACK_BUFFER_ARB,
300 						GL_WRITE_ONLY);
301 			}
302 			else {
303 				pbo_mem = (GLushort *)
304 					malloc(sizeof(GLushort) * max);
305 			}
306 			for (i = 0; i < max; i++)
307 				pbo_mem[i] = max - i - 1;
308 
309 			if (use_unpack) {
310 				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
311 				glPixelMapusv(GL_PIXEL_MAP_R_TO_R, max, NULL);
312 				glPixelMapusv(GL_PIXEL_MAP_G_TO_G, max, NULL);
313 				glPixelMapusv(GL_PIXEL_MAP_B_TO_B, max, NULL);
314 				glPixelMapusv(GL_PIXEL_MAP_A_TO_A, max, NULL);
315 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
316 						0);
317 			}
318 			else {
319 				glPixelMapusv(GL_PIXEL_MAP_R_TO_R, max,
320 					      pbo_mem);
321 				glPixelMapusv(GL_PIXEL_MAP_G_TO_G, max,
322 					      pbo_mem);
323 				glPixelMapusv(GL_PIXEL_MAP_B_TO_B, max,
324 					      pbo_mem);
325 				glPixelMapusv(GL_PIXEL_MAP_A_TO_A, max,
326 					      pbo_mem);
327 				free(pbo_mem);
328 			}
329 
330 
331 			glGetIntegerv(GL_PIXEL_MAP_R_TO_R_SIZE, &size);
332 			if (size != max) {
333 				REPORT_FAILURE("glPixelMap failed");
334 				return PIGLIT_FAIL;
335 			}
336 			glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
337 
338 			/* Read back pixel map */
339 			if (use_pack) {
340 				glGenBuffersARB(1, pb_pack);
341 				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
342 						pb_pack[0]);
343 				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
344 						max * sizeof(GLushort),
345 						NULL, GL_STREAM_DRAW);
346 				glGetPixelMapusv(GL_PIXEL_MAP_R_TO_R, NULL);
347 				pbo_mem = (GLushort *) glMapBufferARB(
348 						GL_PIXEL_PACK_BUFFER_ARB,
349 						GL_READ_ONLY);
350 			}
351 			else {
352 				pbo_mem = (GLushort *)
353 					malloc(sizeof(GLushort) * max);
354 				glGetPixelMapusv(GL_PIXEL_MAP_R_TO_R, pbo_mem);
355 			}
356 
357 			for (i = 0; i < max; i++) {
358 				if (pbo_mem[i] != max - i - 1) {
359 					REPORT_FAILURE("get PixelMap failed");
360 					return PIGLIT_FAIL;
361 				}
362 			}
363 
364 
365 			if (use_pack) {
366 				glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
367 				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
368 				glDeleteBuffersARB(1, pb_pack);
369 			}
370 			else {
371 				free(pbo_mem);
372 			}
373 
374 			if (use_unpack) {
375 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
376 						0);
377 				glDeleteBuffersARB(1, pb_unpack);
378 			}
379 
380 			if (!piglit_automatic)
381 				piglit_present_results();
382 
383 		}
384 	}
385 
386 	return PIGLIT_PASS;
387 }
388 
389 enum piglit_result
test_bitmap(void * null)390 test_bitmap(void *null)
391 {
392 	GLuint pb_unpack[1];
393 	GLuint pb_pack[1];
394 	int use_unpack = 1;
395 	int use_pack = 0;
396 	GLubyte bitmap[TEXSIZE * TEXSIZE / 8];
397 	GLfloat buf[WINSIZE * WINSIZE * 3];
398 	GLfloat white[3] = { 1.0, 1.0, 1.0 };
399 	GLfloat black[3] = { 0.0, 0.0, 0.0 };
400 	int i, j;
401 	GLubyte *pbo_unpack_mem = NULL;
402 	GLfloat *pbo_pack_mem = NULL;
403 	GLfloat expected[WINSIZE * WINSIZE * 3];
404 	float tolerance[4];
405 	bool pass = true;
406 
407 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
408 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
409 
410 	for (use_pack = 0; use_pack < 2; use_pack++) {
411 		for (use_unpack = 0; use_unpack < 2;
412 		   use_unpack++) {
413 			glClearColor(0.0, 0.0, 0.0, 1.0);
414 			glClear(GL_COLOR_BUFFER_BIT);
415 
416 			if (use_unpack) {
417 				glGenBuffersARB(1, pb_unpack);
418 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
419 						pb_unpack[0]);
420 				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
421 						TEXSIZE * TEXSIZE,
422 						NULL, GL_STREAM_DRAW);
423 				pbo_unpack_mem = (GLubyte *) glMapBufferARB(
424 						GL_PIXEL_UNPACK_BUFFER_ARB,
425 						GL_WRITE_ONLY);
426 			}
427 			else {
428 				pbo_unpack_mem = bitmap;
429 			}
430 
431 			for (i = 0; i < TEXSIZE * TEXSIZE / 8; i++) {
432 				pbo_unpack_mem[i] = 0xAA; /* Binary 10101010 */
433 			}
434 
435 
436 			glColor4f(1.0, 1.0, 1.0, 0.0);
437 			glRasterPos2f(0.0, 0.0);
438 			if (use_unpack) {
439 				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
440 				/* Draw white into every other pixel,
441 				 * for a white/black checkerboard. */
442 				glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0, NULL);
443 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
444 						0);
445 			}
446 			else {
447 				glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0,
448 					 pbo_unpack_mem);
449 			}
450 
451 			if (!piglit_automatic)
452 				piglit_present_results();
453 
454 			/* Check the result */
455 			if (use_pack) {
456 				glGenBuffersARB(1, pb_pack);
457 				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
458 						pb_pack[0]);
459 				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
460 						WINSIZE * WINSIZE *
461 						4 * sizeof(GLfloat), NULL,
462 						GL_STREAM_DRAW);
463 				glReadPixels(0, 0, WINSIZE, WINSIZE,
464 					     GL_RGB, GL_FLOAT,
465 					     NULL);
466 				pbo_pack_mem =
467 					(GLfloat *) glMapBufferARB(
468 						GL_PIXEL_PACK_BUFFER_ARB,
469 						GL_READ_ONLY);
470 			}
471 			else {
472 				pbo_pack_mem = buf;
473 				glReadPixels(0, 0, WINSIZE, WINSIZE,
474 					     GL_RGB, GL_FLOAT, pbo_pack_mem);
475 			}
476 
477 			/* Compute expected and compare it to the result. */
478 			for (j = 0; j < WINSIZE; j++) {
479 				for (i = 0; i < WINSIZE; i++) {
480 					int idx = (j * WINSIZE + i) * 3;
481 					if ((i & 1) || (i >= TEXSIZE) ||
482 					   (j >= TEXSIZE)) {
483 						expected[idx + 0] = black[0];
484 						expected[idx + 1] = black[1];
485 						expected[idx + 2] = black[2];
486 					}
487 					else {
488 						expected[idx + 0] = white[0];
489 						expected[idx + 1] = white[1];
490 						expected[idx + 2] = white[2];
491 					}
492 				}
493 			}
494 			piglit_compute_probe_tolerance(GL_RGB, &tolerance[0]);
495 			pass &= piglit_compare_images_color(0, 0, WINSIZE,
496 							    WINSIZE, 3,
497 							    tolerance,
498 							    expected,
499 							    pbo_pack_mem);
500 
501 			if (use_pack) {
502 				glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
503 				glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
504 				glDeleteBuffersARB(1, pb_pack);
505 			}
506 
507 			if (use_unpack) {
508 				glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
509 				glDeleteBuffersARB(1, pb_unpack);
510 			}
511 		}
512 	}
513 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
514 }
515 
516 #define TEXTURE_SIZE TEXSIZE * TEXSIZE * 3
517 #define WINDOW_SIZE WINSIZE * WINSIZE * 3
518 
519 enum piglit_result
test_tex_image(void * null)520 test_tex_image(void *null)
521 {
522 	bool pass = true;
523 
524 	int break_pbo_cow, break_tex_cow; /* cow = copy on write */
525 	int use_unpack, use_pack;
526 	GLuint unpack_pb[1];
527 	GLuint pack_pb[1];
528 	GLenum pack = GL_PIXEL_PACK_BUFFER_ARB;
529 	GLenum unpack = GL_PIXEL_UNPACK_BUFFER_ARB;
530 	GLfloat t1[TEXTURE_SIZE];
531 	GLfloat t2[TEXTURE_SIZE];
532 	GLfloat *pbo_mem = NULL;
533 	int i, j;
534 	GLfloat green[3] = { 1.0, 1.0, 0.0 };
535 	GLfloat black[3] = { 0.0, 0.0, 0.0 };
536 	GLfloat buf[WINDOW_SIZE];
537 	GLfloat exp_tex[TEXTURE_SIZE];
538 	GLfloat exp_win[WINDOW_SIZE];
539 	GLfloat tolerance[4];
540 
541 	piglit_compute_probe_tolerance(GL_RGB, tolerance);
542 
543 	glBindBufferARB(unpack, 0);
544 	glBindBufferARB(pack, 0);
545 
546 	glClearColor(0.0, 0.0, 0.0, 1.0);
547 	glClear(GL_COLOR_BUFFER_BIT);
548 
549 	for (use_pack = 0; use_pack < 2; use_pack++) {
550 		for (use_unpack = 0; use_unpack < 2;
551 			  use_unpack++) {
552 			for (break_pbo_cow = 0; break_pbo_cow < use_unpack + 1;
553 				  break_pbo_cow++) {
554 				for (break_tex_cow = 0;
555 					  break_tex_cow < use_unpack + 1;
556 					  break_tex_cow++) {
557 					if (use_unpack) {
558 						glGenBuffersARB(1, unpack_pb);
559 						glBindBufferARB(unpack,
560 						   unpack_pb[0]);
561 						glBufferDataARB(unpack,
562 							TEXTURE_SIZE *
563 							sizeof(GLfloat),
564 							NULL, GL_STREAM_DRAW);
565 					}
566 
567 					glTexParameteri(GL_TEXTURE_2D,
568 							GL_TEXTURE_MIN_FILTER,
569 							GL_NEAREST);
570 					glTexParameteri(GL_TEXTURE_2D,
571 							GL_TEXTURE_MAG_FILTER,
572 							GL_NEAREST);
573 
574 					if (use_unpack) {
575 						pbo_mem = (GLfloat *)
576 							glMapBufferARB(unpack,
577 							GL_WRITE_ONLY);
578 					}
579 					else {
580 						pbo_mem = t1;
581 					}
582 
583 					for (i = 0; i < TEXTURE_SIZE/3; i++) {
584 						pbo_mem[3 * i] = 1.0;
585 						pbo_mem[3 * i + 1] = 1.0;
586 						pbo_mem[3 * i + 2] = 0.0;
587 					}
588 
589 					if (use_unpack) {
590 						glUnmapBufferARB(unpack);
591 						glTexImage2D(GL_TEXTURE_2D, 0,
592 							     GL_RGB, TEXSIZE,
593 							     TEXSIZE, 0,
594 							     GL_RGB, GL_FLOAT,
595 							     NULL);
596 						glBindBufferARB(unpack, 0);
597 					}
598 					else
599 						glTexImage2D(GL_TEXTURE_2D, 0,
600 							     GL_RGB, TEXSIZE,
601 							     TEXSIZE, 0,
602 							     GL_RGB, GL_FLOAT,
603 							     pbo_mem);
604 
605 					if (use_unpack && break_pbo_cow) {
606 						glBindBufferARB(unpack,
607 							        unpack_pb[0]);
608 						pbo_mem = (GLfloat *)
609 							 glMapBufferARB(
610 							    unpack,
611 							    GL_WRITE_ONLY);
612 						for (i = 0; i < TEXTURE_SIZE; i++)
613 							pbo_mem[i] = 0.2;
614 						glUnmapBufferARB(unpack);
615 						glBindBufferARB(unpack, 0);
616 					}
617 
618 					if (use_unpack && break_tex_cow) {
619 						GLfloat temp[3];
620 						for (i = 0; i < 3; i++)
621 							temp[i] = 0.8;
622 						glTexSubImage2D(GL_TEXTURE_2D,
623 								0, 0, 0, 1, 1,
624 								GL_RGB,
625 								GL_FLOAT,
626 								temp);
627 					}
628 
629 					/* Check PBO's content */
630 					if (use_unpack) {
631 						glBindBufferARB(unpack,
632 							        unpack_pb[0]);
633 						pbo_mem = (GLfloat *)
634 							 glMapBuffer(unpack,
635 							 GL_READ_ONLY);
636 						if (break_pbo_cow) {
637 							for (i = 0; i < TEXTURE_SIZE; i++)
638 								if (fabsf(pbo_mem[i] - 0.2f) > tolerance[0]) {
639 									REPORT_FAILURE
640 										("PBO modified by someone else, "
641 										 "there must be something wrong");
642 									return PIGLIT_FAIL;
643 								}
644 						}
645 						glUnmapBufferARB(unpack);
646 						glBindBufferARB(unpack, 0);
647 					}
648 
649 
650 					/* Read texture back */
651 					if (use_pack) {
652 						glGenBuffersARB(1, pack_pb);
653 						glBindBufferARB(pack, pack_pb[0]);
654 						glBufferDataARB(pack,
655 								TEXTURE_SIZE *
656 								sizeof(GLfloat),
657 								NULL, GL_STREAM_DRAW);
658 						glGetTexImage(GL_TEXTURE_2D,
659 							      0, GL_RGB,
660 							      GL_FLOAT, NULL);
661 						pbo_mem = (GLfloat *)
662 							 glMapBufferARB(pack,
663 							 GL_READ_ONLY);
664 					}
665 					else {
666 						glGetTexImage(GL_TEXTURE_2D,
667 							      0, GL_RGB,
668 							      GL_FLOAT, t2);
669 						pbo_mem = t2;
670 					}
671 
672 					/* Check texture image */
673 					for (i = 0; i < TEXTURE_SIZE/3; i++) {
674 						int idx = i * 3;
675 						if (i == 0 && break_tex_cow
676 						   && use_unpack) {
677 							exp_tex[idx + 0] = 0.8;
678 							exp_tex[idx + 1] = 0.8;
679 							exp_tex[idx + 2] = 0.8;
680 						}
681 						else {
682 							exp_tex[idx + 0] = 1.0;
683 							exp_tex[idx + 1] = 1.0;
684 							exp_tex[idx + 2] = 0.0;
685 						}
686 					}
687 					pass &= piglit_compare_images_color(0,
688 							0, TEXSIZE,
689 							TEXSIZE, 3,
690 							tolerance, exp_tex,
691 							pbo_mem);
692 
693 					if (use_pack) {
694 						glUnmapBufferARB(pack);
695 						glBindBufferARB(pack, 0);
696 						glDeleteBuffersARB(1, pack_pb);
697 					}
698 					if (use_unpack) {
699 						glDeleteBuffersARB(1, unpack_pb);
700 					}
701 
702 					glEnable(GL_TEXTURE_2D);
703 					glBegin(GL_POLYGON);
704 					glTexCoord2f(0, 0);
705 					glVertex2f(0, 0);
706 					glTexCoord2f(1, 0);
707 					glVertex2f(TEXSIZE, 0);
708 					glTexCoord2f(1, 1);
709 					glVertex2f(TEXSIZE, TEXSIZE);
710 					glTexCoord2f(0, 1);
711 					glVertex2f(0, TEXSIZE);
712 					glEnd();
713 					glDisable(GL_TEXTURE_2D);
714 
715 					glReadPixels(0, 0, WINSIZE, WINSIZE,
716 						     GL_RGB, GL_FLOAT,
717 						     buf);
718 
719 					for (j = 0; j < WINSIZE; j++) {
720 						for (i = 0; i < WINSIZE; i++) {
721 							int idx = (j * WINSIZE + i) * 3;
722 							if (i == 0 && j == 0
723 							    && break_tex_cow
724 							    && use_unpack) {
725 								exp_win[idx + 0] = 0.8;
726 								exp_win[idx + 1] = 0.8;
727 								exp_win[idx + 2] = 0.8;
728 							}
729 							else if (i < TEXSIZE && j < TEXSIZE) {
730 								exp_win[idx + 0] = green[0];
731 								exp_win[idx + 1] = green[1];
732 								exp_win[idx + 2] = green[2];
733 							}
734 							else {
735 								exp_win[idx + 0] = black[0];
736 								exp_win[idx + 1] = black[1];
737 								exp_win[idx + 2] = black[2];
738 							}
739 						}
740 					}
741 					pass &= piglit_compare_images_color(0,
742 							0, WINSIZE,
743 							WINSIZE, 3,
744 							tolerance, exp_win,
745 							buf);
746 				}
747 			}
748 		}
749 	}
750 
751 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
752 }
753 
754 enum piglit_result
test_tex_sub_image(void * null)755 test_tex_sub_image(void *null)
756 {
757 	GLuint pbs[1];
758 	GLfloat t[TEXSIZE * TEXSIZE * 3];
759 	int i, j;
760 	int use_unpack = 0;
761 	GLfloat green[3] = { 0.0, 1.0, 0.0 };
762 	GLfloat black[3] = { 0.0, 0.0, 0.0 };
763 	GLfloat *pbo_mem = NULL;
764 	GLfloat buf[WINSIZE * WINSIZE * 3];
765 	bool pass = true;
766 	GLfloat expected[WINSIZE * WINSIZE * 3];
767 	GLfloat tolerance[4];
768 	piglit_compute_probe_tolerance(GL_RGB, &tolerance[0]);
769 
770 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
771 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
772 
773 	for (use_unpack = 0; use_unpack < 2; use_unpack++) {
774 		pbo_mem = NULL;
775 		glClearColor(0.0, 0.0, 0.0, 1.0);
776 		glClear(GL_COLOR_BUFFER_BIT);
777 
778 		if (use_unpack) {
779 			glGenBuffersARB(1, pbs);
780 			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbs[0]);
781 			glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
782 					TEXSIZE * TEXSIZE * 3 *
783 					sizeof(GLfloat), NULL, GL_STREAM_DRAW);
784 			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
785 		}
786 
787 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
788 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
789 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE, TEXSIZE, 0, GL_RGB,
790 						 GL_FLOAT, NULL);
791 
792 		if (use_unpack) {
793 			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbs[0]);
794 			pbo_mem = (GLfloat *) glMapBufferARB(
795 					GL_PIXEL_UNPACK_BUFFER_ARB,
796 					GL_WRITE_ONLY);
797 		}
798 		else {
799 			pbo_mem = t;
800 		}
801 
802 		for (i = 0; i < TEXSIZE * TEXSIZE; i++) {
803 			pbo_mem[3 * i] = 0.0;
804 			pbo_mem[3 * i + 1] = 1.0;
805 			pbo_mem[3 * i + 2] = 0.0;
806 		}
807 
808 		if (use_unpack) {
809 			glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
810 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE,
811 					TEXSIZE, GL_RGB, GL_FLOAT, NULL);
812 			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
813 		}
814 		else
815 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE,
816 					TEXSIZE, GL_RGB, GL_FLOAT, pbo_mem);
817 
818 		glEnable(GL_TEXTURE_2D);
819 		glBegin(GL_POLYGON);
820 		glTexCoord2f(0, 0);
821 		glVertex2f(0, 0);
822 		glTexCoord2f(1, 0);
823 		glVertex2f(10, 0);
824 		glTexCoord2f(1, 1);
825 		glVertex2f(10, 10);
826 		glTexCoord2f(0, 1);
827 		glVertex2f(0, 10);
828 		glEnd();
829 		glDisable(GL_TEXTURE_2D);
830 
831 		glReadPixels(0, 0, WINSIZE, WINSIZE, GL_RGB, GL_FLOAT, buf);
832 
833 		for (j = 0; j < WINSIZE; j++) {
834 			for (i = 0; i < WINSIZE; i++) {
835 				int idx = (j * WINSIZE + i) * 3;
836 				if (i < 10 && j < 10) {
837 					expected[idx + 0] = green[0];
838 					expected[idx + 1] = green[1];
839 					expected[idx + 2] = green[2];
840 				}
841 				else {
842 					expected[idx + 0] = black[0];
843 					expected[idx + 1] = black[1];
844 					expected[idx + 2] = black[2];
845 				}
846 			}
847 		}
848 		pass &= piglit_compare_images_color(0, 0, WINSIZE,
849 						    WINSIZE, 3, tolerance,
850 						    expected, buf);
851 	}
852 
853 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
854 }
855 
856 enum piglit_result
test_polygon_stip(void * null)857 test_polygon_stip(void *null)
858 {
859 	int use_unpack = 0;
860 	int use_pack = 0;
861 	GLuint unpack_pb[1];
862 	GLuint pack_pb[1];
863 	GLubyte t1[32 * 32 / 8];
864 	GLubyte t2[32 * 32 / 8];
865 	GLubyte *pbo_mem = NULL;
866 	int i, j;
867 	GLfloat white[3] = { 1.0, 1.0, 1.0 };
868 	GLfloat black[3] = { 0.0, 0.0, 0.0 };
869 	GLfloat buf[WINSIZE * WINSIZE * 3];
870 	bool pass = true;
871 	GLfloat expected[WINSIZE * WINSIZE * 3];
872 	GLfloat tolerance[4];
873 
874 	piglit_compute_probe_tolerance(GL_RGB, &tolerance[0]);
875 
876 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
877 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
878 
879 	for (use_unpack = 0; use_unpack < 2; use_unpack++) {
880 		for (use_pack = 0; use_pack < 2; use_pack++) {
881 			glClearColor(0.0, 0.0, 0.0, 1.0);
882 			glClear(GL_COLOR_BUFFER_BIT);
883 
884 			if (use_unpack) {
885 				glGenBuffersARB(1, unpack_pb);
886 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
887 						unpack_pb[0]);
888 				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
889 						32 * 32 / 8, NULL,
890 						GL_STREAM_DRAW);
891 				pbo_mem = (GLubyte *) glMapBufferARB(
892 						GL_PIXEL_UNPACK_BUFFER_ARB,
893 						GL_WRITE_ONLY);
894 			}
895 			else {
896 				pbo_mem = t1;
897 			}
898 
899 			/* Fill in the stipple pattern */
900 			for (i = 0; i < 32 * 32 / 8; i++) {
901 				pbo_mem[i] = 0xAA; /* Checkerboard */
902 			}
903 
904 			if (use_unpack) {
905 				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
906 				glPolygonStipple(NULL);
907 			}
908 			else {
909 				glPolygonStipple(pbo_mem);
910 			}
911 
912 			/* Read back the stipple pattern */
913 			if (use_pack) {
914 				glGenBuffersARB(1, pack_pb);
915 				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
916 					pack_pb[0]);
917 				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
918 						32 * 32 / 8, NULL,
919 						GL_STREAM_DRAW);
920 				glGetPolygonStipple(NULL);
921 				pbo_mem = (GLubyte *) glMapBufferARB(
922 					GL_PIXEL_PACK_BUFFER_ARB,
923 					GL_READ_ONLY);
924 			}
925 			else {
926 				glGetPolygonStipple(t2);
927 				pbo_mem = t2;
928 			}
929 
930 			for (i = 0; i < 32 * 32 / 8; i++) {
931 				if (pbo_mem[i] != 0xAA) {
932 					REPORT_FAILURE("glGetPolygonStipple failed");
933 					return PIGLIT_FAIL;
934 				}
935 			}
936 
937 
938 			if (use_unpack) {
939 				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
940 				glDeleteBuffersARB(1, unpack_pb);
941 			}
942 			if (use_pack) {
943 				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
944 				glDeleteBuffersARB(1, pack_pb);
945 			}
946 
947 			glEnable(GL_POLYGON_STIPPLE);
948 			glColor4f(1.0, 1.0, 1.0, 0.0);
949 			glBegin(GL_POLYGON);
950 			glVertex2f(0, 0);
951 			glVertex2f(10, 0);
952 			glVertex2f(10, 10);
953 			glVertex2f(0, 10);
954 			glEnd();
955 
956 			glDisable(GL_POLYGON_STIPPLE);
957 
958 			/* Check the result */
959 			glReadPixels(0, 0, WINSIZE, WINSIZE, GL_RGB, GL_FLOAT, buf);
960 
961 			for (j = 0; j < WINSIZE; j++) {
962 				for (i = 0; i < WINSIZE; i++) {
963 					int idx = (j * WINSIZE + i) * 3;
964 					if (!(i & 1) && i < 10 && j < 10) {
965 						expected[idx + 0] = white[0];
966 						expected[idx + 1] = white[1];
967 						expected[idx + 2] = white[2];
968 					}
969 					else {
970 						expected[idx + 0] = black[0];
971 						expected[idx + 1] = black[1];
972 						expected[idx + 2] = black[2];
973 					}
974 				}
975 			}
976 			pass &= piglit_compare_images_color(0, 0, WINSIZE,
977 						            WINSIZE, 3,
978 							    tolerance,
979 							    expected, buf);
980 
981 		}
982 	}
983 
984 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
985 }
986 
987 enum piglit_result
test_error_handling(void * null)988 test_error_handling(void *null)
989 {
990 	bool pass = true;
991 	GLuint fbs[1];
992 	GLuint tex;
993 
994 	if (piglit_khr_no_error)
995 		return PIGLIT_SKIP;
996 
997 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
998 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
999 
1000 	/* glDrawPixels raises an error when the buffer is too small */
1001 	glGenBuffersARB(1, fbs);
1002 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, fbs[0]);
1003 	glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 32 * 32 * 4, NULL,
1004 						 GL_STREAM_DRAW);
1005 	glDrawPixels(32, 32 + 1, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1006 	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
1007 
1008 	glDeleteBuffersARB(1, fbs);
1009 	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
1010 
1011 	/* test that glReadPixels into too small of buffer raises error */
1012 	glGenBuffersARB(1, fbs);
1013 	glBindBufferARB(GL_PIXEL_PACK_BUFFER, fbs[0]);
1014 	glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, 32 * 32 * 4, NULL,
1015 						 GL_STREAM_DRAW);
1016 	glReadPixels(0, 0, 32, 32 + 1, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1017 	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
1018 
1019 	glDeleteBuffersARB(1, fbs);
1020 	glBindBufferARB(GL_PIXEL_PACK_BUFFER, 0);
1021 
1022 	/* test that glTexImage2D raises an error when the buffer is too small */
1023 	glGenBuffers(1, fbs);
1024 	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, fbs[0]);
1025 	glBufferData(GL_PIXEL_UNPACK_BUFFER, 4 * (32 * 32 - 1), NULL, GL_STREAM_DRAW);
1026 
1027 	glGenTextures(1, &tex);
1028 	glBindTexture(GL_TEXTURE_2D, tex);
1029 
1030 	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
1031 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0,
1032 		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1033 	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
1034 
1035 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 16, 0,
1036 		     GL_RGBA, GL_UNSIGNED_BYTE, (void*)(32 * 16 * 4));
1037 	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
1038 
1039 	glDeleteTextures(1, &tex);
1040 	glDeleteBuffers(1, fbs);
1041 
1042 	/* test that glGetTexImage raises an error when the buffer is too small */
1043 	glGenBuffers(1, fbs);
1044 	glBindBuffer(GL_PIXEL_PACK_BUFFER, fbs[0]);
1045 	glBufferData(GL_PIXEL_PACK_BUFFER, 4 * (32 * 32 - 1), NULL, GL_STREAM_DRAW);
1046 
1047 	glGenTextures(1, &tex);
1048 	glBindTexture(GL_TEXTURE_2D, tex);
1049 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1050 
1051 	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
1052 	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1053 	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
1054 
1055 	glDeleteTextures(1, &tex);
1056 	glDeleteBuffers(1, fbs);
1057 
1058 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
1059 }
1060 
1061 enum piglit_result
piglit_display(void)1062 piglit_display(void)
1063 {
1064 	enum piglit_result result = PIGLIT_PASS;
1065 	static struct piglit_subtest funcs[] = {
1066 		{ "test_sanity", "", test_sanity, NULL },
1067 		{ "test_draw_pixels", "", test_draw_pixels, NULL },
1068 		{ "test_pixel_map", "", test_pixel_map, NULL },
1069 		{ "test_bitmap", "", test_bitmap, NULL },
1070 		{ "test_tex_image", "", test_tex_image, NULL },
1071 		{ "test_tex_sub_image", "", test_tex_sub_image, NULL },
1072 		{ "test_polygon_stip", "", test_polygon_stip, NULL },
1073 		{ "test_error_handling", "", test_error_handling, NULL },
1074 		{ NULL, NULL, NULL, NULL } /* End of list sentinal */
1075 	};
1076 
1077 	result = piglit_run_selected_subtests(funcs, NULL, 0, result);
1078 
1079 	return result;
1080 }
1081