[Piglit] [PATCH 02/24] arb_direct_state_access: glTextureSubImage*D test.

Neil Roberts neil at linux.intel.com
Thu Dec 18 13:29:06 PST 2014


Today I pushed some patches to the original version of this test which
change it quite a lot. Previously it updated a sub-region of the texture
with the exact same contents as were already in the texture so an
implementation that did nothing on glTexSubImage[123]D would actually
pass the test. It might be worth updating this test to the new version
otherwise it's really not testing very much and it doesn't test
glTextureSubImage3D at all.

On the other hand I think testing textures with all possible formats
might be a bit overkill just for testing DSA and it's a shame to have so
much duplicated code. I wonder if it would be better to make a simpler
test that only tests one format and one target per function?

http://cgit.freedesktop.org/piglit/commit/?id=5cfdc9d1d46fce911284576
http://cgit.freedesktop.org/piglit/commit/?id=8433c118dfa6f03f615724d
http://cgit.freedesktop.org/piglit/commit/?id=e4e88dfdb22be7b75150eae

I've also just posted some patches today to test it with array textures
but I don't think it would make sense to apply those for DSA.

Regards,
- Neil

Laura Ekstrand <laura at jlekstrand.net> writes:

> ---
>  tests/all.py                                       |   1 +
>  .../spec/arb_direct_state_access/CMakeLists.gl.txt |   1 +
>  .../spec/arb_direct_state_access/texturesubimage.c | 415 +++++++++++++++++++++
>  3 files changed, 417 insertions(+)
>  create mode 100644 tests/spec/arb_direct_state_access/texturesubimage.c
>
> diff --git a/tests/all.py b/tests/all.py
> index 84639c2..5ed0444 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -4308,6 +4308,7 @@ import_glsl_parser_tests(arb_derivative_control,
>  
>  spec['ARB_direct_state_access'] = {}
>  spec['ARB_direct_state_access']['dsa-textures'] = PiglitGLTest('arb_direct_state_access-dsa-textures', run_concurrent=True)
> +spec['ARB_direct_state_access']['texturesubimage'] = PiglitGLTest('arb_direct_state_access-texturesubimage', run_concurrent=True)
>  
>  profile.tests['hiz'] = hiz
>  profile.tests['fast_color_clear'] = fast_color_clear
> diff --git a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
> index cb0f7da..102579c 100644
> --- a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
> +++ b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
> @@ -10,4 +10,5 @@ link_libraries (
>  )
>  
>  piglit_add_executable (arb_direct_state_access-dsa-textures dsa-textures.c dsa-utils.c)
> +piglit_add_executable (arb_direct_state_access-dsa-texturesubimage texturesubimage.c)
>  # vim: ft=cmake:
> diff --git a/tests/spec/arb_direct_state_access/texturesubimage.c b/tests/spec/arb_direct_state_access/texturesubimage.c
> new file mode 100644
> index 0000000..b3a09e6
> --- /dev/null
> +++ b/tests/spec/arb_direct_state_access/texturesubimage.c
> @@ -0,0 +1,415 @@
> +/*
> + * Copyright © 2011 VMware, Inc.
> + * Copyright © 2014 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + */
> +
> +
> +/**
> + * This should expose any errors in texel addressing within a texture image
> + * when calling glTextureSubImage1D/2D/3D().
> + *
> + * Brian Paul
> + * October 2011
> + *
> + * Adapted for testing ARB_direct_state_access by
> + * Laura Ekstrand
> + * October 2014
> + */
> +
> +
> +#include "piglit-util-gl.h"
> +#include "../fbo/fbo-formats.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +
> +	config.supports_gl_compat_version = 10;
> +
> +	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +/**
> + * This is a subset of the formats in fbo-formats.h
> + * We don't test non-color, float, or int/uint textures at this time.
> + */
> +static const struct test_desc texsubimage_test_sets[] = {
> +	{
> +		core,
> +		ARRAY_SIZE(core),
> +		"Core formats",
> +		GL_UNSIGNED_NORMALIZED,
> +	},
> +	{
> +		tdfx_texture_compression_fxt1,
> +		ARRAY_SIZE(tdfx_texture_compression_fxt1),
> +		"GL_3DFX_texture_compression_FXT1",
> +		GL_UNSIGNED_NORMALIZED,
> +		{"GL_ARB_texture_compression",
> +		 "GL_3DFX_texture_compression_FXT1"},
> +	},
> +	{
> +		ext_texture_compression_s3tc,
> +		ARRAY_SIZE(ext_texture_compression_s3tc),
> +		"GL_EXT_texture_compression_s3tc",
> +		GL_UNSIGNED_NORMALIZED,
> +		{"GL_ARB_texture_compression",
> +		 "GL_EXT_texture_compression_s3tc"},
> +	},
> +	{
> +		ext_texture_compression_rgtc,
> +		ARRAY_SIZE(ext_texture_compression_rgtc),
> +		"GL_EXT_texture_compression_rgtc",
> +		GL_UNSIGNED_NORMALIZED,
> +		{"GL_EXT_texture_compression_rgtc"}
> +	},
> +	{
> +		ext_texture_compression_latc,
> +		ARRAY_SIZE(ext_texture_compression_latc),
> +		"GL_EXT_texture_compression_latc",
> +		GL_UNSIGNED_NORMALIZED,
> +		{"GL_EXT_texture_compression_latc"}
> +	}
> +};
> +
> +
> +/**
> + * XXX add this to piglit-util if useful elsewhere.
> + */
> +static GLvoid
> +piglit_draw_rect_tex3d(float x, float y, float w, float h,
> +		       float tx, float ty, float tw, float th,
> +		       float tz0, float tz1)
> +{
> +	float verts[4][4];
> +	float tex[4][3];
> +
> +	verts[0][0] = x;
> +	verts[0][1] = y;
> +	verts[0][2] = 0.0;
> +	verts[0][3] = 1.0;
> +	tex[0][0] = tx;
> +	tex[0][1] = ty;
> +	tex[0][2] = tz0;
> +	verts[1][0] = x + w;
> +	verts[1][1] = y;
> +	verts[1][2] = 0.0;
> +	verts[1][3] = 1.0;
> +	tex[1][0] = tx + tw;
> +	tex[1][1] = ty;
> +	tex[1][2] = tz1;
> +	verts[2][0] = x + w;
> +	verts[2][1] = y + h;
> +	verts[2][2] = 0.0;
> +	verts[2][3] = 1.0;
> +	tex[2][0] = tx + tw;
> +	tex[2][1] = ty + th;
> +	tex[2][2] = tz1;
> +	verts[3][0] = x;
> +	verts[3][1] = y + h;
> +	verts[3][2] = 0.0;
> +	verts[3][3] = 1.0;
> +	tex[3][0] = tx;
> +	tex[3][1] = ty + th;
> +	tex[3][2] = tz0;
> +
> +	glVertexPointer(4, GL_FLOAT, 0, verts);
> +	glTexCoordPointer(3, GL_FLOAT, 0, tex);
> +	glEnableClientState(GL_VERTEX_ARRAY);
> +	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
> +
> +	glDrawArrays(GL_QUADS, 0, 4);
> +
> +	glDisableClientState(GL_VERTEX_ARRAY);
> +	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
> +}
> +
> +
> +static GLboolean
> +equal_images(const GLubyte *img1, const GLubyte *img2,
> +             GLuint w, GLuint h)
> +{
> +	return memcmp(img1, img2, w*h*4) == 0;
> +}
> +
> +
> +/**
> + * Get block size for compressed format.
> + * \return GL_TRUE if format is compressed, GL_FALSE otherwise
> + * XXX this could be a piglit util function if useful elsewhere.
> + */
> +static GLboolean
> +get_format_block_size(GLenum format, GLuint *bw, GLuint *bh)
> +{
> +	switch (format) {
> +	case GL_COMPRESSED_RGB_FXT1_3DFX:
> +	case GL_COMPRESSED_RGBA_FXT1_3DFX:
> +		*bw = 8;
> +		*bh = 4;
> +		return GL_TRUE;
> +	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
> +	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
> +	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
> +	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
> +	case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
> +	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
> +	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
> +	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
> +		*bw = 4;
> +		*bh = 4;
> +		return GL_TRUE;
> +	case GL_COMPRESSED_RED:
> +	case GL_COMPRESSED_RED_RGTC1_EXT:
> +	case GL_COMPRESSED_RG:
> +	case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
> +		*bw = 4;
> +		*bh = 4;
> +		return GL_TRUE;
> +	case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
> +	case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
> +		*bw = 4;
> +		*bh = 4;
> +		return GL_TRUE;
> +	default:
> +		*bw = *bh = 1;
> +		return GL_FALSE;
> +	}
> +}
> +
> +
> +/**
> + * 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);
> +
> +	glCreateTextures(target, 1, &tex);
> +	glBindTextureUnit(0, tex);
> +	glTextureParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> +	glTextureParameteri(tex, 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) {
> +		glTextureStorage1D(tex, 1, intFormat, w);
> +		glTextureSubImage1D(tex, 0, 0, w, srcFormat, 
> +			GL_UNSIGNED_BYTE, img);
> +	}
> +	else if (target == GL_TEXTURE_2D) {
> +		glTextureStorage2D(tex, 1, intFormat, w, h);
> +		glTextureSubImage2D(tex, 0, 0, 0, w, h, srcFormat,
> +			     GL_UNSIGNED_BYTE, img);
> +	}
> +	else if (target == GL_TEXTURE_3D) {
> +		glTextureStorage3D(tex, 1, intFormat, w, h, d);
> +		glTextureSubImage3D(tex, 0, 0, 0, 0, w, h, d, 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) {
> +			glTextureSubImage1D(tex, 0, tx, tw,
> +					srcFormat, GL_UNSIGNED_BYTE, img);
> +		}
> +		else if (target == GL_TEXTURE_2D) {
> +			glTextureSubImage2D(tex, 0, tx, ty, tw, th,
> +					srcFormat, GL_UNSIGNED_BYTE, img);
> +		}
> +		else if (target == GL_TEXTURE_2D) {
> +			glTextureSubImage3D(tex, 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);
> +
> +		piglit_present_results();
> +
> +		if (!equal_images(ref, testImg, w, h)) {
> +			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;
> +		}
> +	}
> +
> +	glDisable(target);
> +
> +	free(img);
> +	free(ref);
> +	free(testImg);
> +
> +	glDeleteTextures(1, &tex);
> +	return pass;
> +}
> +
> +
> +/**
> + * Test all formats in texsubimage_test_sets[] for the given
> + * texture target.
> + */
> +static GLboolean
> +test_formats(GLenum target)
> +{
> +	GLboolean pass = GL_TRUE;
> +	int i, j;
> +
> +	/* loop over the format groups */
> +	for (i = 0; i < ARRAY_SIZE(texsubimage_test_sets); i++) {
> +		const struct test_desc *set = &texsubimage_test_sets[i];
> +		GLboolean skip = GL_FALSE;
> +
> +		/* only test compressed formats with 2D textures */
> +		if (i > 0 && target != GL_TEXTURE_2D)
> +			continue;
> +
> +		/* skip formats for unsupported extensions */
> +		for (j = 0; j < ARRAY_SIZE(set->ext); j++) {
> +			if (set->ext[j] &&
> +			    !piglit_is_extension_supported(set->ext[j])) {
> +				/* req'd extension not supported */
> +				skip = GL_TRUE;
> +				break;
> +			}
> +		}
> +		if (skip)
> +			continue;
> +
> +		/* loop over formats in the set */
> +		for (j = 0; j < set->num_formats; j++) {
> +			if (!test_format(target,
> +					 set->format[j].internalformat)) {
> +				pass = GL_FALSE;
> +			}
> +		}
> +	}
> +
> +	return pass;
> +}
> +
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	static const GLenum targets[] = {
> +		GL_TEXTURE_1D,
> +		GL_TEXTURE_2D,
> +		GL_TEXTURE_3D
> +	};
> +	GLboolean pass = GL_TRUE;
> +	int i;
> +
> +	/* Loop over 1/2/3D texture targets */
> +	for (i = 0; i < ARRAY_SIZE(targets); i++) {
> +		pass = test_formats(targets[i]) && pass;
> +	}
> +
> +	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> +
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	piglit_require_extension("GL_ARB_direct_state_access");
> +
> +	fbo_formats_init(argc, argv, 0);
> +	(void) fbo_formats_display;
> +
> +	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
> +}
> -- 
> 2.1.0
>
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit


More information about the Piglit mailing list