cmake: respect indentation
[piglit.git] / tests / texturing / texsubimage.c
blobce8ff89be0d257a6c4e5bb848da5443b6ccc006f
1 /*
2 * Copyright © 2011 VMware, Inc.
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:
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.
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
21 * DEALINGS IN THE SOFTWARE.
26 /**
27 * This should expose any errors in texel addressing within a texture image
28 * when calling glTexSubImage1D/2D/3D().
30 * Brian Paul
31 * October 2011
35 #include "piglit-util-gl.h"
36 #include "../fbo/fbo-formats.h"
38 #define STR(x) #x
39 #define STRINGIFY(x) STR(x)
41 PIGLIT_GL_TEST_CONFIG_BEGIN
43 config.supports_gl_compat_version = 10;
45 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
46 config.khr_no_error_support = PIGLIT_NO_ERRORS;
48 config.window_width = 512;
49 config.window_height = 512;
51 PIGLIT_GL_TEST_CONFIG_END
53 /**
54 * This is a subset of the formats in fbo-formats.h
55 * We don't test non-color, float, or int/uint textures at this time.
57 static const struct test_desc texsubimage_test_sets[] = {
59 core,
60 ARRAY_SIZE(core),
61 "Core formats",
62 GL_UNSIGNED_NORMALIZED,
65 tdfx_texture_compression_fxt1,
66 ARRAY_SIZE(tdfx_texture_compression_fxt1),
67 "GL_3DFX_texture_compression_FXT1",
68 GL_UNSIGNED_NORMALIZED,
69 {"GL_ARB_texture_compression",
70 "GL_3DFX_texture_compression_FXT1"},
73 ext_texture_compression_s3tc,
74 ARRAY_SIZE(ext_texture_compression_s3tc),
75 "GL_EXT_texture_compression_s3tc",
76 GL_UNSIGNED_NORMALIZED,
77 {"GL_ARB_texture_compression",
78 "GL_EXT_texture_compression_s3tc"},
81 ext_texture_compression_rgtc,
82 ARRAY_SIZE(ext_texture_compression_rgtc),
83 "GL_EXT_texture_compression_rgtc",
84 GL_UNSIGNED_NORMALIZED,
85 {"GL_EXT_texture_compression_rgtc"}
88 ext_texture_compression_latc,
89 ARRAY_SIZE(ext_texture_compression_latc),
90 "GL_EXT_texture_compression_latc",
91 GL_UNSIGNED_NORMALIZED,
92 {"GL_EXT_texture_compression_latc"}
93 }, {
94 arb_texture_compression_bptc_unorm,
95 ARRAY_SIZE(arb_texture_compression_bptc_unorm),
96 "GL_ARB_texture_compression_bptc-unorm",
97 GL_UNSIGNED_NORMALIZED,
98 {"GL_ARB_texture_compression_bptc"}
99 }, {
100 arb_texture_compression_bptc_float,
101 ARRAY_SIZE(arb_texture_compression_bptc_float),
102 "GL_ARB_texture_compression_bptc-float",
103 GL_FLOAT,
104 {"GL_ARB_texture_compression_bptc"}
108 /* Default texture size. Other values might be used if the texture has
109 * less dimensions or other restrictions */
110 #define DEFAULT_TEX_WIDTH 128
111 #define DEFAULT_TEX_HEIGHT 64
112 #define DEFAULT_TEX_DEPTH 8
114 static const GLenum srcFormat = GL_RGBA;
116 /* List of texture targets to test, terminated by GL_NONE */
117 static const GLenum *test_targets;
119 /* If set to GL_TRUE then the texture sub image upload will be read
120 * from a PBO */
121 static GLboolean use_pbo = GL_FALSE;
123 struct sub_region {
124 int tx, ty, tz, tw, th, td;
127 /* If set, format and sub-region are given from command line. */
128 struct single_test {
129 bool enabled;
130 GLenum targets[2];
131 GLenum format;
132 struct sub_region region;
135 static struct single_test manual_dispatch = {
136 .enabled = false, .targets = { GL_NONE, GL_NONE }
139 static const char fragment_1d_array[] =
140 "#extension GL_EXT_texture_array : require\n"
141 "uniform sampler1DArray tex;\n"
142 "const float TEX_HEIGHT = " STRINGIFY(DEFAULT_TEX_HEIGHT) ".0;\n"
143 "void\n"
144 "main()\n"
145 "{\n"
146 " float layer = gl_TexCoord[0].t * TEX_HEIGHT - 0.5;\n"
147 " gl_FragColor = texture1DArray(tex, vec2(gl_TexCoord[0].s,\n"
148 " layer));\n"
149 "}\n";
151 static const char fragment_2d_array[] =
152 "#extension GL_EXT_texture_array : require\n"
153 "uniform sampler2DArray tex;\n"
154 "const float TEX_DEPTH = " STRINGIFY(DEFAULT_TEX_DEPTH) ".0;\n"
155 "void\n"
156 "main()\n"
157 "{\n"
158 " float layer = gl_TexCoord[0].p * TEX_DEPTH - 0.5;\n"
159 " gl_FragColor = texture2DArray(tex, vec3(gl_TexCoord[0].st,\n"
160 " layer));\n"
161 "}\n";
163 static const char vertex_cube_map_array[] =
164 "const float N_SIDES = 6.0;\n"
165 "const float TEX_DEPTH = " STRINGIFY(DEFAULT_TEX_DEPTH) ".0 *\n"
166 " N_SIDES;\n"
167 "void\n"
168 "main()\n"
169 "{\n"
170 " vec2 face_coord;\n"
171 " vec3 res;\n"
172 " float slice = gl_MultiTexCoord0.p * TEX_DEPTH - 0.5;\n"
173 " float layer = floor(slice / N_SIDES);\n"
174 " int face = int(floor(mod(slice, N_SIDES)));\n"
175 "\n"
176 " face_coord = gl_MultiTexCoord0.st * 2.0 - 1.0;\n"
177 " if (face == 0)\n"
178 " res = vec3(1.0, -face_coord.ts);\n"
179 " else if (face == 1)\n"
180 " res = vec3(-1.0, face_coord.ts * vec2(-1.0, 1.0));\n"
181 " else if (face == 2)\n"
182 " res = vec3(face_coord.s, 1.0, face_coord.t);\n"
183 " else if (face == 3)\n"
184 " res = vec3(face_coord.s, -1.0, -face_coord.t);\n"
185 " else if (face == 4)\n"
186 " res = vec3(face_coord.st * vec2(1.0, -1.0), 1.0);\n"
187 " else\n"
188 " res = vec3(-face_coord.st, -1.0);\n"
189 " gl_TexCoord[0] = vec4(res, layer);\n"
190 " gl_Position = ftransform();\n"
191 "}\n";
193 static const char fragment_cube_map_array[] =
194 "#extension GL_ARB_texture_cube_map_array : require\n"
195 "uniform samplerCubeArray tex;\n"
196 "void\n"
197 "main()\n"
198 "{\n"
199 " gl_FragColor = texture(tex, gl_TexCoord[0]);\n"
200 "}\n";
203 * XXX add this to piglit-util if useful elsewhere.
205 static GLvoid
206 piglit_draw_rect_tex3d(float x, float y, float w, float h,
207 float tx, float ty, float tw, float th,
208 float tz0, float tz1)
210 float verts[4][4];
211 float tex[4][3];
213 verts[0][0] = x;
214 verts[0][1] = y;
215 verts[0][2] = 0.0;
216 verts[0][3] = 1.0;
217 tex[0][0] = tx;
218 tex[0][1] = ty;
219 tex[0][2] = tz0;
220 verts[1][0] = x + w;
221 verts[1][1] = y;
222 verts[1][2] = 0.0;
223 verts[1][3] = 1.0;
224 tex[1][0] = tx + tw;
225 tex[1][1] = ty;
226 tex[1][2] = tz1;
227 verts[2][0] = x + w;
228 verts[2][1] = y + h;
229 verts[2][2] = 0.0;
230 verts[2][3] = 1.0;
231 tex[2][0] = tx + tw;
232 tex[2][1] = ty + th;
233 tex[2][2] = tz1;
234 verts[3][0] = x;
235 verts[3][1] = y + h;
236 verts[3][2] = 0.0;
237 verts[3][3] = 1.0;
238 tex[3][0] = tx;
239 tex[3][1] = ty + th;
240 tex[3][2] = tz0;
242 glVertexPointer(4, GL_FLOAT, 0, verts);
243 glTexCoordPointer(3, GL_FLOAT, 0, tex);
244 glEnableClientState(GL_VERTEX_ARRAY);
245 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
247 glDrawArrays(GL_QUADS, 0, 4);
249 glDisableClientState(GL_VERTEX_ARRAY);
250 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
253 static GLboolean
254 equal_images(GLenum target,
255 const GLubyte *original_ref,
256 const GLubyte *updated_ref,
257 const GLubyte *testImg,
258 GLuint w, GLuint h, GLuint d,
259 GLuint tx, GLuint ty, GLuint tz,
260 GLuint tw, GLuint th, GLuint td)
262 switch (target) {
263 case GL_TEXTURE_1D:
264 ty = 0;
265 th = 1;
266 /* flow through */
267 case GL_TEXTURE_2D:
268 case GL_TEXTURE_1D_ARRAY:
269 tz = 0;
270 td = 1;
271 break;
274 return piglit_equal_images_update_rgba8(original_ref, updated_ref, testImg,
275 w, h, d,
276 tx, ty, tz, tw, th, td,
281 * Draw each image of the texture to the framebuffer and then save the
282 * entire thing to a buffer with glReadPixels().
284 static void
285 draw_and_read_texture(GLuint w, GLuint h, GLuint d, GLubyte *ref)
287 int i;
289 for (i = 0; i < d; i++) {
290 float tz = (i + 0.5f) / d;
291 piglit_draw_rect_tex3d(i / 8 * w, i % 8 * h, /* x/y */
292 w, h,
293 0.0, 0.0, /* tx/ty */
294 1.0, 1.0, /* tw/th */
295 tz, tz /* tz0/tz1 */);
298 for (i = 0; i < d; i += 8) {
299 glReadPixels(i / 8 * w, i % 8 * h,
300 w, h * MIN2(8, d - i),
301 GL_RGBA, GL_UNSIGNED_BYTE,
302 ref);
303 ref += 8 * w * h * 4;
307 static GLuint
308 create_texture(GLenum target,
309 GLenum intFormat,
310 GLsizei w, GLsizei h, GLsizei d,
311 GLenum srcFormat,
312 const GLubyte *img)
314 GLuint tex;
316 glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
317 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, h);
319 glGenTextures(1, &tex);
320 glBindTexture(target, tex);
321 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
322 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
323 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
324 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
325 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
326 if (d > 1) {
327 glTexImage3D(target, 0, intFormat, w, h, d, 0,
328 srcFormat, GL_UNSIGNED_BYTE, img);
330 else if (h > 1) {
331 glTexImage2D(target, 0, intFormat, w, h, 0,
332 srcFormat, GL_UNSIGNED_BYTE, img);
334 else if (w > 1) {
335 glTexImage1D(target, 0, intFormat, w, 0,
336 srcFormat, GL_UNSIGNED_BYTE, img);
337 } else {
338 assert(!"Unknown texture dimensions");
341 return tex;
344 static bool
345 test_region(GLuint pbo, GLenum target, GLenum internal_format,
346 const unsigned char *original_img,
347 const unsigned char *original_ref,
348 const unsigned char *updated_img,
349 const unsigned char *updated_ref,
350 unsigned w, unsigned h, unsigned d,
351 const struct sub_region *region)
353 bool pass = true;
354 GLuint tex;
355 unsigned char *test_img = (unsigned char *)malloc(w * h * d * 4);
357 /* Recreate the original texture */
358 tex = create_texture(target, internal_format, w, h, d,
359 srcFormat, original_img);
361 if (use_pbo)
362 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
364 /* replace texture region with data from updated image */
365 glPixelStorei(GL_UNPACK_SKIP_PIXELS, region->tx);
366 glPixelStorei(GL_UNPACK_SKIP_ROWS, region->ty);
367 glPixelStorei(GL_UNPACK_SKIP_IMAGES, region->tz);
368 if (d > 1) {
369 glTexSubImage3D(target, 0,
370 region->tx, region->ty, region->tz,
371 region->tw, region->th, region->td,
372 srcFormat, GL_UNSIGNED_BYTE,
373 use_pbo ? NULL : updated_img);
374 } else if (h > 1) {
375 glTexSubImage2D(target, 0,
376 region->tx, region->ty,
377 region->tw, region->th,
378 srcFormat, GL_UNSIGNED_BYTE,
379 use_pbo ? NULL : updated_img);
380 } else if (w > 1) {
381 glTexSubImage1D(target, 0, region->tx, region->tw,
382 srcFormat, GL_UNSIGNED_BYTE,
383 use_pbo ? NULL : updated_img);
384 } else {
385 assert(!"Unknown image dimensions");
388 if (use_pbo)
389 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
391 /* draw test image */
392 draw_and_read_texture(w, h, d, test_img);
394 glDeleteTextures(1, &tex);
396 piglit_present_results();
398 if (!equal_images(target,
399 original_ref, updated_ref, test_img,
400 w, h, d,
401 region->tx, region->ty, region->tz,
402 region->tw, region->th, region->td)) {
403 printf("texsubimage failed\n");
404 printf(" target: %s\n", piglit_get_gl_enum_name(target));
405 printf(" internal format: %s\n",
406 get_format_name(internal_format));
407 printf(" region: %d, %d %d x %d\n",
408 region->tx, region->ty, region->tw, region->th);
409 pass = false;
412 free(test_img);
414 return pass;
418 * Create two textures with different reference values. Draw both of
419 * the textures to the framebuffer and save the reference images with
420 * glReadPixels.
422 * Loop:
423 * - Create another texture with the same initial values as the first
424 * texture
425 * - replace a random sub-region of the texture image with values from
426 * the 2nd texture
427 * - draw the texture to the framebuffer and read back with glReadPixels
428 * - compare reference images to test image choosing either the first
429 * or second reference image for each pixel depending on whether it
430 * is within the updated region
431 * \param target GL_TEXTURE_1D/2D/3D
432 * \param intFormat the internal texture format
434 static GLboolean
435 test_format(GLenum target, GLenum intFormat,
436 unsigned w, unsigned h, unsigned d,
437 const struct sub_region *regions, unsigned num_regions)
439 GLuint tex, i, j, k, n, t;
440 GLubyte *original_img, *original_ref;
441 GLubyte *updated_img, *updated_ref;
442 GLboolean pass = GL_TRUE;
443 GLuint pbo = 0;
445 original_img = (GLubyte *) malloc(w * h * d * 4);
446 original_ref = (GLubyte *) malloc(w * h * d * 4);
447 updated_img = (GLubyte *) malloc(w * h * d * 4);
448 updated_ref = (GLubyte *) malloc(w * h * d * 4);
450 /* fill source tex images */
451 n = 0;
452 for (i = 0; i < d; i++) {
453 for (j = 0; j < h; j++) {
454 for (k = 0; k < w; k++) {
455 original_img[n + 0] = j * 4;
456 original_img[n + 1] = k * 2;
457 original_img[n + 2] = i * 128 / d;
458 original_img[n + 3] = 255;
460 /* Swizzle the components in the
461 * updated image
463 updated_img[n + 0] = original_img[n + 1];
464 updated_img[n + 1] = original_img[n + 2];
465 updated_img[n + 2] = original_img[n + 0];
466 updated_img[n + 3] = original_img[n + 3];
468 n += 4;
473 if (use_pbo) {
474 glGenBuffers(1, &pbo);
475 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
476 glBufferData(GL_PIXEL_UNPACK_BUFFER,
477 w * h * d * 4,
478 updated_img,
479 GL_STATIC_DRAW);
480 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
483 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
486 /* draw original reference image */
487 tex = create_texture(target, intFormat, w, h, d,
488 srcFormat, original_img);
489 glClear(GL_COLOR_BUFFER_BIT);
490 draw_and_read_texture(w, h, d, original_ref);
491 glDeleteTextures(1, &tex);
493 /* draw updated reference image */
494 tex = create_texture(target, intFormat, w, h, d,
495 srcFormat, updated_img);
496 glClear(GL_COLOR_BUFFER_BIT);
497 draw_and_read_texture(w, h, d, updated_ref);
498 glDeleteTextures(1, &tex);
500 for (t = 0; t < num_regions; t++) {
501 if (!test_region(pbo, target, intFormat,
502 original_img, original_ref,
503 updated_img, updated_ref,
504 w, h, d, &regions[t])) {
505 pass = GL_FALSE;
506 break;
510 free(original_img);
511 free(original_ref);
512 free(updated_img);
513 free(updated_ref);
514 if (use_pbo)
515 glDeleteBuffers(1, &pbo);
517 return pass;
520 static void
521 select_regions(unsigned w, unsigned h, unsigned d, GLenum internal_format,
522 struct sub_region *regions, unsigned num_regions)
524 int i;
525 GLuint bw, bh, bb, wMask, hMask, dMask;
527 piglit_get_compressed_block_size(internal_format, &bw, &bh, &bb);
528 wMask = ~(bw-1);
529 hMask = ~(bh-1);
530 dMask = ~0;
532 for (i = 0; i < num_regions; i++) {
533 /* Choose random region of texture to update.
534 * Use sizes and positions that are multiples of
535 * the compressed block size.
537 regions[i].tw = (rand() % w) & wMask;
538 regions[i].th = (rand() % h) & hMask;
539 regions[i].td = (rand() % d) & dMask;
540 regions[i].tx = (rand() % (w - regions[i].tw)) & wMask;
541 regions[i].ty = (rand() % (h - regions[i].th)) & hMask;
542 regions[i].tz = (rand() % (d - regions[i].td)) & dMask;
544 assert(regions[i].tx + regions[i].tw <= w);
545 assert(regions[i].ty + regions[i].th <= h);
546 assert(regions[i].tz + regions[i].td <= d);
551 * Test all formats in texsubimage_test_sets[] for the given
552 * texture target.
554 static GLboolean
555 test_formats(GLenum target, unsigned w, unsigned h, unsigned d)
557 GLboolean pass = GL_TRUE;
558 int i, j;
560 /* loop over the format groups */
561 for (i = 0; i < ARRAY_SIZE(texsubimage_test_sets); i++) {
562 const struct test_desc *set = &texsubimage_test_sets[i];
563 GLboolean skip = GL_FALSE;
565 /* only test compressed formats with 2D textures */
566 if (i > 0 && target != GL_TEXTURE_2D)
567 continue;
569 /* skip formats for unsupported extensions */
570 for (j = 0; j < ARRAY_SIZE(set->ext); j++) {
571 if (set->ext[j] &&
572 !piglit_is_extension_supported(set->ext[j])) {
573 /* req'd extension not supported */
574 skip = GL_TRUE;
575 break;
578 if (skip)
579 continue;
581 /* loop over formats in the set */
582 for (j = 0; j < set->num_formats; j++) {
583 struct sub_region regions[10];
585 select_regions(w, h, d, set->format[j].internalformat,
586 regions, ARRAY_SIZE(regions));
588 if (!test_format(target,
589 set->format[j].internalformat,
590 w, h, d,
591 regions, ARRAY_SIZE(regions))) {
592 pass = GL_FALSE;
597 return pass;
600 static GLuint
601 prepare_tex_to_fbo_blit_program(GLenum target)
603 GLuint program = 0;
605 switch (target) {
606 case GL_TEXTURE_1D_ARRAY:
607 program = piglit_build_simple_program(NULL, fragment_1d_array);
608 break;
609 case GL_TEXTURE_2D_ARRAY:
610 program = piglit_build_simple_program(NULL, fragment_2d_array);
611 break;
612 case GL_TEXTURE_CUBE_MAP_ARRAY:
613 program = piglit_build_simple_program(vertex_cube_map_array,
614 fragment_cube_map_array);
615 break;
616 default:
617 glEnable(target);
618 break;
621 if (program != 0) {
622 GLuint tex_location;
624 glUseProgram(program);
625 tex_location = glGetUniformLocation(program, "tex");
626 glUniform1i(tex_location, 0);
629 return program;
632 static void
633 print_usage_and_exit(const char *s)
635 printf("Invalid argument: %s\n", s);
636 printf("Usage: texsubimage <pbo> manual <target> <format> "
637 "<tx> <ty> <tz> <tw> <th> <tz>");
640 static unsigned
641 read_integer(const char *s)
643 char *endptr = NULL;
644 unsigned res = strtol(s, &endptr, 0);
646 if (endptr != s + strlen(s))
647 print_usage_and_exit(s);
649 return res;
652 static void
653 init_manual_dispatch(char **argv, unsigned argc)
655 static const unsigned manual_arg_num = 8;
656 if (argc < manual_arg_num)
657 print_usage_and_exit(argv[0]);
659 manual_dispatch.targets[0] = piglit_get_gl_enum_from_name(argv[0]);
660 manual_dispatch.format = piglit_get_gl_enum_from_name(argv[1]);
662 manual_dispatch.region.tx = read_integer(argv[2]);
663 manual_dispatch.region.ty = read_integer(argv[3]);
664 manual_dispatch.region.tz = read_integer(argv[4]);
665 manual_dispatch.region.tw = read_integer(argv[5]);
666 manual_dispatch.region.th = read_integer(argv[6]);
667 manual_dispatch.region.td = read_integer(argv[7]);
669 manual_dispatch.enabled = true;
672 static void
673 adjust_tex_dimensions(GLenum target, unsigned *w, unsigned *h, unsigned *d)
675 if (target == GL_TEXTURE_CUBE_MAP_ARRAY_ARB) {
676 *w = *h;
677 *d *= 6;
678 } else if (target != GL_TEXTURE_3D &&
679 target != GL_TEXTURE_2D_ARRAY) {
680 *d = 1;
683 if (target == GL_TEXTURE_1D)
684 *h = 1;
687 enum piglit_result
688 piglit_display(void)
690 GLboolean pass = GL_TRUE;
691 int i;
693 if (manual_dispatch.enabled)
694 test_targets = manual_dispatch.targets;
696 /* Loop over 1/2/3D texture targets */
697 for (i = 0; test_targets[i] != GL_NONE; i++) {
698 unsigned w = DEFAULT_TEX_WIDTH;
699 unsigned h = DEFAULT_TEX_HEIGHT;
700 unsigned d = DEFAULT_TEX_DEPTH;
701 const GLuint program =
702 prepare_tex_to_fbo_blit_program(test_targets[i]);
704 adjust_tex_dimensions(test_targets[i], &w, &h, &d);
706 if (manual_dispatch.enabled) {
707 pass = test_format(test_targets[i],
708 manual_dispatch.format,
709 w, h, d,
710 &manual_dispatch.region, 1);
711 } else {
712 pass = test_formats(test_targets[i], w, h, d) && pass;
715 if (program == 0) {
716 glDisable(test_targets[i]);
717 } else {
718 glUseProgram(0);
719 glDeleteProgram(program);
723 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
727 void
728 piglit_init(int argc, char **argv)
730 static const GLenum core_targets[] = {
731 GL_TEXTURE_1D,
732 GL_TEXTURE_2D,
733 GL_TEXTURE_3D,
734 GL_NONE
736 static const GLenum array_targets[] = {
737 GL_TEXTURE_1D_ARRAY_EXT,
738 GL_TEXTURE_2D_ARRAY_EXT,
739 GL_NONE
741 static const GLenum cube_map_array_targets[] = {
742 GL_TEXTURE_CUBE_MAP_ARRAY_ARB,
743 GL_NONE
745 int remaining_argc = 1;
746 int i;
748 test_targets = core_targets;
750 for (i = 1; i < argc; i++) {
751 if (!strcmp(argv[i], "array")) {
752 piglit_require_extension("GL_EXT_texture_array");
753 piglit_require_fragment_shader();
754 test_targets = array_targets;
755 } else if (!strcmp(argv[i], "cube_map_array")) {
756 piglit_require_extension
757 ("GL_ARB_texture_cube_map_array");
758 piglit_require_vertex_shader();
759 piglit_require_fragment_shader();
760 test_targets = cube_map_array_targets;
761 } else if (!strcmp(argv[i], "pbo")) {
762 piglit_require_extension("GL_ARB_pixel_buffer_object");
763 use_pbo = GL_TRUE;
764 } else if (!strcmp(argv[i], "manual")) {
765 init_manual_dispatch(argv + i + 1, argc - (i + 1));
766 break;
767 } else {
768 argv[remaining_argc++] = argv[i];
772 if (!manual_dispatch.enabled)
773 fbo_formats_init(remaining_argc, argv, 0);
774 (void) fbo_formats_display;
776 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);