/** is the texture format allowed for the texture target? */ static bool supported_target_format(GLenum target, GLenum format) { /* all the compressed formats we test (so far) are 2D only */ if (is_compressed_format(format) && target == GL_TEXTURE_1D) { return false; } return true; }
/** * Test a specific texture target and format combination. */ static GLboolean test_target_and_format(GLint x, GLint y, GLenum target, GLenum format, const GLfloat *expected) { GLboolean pass = GL_TRUE; GLuint k; GLuint prog = 0; printf("Texture target = %s, Internal format = %s", piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(format)); if (!supported_format(format) || !supported_target_format(target, format)) { printf(" - skipped\n"); return GL_TRUE; /* not a failure */ } else { printf("\n"); } /* To avoid failures not related to this test case, * loosen up the tolerence for compressed texture * formats */ if (is_compressed_format(format)) piglit_set_tolerance_for_bits(5, 5, 5, 5); else piglit_set_tolerance_for_bits(8, 8, 8, 8); switch(target) { case GL_TEXTURE_1D: draw(format, 1.0); glCopyTexImage1D(GL_TEXTURE_1D, 0, format, 0, 0, IMAGE_SIZE, 0); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target); piglit_draw_rect_tex(x, y, IMAGE_SIZE, IMAGE_SIZE, 0, 0, 1, 1); pass = piglit_probe_rect_rgba(x, y, IMAGE_SIZE, IMAGE_SIZE, expected) && pass; break; case GL_TEXTURE_2D: draw(format, 1.0); glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target); piglit_draw_rect_tex(x, y, IMAGE_SIZE, IMAGE_SIZE, 0, 0, 1, 1); pass = piglit_probe_rect_rgba(x, y, IMAGE_SIZE, IMAGE_SIZE, expected) && pass; break; case GL_TEXTURE_3D: glTexImage3D(GL_TEXTURE_3D, 0, format, IMAGE_SIZE, IMAGE_SIZE, 4, 0, GL_RGBA, get_type(format), NULL); for (k = 0; k < 4; k++) { draw(format, 1.0 - k*0.2); glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, k, 0, 0, IMAGE_SIZE, IMAGE_SIZE); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target); for (k = 0; k < 4; k++) { const float tz = k * 0.25; draw_rect_tex_3d(x, y, IMAGE_SIZE, IMAGE_SIZE, 0, 0, tz, 1, 1); pass = probe_rect(x, y, IMAGE_SIZE, IMAGE_SIZE, expected, 1.0 - k*0.2) && pass; } break; case GL_TEXTURE_CUBE_MAP: for (k = 0; k < 6; k++) { draw(format, 1.0 - k*0.15); glCopyTexImage2D(cube_face_targets[k], 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target); for (k = 0; k < 6; k++) { draw_rect_tex_cube_face(x, y, IMAGE_SIZE, IMAGE_SIZE, k); pass = probe_rect(x, y, IMAGE_SIZE, IMAGE_SIZE, expected, 1.0 - k*0.15) && pass; } break; case GL_TEXTURE_1D_ARRAY: glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, format, IMAGE_SIZE, 16, 0, get_format(format), get_type(format), NULL); for (k = 0; k < 4; k++) { draw(format, 1.0 - 0.2*k); glCopyTexSubImage2D(GL_TEXTURE_1D_ARRAY, 0, 0, 4*k, 0, 0, IMAGE_SIZE, 4); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; prog = piglit_build_simple_program(NULL, array1D_shader_text); glUseProgram(prog); glDeleteProgram(prog); for (k = 0; k < 16; k++) { piglit_draw_rect_tex(x, y, IMAGE_SIZE, IMAGE_SIZE, 0, k, 1, 0); pass = probe_rect(x, y, IMAGE_SIZE, IMAGE_SIZE, expected, 1.0 - 0.2*(k/4)) && pass; } break; case GL_TEXTURE_2D_ARRAY: glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format, IMAGE_SIZE, IMAGE_SIZE, 4, 0, get_format(format), get_type(format), NULL); for (k = 0; k < 4; k++) { draw(format, 1.0 - k*0.2); glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, k, 0, 0, IMAGE_SIZE, IMAGE_SIZE); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; prog = piglit_build_simple_program(NULL, array2D_shader_text); glUseProgram(prog); glDeleteProgram(prog); for (k = 0; k < 4; k++) { draw_rect_tex_3d(x, y, IMAGE_SIZE, IMAGE_SIZE, 0, 0, k, 1, 1); pass = probe_rect(x, y, IMAGE_SIZE, IMAGE_SIZE, expected, 1.0 - k*0.2) && pass; } break; case GL_TEXTURE_RECTANGLE: draw(format, 1.0); glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target); piglit_draw_rect_tex(x, y, IMAGE_SIZE, IMAGE_SIZE, 0, 0, IMAGE_SIZE - 1, IMAGE_SIZE - 1); pass = piglit_probe_rect_rgba(x, y, IMAGE_SIZE, IMAGE_SIZE, expected) && pass; break; } /* If a GLSL program is in use, then the preceeding code should not * have called glEnable(target). In that case, this code should not * disable it. For some targets, like GL_TEXTURE_1D_ARRAY, * glDisable(target) will generate an error. */ if (prog == 0) glDisable(target); else glUseProgram(0); return pass; }
enum piglit_result piglit_display(void) { GLfloat buf_fcolor[IMAGE_SIZE][IMAGE_SIZE][4]; GLuint tex; GLboolean pass = GL_TRUE; GLenum format; const GLfloat *expected; int i, j; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Image data setup */ for (i = 0; i < IMAGE_SIZE; i++) { for (j = 0; j < IMAGE_SIZE; j++) { buf_fcolor[i][j][0] = 0.5; buf_fcolor[i][j][1] = 0.2; buf_fcolor[i][j][2] = 0.8; buf_fcolor[i][j][3] = 0.4; } } /* Do glCopyPixels and draw a textured rectangle for each format * and each texture target */ for (j = 0; j < ARRAY_SIZE(target); j++) { /* Draw a pixel rectangle with float color data. As per OpenGL 3.0 * specification integer formats are not allowed in glDrawPixels */ glDrawPixels(IMAGE_SIZE, IMAGE_SIZE, GL_RGBA, GL_FLOAT, buf_fcolor); /* Texture setup */ glGenTextures(1, &tex); glBindTexture(target[j], tex); glTexParameteri(target[j], GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target[j], GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target[j], GL_GENERATE_MIPMAP, GL_FALSE); glEnableClientState(GL_TEXTURE_COORD_ARRAY); for (i = 0; i < ARRAY_SIZE(test_vectors); i++) { GLint x = IMAGE_SIZE * (i + 1); GLint y = 0; GLfloat vertices_1d[2][2] = { {x, y}, {x + IMAGE_SIZE, y} }; format = test_vectors[i].format; expected = (const float*)test_vectors[i].expected; if(!piglit_automatic) printf("Texture target = %s, Internal" " format = %s\n", piglit_get_gl_enum_name(target[j]), piglit_get_gl_enum_name(format)); if (!supported_format(format) || !supported_target_format(target[j], format)) { if (!piglit_automatic) printf("Internal format = %s skipped\n", piglit_get_gl_enum_name(format)); continue; } /* To avoid failures not related to this test case, * loosen up the tolerence for compressed texture * formats */ if (is_compressed_format(format)) piglit_set_tolerance_for_bits(7, 7, 7, 7); else piglit_set_tolerance_for_bits(8, 8, 8, 8); switch(target[j]) { case GL_TEXTURE_1D: glCopyTexImage1D(GL_TEXTURE_1D, 0, format, 0, 0, IMAGE_SIZE, 0); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target[j]); glEnableClientState(GL_VERTEX_ARRAY); glTexCoordPointer(1, GL_FLOAT, 0, texCoords_1d); glVertexPointer(2, GL_FLOAT, 0, vertices_1d); glDrawArrays(GL_LINES, 0, 2); pass = piglit_probe_pixel_rgba(x, 0, expected) && pass; pass = piglit_probe_pixel_rgba(x + IMAGE_SIZE - 1, 0, expected) && pass; break; case GL_TEXTURE_2D: glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target[j]); glTexCoordPointer(2, GL_FLOAT, 0, texCoords_2d); piglit_draw_rect(x, y, IMAGE_SIZE, IMAGE_SIZE); pass = piglit_probe_rect_rgba(x, y, IMAGE_SIZE, IMAGE_SIZE, expected) && pass; break; case GL_TEXTURE_CUBE_MAP: glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glEnable(target[j]); /* Draw a rect with +X cubemap face as texture */ glTexCoordPointer(3, GL_FLOAT, 0, cube_face_texcoords[0]); piglit_draw_rect(x, y, IMAGE_SIZE, IMAGE_SIZE); pass = piglit_probe_rect_rgba(x, y, IMAGE_SIZE, IMAGE_SIZE, expected) && pass; /* Draw a rect with +Z cubemap face as texture */ glTexCoordPointer(3, GL_FLOAT, 0, cube_face_texcoords[2]); piglit_draw_rect(x, y, IMAGE_SIZE, IMAGE_SIZE); pass = piglit_probe_rect_rgba(x, y, IMAGE_SIZE, IMAGE_SIZE, expected) && pass; break; } glDisable(target[j]); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); } if (!piglit_automatic) piglit_present_results(); return (pass ? PIGLIT_PASS : PIGLIT_FAIL); }