/** * Test glBegin(GL_TRIANGLE/LINE_STRIP), glPrimitiveRestartNV(), glEnd(). */ static bool test_begin_end(GLenum primMode) { const GLfloat x0 = 0.0, x1 = piglit_width - 10.0, dx = 20.0; const GLfloat y0 = 0.5 * piglit_height - 10.0, y1 = y0 + 20.0, dy = 20.0; GLfloat x, y; GLint vert; bool pass; piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glClear(GL_COLOR_BUFFER_BIT); glColor4fv(green); if (primMode == GL_TRIANGLE_STRIP) { /* Draw a tri-strip across the window, using restart to actually render * a series of quads/boxes. */ glBegin(GL_TRIANGLE_STRIP); vert = 0; for (x = x0; x <= x1; x += dx) { for (y = y0; y <= y1; y += dy) { glVertex2f(x, y); } vert++; if (vert % 2 == 0) glPrimitiveRestartNV(); } glEnd(); } else { /* Draw a line strip across the window, using restart to actually render * a series of disconnected lines. */ glLineWidth(5.0); glBegin(GL_LINE_STRIP); vert = 0; for (x = x0; x <= x1; x += dx) { y = 0.5 * piglit_height; glVertex2f(x, y); vert++; if (vert % 2 == 0) glPrimitiveRestartNV(); } glEnd(); } glFinish(); pass = check_rendering(); if (!pass) { fprintf(stderr, "%s: failure drawing with glBegin(%s) / glEnd()\n", TestName, (primMode == GL_TRIANGLE_STRIP ? "GL_TRIANGLE_STRIP" : "GL_LINE_STRIP")); } piglit_present_results(); return pass; }
/** * Test glDrawElements() with glPrimitiveRestartIndexNV(). */ static bool test_draw_by_index(VBO_CFG vbo_cfg, bool one_by_one, GLenum primMode, GLenum indexType) { #define NUM_VERTS 48 #define NUM_ELEMS (NUM_VERTS * 5 / 4) GLfloat verts[NUM_VERTS+2][2]; GLubyte indices[sizeof(GLuint) * NUM_ELEMS]; GLfloat x, dx; GLuint restart_index; GLuint num_elems; bool pass = true; const char *typeStr = NULL, *primStr = NULL; GLuint vbo1, vbo2; bool create_vbo1 = false; bool create_vbo2 = false; uintptr_t index_offset = 0; uintptr_t vbo_data_size = sizeof(verts) + sizeof(indices); GLuint i, j; if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_INDEX_ONLY)) { create_vbo1 = true; } if ((vbo_cfg == VBO_INDEX_ONLY) || (vbo_cfg == VBO_SEPARATE_VERTEX_AND_INDEX)) { create_vbo2 = true; } if ((vbo_cfg == DISABLE_VBO) || (vbo_cfg == VBO_VERTEX_ONLY)) { index_offset = (uintptr_t) indices; } else if (vbo_cfg == VBO_COMBINED_VERTEX_AND_INDEX) { index_offset = sizeof(verts); } else { index_offset = 0; } switch (indexType) { case GL_UNSIGNED_BYTE: restart_index = 255; typeStr = "GL_UNSIGNED_BYTE"; break; case GL_UNSIGNED_SHORT: restart_index = 1000; typeStr = "GL_UNSIGNED_SHORT"; break; case GL_UNSIGNED_INT: restart_index = 1000 * 1000; typeStr = "GL_UNSIGNED_INT"; break; default: assert(0); restart_index = 0; } x = 0.0; dx = 20.0; if (primMode == GL_TRIANGLE_STRIP) { const GLfloat y = 0.5 * piglit_height - 10.0, dy = 20.0; for (i = 0; i < NUM_VERTS / 2; i++) { verts[i*2+0][0] = x; verts[i*2+0][1] = y; verts[i*2+1][0] = x; verts[i*2+1][1] = y + dy; x += dx; } /* setup elements to draw series of squares w/ tri strip */ for (i = j = 0; i < NUM_VERTS; i++) { write_index_value(indices, indexType, j, i); j++; if (i > 0 && i % 4 == 3) { write_index_value(indices, indexType, j, restart_index); j++; } } num_elems = j; primStr = "GL_TRIANGLE_STRIP"; } else { const GLfloat y = 0.5 * piglit_height; assert(primMode == GL_LINE_STRIP); glLineWidth(5.0); for (i = 0; i < NUM_VERTS; i++) { verts[i][0] = x; verts[i][1] = y; x += dx; } /* setup elements to draw series of disjoint lines w/ line strip */ for (i = j = 0; i < NUM_VERTS / 2; i++) { write_index_value(indices, indexType, j, i); j++; if (i > 0 && i % 2 == 1) { write_index_value(indices, indexType, j, restart_index); j++; } } num_elems = j; primStr = "GL_LINE_STRIP"; } assert(num_elems <= NUM_ELEMS); /* debug */ if (0) { for (i = 0; i < num_elems; i++) printf("%2d: %d\n", i, read_index_value(indices, indexType, i)); } piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glClear(GL_COLOR_BUFFER_BIT); glColor4fv(green); if (create_vbo1) { glGenBuffers(1, &vbo1); glBindBuffer(GL_ARRAY_BUFFER, vbo1); glBufferData(GL_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW); } if (create_vbo2) { glGenBuffers(1, &vbo2); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2); glBufferData(GL_ELEMENT_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW); } else { vbo2 = vbo1; } if (create_vbo1) { /* Load vertex data into VBO */ glBindBuffer(GL_ARRAY_BUFFER, vbo1); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts); glVertexPointer(2, GL_FLOAT, 0, (void *)0); } else { glVertexPointer(2, GL_FLOAT, 0, (void *)verts); } if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_VERTEX_ONLY)) { /* Load index data into VBO */ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index_offset, type_array_size(indexType, num_elems), indices); } glEnableClientState(GL_VERTEX_ARRAY); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; enable_restart(restart_index); /* Draw */ if (one_by_one) { do_ArrayElement(primMode, num_elems, indexType, indices); } else { glDrawElements(primMode, num_elems, indexType, (void*) index_offset); } disable_restart(); glDisableClientState(GL_VERTEX_ARRAY); if (vbo_cfg != DISABLE_VBO) { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } if (create_vbo1) { glDeleteBuffers(1, &vbo1); } if (create_vbo2) { glDeleteBuffers(1, &vbo2); } if (!check_rendering()) { fprintf(stderr, "%s: failure drawing with %s(%s, %s), %s\n", TestName, one_by_one ? "glArrayElement" : "glDrawElements", primStr, typeStr, vbo_cfg_names[vbo_cfg]); pass = false; } piglit_present_results(); return pass; #undef NUM_VERTS }
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; }