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