Beispiel #1
0
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;
}
enum piglit_result
piglit_display(void)
{
	GLuint tex, tex_src;
	bool pass;
	int level;
	unsigned bw, bh, bs;

	piglit_get_compressed_block_size(format->token, &bw, &bh, &bs);
	glClearColor(0.5, 0.5, 0.5, 0.5);
	glClear(GL_COLOR_BUFFER_BIT);

	tex_src = piglit_rgbw_texture(format->token, SIZE, SIZE,
				      true, false,
				      GL_UNSIGNED_NORMALIZED);
	glCreateTextures(GL_TEXTURE_2D, 1, &tex);

	for (level = 0; (SIZE >> level) > 0; level++) {
		int w, h;
		int expected_size, size;
		void *compressed;

		w = SIZE >> level;
		h = SIZE >> level;
		expected_size = piglit_compressed_image_size(format->token, w, h);

		glBindTexture(GL_TEXTURE_2D, tex_src);
		glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
					 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
					 &size);

		if (size != expected_size) {
			fprintf(stderr, "Format %s level %d (%dx%d) size %d "
				"doesn't match expected size %d\n",
				piglit_get_gl_enum_name(format->token),
				level, w, h, size, expected_size);
			piglit_report_result(PIGLIT_FAIL);
		}

		compressed = malloc(size);

		glGetCompressedTextureImage(tex_src, level, size, compressed);

		glBindTexture(GL_TEXTURE_2D, tex);
		glCompressedTexImage2D(GL_TEXTURE_2D, level, format->token,
				       w, h, 0, size, compressed);
		if (!piglit_check_gl_error(GL_NO_ERROR))
			piglit_report_result(PIGLIT_FAIL);

		free(compressed);
	}

	glDeleteTextures(1, &tex_src);
	glBindTextureUnit(tex, 0);

	display_mipmaps(10, 10);
	pass = check_resulting_mipmaps(10, 10);

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}