[Piglit] [PATCH 1/2] Add a new comprehensive test for textureSize().

Kenneth Graunke kenneth at whitecape.org
Fri Nov 18 02:31:56 PST 2011


On 11/17/2011 10:48 PM, Kenneth Graunke wrote:
> This exhaustively tests of GLSL 1.30's textureSize variants, both in the
> vertex and fragment shaders.  It covers:
> - Sampler data type (floating point, signed integer, unsigned integer)
> - Dimensionality (1D, 2D, 3D, Cube, 1DArray, 2DArray)
> - Color and shadow samplers
> - Mipmapped textures
> - Non-power-of-two textures
> 
> It doesn't cover texture format variations.  In fact, the test never
> actually provides any content for the textures, because it should be
> irrelevant for textureSize(), is easier to program, and also extra mean.
> 
> The new "textureSize" binary takes two arguments: shader stage and
> sampler type.  For example:
> 
> ./bin/textureSize fs sampler1DArrayShadow
> ./bin/textureSize vs usamplerCube
> 
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
>  tests/all.tests                                  |    5 +
>  tests/spec/glsl-1.30/execution/CMakeLists.gl.txt |    1 +
>  tests/spec/glsl-1.30/execution/textureSize.c     |  327 ++++++++++++++++++++++
>  3 files changed, 333 insertions(+), 0 deletions(-)
>  create mode 100644 tests/spec/glsl-1.30/execution/textureSize.c
> 
> diff --git a/tests/all.tests b/tests/all.tests
> index 48ce2cb..ddfc42a 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -872,6 +872,11 @@ import_glsl_parser_tests(spec['glsl-1.30'],
>  			 os.path.join(generatedTestDir, 'spec', 'glsl-1.30'),
>  			 ['compiler'])
>  spec['glsl-1.30']['execution'] = Group()
> +sampler_types = ['sampler1D', 'sampler2D', 'samplerCube', 'sampler1DShadow', 'sampler2DShadow', 'sampler1DArray', 'sampler2DArray', 'sampler1DArrayShadow', 'sampler2DArrayShadow', 'isampler1D', 'isampler2D', 'isamplerCube', 'isampler1DArray', 'isampler2DArray', 'usampler1D', 'usampler2D', 'usamplerCube', 'usampler1DArray', 'usampler2DArray']
> +for stage in ['vs', 'fs']:
> +	for sampler in sampler_types:
> +		test_name = stage + '-textureSize-' + sampler
> +		spec['glsl-1.30']['execution'][test_name] = PlainExecTest(['textureSize', stage, sampler, '-auto', '-fbo'])
>  add_plain_test(spec['glsl-1.30']['execution'], 'fs-textureSize-2D')
>  add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetch-2D')
>  add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetchOffset-2D')
> diff --git a/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt b/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt
> index c9a816d..d80bebe 100644
> --- a/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt
> +++ b/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt
> @@ -16,6 +16,7 @@ link_libraries (
>  add_executable (fs-textureSize-2D fs-textureSize-2D.c)
>  add_executable (fs-texelFetch-2D fs-texelFetch-2D.c)
>  add_executable (fs-texelFetchOffset-2D fs-texelFetchOffset-2D.c)
> +add_executable (textureSize textureSize.c)
>  IF (NOT MSVC)
>  	add_executable (isinf-and-isnan isinf-and-isnan.c)
>  ENDIF (NOT MSVC)
> diff --git a/tests/spec/glsl-1.30/execution/textureSize.c b/tests/spec/glsl-1.30/execution/textureSize.c
> new file mode 100644
> index 0000000..dcde354
> --- /dev/null
> +++ b/tests/spec/glsl-1.30/execution/textureSize.c
> @@ -0,0 +1,327 @@
> +/*
> + * Copyright © 2011 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.
> + */
> +
> +/**
> + * \file textureSize.c
> + *
> + * Tests the GLSL 1.30 built-in function textureSize().
> + *
> + * Creates a mipmapped 64x32 2D texture and draws a series of squares whose
> + * color contains the width (red) and height (green) of each mipmap level.
> + */

Oops.  This comment is out of date...that's what the /old/ test did. :)
 It basically does that now too, but for newer dimensions.  I'll update
the comment.

> +#include "piglit-util.h"
> +
> +int piglit_width = 150, piglit_height = 30;
> +int piglit_window_mode = GLUT_RGBA | GLUT_DOUBLE;
> +
> +#define BS 500
> +static char vs_code[BS];
> +static char fs_code[BS];
> +
> +static int lod_location;
> +
> +/** Array containing the dimensions of the texture */
> +int tex_size[3] = { 65, 32, 0 };
> +int miplevels;
> +
> +enum shader_target {
> +	UNKNOWN,
> +	VS,
> +	FS
> +};
> +
> +struct sampler_info {
> +	const char *name;
> +	int size;
> +	GLenum gl_target;
> +	bool shadow;
> +};
> +
> +const struct sampler_info *sampler = NULL;
> +
> +static float max2(float x, float y) { return (x > y) ? x : y; }
> +static float max3(float x, float y, float z) { return max2(x, max2(y, z)); }
> +
> +enum piglit_result
> +piglit_display()
> +{
> +	bool pass = true;
> +	int is_array = sampler->gl_target == GL_TEXTURE_1D_ARRAY ||
> +		       sampler->gl_target == GL_TEXTURE_2D_ARRAY;
> +	int i, l;
> +
> +	glClearColor(0.5, 0.5, 0.5, 1.0);
> +	glClear(GL_COLOR_BUFFER_BIT);
> +
> +	int level_size[3] = { 1, 1, 1 };
> +	for (i = 0; i < sampler->size; i++)
> +		level_size[i] = tex_size[i];
> +
> +	/* Draw consecutive squares for each mipmap level */
> +	for (l = 0; l < miplevels; l++) {
> +		const int x = 10 + l * 20;
> +		float expected_color[4] = { 0.0, 0.0, 0.0, 1.0 };
> +		for (i = 0; i < sampler->size; i++)
> +			expected_color[i] = 0.01 * level_size[i];
> +
> +		piglit_Uniform1i(lod_location, l);
> +		glViewport(x, 10, 10, 10);
> +		piglit_draw_rect(-1, -1, 2, 2);
> +
> +		pass &= piglit_probe_rect_rgba(x, 10, 10, 10, expected_color);
> +
> +		/* For arrays, the # of slices never changes; don't divide */
> +		for (i = 0; i < sampler->size - is_array; i++)
> +			level_size[i] = max2(level_size[i] / 2, 1);
> +	}
> +
> +	piglit_present_results();
> +
> +	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> +
> +void
> +generate_texture()
> +{
> +	int i;
> +	GLuint tex;
> +	GLenum target = sampler->gl_target;
> +	GLenum format = sampler->shadow ? GL_DEPTH_COMPONENT : GL_RGBA;
> +
> +	glActiveTexture(GL_TEXTURE0);
> +
> +	glGenTextures(1, &tex);
> +	glBindTexture(target, tex);
> +	glEnable(target);
> +	glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
> +	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
> +	glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +	glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +
> +	switch (sampler->gl_target) {
> +	case GL_TEXTURE_1D:
> +		glTexImage1D(GL_TEXTURE_1D, 0, format,
> +			     tex_size[0],
> +			     0, format, GL_FLOAT, NULL);
> +		break;
> +	case GL_TEXTURE_2D:
> +		glTexImage2D(GL_TEXTURE_2D, 0, format,
> +			     tex_size[0], tex_size[1],
> +			     0, format, GL_FLOAT, NULL);
> +		break;
> +	case GL_TEXTURE_3D:
> +		tex_size[2] = 64;
> +		glTexImage3D(GL_TEXTURE_3D, 0, format,
> +			     tex_size[0], tex_size[1], tex_size[2],
> +			     0, format, GL_FLOAT, NULL);
> +		break;
> +	case GL_TEXTURE_CUBE_MAP:
> +		/* Cube face width/height must be the same */
> +		tex_size[1] = tex_size[0];
> +		for (i = 0; i < 6; i++) {
> +			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
> +				     format, tex_size[0], tex_size[1], 0,
> +				     format, GL_FLOAT, NULL);
> +		}
> +		break;
> +	case GL_TEXTURE_1D_ARRAY:
> +		tex_size[0] = 64;
> +		tex_size[1] = 40;
> +		glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, format,
> +			     tex_size[0], tex_size[1],
> +			     0, format, GL_FLOAT, NULL);
> +		break;
> +	case GL_TEXTURE_2D_ARRAY:
> +		tex_size[2] = 40;
> +		glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format,
> +			     tex_size[0], tex_size[1], tex_size[2],
> +			     0, format, GL_FLOAT, NULL);
> +		break;
> +	}
> +	glGenerateMipmap(target);
> +
> +	miplevels = (int) log2f(max3(tex_size[0], tex_size[1], tex_size[2]))+1;
> +
> +	for (i = sampler->size; i < 3; i++)
> +		tex_size[i] = 0;
> +}
> +
> +
> +int
> +generate_GLSL(enum shader_target test_stage)
> +{
> +	int vs, fs;
> +	static const char *zeros[3] = { "", "0, ", "0, 0, " };
> +	assert(sampler->size >= 1 && sampler->size <= 3);
> +
> +	switch (test_stage) {
> +	case VS:
> +		snprintf(vs_code, BS,
> +			 "#version 130\n"
> +			 "#define vec1 float\n"
> +			 "uniform int lod;\n"
> +			 "uniform %s tex;\n"
> +			 "out vec%d size;\n"
> +			 "void main()\n"
> +			 "{\n"
> +			 "    size = textureSize(tex, lod);\n"
> +			 "    gl_Position = gl_Vertex;\n"
> +			 "}\n",
> +			 sampler->name, sampler->size);
> +		snprintf(fs_code, BS,
> +			 "#version 130\n"
> +			 "#define vec1 float\n"
> +			 "in vec%d size;\n"
> +			 "void main()\n"
> +			 "{\n"
> +			 "    gl_FragColor = vec4(0.01 * size,%s 1);\n"
> +			 "}\n",
> +			 sampler->size, zeros[3 - sampler->size]);
> +		break;
> +	case FS:
> +		snprintf(vs_code, BS,
> +			 "#version 130\n"
> +			 "void main()\n"
> +			 "{\n"
> +			 "    gl_Position = gl_Vertex;\n"
> +			 "}\n");
> +		snprintf(fs_code, BS,
> +			 "#version 130\n"
> +			 "#define ivec1 int\n"
> +			 "uniform int lod;\n"
> +			 "uniform %s tex;\n"
> +			 "void main()\n"
> +			 "{\n"
> +			 "    ivec%d size = textureSize(tex, lod);\n"
> +			 "    gl_FragColor = vec4(0.01 * size,%s 1);\n"
> +			 "}\n",
> +			 sampler->name, sampler->size, zeros[3-sampler->size]);
> +		break;
> +	default:
> +		assert(!"Should not get here.");
> +		break;
> +	}
> +
> +	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
> +	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
> +	return piglit_link_simple_program(vs, fs);
> +}
> +
> +void
> +select_sampler(char *name)
> +{
> +	int i;
> +	static const struct sampler_info samplers[] =
> +	{
> +		{ "sampler1D",            1, GL_TEXTURE_1D,       false },
> +		{ "sampler2D",            2, GL_TEXTURE_2D,       false },
> +		{ "sampler3D",            3, GL_TEXTURE_3D,       false },
> +		{ "samplerCube",          2, GL_TEXTURE_CUBE_MAP, false },
> +		{ "sampler1DShadow",      1, GL_TEXTURE_1D,       true },
> +		{ "sampler2DShadow",      2, GL_TEXTURE_2D,       true },
> +		{ "samplerCubeShadow",    2, GL_TEXTURE_CUBE_MAP, true },
> +		{ "sampler1DArray",       2, GL_TEXTURE_1D_ARRAY, false },
> +		{ "sampler2DArray",       3, GL_TEXTURE_2D_ARRAY, false },
> +		{ "sampler1DArrayShadow", 2, GL_TEXTURE_1D_ARRAY, true},
> +		{ "sampler2DArrayShadow", 3, GL_TEXTURE_2D_ARRAY, true}
> +	};
> +
> +	for (i = 0; i < ARRAY_SIZE(samplers); i++) {
> +		if (strcmp(samplers[i].name, name) == 0) {
> +			sampler = &samplers[i];
> +			return;
> +		}
> +	}
> +}
> +
> +void
> +fail_and_show_usage()
> +{
> +	printf("Usage: textureSize <vs|fs> <sampler type> [piglit args...]\n");
> +	piglit_report_result(PIGLIT_SKIP);
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	int prog;
> +	int tex_location;
> +	int i;
> +	enum shader_target test_stage = UNKNOWN;
> +	bool integer_format = false;
> +
> +	piglit_require_GLSL_version(130);
> +
> +	for (i = 1; i < argc; i++) {
> +		/* Ignore piglit arguments like -auto and -fbo */
> +		if (argv[i][0] == '-')
> +			continue;
> +
> +		if (test_stage == UNKNOWN) {
> +			/* Maybe it's the shader stage? */
> +			if (strcmp(argv[i], "vs") == 0) {
> +				test_stage = VS;
> +				continue;
> +			} else if (strcmp(argv[i], "fs") == 0) {
> +				test_stage = FS;
> +				continue;
> +			}
> +		}
> +
> +		if (sampler == NULL) {
> +			/* Maybe it's the sampler type? */
> +			if (argv[i][0] == 'i' || argv[i][0] == 'u') {
> +				integer_format = true;
> +				select_sampler(argv[i] + 1);
> +			} else {
> +				integer_format = false;
> +				select_sampler(argv[i]);
> +			}
> +
> +			if (sampler != NULL)
> +				continue;
> +		}
> +
> +		fail_and_show_usage();
> +	}
> +
> +	if (test_stage == UNKNOWN || sampler == NULL)
> +		fail_and_show_usage();
> +
> +	/* Skip if the driver doesn't export VS texture units */
> +	glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &i);
> +	if (test_stage == VS && i <= 0)
> +		piglit_report_result(PIGLIT_SKIP);
> +
> +	prog = generate_GLSL(test_stage);
> +
> +	tex_location = piglit_GetUniformLocation(prog, "tex");
> +	lod_location = piglit_GetUniformLocation(prog, "lod");
> +	piglit_UseProgram(prog);
> +	piglit_Uniform1i(tex_location, 0);
> +
> +	if (integer_format && sampler->shadow)
> +		piglit_report_result(PIGLIT_SKIP);
> +
> +	generate_texture();
> +}



More information about the Piglit mailing list