ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_direct_state_access / gettextureimage-formats.c
blobccf28ba134889da3586a3895fba73a4406618923
1 /*
2 * Copyright (c) 2011 VMware, Inc.
3 * Copyright (c) 2014 Intel Corporation.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NON-INFRINGEMENT. IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
27 /**
28 * @file gettextureimage-formats.c
32 #include "piglit-util-gl.h"
33 #include "../fbo/fbo-formats.h"
34 #include "dsa-utils.h"
36 PIGLIT_GL_TEST_CONFIG_BEGIN
38 config.supports_gl_compat_version = 20;
39 config.supports_gl_core_version = 31;
41 config.window_width = 600;
42 config.window_height = 200;
43 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
44 config.khr_no_error_support = PIGLIT_NO_ERRORS;
46 PIGLIT_GL_TEST_CONFIG_END
48 static const char *TestName = "gettextureimage-formats";
50 static const GLfloat clearColor[4] = { 0.4, 0.4, 0.4, 0.0 };
51 static GLuint texture_id;
52 static GLuint prog;
53 static bool init_by_rendering;
55 #define TEX_SIZE 128
57 #define DO_BLEND 1
60 /**
61 * Make a simple texture image where red increases from left to right,
62 * green increases from bottom to top, blue stays constant (50%) and
63 * the alpha channel is a checkerboard pattern.
64 * \return true for success, false if unsupported format
66 static bool
67 make_texture_image(GLenum intFormat, GLubyte upperRightTexel[4])
69 GLubyte tex[TEX_SIZE][TEX_SIZE][4];
70 int i, j;
71 GLuint fb, status;
73 for (i = 0; i < TEX_SIZE; i++) {
74 for (j = 0; j < TEX_SIZE; j++) {
75 tex[i][j][0] = j * 255 / TEX_SIZE;
76 tex[i][j][1] = i * 255 / TEX_SIZE;
77 tex[i][j][2] = 128;
78 if (((i >> 4) ^ (j >> 4)) & 1)
79 tex[i][j][3] = 255; /* opaque */
80 else
81 tex[i][j][3] = 125; /* transparent */
85 memcpy(upperRightTexel, tex[TEX_SIZE-1][TEX_SIZE-1], 4);
87 if (init_by_rendering) {
88 /* Initialize the mipmap levels. */
89 for (i = TEX_SIZE, j = 0; i; i >>= 1, j++) {
90 glTexImage2D(GL_TEXTURE_2D, j, intFormat, i, i, 0,
91 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
94 /* Initialize the texture with glDrawPixels. */
95 glGenFramebuffers(1, &fb);
96 glBindFramebuffer(GL_FRAMEBUFFER, fb);
97 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
98 GL_TEXTURE_2D, texture_id, 0);
99 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
100 if (status != GL_FRAMEBUFFER_COMPLETE) {
101 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
102 glDeleteFramebuffers(1, &fb);
103 return false;
106 glViewport(0, 0, TEX_SIZE, TEX_SIZE);
108 glWindowPos2iARB(0, 0);
109 glDrawPixels(TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, tex);
110 glGenerateTextureMipmap(texture_id);
112 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
113 glDeleteFramebuffers(1, &fb);
114 glViewport(0, 0, piglit_width, piglit_height);
115 } else {
116 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
117 glTexImage2D(GL_TEXTURE_2D, 0, intFormat, TEX_SIZE, TEX_SIZE, 0,
118 GL_RGBA, GL_UNSIGNED_BYTE, tex);
121 return glGetError() == GL_NO_ERROR;
124 static GLfloat
125 ubyte_to_float(GLubyte b, GLint bits)
127 if (bits <= 8) {
128 GLint b2 = b >> (8 - bits);
129 GLint max = 255 >> (8 - bits);
130 return b2 / (float) max;
131 } else {
132 return b / 255.0;
137 static GLfloat
138 bits_to_tolerance(GLint bits, bool compressed)
140 GLfloat t;
142 if (bits == 0) {
143 return 0.25;
144 } else if (bits == 1) {
145 return 0.5;
146 } else if (bits > 8) {
147 /* The original texture was specified as GLubyte and we
148 * assume that the window/surface is 8-bits/channel.
150 t = 4.0 / 255;
151 } else {
152 t = 4.0 / (1 << (bits - 1));
155 if (compressed) {
156 /* Use a fudge factor. The queries for GL_TEXTURE_RED/
157 * GREEN/BLUE/ALPHA_SIZE don't return well-defined values for
158 * compressed formats so using them is unreliable. This is
159 * pretty loose, but good enough to catch some Mesa bugs during
160 * development.
162 t = 0.3;
164 return t;
168 static void
169 compute_expected_color(const struct format_desc *fmt,
170 const GLubyte upperRightTexel[4],
171 GLfloat expected[4], GLfloat tolerance[4])
173 GLfloat texel[4];
174 GLint compressed;
175 int bits[4];
177 bits[0] = bits[1] = bits[2] = bits[3] = 0;
179 /* Handle special cases first */
180 if (fmt->internalformat == GL_R11F_G11F_B10F_EXT) {
181 bits[0] = bits[1] = bits[2] = 8;
182 bits[3] = 0;
183 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
184 texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
185 texel[2] = ubyte_to_float(upperRightTexel[2], bits[2]);
186 texel[3] = 1.0;
187 compressed = GL_FALSE;
188 } else {
189 GLint r, g, b, a, l, i;
190 GLenum baseFormat = 0;
192 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
193 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
194 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
195 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
196 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
197 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
198 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &compressed);
200 if (0)
201 printf("r=%d g=%d b=%d a=%d l=%d i=%d\n", r, g, b, a, l, i);
203 if (i > 0) {
204 baseFormat = GL_INTENSITY;
205 bits[0] = i;
206 bits[1] = 0;
207 bits[2] = 0;
208 bits[3] = i;
209 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
210 texel[1] = 0.0;
211 texel[2] = 0.0;
212 texel[3] = ubyte_to_float(upperRightTexel[0], bits[3]);
213 } else if (a > 0) {
214 if (l > 0) {
215 baseFormat = GL_LUMINANCE_ALPHA;
216 bits[0] = l;
217 bits[1] = 0;
218 bits[2] = 0;
219 bits[3] = a;
220 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
221 texel[1] = 0.0;
222 texel[2] = 0.0;
223 texel[3] = ubyte_to_float(upperRightTexel[3], bits[3]);
224 } else if (r > 0 && g > 0 && b > 0) {
225 baseFormat = GL_RGBA;
226 bits[0] = r;
227 bits[1] = g;
228 bits[2] = b;
229 bits[3] = a;
230 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
231 texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
232 texel[2] = ubyte_to_float(upperRightTexel[2], bits[2]);
233 texel[3] = ubyte_to_float(upperRightTexel[3], bits[3]);
234 } else if (r == 0 && g == 0 && b == 0) {
235 baseFormat = GL_ALPHA;
236 bits[0] = 0;
237 bits[1] = 0;
238 bits[2] = 0;
239 bits[3] = a;
240 texel[0] = 0.0;
241 texel[1] = 0.0;
242 texel[2] = 0.0;
243 texel[3] = ubyte_to_float(upperRightTexel[3], bits[3]);
244 } else {
245 baseFormat = 0; /* ??? */
246 texel[0] = 0.0;
247 texel[1] = 0.0;
248 texel[2] = 0.0;
249 texel[3] = 0.0;
251 } else if (l > 0) {
252 baseFormat = GL_LUMINANCE;
253 bits[0] = l;
254 bits[1] = 0;
255 bits[2] = 0;
256 bits[3] = 0;
257 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
258 texel[1] = 0.0;
259 texel[2] = 0.0;
260 texel[3] = 1.0;
261 } else if (r > 0) {
262 if (g > 0) {
263 if (b > 0) {
264 baseFormat = GL_RGB;
265 bits[0] = r;
266 bits[1] = g;
267 bits[2] = b;
268 bits[3] = 0;
269 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
270 texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
271 texel[2] = ubyte_to_float(upperRightTexel[2], bits[2]);
272 texel[3] = 1.0;
273 } else {
274 baseFormat = GL_RG;
275 bits[0] = r;
276 bits[1] = g;
277 bits[2] = 0;
278 bits[3] = 0;
279 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
280 texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
281 texel[2] = 0.0;
282 texel[3] = 1.0;
284 } else {
285 baseFormat = GL_RED;
286 bits[0] = r;
287 bits[1] = 0;
288 bits[2] = 0;
289 bits[3] = 0;
290 texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
291 texel[1] = 0.0;
292 texel[2] = 0.0;
293 texel[3] = 1.0;
295 } else {
296 assert(!"Unexpected texture component sizes");
297 texel[0] = 0.0;
298 texel[1] = 0.0;
299 texel[2] = 0.0;
300 texel[3] = 0.0;
303 (void) baseFormat; /* not used, at this time */
306 /* compute texel color blended with background color */
307 #if DO_BLEND
308 expected[0] = texel[0] * texel[3] + clearColor[0] * (1.0 - texel[3]);
309 expected[1] = texel[1] * texel[3] + clearColor[1] * (1.0 - texel[3]);
310 expected[2] = texel[2] * texel[3] + clearColor[2] * (1.0 - texel[3]);
311 expected[3] = texel[3] * texel[3] + clearColor[3] * (1.0 - texel[3]);
312 #else
313 expected[0] = texel[0];
314 expected[1] = texel[1];
315 expected[2] = texel[2];
316 expected[3] = texel[3];
317 #endif
319 assert(expected[0] == expected[0]);
321 tolerance[0] = bits_to_tolerance(bits[0], compressed);
322 tolerance[1] = bits_to_tolerance(bits[1], compressed);
323 tolerance[2] = bits_to_tolerance(bits[2], compressed);
324 tolerance[3] = bits_to_tolerance(bits[3], compressed);
328 static bool
329 colors_equal(const GLfloat expected[4], const GLfloat pix[4],
330 GLfloat tolerance[4])
332 if (fabsf(expected[0] - pix[0]) > tolerance[0] ||
333 fabsf(expected[1] - pix[1]) > tolerance[1] ||
334 fabsf(expected[2] - pix[2]) > tolerance[2] ||
335 fabsf(expected[3] - pix[3]) > tolerance[3]) {
336 return false;
338 return true;
342 static bool
343 test_format(const struct test_desc *test,
344 const struct format_desc *fmt)
346 int x, y;
347 int w = TEX_SIZE, h = TEX_SIZE;
348 GLfloat readback[TEX_SIZE][TEX_SIZE][4];
349 GLubyte upperRightTexel[4];
350 int level;
351 GLfloat expected[4], pix[4], tolerance[4];
352 bool pass = true;
354 glClear(GL_COLOR_BUFFER_BIT);
356 /* The RGBA_DXT1 formats seem to expose a Mesa/libtxc_dxtn bug.
357 * Just skip them for now. Testing the other compressed formats
358 * is good enough.
360 if (fmt->internalformat != GL_COMPRESSED_RGBA_S3TC_DXT1_EXT &&
361 fmt->internalformat != GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) {
362 /* init texture image */
363 if (!make_texture_image(fmt->internalformat, upperRightTexel))
364 return true; /* unsupported = OK */
366 x = 10;
367 y = 40;
369 compute_expected_color(fmt, upperRightTexel, expected, tolerance);
371 /* Draw with the texture */
372 glUseProgram(prog);
373 dsa_set_xform(prog, piglit_width, piglit_height);
374 #if DO_BLEND
375 glEnable(GL_BLEND);
376 #endif
377 piglit_draw_rect_tex(x, y, w, h, 0.0, 0.0, 1.0, 1.0);
378 glUseProgram(0);
379 glDisable(GL_BLEND);
381 x += TEX_SIZE + 20;
383 level = 0;
384 while (w > 0) {
385 /* Get the texture image */
386 glGetTextureImage(texture_id, level, GL_RGBA,
387 GL_FLOAT, sizeof(readback),
388 readback);
390 /* Draw the texture image */
391 glWindowPos2iARB(x, y);
392 #if DO_BLEND
393 glEnable(GL_BLEND);
394 #endif
395 glDrawPixels(w, h, GL_RGBA, GL_FLOAT, readback);
396 glDisable(GL_BLEND);
398 if (level <= 2) {
399 GLint rx = x + w-1;
400 GLint ry = y + h-1;
401 glReadPixels(rx, ry, 1, 1, GL_RGBA, GL_FLOAT, pix);
402 if (!colors_equal(expected, pix, tolerance)) {
403 printf("%s failure: format: %s, level %d at pixel(%d, %d)\n",
404 TestName,
405 get_format_name(
406 fmt->internalformat),
407 level, rx, ry);
408 printf(" Expected (%f, %f, %f, %f)\n",
409 expected[0], expected[1], expected[2], expected[3]);
410 printf(" Found (%f, %f, %f, %f)\n",
411 pix[0], pix[1], pix[2], pix[3]);
412 printf("Tolerance (%f, %f, %f, %f)\n",
413 tolerance[0], tolerance[1], tolerance[2], tolerance[3]);
414 pass = false;
418 x += w + 20;
419 w /= 2;
420 h /= 2;
421 level++;
426 piglit_present_results();
428 return pass;
433 * Is the given set of formats supported?
434 * This checks if required extensions are present and if this piglit test
435 * can actually grok the formats.
437 static bool
438 supported_format_set(const struct test_desc *set)
440 if (!supported(set))
441 return false;
443 if (set->format == ext_texture_integer ||
444 set->format == ext_packed_depth_stencil ||
445 set->format == arb_texture_rg_int ||
446 set->format == arb_depth_texture ||
447 set->format == arb_depth_buffer_float) {
448 /* texture_integer requires a fragment shader, different
449 * glTexImage calls. Depth/stencil formats not implemented.
451 return false;
454 return true;
458 static bool
459 test_all_formats(void)
461 bool pass = true;
462 int i, j;
464 for (i = 0; i < ARRAY_SIZE(test_sets); i++) {
465 const struct test_desc *set = &test_sets[i];
466 if (supported_format_set(set)) {
467 for (j = 0; j < set->num_formats; j++) {
468 if (!test_format(set, &set->format[j])) {
469 pass = false;
475 return pass;
479 enum piglit_result
480 piglit_display(void)
482 bool pass;
484 piglit_ortho_projection(piglit_width, piglit_height, false);
486 if (piglit_automatic) {
487 pass = test_all_formats();
488 } else {
489 const struct test_desc *set = &test_sets[test_index];
490 if (supported_format_set(set)) {
491 pass = test_format(set, &set->format[format_index]);
492 } else {
493 /* unsupported format - not a failure */
494 pass = true;
495 glClear(GL_COLOR_BUFFER_BIT);
496 piglit_present_results();
500 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
503 void
504 piglit_init(int argc, char **argv)
506 int i;
508 piglit_require_extension("GL_ARB_direct_state_access");
510 fbo_formats_init(1, argv, !piglit_automatic);
511 (void) fbo_formats_display;
513 for (i = 1; i < argc; i++) {
514 if (strcmp(argv[i], "init-by-rendering") == 0) {
515 init_by_rendering = true;
516 puts("The textures will be initialized by rendering "
517 "to them using glDrawPixels.");
518 break;
522 glGenTextures(1, &texture_id);
523 glBindTexture(GL_TEXTURE_2D, texture_id);
524 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
525 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
527 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
529 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
531 prog = dsa_create_program(GL_TEXTURE_2D);