Exemplo n.º 1
0
/**
 * Create a texture image with reference values.  Draw a textured quad.
 * Save reference image 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
 * \param target  GL_TEXTURE_1D/2D/3D
 * \param intFormat  the internal texture format
 */
static GLboolean
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;
	GLboolean pass = GL_TRUE;
	GLuint bw, bh, wMask, hMask, dMask;
	get_format_block_size(intFormat, &bw, &bh);
	wMask = ~(bw-1);
	hMask = ~(bh-1);
	dMask = ~0;

	if (target != GL_TEXTURE_3D)
		d = 1;
	if (target == GL_TEXTURE_1D)
		h = 1;

	img = (GLubyte *) malloc(w * h * d * 4);
	ref = (GLubyte *) malloc(w * h * d * 4);
	testImg = (GLubyte *) malloc(w * h * d * 4);

	/* fill source tex image */
	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;
			}
		}
	}

	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 */
	glClear(GL_COLOR_BUFFER_BIT);
	piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0);
	glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ref);

	for (t = 0; t < 10; t++) {
		/* Choose random region of texture to update.
		 * Use sizes and positions that are multiples of
		 * the compressed block size.
		 */
		GLint tw = (rand() % w) & wMask;
		GLint th = (rand() % h) & hMask;
		GLint td = (rand() % d) & dMask;
		GLint tx = (rand() % (w - tw)) & wMask;
		GLint ty = (rand() % (h - th)) & hMask;
		GLint tz = (rand() % (d - td)) & dMask;

		assert(tx + tw <= w);
		assert(ty + th <= h);
		assert(tz + td <= d);

		/* replace texture region (with same data) */
		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);
		}
		else if (target == GL_TEXTURE_2D) {
			glTexSubImage2D(target, 0, tx, ty, tw, th,
					srcFormat, GL_UNSIGNED_BYTE, img);
		}
		else if (target == GL_TEXTURE_2D) {
			glTexSubImage3D(target, 0, tx, ty, tz, tw, th, td,
					srcFormat, GL_UNSIGNED_BYTE, img);
		}

		/* draw test image */
		glClear(GL_COLOR_BUFFER_BIT);
		piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0);
		glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, testImg);

		glutSwapBuffers();

		if (!equal_images(ref, testImg, w, h)) {
			printf("texsubimage failed\n");
			printf("  target: 0x%x\n", target);
			printf("  internal format: 0x%x\n", intFormat);
			printf("  region: %d, %d  %d x %d\n", tx, ty, tw, th);
			pass = GL_FALSE;
			break;
		}
	}

	glDisable(target);

	free(img);
	free(ref);
	free(testImg);

	glDeleteTextures(1, &tex);
	return pass;
}
Exemplo n.º 2
0
/**
 * Create two textures with different reference values. Draw both of
 * the textures to the framebuffer and save the reference images with
 * glReadPixels.
 *
 * Loop:
 *  - 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
 */
static GLboolean
test_format(GLenum target, GLenum intFormat)
{
	const GLenum srcFormat = GL_RGBA;
	GLuint w = DEFAULT_TEX_WIDTH;
	GLuint h = DEFAULT_TEX_HEIGHT;
	GLuint d = DEFAULT_TEX_DEPTH;
	GLuint tex, i, j, k, n, t;
	GLubyte *original_img, *original_ref;
	GLubyte *updated_img, *updated_ref;
	GLubyte *testImg;
	GLboolean pass = GL_TRUE;
	GLuint bw, bh, bb, wMask, hMask, dMask;
	GLuint pbo = 0;
	piglit_get_compressed_block_size(intFormat, &bw, &bh, &bb);
	wMask = ~(bw-1);
	hMask = ~(bh-1);
	dMask = ~0;

	if (target == GL_TEXTURE_CUBE_MAP_ARRAY_ARB) {
		w = h;
		d *= 6;
	} else if (target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY) {
		d = 1;
	}

	if (target == GL_TEXTURE_1D)
		h = 1;

	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 images */
	n = 0;
	for (i = 0; i < d; i++) {
		for (j = 0; j < h; j++) {
			for (k = 0; k < w; k++) {
				original_img[n + 0] = j * 4;
				original_img[n + 1] = k * 2;
				original_img[n + 2] = i * 128 / d;
				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;
			}
		}
	}

	if (use_pbo) {
		glGenBuffers(1, &pbo);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
		glBufferData(GL_PIXEL_UNPACK_BUFFER,
			     w * h * d * 4,
			     updated_img,
			     GL_STATIC_DRAW);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
	}

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);


	/* 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, updated_ref);
	glDeleteTextures(1, &tex);

	for (t = 0; t < 10; t++) {
		/* Choose random region of texture to update.
		 * Use sizes and positions that are multiples of
		 * the compressed block size.
		 */
		GLint tw = (rand() % w) & wMask;
		GLint th = (rand() % h) & hMask;
		GLint td = (rand() % d) & dMask;
		GLint tx = (rand() % (w - tw)) & wMask;
		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);

		if (use_pbo)
			glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);

		/* 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 (d > 1) {
			glTexSubImage3D(target, 0, tx, ty, tz, tw, th, td,
					srcFormat, GL_UNSIGNED_BYTE,
					use_pbo ? NULL : updated_img);
		} else if (h > 1) {
			glTexSubImage2D(target, 0, tx, ty, tw, th,
					srcFormat, GL_UNSIGNED_BYTE,
					use_pbo ? NULL : updated_img);
		} else if (w > 1) {
			glTexSubImage1D(target, 0, tx, tw,
					srcFormat, GL_UNSIGNED_BYTE,
					use_pbo ? NULL : updated_img);
		} else {
			assert(!"Unknown image dimensions");
		}

		if (use_pbo)
			glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

		/* 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(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));
			printf("  region: %d, %d  %d x %d\n", tx, ty, tw, th);
			pass = GL_FALSE;
			break;
		}
	}

	free(original_img);
	free(original_ref);
	free(updated_img);
	free(updated_ref);
	free(testImg);
	if (use_pbo)
		glDeleteBuffers(1, &pbo);

	return pass;
}