s3tc-errors: Fix GCC unused-function warning.
[piglit.git] / tests / texturing / s3tc-errors.c
bloba356ea2149ce0bd12756226fcd810d057c198208
1 /*
2 * Copyright 2012 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 DEALINGS
21 * IN THE SOFTWARE.
24 /**
25 * Verify error checking for compressed texture functions, using s3tc as
26 * the specific compression formats.
27 * Some rendering is also tested, but it's not the focus here.
28 * Other compressed formats could be added as well (the test should probably
29 * be renamed at that point.)
31 * Brian Paul
32 * Sep 20, 2012
35 #include "piglit-util-gl.h"
37 PIGLIT_GL_TEST_CONFIG_BEGIN
39 #ifdef PIGLIT_USE_OPENGL
40 config.supports_gl_compat_version = 11;
41 #else // PIGLIT_USE_OPENGL_ES2
42 config.supports_gl_es_version = 20;
43 #endif
45 config.window_width = 200;
46 config.window_height = 200;
47 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
48 config.khr_no_error_support = PIGLIT_HAS_ERRORS;
50 PIGLIT_GL_TEST_CONFIG_END
52 static const float red[4] = {1.0, 0.0, 0.0, 1.0};
53 static const float green[4] = {0.0, 1.0, 0.0, 1.0};
54 static const float blue[4] = {0.0, 0.0, 1.0, 1.0};
55 static const float white[4] = {1.0, 1.0, 1.0, 1.0};
57 #ifdef PIGLIT_USE_OPENGL_ES2
59 const char *vs_source =
60 "#version 100\n"
61 "attribute vec4 piglit_vertex;\n"
62 "attribute vec2 piglit_texcoord;\n"
63 "varying mediump vec2 tex_coord;\n"
64 "uniform mat4 proj;\n"
65 "\n"
66 "void main()\n"
67 "{\n"
68 " gl_Position = proj * piglit_vertex;\n"
69 " tex_coord = piglit_texcoord;\n"
70 "}\n";
72 const char *fs_source =
73 "#version 100\n"
74 "varying mediump vec2 tex_coord;\n"
75 "uniform sampler2D tex;\n"
76 "\n"
77 "void main()\n"
78 "{\n"
79 " gl_FragColor = texture2D(tex, tex_coord);\n"
80 "}\n";
82 #include "piglit-matrix.h"
84 GLint tex_program, proj_loc;
86 #endif
88 static const GLenum s3tc_formats[] = {
89 GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
90 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
91 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
92 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
96 static bool
97 check_rendering_(int width, int height, int line)
99 const int w = width / 2 - 2;
100 const int h = height / 2 - 2;
101 bool pass = true;
103 #ifdef PIGLIT_USE_OPENGL
104 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
105 #else
106 glUseProgram(tex_program);
107 piglit_ortho_uniform(proj_loc, piglit_width, piglit_height);
108 #endif
110 glClear(GL_COLOR_BUFFER_BIT);
112 #ifdef PIGLIT_USE_OPENGL
113 glEnable(GL_TEXTURE_2D);
114 glColor3f(1, 1, 1);
115 #endif
117 /* draw the texture */
118 piglit_draw_rect_tex(0, 0, width, height, 0, 0, 1, 1);
120 /* NOTE: don't probe the border pixels of the quadrants just to
121 * avoid potential off-by one errors.
124 /* lower-left red */
125 pass = piglit_probe_rect_rgb(1, 1, w, h, red) && pass;
127 /* lower-right green */
128 pass = piglit_probe_rect_rgb(width/2 + 1, 1, w, h, green) && pass;
130 /* upper-left blue */
131 pass = piglit_probe_rect_rgb(1, height/2 + 1, w, h, blue) && pass;
133 /* upper-right white */
134 pass = piglit_probe_rect_rgb(width/2 + 1, height/2 + 1,
135 w, h, white) && pass;
137 piglit_present_results();
139 if (!pass) {
140 printf("s3tc-errors failure at line %d\n", line);
143 return pass;
147 #define check_rendering(w, h) check_rendering_(w, h, __LINE__)
150 #ifdef PIGLIT_USE_OPENGL
152 * Check for either of two expected GL errors.
153 * XXX this could be a piglit util function
155 static bool
156 check_gl_error2_(GLenum err1, GLenum err2, int line)
158 GLenum err = glGetError();
159 if (err != err1 && err != err2) {
160 printf("Unexpected error %s at %s:%d\n",
161 piglit_get_gl_error_name(err), __FILE__, line);
162 return false;
164 return true;
167 #define check_gl_error2(err1, err2) check_gl_error2_(err1, err2, __LINE__)
168 #endif
171 static bool
172 test_format(int width, int height, GLfloat *image, GLenum requested_format)
174 #ifdef PIGLIT_USE_OPENGL
175 GLubyte *compressed_image;
176 GLenum format2;
177 #endif
178 int x, y, w, h;
179 GLuint tex;
180 bool pass = true;
181 GLuint expected_size;
182 GLint is_compressed;
183 GLint compressed_size;
184 GLint format;
186 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
187 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
188 glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
190 /* Setup initial texture */
191 glGenTextures(1, &tex);
192 glBindTexture(GL_TEXTURE_2D, tex);
193 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
195 glTexImage2D(GL_TEXTURE_2D, 0, requested_format, width, height, 0,
196 GL_RGBA, GL_FLOAT, image);
198 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
199 pass = check_rendering(width, height) && pass;
201 if (!piglit_is_gles() || piglit_get_gl_version() >= 31) {
203 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED,
204 &is_compressed);
205 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
206 GL_TEXTURE_INTERNAL_FORMAT, &format);
207 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
208 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
209 &compressed_size);
211 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
213 if (!is_compressed) {
214 printf("Image was not compressed\n");
215 pass = false;
218 if (format != requested_format) {
219 printf("Internal Format mismatch. Found: 0x%04x Expected: 0x%04x\n",
220 format, requested_format);
221 pass = false;
224 expected_size = piglit_compressed_image_size(requested_format,
225 width, height);
227 if (compressed_size != expected_size) {
228 printf("Compressed image size mismatch. Found: %u Expected: %u\n",
229 compressed_size, expected_size);
230 pass = false;
234 #ifdef PIGLIT_USE_OPENGL
235 /* Use GL_TEXTURE_COMPRESSED_IMAGE_SIZE even if it wasn't what we
236 * expected to avoid corruption due to under-allocated buffer.
238 compressed_image = malloc(compressed_size);
240 /* Read back the compressed image data */
241 glGetCompressedTexImage(GL_TEXTURE_2D, 0, compressed_image);
242 #endif
244 /* Try texsubimage on 4-texel boundary - should work */
245 x = 20;
246 y = 12;
247 w = 16;
248 h = 8;
249 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
250 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
251 glTexSubImage2D(GL_TEXTURE_2D, 0,
252 x, y, w, h,
253 GL_RGBA, GL_FLOAT, image);
255 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
256 pass = check_rendering(width, height) && pass;
258 /* Try texsubimage on non 4-texel boundary - should not work */
259 x = 10;
260 y = 11;
261 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
262 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
263 glTexSubImage2D(GL_TEXTURE_2D, 0,
264 x, y, w, h,
265 GL_RGBA, GL_FLOAT, image);
267 pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
269 #ifdef PIGLIT_USE_OPENGL
270 /* Try compressed subimage on 4-texel boundary - should work */
271 x = 12;
272 y = 8;
273 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
274 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
275 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
276 x, y, w, h,
277 format,
278 piglit_compressed_image_size(format, w, h),
279 compressed_image +
280 piglit_compressed_pixel_offset(format, width, x, y));
282 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
283 pass = check_rendering(width, height) && pass;
285 /* Try compressed subimage on non 4-texel boundary - should not work */
286 x = 14;
287 y = 9;
288 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
289 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
290 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
291 x, y, w, h,
292 format,
293 piglit_compressed_image_size(format, w, h),
294 compressed_image +
295 piglit_compressed_pixel_offset(format, width, 0, 0));
297 pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
299 /* Try compressed subimage with size not a multiple of 4 -
300 * should not work
302 x = 8;
303 y = 8;
304 w = 14;
305 h = 10;
306 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
307 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
308 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
309 x, y, w, h,
310 format,
311 piglit_compressed_image_size(format, 4, 4),
312 compressed_image +
313 piglit_compressed_pixel_offset(format, width, x, y));
315 /* Note, we can get either of these errors depending on the order
316 * in which glCompressedTexSubImage parameters are checked.
317 * INVALID_OPERATION for the bad size or INVALID_VALUE for the
318 * wrong compressed image size.
320 pass = check_gl_error2(GL_INVALID_OPERATION, GL_INVALID_VALUE) && pass;
322 /* Try compressed subimage with invalid offset - should not work */
323 x = -4;
324 y = 8;
325 w = 4;
326 h = 4;
327 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
328 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
329 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
330 x, y, w, h,
331 format,
332 piglit_compressed_image_size(format, w, h),
333 compressed_image +
334 piglit_compressed_pixel_offset(format, width, 0, 0));
336 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
338 /* Try compressed subimage with too large of image - should not work */
339 x = 16;
340 y = 8;
341 w = width * 2;
342 h = height * 2;
343 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
344 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
345 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
346 x, y, w, h,
347 format,
348 piglit_compressed_image_size(format, w, h),
349 compressed_image +
350 piglit_compressed_pixel_offset(format, width, x, y));
352 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
354 /* Try compressed subimage with different format - should not work */
355 if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
356 format2 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
357 else
358 format2 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
359 x = 4;
360 y = 4;
361 w = 4;
362 h = 4;
363 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
364 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
365 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
366 x, y, w, h,
367 format2,
368 piglit_compressed_image_size(format2, w, h),
369 compressed_image +
370 piglit_compressed_pixel_offset(format2, width, x, y));
372 pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
374 /* Try zero-sized subimage - should not be an error */
375 x = 4;
376 y = 4;
377 w = 0;
378 h = 0;
379 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
380 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
381 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
382 x, y, w, h,
383 format,
384 piglit_compressed_image_size(format, w, h),
385 compressed_image +
386 piglit_compressed_pixel_offset(format, width, x, y));
388 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
391 /* Try CompressedTexSubImage into level 1 (which is missing) */
392 x = 0;
393 y = 0;
394 w = 4;
395 h = 4;
396 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
397 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
398 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1,
399 x, y, w, h,
400 format,
401 piglit_compressed_image_size(format, w, h),
402 compressed_image +
403 piglit_compressed_pixel_offset(format, width, x, y));
405 pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
407 /* Try CompressedTexImage of size zero - should not be an erorr */
408 w = 0;
409 h = 0;
410 glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
411 piglit_compressed_image_size(format, w, h),
412 compressed_image);
414 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
416 /* Try CompressedTexImage with size which is a not a multiple of the
417 * block size - should not be an error
419 w = width - 1;
420 h = height - 1;
421 glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
422 piglit_compressed_image_size(format, w, h),
423 compressed_image);
425 if (piglit_get_gl_version() < 20 &&
426 !piglit_is_extension_supported("GL_ARB_texture_non_power_of_two")) {
427 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
429 /* Reload the original into the texture. */
430 w = width;
431 h = height;
432 glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
433 piglit_compressed_image_size(format, w, h),
434 compressed_image);
437 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
438 pass = check_rendering(width, height) && pass;
440 free(compressed_image);
442 #endif
444 glDeleteTextures(1, &tex);
445 return pass;
449 static bool
450 test_small_mipmap_level(void)
452 bool pass = true;
453 GLuint tex;
454 GLubyte buf[100];
455 int width, height;
456 int format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
458 memset(buf, 0, sizeof(buf));
460 glGenTextures(1, &tex);
461 glBindTexture(GL_TEXTURE_2D, tex);
463 /* test sizes 1x1, 1x2, 2x1, .. 2x4, 4x4 */
464 for (width = 1; width <= 4; width *= 2) {
465 for (height = 1; height <= 4; height *= 2) {
466 /* Initial image */
467 glTexImage2D(GL_TEXTURE_2D, 0, format, width, height,
468 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
470 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
472 /* Try TexSubImage of whole texture */
473 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
474 GL_RGBA, GL_UNSIGNED_BYTE, buf);
476 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
480 glDeleteTextures(1, &tex);
482 return pass;
486 static bool
487 test_non_power_of_two(void)
489 bool pass = true;
491 if (piglit_is_extension_supported("GL_ARB_texture_non_power_of_two")) {
492 GLuint tex;
493 GLubyte buf[800];
494 int width = 11, height = 14;
495 int format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
497 memset(buf, 0, sizeof(buf));
499 /* Setup initial texture */
500 glGenTextures(1, &tex);
501 glBindTexture(GL_TEXTURE_2D, tex);
502 glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
503 GL_RGBA, GL_UNSIGNED_BYTE, buf);
505 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
507 /* Try TexSubImage of partial block on right edge */
508 glTexSubImage2D(GL_TEXTURE_2D, 0,
509 width-3, 0, /* position */
510 3, 4, /* size */
511 GL_RGBA, GL_UNSIGNED_BYTE, buf);
513 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
515 /* Try TexSubImage of partial block on top edge */
516 glTexSubImage2D(GL_TEXTURE_2D, 0,
517 0, height-2, /* position */
518 4, 2, /* size */
519 GL_RGBA, GL_UNSIGNED_BYTE, buf);
521 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
523 /* Try TexSubImage of larger partial block on right edge */
524 glTexSubImage2D(GL_TEXTURE_2D, 0,
525 width-3-4, 0, /* position */
526 3+4, 4, /* size */
527 GL_RGBA, GL_UNSIGNED_BYTE, buf);
529 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
531 /* Try TexSubImage of larger partial block on top edge */
532 glTexSubImage2D(GL_TEXTURE_2D, 0,
533 0, height-2-4, /* position */
534 4, 2+4, /* size */
535 GL_RGBA, GL_UNSIGNED_BYTE, buf);
537 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
539 glDeleteTextures(1, &tex);
543 return pass;
547 static bool
548 test_formats(void)
550 const int num_formats = ARRAY_SIZE(s3tc_formats);
551 const int width = 128, height = 64;
552 GLfloat *image = piglit_rgbw_image(GL_RGBA, width, height,
553 GL_FALSE, /* alpha */
554 GL_UNSIGNED_NORMALIZED);
555 int i;
556 bool pass = true;
558 for (i = 0; i < num_formats; i++) {
559 const GLenum format = s3tc_formats[i];
560 pass = test_format(width, height, image, format) && pass;
563 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
564 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
565 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
567 free(image);
569 return pass;
573 enum piglit_result
574 piglit_display(void)
576 bool pass = test_formats();
577 pass = test_small_mipmap_level() && pass;
578 pass = test_non_power_of_two() && pass;
580 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
584 void
585 piglit_init(int argc, char **argv)
587 piglit_require_extension("GL_EXT_texture_compression_s3tc");
589 #ifdef PIGLIT_USE_OPENGL_ES2
590 tex_program = piglit_build_simple_program(vs_source, fs_source);
591 proj_loc = glGetUniformLocation(tex_program, "proj");
592 #endif