[Piglit] [PATCH piglit 3/3] texsubimage: Update the textures with different values

Neil Roberts neil at linux.intel.com
Wed Dec 17 09:45:14 PST 2014


Previously the test was updating sub regions of the test texture with
the same values that were already in the texture. Therefore an
implementation that does nothing on glTexSubImage2D would pass which
doesn't seem very useful. This patch makes it create two reference
images with different values. At each update the entire texture is
recreated with the values from the first image and then a sub region
is updated with the values from the second image. The values are then
compared as before via glReadPixels but at each texel it decides
whether to compare with the first or second image depending on whether
the texel is in the updated region.
---
 tests/texturing/texsubimage.c | 197 +++++++++++++++++++++++++++++++-----------
 1 file changed, 145 insertions(+), 52 deletions(-)

diff --git a/tests/texturing/texsubimage.c b/tests/texturing/texsubimage.c
index e091fd1..d2aab25 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;
 }
 
-- 
1.9.3



More information about the Piglit mailing list