/* * Copyright © 2011 Intel Corporation * Copyright (c) 2010 VMware, Inc. * Copyright (c) 2011 Dave Airlie * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /** * @file getteximage-clamping.c * * From the GL_EXT_texture_integer spec: * * * "(modify the section labeled "Final Conversion", p. 222) * * For a floating-point RGBA color, each component is first * clamped to [0, 1]. Then the appropriate conversion formula * from table 4.7 is applied to the component. For an integer * RGBA color, each component is clamped to the representable * range of ." * * This test checks the conversion and clamping by making a texture of * every sized internal format it can, and reads it to every * format/type combo it can. */ #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 10; config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE; config.khr_no_error_support = PIGLIT_NO_ERRORS; PIGLIT_GL_TEST_CONFIG_END struct format_info { const char *name; GLenum internal_format, base_format; int size; bool sign; }; /* FINISHME: I'd like this set of texture formats to be sanitized a * bit, and it should probably be shared with the other testcases in * this directory. */ static const struct format_info formats[] = { { "GL_RGBA8I", GL_RGBA8I, GL_RGBA_INTEGER, 8, true }, { "GL_RGBA8UI", GL_RGBA8UI , GL_RGBA_INTEGER, 8, false }, { "GL_RGBA16I", GL_RGBA16I, GL_RGBA_INTEGER, 16, true }, { "GL_RGBA16UI", GL_RGBA16UI, GL_RGBA_INTEGER, 16, false }, { "GL_RGBA32I", GL_RGBA32I, GL_RGBA_INTEGER, 32, true }, { "GL_RGBA32UI", GL_RGBA32UI, GL_RGBA_INTEGER, 32, false }, { "GL_RGBA8I (bgra)", GL_RGBA8I, GL_BGRA_INTEGER, 8, true }, { "GL_RGBA8UI (bgra)", GL_RGBA8UI , GL_BGRA_INTEGER, 8, false }, { "GL_RGBA16I (bgra)", GL_RGBA16I, GL_BGRA_INTEGER, 16, true }, { "GL_RGBA16UI (bgra)", GL_RGBA16UI, GL_BGRA_INTEGER, 16, false }, { "GL_RGBA32I (bgra)", GL_RGBA32I, GL_BGRA_INTEGER, 32, true }, { "GL_RGBA32UI (bgra)", GL_RGBA32UI, GL_BGRA_INTEGER, 32, false }, { "GL_RGB8I", GL_RGB8I, GL_RGB_INTEGER, 8, true }, { "GL_RGB8UI", GL_RGB8UI , GL_RGB_INTEGER, 8, false }, { "GL_RGB16I", GL_RGB16I, GL_RGB_INTEGER, 16, true }, { "GL_RGB16UI", GL_RGB16UI, GL_RGB_INTEGER, 16, false }, { "GL_RGB32I", GL_RGB32I, GL_RGB_INTEGER, 32, true }, { "GL_RGB32UI", GL_RGB32UI, GL_RGB_INTEGER, 32, false }, { "GL_ALPHA8I_EXT", GL_ALPHA8I_EXT, GL_ALPHA_INTEGER_EXT, 8, true }, { "GL_ALPHA8UI_EXT", GL_ALPHA8UI_EXT , GL_ALPHA_INTEGER_EXT, 8, false }, { "GL_ALPHA16I_EXT", GL_ALPHA16I_EXT, GL_ALPHA_INTEGER_EXT, 16, true }, { "GL_ALPHA16UI_EXT", GL_ALPHA16UI_EXT, GL_ALPHA_INTEGER_EXT, 16, false }, { "GL_ALPHA32I_EXT", GL_ALPHA32I_EXT, GL_ALPHA_INTEGER_EXT, 32, true }, { "GL_ALPHA32UI_EXT", GL_ALPHA32UI_EXT, GL_ALPHA_INTEGER_EXT, 32, false }, { "GL_LUMINANCE8I_EXT", GL_LUMINANCE8I_EXT, GL_LUMINANCE_INTEGER_EXT, 8, true }, { "GL_LUMINANCE8UI_EXT", GL_LUMINANCE8UI_EXT , GL_LUMINANCE_INTEGER_EXT, 8, false }, { "GL_LUMINANCE16I_EXT", GL_LUMINANCE16I_EXT, GL_LUMINANCE_INTEGER_EXT, 16, true }, { "GL_LUMINANCE16UI_EXT", GL_LUMINANCE16UI_EXT, GL_LUMINANCE_INTEGER_EXT, 16, false }, { "GL_LUMINANCE32I_EXT", GL_LUMINANCE32I_EXT, GL_LUMINANCE_INTEGER_EXT, 32, true }, { "GL_LUMINANCE32UI_EXT", GL_LUMINANCE32UI_EXT, GL_LUMINANCE_INTEGER_EXT, 32, false }, { "GL_LUMINANCE_ALPHA8I_EXT", GL_LUMINANCE_ALPHA8I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 8, true }, { "GL_LUMINANCE_ALPHA8UI_EXT", GL_LUMINANCE_ALPHA8UI_EXT , GL_LUMINANCE_ALPHA_INTEGER_EXT, 8, false }, { "GL_LUMINANCE_ALPHA16I_EXT", GL_LUMINANCE_ALPHA16I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 16, true }, { "GL_LUMINANCE_ALPHA16UI_EXT", GL_LUMINANCE_ALPHA16UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 16, false }, { "GL_LUMINANCE_ALPHA32I_EXT", GL_LUMINANCE_ALPHA32I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 32, true }, { "GL_LUMINANCE_ALPHA32UI_EXT", GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 32, false }, { "GL_INTENSITY8I_EXT", GL_INTENSITY8I_EXT, GL_RED_INTEGER_EXT, 8, true }, { "GL_INTENSITY8UI_EXT", GL_INTENSITY8UI_EXT , GL_RED_INTEGER_EXT, 8, false }, { "GL_INTENSITY16I_EXT", GL_INTENSITY16I_EXT, GL_RED_INTEGER_EXT, 16, true }, { "GL_INTENSITY16UI_EXT", GL_INTENSITY16UI_EXT, GL_RED_INTEGER_EXT, 16, false }, { "GL_INTENSITY32I_EXT", GL_INTENSITY32I_EXT, GL_RED_INTEGER_EXT, 32, true }, { "GL_INTENSITY32UI_EXT", GL_INTENSITY32UI_EXT, GL_RED_INTEGER_EXT, 32, false }, { "GL_RG8I", GL_RG8I, GL_RG_INTEGER, 8, true }, { "GL_RG8UI", GL_RG8UI , GL_RG_INTEGER, 8, false }, { "GL_RG16I", GL_RG16I, GL_RG_INTEGER, 16, true }, { "GL_RG16UI", GL_RG16UI, GL_RG_INTEGER, 16, false }, { "GL_RG32I", GL_RG32I, GL_RG_INTEGER, 32, true }, { "GL_RG32UI", GL_RG32UI, GL_RG_INTEGER, 32, false }, { "GL_R8I", GL_R8I, GL_RED_INTEGER, 8, true }, { "GL_R8UI", GL_R8UI , GL_RED_INTEGER, 8, false }, { "GL_R16I", GL_R16I, GL_RED_INTEGER, 16, true }, { "GL_R16UI", GL_R16UI, GL_RED_INTEGER, 16, false }, { "GL_R32I", GL_R32I, GL_RED_INTEGER, 32, true }, { "GL_R32UI", GL_R32UI, GL_RED_INTEGER, 32, false }, { "GL_RGB10_A2UI", GL_RGB10_A2UI, GL_RGBA_INTEGER, 10, false }, { "GL_RGB10_A2UI (bgra)", GL_RGB10_A2UI, GL_BGRA_INTEGER, 10, false }, { "GL_RGB10_A2UI (rev)", GL_RGB10_A2UI, GL_RGBA_INTEGER, 10, true }, { "GL_RGB10_A2UI (rev bgra)", GL_RGB10_A2UI, GL_BGRA_INTEGER, 10, true }, }; struct read_format_info { GLenum format, type; int size; bool sign; }; /* Integer formats from table 3.5 and 3.6 of the GL 3.0 specification */ static const struct read_format_info read_formats[] = { { GL_RGBA_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_RGBA_INTEGER, GL_INT, 32, true }, { GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_RGBA_INTEGER, GL_SHORT, 16, true }, { GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_RGBA_INTEGER, GL_BYTE, 8, true }, { GL_RED_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_RED_INTEGER, GL_INT, 32, true }, { GL_RED_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_RED_INTEGER, GL_SHORT, 16, true }, { GL_RED_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_RED_INTEGER, GL_BYTE, 8, true }, { GL_GREEN_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_GREEN_INTEGER, GL_INT, 32, true }, { GL_GREEN_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_GREEN_INTEGER, GL_SHORT, 16, true }, { GL_GREEN_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_GREEN_INTEGER, GL_BYTE, 8, true }, { GL_BLUE_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_BLUE_INTEGER, GL_INT, 32, true }, { GL_BLUE_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_BLUE_INTEGER, GL_SHORT, 16, true }, { GL_BLUE_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_BLUE_INTEGER, GL_BYTE, 8, true }, { GL_ALPHA_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_ALPHA_INTEGER, GL_INT, 32, true }, { GL_ALPHA_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_ALPHA_INTEGER, GL_SHORT, 16, true }, { GL_ALPHA_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_ALPHA_INTEGER, GL_BYTE, 8, true }, { GL_RG_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_RG_INTEGER, GL_INT, 32, true }, { GL_RG_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_RG_INTEGER, GL_SHORT, 16, true }, { GL_RG_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_RG_INTEGER, GL_BYTE, 8, true }, { GL_RGB_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_RGB_INTEGER, GL_INT, 32, true }, { GL_RGB_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_RGB_INTEGER, GL_SHORT, 16, true }, { GL_RGB_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_RGB_INTEGER, GL_BYTE, 8, true }, /* RGBA was put at the top so that the more obvious failures come first. */ { GL_BGR_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_BGR_INTEGER, GL_INT, 32, true }, { GL_BGR_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_BGR_INTEGER, GL_SHORT, 16, true }, { GL_BGR_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_BGR_INTEGER, GL_BYTE, 8, true }, { GL_BGRA_INTEGER, GL_UNSIGNED_INT, 32, false }, { GL_BGRA_INTEGER, GL_INT, 32, true }, { GL_BGRA_INTEGER, GL_UNSIGNED_SHORT, 16, false }, { GL_BGRA_INTEGER, GL_SHORT, 16, true }, { GL_BGRA_INTEGER, GL_UNSIGNED_BYTE, 8, false }, { GL_BGRA_INTEGER, GL_BYTE, 8, true }, /* FINISHME: Add more RGB10_A2UI. Note the other packed formats * besides 10/10/10/2 included in the spec! */ { GL_RGBA_INTEGER, GL_UNSIGNED_INT_10_10_10_2, 32, false }, { GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, 32, false }, }; static bool test_rg = false; static bool test_rgb10_a2ui = false; static void usage(void) { fprintf(stderr, "usage:\n"); fprintf(stderr, "ext_texture_integer-teximage-clamping " "[GL_ARB_texture_rg | GL_ARB_texture_rgb10_a2ui]\n"); exit(1); } static const uint32_t texels_u[][4] = { { 0xfffffff0, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0xfffffff0, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0xfffffff0, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0xfffffff0 }, { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, }; static const uint32_t texels_s[][4] = { { 0x7fffffff, 0x80000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x7fffffff, 0x80000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x7fffffff, 0x80000000 }, { 0x80000000, 0x00000000, 0x00000000, 0x7fffffff }, { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, }; static void print_packed(const struct read_format_info *read_info, char *read, int pixel, int chans) { int i; char *read_pixel = read + pixel * chans * read_info->size / 8; switch (read_info->type) { case GL_UNSIGNED_INT: case GL_INT: for (i = 0; i < chans; i++) fprintf(stderr, " 0x%08x", ((uint32_t *)read_pixel)[i]); for (; i < 4; i++) fprintf(stderr, " "); break; case GL_UNSIGNED_SHORT: case GL_SHORT: for (i = 0; i < chans; i++) fprintf(stderr, " 0x%04x", ((uint16_t *)read)[i]); for (; i < 4; i++) fprintf(stderr, " "); break; case GL_UNSIGNED_BYTE: case GL_BYTE: for (i = 0; i < chans; i++) fprintf(stderr, " 0x%02x", ((uint8_t *)read)[i]); for (; i < 4; i++) fprintf(stderr, " "); break; default: /* FINISHME: GL_texture_rgb10_a2ui */ abort(); } } static void report_fail(const struct format_info *tex_info, const char *format_name, const struct read_format_info *read_info, uint32_t texels[][4], void *read, void *expected, int pixels, int chans) { int i; fprintf(stderr, "Failure reading from %s to %s/%s\n", format_name, piglit_get_gl_enum_name(read_info->format), piglit_get_gl_enum_name(read_info->type)); /* 10/channel + 3 spaces. */ fprintf(stderr, " %43s", "expected RGBA in texels"); if (read_info->size == 32) fprintf(stderr, " %43s", "expected packed"); else if (read_info->size == 16) fprintf(stderr, " %31s", "expected packed"); else if (read_info->size == 8) fprintf(stderr, " %19s", "expected packed"); else abort(); /* FINISHME: GL_ARB_texture_rgb10_a2ui */ fprintf(stderr, " read values"); fprintf(stderr, "\n"); for (i = 0; i < pixels; i++) { fprintf(stderr, " 0x%08x 0x%08x 0x%08x 0x%08x", texels[i][0], texels[i][1], texels[i][2], texels[i][3]); fprintf(stderr, " "); print_packed(read_info, expected, i, chans); fprintf(stderr, " "); print_packed(read_info, read, i, chans); fprintf(stderr, "\n"); } } static void pack(const struct read_format_info *read_info, void *packed, int pixel, int chan, int values_per_pixel, uint32_t value) { int32_t ivalue = value; void *pack_dst = ((char *)packed) + ((pixel * values_per_pixel + chan) * read_info->size / 8); switch (read_info->type) { case GL_UNSIGNED_INT: case GL_INT: *(uint32_t *)pack_dst = value; break; case GL_UNSIGNED_SHORT: if (value > 0xffff) value = 0xffff; *(uint16_t *)pack_dst = value; break; case GL_SHORT: if (ivalue > 32767) ivalue = 32767; else if (ivalue < -32768) ivalue = -32768; *(int16_t *)pack_dst = ivalue; break; case GL_UNSIGNED_BYTE: if (value > 0xff) value = 0xff; *(uint8_t *)pack_dst = value; break; case GL_BYTE: if (ivalue > 127) ivalue = 127; else if (ivalue < -128) ivalue = -128; *(int8_t *)pack_dst = ivalue; break; default: /* FINISHME: GL_texture_rgb10_a2ui */ abort(); } } static enum piglit_result read_format(const struct format_info *tex_info, const struct read_format_info *read_info, uint32_t texels[][4], int num_texels) { size_t texels_size = num_texels * 4 * sizeof(uint32_t); char *expected; char *read; int i; int chans = 0; enum piglit_result result; const char *suffix; char *name; if (tex_info->internal_format == GL_RGB10_A2UI) { if (tex_info->base_format == GL_BGRA_INTEGER) { if (tex_info->sign) suffix = " (rev bgra)"; else suffix = " (bgra)"; } else { if (tex_info->sign) suffix = " (rev)"; else suffix = ""; } } else if (tex_info->base_format == GL_BGRA_INTEGER) suffix = " (bgra)"; else suffix = ""; asprintf(&name, "%s%s:\n", piglit_get_gl_enum_name(tex_info->internal_format), suffix); if (!test_rg && (read_info->format == GL_RED_INTEGER || read_info->format == GL_RG_INTEGER)) { return PIGLIT_SKIP; } if (!test_rgb10_a2ui) { /* Packed integer pixel formats were introduced with * GL_texture_rgb10_a2ui. */ switch (read_info->type) { case GL_INT: case GL_UNSIGNED_INT: case GL_SHORT: case GL_UNSIGNED_SHORT: case GL_BYTE: case GL_UNSIGNED_BYTE: break; default: return PIGLIT_SKIP; } } /* FINISHME: Again, not really sure how to handle sign conversion. */ if (tex_info->sign != read_info->sign) return PIGLIT_SKIP; printf("Reading from %s to %s/%s\n", name, piglit_get_gl_enum_name(read_info->format), piglit_get_gl_enum_name(read_info->type)); expected = (char *)malloc(texels_size); read = (char *)malloc(texels_size); memset(expected, 0xd0, texels_size); memset(read, 0xd0, texels_size); glGetTexImage(GL_TEXTURE_2D, 0, read_info->format, read_info->type, read); switch (read_info->format) { case GL_RGBA_INTEGER: chans = 4; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][0]); pack(read_info, expected, i, 1, chans, texels[i][1]); pack(read_info, expected, i, 2, chans, texels[i][2]); pack(read_info, expected, i, 3, chans, texels[i][3]); } break; case GL_BGRA_INTEGER: chans = 4; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][2]); pack(read_info, expected, i, 1, chans, texels[i][1]); pack(read_info, expected, i, 2, chans, texels[i][0]); pack(read_info, expected, i, 3, chans, texels[i][3]); } break; case GL_RGB_INTEGER: chans = 3; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][0]); pack(read_info, expected, i, 1, chans, texels[i][1]); pack(read_info, expected, i, 2, chans, texels[i][2]); } break; case GL_BGR_INTEGER: chans = 3; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][2]); pack(read_info, expected, i, 1, chans, texels[i][1]); pack(read_info, expected, i, 2, chans, texels[i][0]); } break; case GL_RED_INTEGER: chans = 1; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][0]); } break; case GL_GREEN_INTEGER: chans = 1; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][1]); } break; case GL_BLUE_INTEGER: chans = 1; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][2]); } break; case GL_ALPHA_INTEGER: chans = 1; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][3]); } break; case GL_RG_INTEGER: chans = 2; for (i = 0; i < num_texels; i++) { pack(read_info, expected, i, 0, chans, texels[i][0]); pack(read_info, expected, i, 1, chans, texels[i][1]); } break; default: assert(0); return PIGLIT_SKIP; } if (memcmp(expected, read, num_texels * chans * read_info->size / 8)) { report_fail(tex_info, name, read_info, texels, read, expected, num_texels, chans); result = PIGLIT_FAIL; } else { result = PIGLIT_PASS; } free(read); free(expected); free(name); return result; } static enum piglit_result test_format(const struct format_info *info) { int num_texels = ARRAY_SIZE(texels_s); uint32_t texels[ARRAY_SIZE(texels_s)][4]; GLenum type; int lbits, abits, ibits, rbits, gbits, bbits; int i, readf; enum piglit_result result = PIGLIT_SKIP; const char *name = piglit_get_gl_enum_name(info->internal_format); if (!test_rg && ((info->base_format == GL_RED_INTEGER && !strstr(name, "GL_INTENSITY")) || info->base_format == GL_RG_INTEGER)) { return PIGLIT_SKIP; } if (!test_rgb10_a2ui && info->internal_format == GL_RGB10_A2UI) return PIGLIT_SKIP; /* FINISHME: We only test conversion from large signed to * small signed or large unsigned to small unsigned. The * rules just say that when reading pixels, the value is * clamped to the representable range, not how/when sign * extension occurs, and whether the clamping applies before * or after */ if (info->size != 32) return PIGLIT_SKIP; if (info->sign) { memcpy(texels, texels_s, sizeof(texels_s)); type = GL_INT; } else { memcpy(texels, texels_u, sizeof(texels_u)); type = GL_UNSIGNED_INT; } glTexImage2D(GL_TEXTURE_2D, 0, info->internal_format, num_texels, 1, 0, GL_RGBA_INTEGER_EXT, type, texels); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &lbits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &abits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &ibits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &rbits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &gbits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &bbits); /* Compute the RGBA channels that should be read from the * texture given the input RGBA texels we gave. See Table 6.1 * ("Texture, table, and filter return values") of the GL 3.0 * specification. Note that input R is always mapped to L or * I, and comes back out in R (except for ALPHA). */ if (ibits || lbits) { for (i = 0; i < num_texels; i++) { texels[i][1] = 0; texels[i][2] = 0; } } else { if (!rbits) { for (i = 0; i < num_texels; i++) texels[i][0] = 0; } if (!gbits) { for (i = 0; i < num_texels; i++) texels[i][1] = 0; } if (!bbits) { for (i = 0; i < num_texels; i++) texels[i][2] = 0; } } /* Everybody's consistent on A bits in table 6.1. */ if (!abits) { for (i = 0; i < num_texels; i++) texels[i][3] = 1; } for (readf = 0; readf < ARRAY_SIZE(read_formats); readf++) { piglit_merge_result(&result, read_format(info, &read_formats[readf], texels, num_texels)); if (result == PIGLIT_FAIL) return result; } return result; } enum piglit_result piglit_display(void) { /* unreached */ return PIGLIT_FAIL; } void piglit_init(int argc, char **argv) { GLuint tex; int i, texf; enum piglit_result result = PIGLIT_SKIP; /* Note: We test later extensions by testing them against all * combinations of (storage format, read format) including the * formats from previous extensions. */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "GL_ARB_texture_rg") == 0) { piglit_require_extension(argv[i]); test_rg = true; } else if (strcmp(argv[i], "GL_ARB_texture_rgb10_a2ui") == 0) { piglit_require_extension(argv[i]); test_rg = true; test_rgb10_a2ui = true; } else { usage(); exit(1); } } piglit_require_extension("GL_EXT_texture_integer"); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); for (texf = 0; texf < ARRAY_SIZE(formats); texf++) piglit_merge_result(&result, test_format(&formats[texf])); piglit_report_result(result); }