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

Kenneth Graunke kenneth at whitecape.org
Tue Nov 29 23:32:27 PST 2011


This exhaustively tests all 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                           |    4 +
 tests/texturing/CMakeLists.txt            |    1 +
 tests/texturing/shaders/CMakeLists.gl.txt |   16 ++
 tests/texturing/shaders/CMakeLists.txt    |    1 +
 tests/texturing/shaders/textureSize.c     |  339 +++++++++++++++++++++++++++++
 5 files changed, 361 insertions(+), 0 deletions(-)
 create mode 100644 tests/texturing/shaders/CMakeLists.gl.txt
 create mode 100644 tests/texturing/shaders/CMakeLists.txt
 create mode 100644 tests/texturing/shaders/textureSize.c

v2:
 - Move to a new tests/texturing/shaders directory
 - Add forgotten sampler3D variants to all.tests
 - Use "flat ivec4 color" instead of floats.
 - Typo fixes.

I have a i965 branch that passes all of these except samplerCubeShadow.

diff --git a/tests/all.tests b/tests/all.tests
index 61a020d..b153da9 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -881,6 +881,10 @@ import_glsl_parser_tests(spec['glsl-1.30'],
 			 os.path.join(generatedTestDir, 'spec', 'glsl-1.30'),
 			 ['compiler'])
 spec['glsl-1.30']['execution'] = Group()
+for stage in ['vs', 'fs']:
+	# textureSize():
+	for sampler in ['sampler1D', 'sampler2D', 'sampler3D', 'samplerCube', 'sampler1DShadow', 'sampler2DShadow', 'samplerCubeShadow', 'sampler1DArray', 'sampler2DArray', 'sampler1DArrayShadow', 'sampler2DArrayShadow', 'isampler1D', 'isampler2D', 'isampler3D', 'isamplerCube', 'isampler1DArray', 'isampler2DArray', 'usampler1D', 'usampler2D', 'usampler3D', 'usamplerCube', 'usampler1DArray', 'usampler2DArray']:
+		spec['glsl-1.30']['execution'][stage + '-textureSize-' + sampler] = 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/texturing/CMakeLists.txt b/tests/texturing/CMakeLists.txt
index 144a306..1bc9f55 100644
--- a/tests/texturing/CMakeLists.txt
+++ b/tests/texturing/CMakeLists.txt
@@ -1 +1,2 @@
+add_subdirectory (shaders)
 piglit_include_target_api()
diff --git a/tests/texturing/shaders/CMakeLists.gl.txt b/tests/texturing/shaders/CMakeLists.gl.txt
new file mode 100644
index 0000000..97e53f4
--- /dev/null
+++ b/tests/texturing/shaders/CMakeLists.gl.txt
@@ -0,0 +1,16 @@
+include_directories(
+	${GLEXT_INCLUDE_DIR}
+	${OPENGL_INCLUDE_PATH}
+	${GLUT_INCLUDE_DIR}
+	${piglit_SOURCE_DIR}/tests/mesa/util
+	${piglit_SOURCE_DIR}/tests/util
+)
+
+link_libraries (
+	piglitutil
+	${OPENGL_gl_LIBRARY}
+	${OPENGL_glu_LIBRARY}
+	${GLUT_glut_LIBRARY}
+)
+
+add_executable (textureSize textureSize.c)
diff --git a/tests/texturing/shaders/CMakeLists.txt b/tests/texturing/shaders/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/texturing/shaders/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/texturing/shaders/textureSize.c b/tests/texturing/shaders/textureSize.c
new file mode 100644
index 0000000..844e497
--- /dev/null
+++ b/tests/texturing/shaders/textureSize.c
@@ -0,0 +1,339 @@
+/*
+ * 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+ textureSize() built-in function.
+ *
+ * The test covers:
+ * - All pipeline stages (VS, FS)
+ * - Sampler data types (floating point, signed integer, unsigned integer)
+ * - Sampler 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 "textureSize" binary takes two arguments: shader stage and sampler type.
+ *
+ * For example:
+ * ./bin/textureSize fs sampler1DArrayShadow
+ * ./bin/textureSize vs usamplerCube
+ */
+#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 ivec1 int\n"
+			 "uniform int lod;\n"
+			 "uniform %s tex;\n"
+			 "flat out ivec%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 ivec1 int\n"
+			 "#define vec1 float\n"
+			 "flat in ivec%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++) {
+		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.3



More information about the Piglit mailing list