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

Kenneth Graunke kenneth at whitecape.org
Thu Nov 17 22:48:41 PST 2011


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.
+ */
+#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();
+}
-- 
1.7.7.2



More information about the Piglit mailing list