static bool try_TexImage(GLenum internalFormat) { bool pass = true; GLuint tex[4]; GLenum expected_error = has_depth_texture ? GL_NO_ERROR : GL_INVALID_VALUE; GLenum alt_error = GL_NO_ERROR; GLenum expected_3D_error = has_depth_texture ? GL_INVALID_OPERATION : GL_INVALID_VALUE; GLenum alt_3D_error = GL_NO_ERROR; GLenum expected_cube_error = has_depth_texture_cube_map ? GL_NO_ERROR : expected_3D_error; GLenum alt_cube_error = GL_NO_ERROR; #if !defined PIGLIT_USE_OPENGL /* The OpenGL ES rules are non-obvious. * * In OpenGL ES 1.x and 2.x, the internal format and the format must * be the same. This even applies in OpenGL ES 2.0 when * GL_OES_depth_texture is available. * * Section 3.7.1 (Texture Image Specification) of the OpenGL ES 1.1.12 * spec says: * * "If internalformat does not match format, the error * INVALID_OPERATION is generated." * * Section 3.7.1 (Texture Image Specification) of the OpenGL ES 2.0.25 * spec says the same thing. * * As a result, in OpenGL ES 1.x or OpenGL ES 2.0 without * GL_OES_depth_texture, glTexImage2D(..., GL_DEPTH24_STENCIL8, ..., * GL_DEPTH_STENCIL, FLOAT_32_UNSIGNED_INT_24_8) may generate *either* * GL_INVALID_VALUE or GL_INVALID_OPERATION depending on the order the * implementation checks the errors. * * In OpenGL ES 3.0, the internal format must not be GL_DEPTH_STENCIL. * Section 3.8.3 (Texture Image Specification) of the OpenGL ES 3.0.3 * spec says: * * "Specifying a combination of values for format, type, and * internalformat that is not listed as a valid combination in * tables 3.2 or 3.3 generates the error INVALID_OPERATION." * * Table 3.2 contains the lines: * * Format Type External Internal * Bytes Format * Per Pixel * DEPTH_STENCIL UNSIGNED_INT_24_8 4 DEPTH24_STENCIL8 * DEPTH_STENCIL FLOAT_32_UNSIGNED_INT_24_8 8 DEPTH32F_STENCIL8 * * The GL_OES_packed_depth_stencil spec still says: * * "Accepted by the <format> parameter of TexImage2D and * TexSubImage2D and by the <internalformat> parameter of * TexImage2D: * * DEPTH_STENCIL_OES 0x84F9" * * An OpenGL ES 3.0 implementation that advertises * GL_OES_packed_depth_stencil should accepth both GL_DEPTH_STENCIL * and GL_DEPTH24_STENCIL8 for internalformat. */ if (has_depth_texture) { if ((piglit_get_gl_version() < 30 && internalFormat != GL_DEPTH_STENCIL) || (piglit_get_gl_version() >= 30 && internalFormat == GL_DEPTH_STENCIL && !piglit_is_extension_supported("GL_OES_packed_depth_stencil"))) { expected_error = GL_INVALID_OPERATION; alt_error = GL_NO_ERROR; /* 3D depth textures are never supported. * GL_INVALID_OPERATION is expected. That * error is already expected due to the * mismatch of internalformat and format. */ expected_3D_error = GL_INVALID_OPERATION; alt_3D_error = GL_NO_ERROR; /* Cube map depth textures are only supported * with GL_OES_depth_texture_cube_map. * Without that extension, * GL_INVALID_OPERATION is expected. That * error is already expected due to the * mismatch of internalformat and format. */ expected_cube_error = GL_INVALID_OPERATION; alt_cube_error = GL_NO_ERROR; } else { expected_error = GL_NO_ERROR; alt_error = GL_NO_ERROR; /* 3D depth textures are never supported. * GL_INVALID_OPERATION is expected. */ expected_3D_error = GL_INVALID_OPERATION; alt_3D_error = GL_NO_ERROR; /* Cube map depth textures are only supported * with GL_OES_depth_texture_cube_map. * Without that extension, * GL_INVALID_OPERATION is expected. */ expected_cube_error = has_depth_texture_cube_map ? GL_NO_ERROR : GL_INVALID_OPERATION; alt_cube_error = GL_NO_ERROR; } } else { assert(piglit_get_gl_version() < 30); if (internalFormat != GL_DEPTH_STENCIL) { /* For all of the cases either GL_INVALID_VALUE could * be generated due to format being GL_DEPTH_STENCIL * or GL_INVALID_OPERATION could be generated due to * format not being the same as internalformat. */ expected_error = GL_INVALID_OPERATION; alt_error = GL_INVALID_VALUE; expected_3D_error = GL_INVALID_OPERATION; alt_3D_error = GL_INVALID_VALUE; expected_cube_error = GL_INVALID_OPERATION; alt_cube_error = GL_INVALID_VALUE; } else { /* For all of these cases, GL_INVALID_VALUE is the * only acceptable error. The OpenGL ES 1.x and 2.0 * specs make no mention of generating * GL_INVALID_OPERATION for the 3D or cube map cases. */ expected_error = GL_INVALID_VALUE; alt_error = GL_NO_ERROR; expected_3D_error = GL_INVALID_VALUE; alt_3D_error = GL_NO_ERROR; expected_cube_error = GL_INVALID_VALUE; alt_cube_error = GL_NO_ERROR; } } #endif /* !defined PIGLIT_USE_OPENGL */ printf("Testing glTexImage with %s...\n", piglit_get_gl_enum_name(internalFormat)); glGenTextures(ARRAY_SIZE(tex), tex); #if defined PIGLIT_USE_OPENGL glBindTexture(GL_TEXTURE_1D, tex[0]); glTexImage1D(GL_TEXTURE_1D, 0, internalFormat, 16, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); pass = check_gl_error2(expected_error, alt_error) && pass; #endif glBindTexture(GL_TEXTURE_2D, tex[1]); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 16, 16, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); pass = check_gl_error2(expected_error, alt_error) && pass; /* Section 3.8.1 (Texture Image Specification) of the OpenGL 2.1 spec * says: * * "Textures with a base internal format of DEPTH_COMPONENT are * supported by texture image specification commands only if * target is TEXTURE_1D, TEXTURE_2D, PROXY_TEXTURE_1D or * PROXY_TEXTURE_2D. Using this format in conjunction with any * other target will result in an INVALID_OPERATION error." * * The OpenGL 4.4 spec lists the same error, but it greatly expands * the list of valid texture targets. */ #if !defined PIGLIT_USE_OPENGL_ES1 if (has_texture_3d) { glBindTexture(GL_TEXTURE_3D, tex[2]); glTexImage3D(GL_TEXTURE_3D, 0, internalFormat, 8, 8, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); pass = check_gl_error2(expected_3D_error, alt_3D_error) && pass; } #else /* Silence "variable ‘expected_3D_error’ set but not used" warnings. */ (void) expected_3D_error; (void) alt_3D_error; #endif if (has_texture_cube_map) { unsigned i; glBindTexture(GL_TEXTURE_CUBE_MAP, tex[3]); for (i = 0; i < 6; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormat, 16, 16, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); pass = check_gl_error2(expected_cube_error, alt_cube_error) && pass; } } #if defined PIGLIT_USE_OPENGL glBindTexture(GL_TEXTURE_1D, 0); #endif glBindTexture(GL_TEXTURE_2D, 0); if (has_texture_3d) glBindTexture(GL_TEXTURE_3D, 0); if (has_texture_cube_map) glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glDeleteTextures(ARRAY_SIZE(tex), tex); printf("Done.\n\n"); return pass; }
static bool test_format(int width, int height, GLfloat *image, GLenum requested_format) { GLubyte *compressed_image; GLenum format2; int x, y, w, h; GLuint tex; bool pass = true; GLuint expected_size; GLint is_compressed; GLint compressed_size; GLint format; glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, width); /* Setup initial texture */ glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, requested_format, width, height, 0, GL_RGBA, GL_FLOAT, image); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; pass = check_rendering(width, height) && pass; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_size); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; if (!is_compressed) { printf("Image was not compressed\n"); pass = false; } if (format != requested_format) { printf("Internal Format mismatch. Found: 0x%04x Expected: 0x%04x\n", format, requested_format); pass = false; } expected_size = piglit_compressed_image_size(requested_format, width, height); if (compressed_size != expected_size) { printf("Compressed image size mismatch. Found: %u Expected: %u\n", compressed_size, expected_size); pass = false; } /* Use GL_TEXTURE_COMPRESSED_IMAGE_SIZE even if it wasn't what we * expected to avoid corruption due to under-allocated buffer. */ compressed_image = malloc(compressed_size); /* Read back the compressed image data */ glGetCompressedTexImage(GL_TEXTURE_2D, 0, compressed_image); /* Try texsubimage on 4-texel boundary - should work */ x = 20; y = 12; w = 16; h = 8; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, image); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; pass = check_rendering(width, height) && pass; /* Try texsubimage on non 4-texel boundary - should not work */ x = 10; y = 11; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, image); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; /* Try compressed subimage on 4-texel boundary - should work */ x = 12; y = 8; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, piglit_compressed_image_size(format, w, h), compressed_image + piglit_compressed_pixel_offset(format, width, x, y)); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; pass = check_rendering(width, height) && pass; /* Try compressed subimage on non 4-texel boundary - should not work */ x = 14; y = 9; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, piglit_compressed_image_size(format, w, h), compressed_image + piglit_compressed_pixel_offset(format, width, 0, 0)); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; /* Try compressed subimage with size not a multiple of 4 - * should not work */ x = 8; y = 8; w = 14; h = 10; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, piglit_compressed_image_size(format, 4, 4), compressed_image + piglit_compressed_pixel_offset(format, width, x, y)); /* Note, we can get either of these errors depending on the order * in which glCompressedTexSubImage parameters are checked. * INVALID_OPERATION for the bad size or INVALID_VALUE for the * wrong compressed image size. */ pass = check_gl_error2(GL_INVALID_OPERATION, GL_INVALID_VALUE) && pass; /* Try compressed subimage with invalid offset - should not work */ x = -3; y = 8; w = 4; h = 4; glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, piglit_compressed_image_size(format, w, h), compressed_image + piglit_compressed_pixel_offset(format, width, 0, 0)); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; /* Try compressed subimage with too large of image - should not work */ x = 16; y = 8; w = width * 2; h = height * 2; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, piglit_compressed_image_size(format, w, h), compressed_image + piglit_compressed_pixel_offset(format, width, x, y)); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; /* Try compressed subimage with different format - should not work */ if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) format2 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; else format2 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; x = 4; y = 4; w = 4; h = 4; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format2, piglit_compressed_image_size(format2, w, h), compressed_image + piglit_compressed_pixel_offset(format2, width, x, y)); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; /* Try zero-sized subimage - should not be an error */ x = 4; y = 4; w = 0; h = 0; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, piglit_compressed_image_size(format, w, h), compressed_image + piglit_compressed_pixel_offset(format, width, x, y)); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; /* Try CompressedTexSubImage into level 1 (which is missing) */ x = 0; y = 0; w = 4; h = 4; glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, x, y, w, h, format, piglit_compressed_image_size(format, w, h), compressed_image + piglit_compressed_pixel_offset(format, width, x, y)); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; /* Try CompressedTexImage of size zero - should not be an erorr */ w = 0; h = 0; glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, piglit_compressed_image_size(format, w, h), compressed_image); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; /* Try CompressedTexImage with size which is a not a multiple of the * block size - should not be an erorr */ w = width - 1; h = height - 1; glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, piglit_compressed_image_size(format, w, h), compressed_image); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; pass = check_rendering(width, height) && pass; glDeleteTextures(1, &tex); free(compressed_image); return pass; }