diff options
Diffstat (limited to 'tests/texturing/texsubimage.c')
-rw-r--r-- | tests/texturing/texsubimage.c | 197 |
1 files changed, 145 insertions, 52 deletions
diff --git a/tests/texturing/texsubimage.c b/tests/texturing/texsubimage.c index e091fd140..d2aab25a5 100644 --- a/tests/texturing/texsubimage.c +++ b/tests/texturing/texsubimage.c @@ -141,14 +141,51 @@ piglit_draw_rect_tex3d(float x, float y, float w, float h, glDisableClientState(GL_TEXTURE_COORD_ARRAY); } - static GLboolean -equal_images(const GLubyte *img1, const GLubyte *img2, - GLuint w, GLuint h, GLuint d) +equal_images(GLenum target, + const GLubyte *original_ref, + const GLubyte *updated_ref, + const GLubyte *testImg, + GLuint w, GLuint h, GLuint d, + GLuint tx, GLuint ty, GLuint tz, + GLuint tw, GLuint th, GLuint td) { - return memcmp(img1, img2, w*h*d*4) == 0; -} + const GLubyte *ref; + GLuint z, y, x; + + switch (target) { + case GL_TEXTURE_1D: + ty = 0; + th = 1; + /* flow through */ + case GL_TEXTURE_2D: + tz = 0; + td = 1; + break; + } + for (z = 0; z < d; z++) { + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (x >= tx && x < tx + tw && + y >= ty && y < ty + th && + z >= tz && z < tz + td) + ref = updated_ref; + else + ref = original_ref; + + if (memcmp(ref, testImg, 4)) + return GL_FALSE; + + testImg += 4; + original_ref += 4; + updated_ref += 4; + } + } + } + + return GL_TRUE; +} /** * Get block size for compressed format. @@ -214,14 +251,55 @@ draw_and_read_texture(GLuint w, GLuint h, GLuint d, GLubyte *ref) glReadPixels(0, 0, w, h * d, GL_RGBA, GL_UNSIGNED_BYTE, ref); } +static GLuint +create_texture(GLenum target, + GLenum intFormat, + GLsizei w, GLsizei h, GLsizei d, + GLenum srcFormat, + const GLubyte *img) +{ + GLuint tex; + + glPixelStorei(GL_UNPACK_ROW_LENGTH, w); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, h); + + glGenTextures(1, &tex); + glBindTexture(target, tex); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); + if (target == GL_TEXTURE_1D) { + glTexImage1D(target, 0, intFormat, w, 0, + srcFormat, GL_UNSIGNED_BYTE, img); + } + else if (target == GL_TEXTURE_2D) { + glTexImage2D(target, 0, intFormat, w, h, 0, + srcFormat, GL_UNSIGNED_BYTE, img); + } + else if (target == GL_TEXTURE_3D) { + glTexImage3D(target, 0, intFormat, w, h, d, 0, + srcFormat, GL_UNSIGNED_BYTE, img); + } + + return tex; +} + /** - * Create a texture image with reference values. Draw a textured quad. - * Save reference image with glReadPixels(). + * Create two textures with different reference values. Draw both of + * the textures to the framebuffer and save the reference images with + * glReadPixels. + * * Loop: - * replace a sub-region of the texture image with same values - * draw test textured quad - * read test image with glReadPixels - * compare reference image to test image + * - Create another texture with the same initial values as the first + * texture + * - replace a random sub-region of the texture image with values from + * the 2nd texture + * - draw the texture to the framebuffer and read back with glReadPixels + * - compare reference images to test image choosing either the first + * or second reference image for each pixel depending on whether it + * is within the updated region * \param target GL_TEXTURE_1D/2D/3D * \param intFormat the internal texture format */ @@ -231,7 +309,9 @@ test_format(GLenum target, GLenum intFormat) const GLenum srcFormat = GL_RGBA; GLuint w = 128, h = 64, d = 8; GLuint tex, i, j, k, n, t; - GLubyte *img, *ref, *testImg; + GLubyte *original_img, *original_ref; + GLubyte *updated_img, *updated_ref; + GLubyte *testImg; GLboolean pass = GL_TRUE; GLuint bw, bh, wMask, hMask, dMask; get_format_block_size(intFormat, &bw, &bh); @@ -244,53 +324,53 @@ test_format(GLenum target, GLenum intFormat) if (target == GL_TEXTURE_1D) h = 1; - img = (GLubyte *) malloc(w * h * d * 4); - ref = (GLubyte *) malloc(w * h * d * 4); + original_img = (GLubyte *) malloc(w * h * d * 4); + original_ref = (GLubyte *) malloc(w * h * d * 4); + updated_img = (GLubyte *) malloc(w * h * d * 4); + updated_ref = (GLubyte *) malloc(w * h * d * 4); testImg = (GLubyte *) malloc(w * h * d * 4); - /* fill source tex image */ + /* fill source tex images */ n = 0; for (i = 0; i < d; i++) { for (j = 0; j < h; j++) { for (k = 0; k < w; k++) { - img[n++] = j * 4; - img[n++] = k * 2; - img[n++] = i * 16; - img[n++] = 255; + original_img[n + 0] = j * 4; + original_img[n + 1] = k * 2; + original_img[n + 2] = i * 16; + original_img[n + 3] = 255; + + /* Swizzle the components in the + * updated image + */ + updated_img[n + 0] = original_img[n + 1]; + updated_img[n + 1] = original_img[n + 2]; + updated_img[n + 2] = original_img[n + 0]; + updated_img[n + 3] = original_img[n + 3]; + + n += 4; } } } - glPixelStorei(GL_UNPACK_ROW_LENGTH, w); - glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, h); - - glGenTextures(1, &tex); - glBindTexture(target, tex); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); - if (target == GL_TEXTURE_1D) { - glTexImage1D(target, 0, intFormat, w, 0, - srcFormat, GL_UNSIGNED_BYTE, img); - } - else if (target == GL_TEXTURE_2D) { - glTexImage2D(target, 0, intFormat, w, h, 0, - srcFormat, GL_UNSIGNED_BYTE, img); - } - else if (target == GL_TEXTURE_3D) { - glTexImage3D(target, 0, intFormat, w, h, d, 0, - srcFormat, GL_UNSIGNED_BYTE, img); - } - glEnable(target); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - /* draw reference image */ + + /* draw original reference image */ + tex = create_texture(target, intFormat, w, h, d, + srcFormat, original_img); + glClear(GL_COLOR_BUFFER_BIT); + draw_and_read_texture(w, h, d, original_ref); + glDeleteTextures(1, &tex); + + /* draw updated reference image */ + tex = create_texture(target, intFormat, w, h, d, + srcFormat, updated_img); glClear(GL_COLOR_BUFFER_BIT); - draw_and_read_texture(w, h, d, ref); + draw_and_read_texture(w, h, d, updated_ref); + glDeleteTextures(1, &tex); for (t = 0; t < 10; t++) { /* Choose random region of texture to update. @@ -304,34 +384,46 @@ test_format(GLenum target, GLenum intFormat) GLint ty = (rand() % (h - th)) & hMask; GLint tz = (rand() % (d - td)) & dMask; + /* Recreate the original texture */ + tex = create_texture(target, intFormat, w, h, d, + srcFormat, original_img); + assert(tx + tw <= w); assert(ty + th <= h); assert(tz + td <= d); - /* replace texture region (with same data) */ + /* replace texture region with data from updated image */ glPixelStorei(GL_UNPACK_SKIP_PIXELS, tx); glPixelStorei(GL_UNPACK_SKIP_ROWS, ty); glPixelStorei(GL_UNPACK_SKIP_IMAGES, tz); if (target == GL_TEXTURE_1D) { glTexSubImage1D(target, 0, tx, tw, - srcFormat, GL_UNSIGNED_BYTE, img); + srcFormat, GL_UNSIGNED_BYTE, + updated_img); } else if (target == GL_TEXTURE_2D) { glTexSubImage2D(target, 0, tx, ty, tw, th, - srcFormat, GL_UNSIGNED_BYTE, img); + srcFormat, GL_UNSIGNED_BYTE, + updated_img); } else if (target == GL_TEXTURE_3D) { glTexSubImage3D(target, 0, tx, ty, tz, tw, th, td, - srcFormat, GL_UNSIGNED_BYTE, img); + srcFormat, GL_UNSIGNED_BYTE, + updated_img); } /* draw test image */ glClear(GL_COLOR_BUFFER_BIT); draw_and_read_texture(w, h, d, testImg); + glDeleteTextures(1, &tex); + piglit_present_results(); - if (!equal_images(ref, testImg, w, h, d)) { + if (!equal_images(target, + original_ref, updated_ref, testImg, + w, h, d, + tx, ty, tz, tw, th, td)) { printf("texsubimage failed\n"); printf(" target: %s\n", piglit_get_gl_enum_name(target)); printf(" internal format: %s\n", piglit_get_gl_enum_name(intFormat)); @@ -343,11 +435,12 @@ test_format(GLenum target, GLenum intFormat) glDisable(target); - free(img); - free(ref); + free(original_img); + free(original_ref); + free(updated_img); + free(updated_ref); free(testImg); - glDeleteTextures(1, &tex); return pass; } |