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

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


This exhaustively tests all of GLSL 1.30's texelFetch variants, both in
the vertex and fragment shaders.  It covers:
- Integer and floating point texture formats
- Sampler dimensionality (1D, 2D, 3D, 1DArray, 2DArray)
- Mipmapping
- Non-power-of-two textures

The new "texelFetch" binary takes two arguments: shader stage and
sampler type.  For example:

./bin/texelFetch fs sampler1DArray
./bin/texelFetch usampler3D vs

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 tests/all.tests                           |    4 +
 tests/texturing/shaders/CMakeLists.gl.txt |    1 +
 tests/texturing/shaders/texelFetch.c      |  638 +++++++++++++++++++++++++++++
 3 files changed, 643 insertions(+), 0 deletions(-)
 create mode 100644 tests/texturing/shaders/texelFetch.c

Here's a first stab at texelFetch() testing.  The test methodology is
insane but cool---check out those 13,815 point primitives! :)

Questions on how things work or suggestions for improvements welcome.
I apologize that it's not very easy to review.

I'm thinking of adding EXT_texture_swizzle support (just set the swizzles
and swap around the expected color components), as well as texelFetchOffset
support (though generating those shaders in C without ralloc_asprintf_append
is going to be awful).

I'm also hoping to adapt this code to create new (separate) tests for the
other texturing functions.

I'm not sure if this makes Dave's fs-texelFetch-2D test redundant or not.
I'm inclined to leave it; it's simple and more tests never hurt.

My i965 branch for VS texturing passes all of these tests.

diff --git a/tests/all.tests b/tests/all.tests
index cc26fcf..f3d5d13 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -885,6 +885,10 @@ 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'])
+	# texelFetch():
+	for sampler in ['sampler1D', 'sampler2D', 'sampler3D', 'sampler1DArray', 'sampler2DArray', 'isampler1D', 'isampler2D', 'isampler3D', 'isampler1DArray', 'isampler2DArray', 'usampler1D', 'usampler2D', 'usampler3D', 'usampler1DArray', 'usampler2DArray']:
+		spec['glsl-1.30']['execution'][stage + '-texelFetch-' + sampler] = PlainExecTest(['textureSize', stage, sampler, '-auto', '-fbo'])
+
 add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetch-2D')
 add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetchOffset-2D')
 add_shader_test_dir(spec['glsl-1.30']['execution'],
diff --git a/tests/texturing/shaders/CMakeLists.gl.txt b/tests/texturing/shaders/CMakeLists.gl.txt
index 97e53f4..eca9933 100644
--- a/tests/texturing/shaders/CMakeLists.gl.txt
+++ b/tests/texturing/shaders/CMakeLists.gl.txt
@@ -14,3 +14,4 @@ link_libraries (
 )
 
 add_executable (textureSize textureSize.c)
+add_executable (texelFetch texelFetch.c)
diff --git a/tests/texturing/shaders/texelFetch.c b/tests/texturing/shaders/texelFetch.c
new file mode 100644
index 0000000..a19ca62
--- /dev/null
+++ b/tests/texturing/shaders/texelFetch.c
@@ -0,0 +1,638 @@
+/*
+ * 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 texelFetch.c
+ *
+ * Tests the GLSL 1.30+ texelFetch() built-in function.
+ *
+ * The "texelFetch" binary takes two arguments: shader stage and sampler type.
+ *
+ * For example:
+ * ./bin/texelFetch fs sampler1DArray
+ * ./bin/texelFetch usampler3D vs
+ *
+ * The test covers:
+ * - All pipeline stages (VS, FS)
+ * - Integer and floating point texture formats
+ * - Sampler dimensionality (1D, 2D, 3D, 1DArray, 2DArray)
+ * - Mipmapping
+ * - Non-power-of-two textures
+ *
+ * Draws a series of "rectangles" which display each miplevel and array slice,
+ * at full size.  They are layed out as follows:
+ *
+ * miplevel 3 +          +          +          +          +
+ *
+ * miplevel 2 +-+        +-+        +-+        +-+        +-+
+ *            +-+        +-+        +-+        +-+        +-+
+ *
+ * miplevel 1 +---+      +---+      +---+      +---+      +---+
+ *            |   |      |   |      |   |      |   |      |   |
+ *            +---+      +---+      +---+      +---+      +---+
+ *
+ *            +------+   +------+   +------+   +------+   +------+
+ * miplevel 0 |      |   |      |   |      |   |      |   |      |
+ *            |      |   |      |   |      |   |      |   |      |
+ *            +------+   +------+   +------+   +------+   +------+
+ *            slice #0   slice #1   slice #2   slice #3   slice #4
+ *
+ * Normally, we could draw each rectangle as a single quad (or two triangles),
+ * interpolate the texture coordinates across the primitive, and let the
+ * fragment shader look up the color values from the texture.
+ *
+ * However, this fails miserably for vertex shader texturing: a quad only has
+ * four vertices, which means we could only fetch/display at most 4 texels.
+ * If we used a simple RGBW checkerboard, as in other Piglit tests, this would
+ * only tell us that we sampled somewhere in the right 1/4 of the texture.
+ *
+ * Instead, we take a clever approach: draw each "rectangle" via a series of
+ * 1-pixel wide GL_POINT primitives.  This gives us one vertex per pixel; by
+ * drawing the texture at full size, each pixel and vertex also correspond to
+ * exactly one texel.  So every texel is sampled and verified for correctness.
+ *
+ * In other words: "One pixel, one texel, one vertex."
+ *
+ * For convenience, we take the same approach for fragment shader testing
+ * as well, since it allows us to reuse the same VBO setup and drawing code.
+ */
+#include "piglit-util.h"
+
+int piglit_width = 355, piglit_height = 250;
+int piglit_window_mode = GLUT_RGBA | GLUT_DOUBLE;
+
+/** Vertex shader attribute locations */
+const int pos_loc = 0;
+const int texcoord_loc = 1;
+
+/** Uniform locations */
+int divisor_loc;
+
+/** The total number of miplevels. */
+int miplevels;
+
+/**
+ * Multidimensional array containing the dimensions of each miplevel, indexed
+ * by miplevel and then x/y/z.  For example, miplevel[0][1] is the height of
+ * miplevel 0, while miplevel[5][2] is the number of slices in miplevel 5.
+ */
+int **level_size;
+
+/**
+ * Expected color data for each rectangle drawn, indexed by miplevel and slice.
+ * For example, expected_colors[1][3] contains the data for miplevel 1 slice 3.
+ */
+float ***expected_colors;
+
+struct sampler_info {
+	/** GLSL sampler name, such as "sampler2DArray" (without 'i' or 'u'). */
+	const char *name;
+
+	/** Sampler coordinate dimensions. */
+	int coord_dim;
+
+	/** OpenGL texture target, such as GL_TEXTURE_2D_ARRAY. */
+	GLenum gl_target;
+
+	/** Size of the base-level texture */
+	int width;
+	int height;
+	int depth;
+};
+
+const struct sampler_info *sampler = NULL;
+
+/** Sampler type being tested, including data type, i.e. 'usampler2D' */
+const char *sampler_name;
+
+/** Data type returned by texelFetch: vec4, ivec4, or uvec4. */
+const char *color_type;
+
+/** OpenGL texture data type: GL_FLOAT, GL_INT, or GL_UNSIGNED_INT */
+GLenum tex_data_type;
+
+/** OpenGL texture format: GL_RGBA or GL_RGBA_INTEGER */
+GLenum tex_format;
+
+/** OpenGL internal texture format: GL_RGBA32F, GL_RGBA32I, or GL_RGBA32UI. */
+GLenum internal_format;
+
+enum shader_target {
+	UNKNOWN,
+	VS,
+	FS
+};
+
+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)); }
+
+/**
+ * Return the divisors necessary to scale the unnormalized texture data to
+ * a floating point color value in the range [0, 1].
+ */
+static void
+compute_divisors(int lod, float *divisors)
+{
+	divisors[0] = max2(level_size[lod][0] - 1, 1);
+	divisors[1] = max2(level_size[lod][1] - 1, 1);
+	divisors[2] = max2(level_size[lod][2] - 1, 1);
+	divisors[3] = 1.0;
+
+	if (tex_data_type != GL_UNSIGNED_INT)
+		divisors[0] = -divisors[0];
+}
+
+enum piglit_result
+piglit_display()
+{
+	int i, l, z;
+	bool pass = true;
+
+	piglit_ortho_projection(piglit_width, piglit_height, false);
+
+	glClearColor(0.1, 0.1, 0.1, 1.0);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glPointSize(1.0);
+
+	i = 0;
+	for (l = 0; l < miplevels; ++l) {
+		for (z = 0; z < level_size[l][2]; z++) {
+			/* Draw the "rectangle" for this miplevel/slice. */
+			int points = level_size[l][0] * level_size[l][1];
+			float divisors[4];
+
+			compute_divisors(l, divisors);
+			glUniform4fv(divisor_loc, 1, divisors);
+
+			glDrawArrays(GL_POINTS, i, points);
+
+			i += points;
+
+			/* Compare results against reference image. */
+			piglit_probe_image_rgba(5 + (5 + sampler->width) * z,
+						5 + (5 + sampler->height) * l,
+						level_size[l][0],
+						level_size[l][1],
+						expected_colors[l][z]);
+		}
+	}
+
+	piglit_present_results();
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+/**
+ * Generate two VBOs for our vertex attributes:
+ * 1. Pixel position (in window coordinates).
+ * 2. Texture coordinates.
+ *
+ * The VBOs contain the data for every rectangle being drawn (as opposed to
+ * creating and binding a separate VBO per miplevel/slice.)
+ */
+void
+generate_VBOs()
+{
+	int x, y, z, l;
+	GLuint pos_vbo, tc_vbo;
+	float *pos, *pos_data;
+	int *tc, *tc_data;
+	bool array_1D = sampler->gl_target == GL_TEXTURE_1D_ARRAY;
+	int num_texels = 0;
+
+	/* Calculate the # of texels a.k.a. size of the VBOs */
+	for (l = 0; l < miplevels; l++) {
+		num_texels += level_size[l][0] * level_size[l][1] * level_size[l][2];
+	}
+
+	pos = pos_data = malloc(num_texels * 4 * sizeof(float));
+	tc = tc_data = malloc(num_texels * 4 * sizeof(int));
+
+	for (l = 0; l < miplevels; l++) {
+		for (z = 0; z < level_size[l][2]; z++) {
+			for (y = 0; y < level_size[l][1]; y++) {
+				for (x = 0; x < level_size[l][0]; x++) {
+					/* Assign pixel positions: */
+					pos[0] = 5.5 + (5 + sampler->width)*z + x;
+					pos[1] = 5.5 + (5 + sampler->height)*l + y;
+					pos[2] = 0.0;
+					pos[3] = 1.0;
+					pos += 4;
+
+					/* Assign texture coordinates:
+					 * 1D:      x _ _ l
+					 * 2D:      x y _ l
+					 * 3D:      x y z l
+					 * 1DArray: x z _ l
+					 * 2DArray: x y z l
+					 */
+					tc[0] = x;
+					tc[1] = array_1D ? z : y;
+					tc[2] = z;
+					tc[3] = l;
+					tc += 4;
+				}
+			}
+		}
+	}
+
+	/* Create VBO for pixel positions in screen-space: */
+	glGenBuffers(1, &pos_vbo);
+	glBindBuffer(GL_ARRAY_BUFFER, pos_vbo);
+	glBufferData(GL_ARRAY_BUFFER,
+		     num_texels * 4 * sizeof(float),
+		     pos_data, GL_STATIC_DRAW);
+	glVertexAttribPointer(pos_loc, 4, GL_FLOAT, false, 0, 0);
+	glEnableVertexAttribArray(pos_loc);
+
+	/* Create VBO for texture coordinates: */
+	glGenBuffers(1, &tc_vbo);
+	glBindBuffer(GL_ARRAY_BUFFER, tc_vbo);
+	glBufferData(GL_ARRAY_BUFFER,
+		     num_texels * 4 * sizeof(int),
+		     tc_data, GL_STATIC_DRAW);
+	glVertexAttribIPointer(texcoord_loc, 4, GL_INT, 0, 0);
+	glEnableVertexAttribArray(texcoord_loc);
+}
+
+/**
+ * Create texel data.
+ */
+void
+generate_texture()
+{
+	int l, x, y, z;
+	unsigned *u_level, *u_ptr;
+	int      *i_level, *i_ptr;
+	float    *f_level, *f_ptr;
+	float    *expected_ptr;
+	void *level_image;
+	float divisors[4];
+	GLuint tex;
+	GLenum target = sampler->gl_target;
+
+	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);
+
+	expected_colors = calloc(miplevels, sizeof(float **));
+
+	for (l = 0; l < miplevels; l++) {
+		expected_colors[l] = calloc(level_size[l][2], sizeof(float **));
+
+		i_ptr = i_level =
+			malloc(level_size[l][0] * level_size[l][1] *
+			       level_size[l][2] * 4 * sizeof(int));
+
+		u_ptr = u_level =
+			malloc(level_size[l][0] * level_size[l][1] *
+			       level_size[l][2] * 4 * sizeof(unsigned));
+
+		f_ptr = f_level =
+			malloc(level_size[l][0] * level_size[l][1] *
+			       level_size[l][2] * 4 * sizeof(float));
+
+		for (z = 0; z < level_size[l][2]; z++) {
+			expected_ptr = expected_colors[l][z] =
+				malloc(level_size[l][0] * level_size[l][1] *
+				       level_size[l][2] * 4 * sizeof(float));
+			for (y = 0; y < level_size[l][1]; y++) {
+				for (x = 0; x < level_size[l][0]; x++) {
+					int nx = tex_data_type == GL_UNSIGNED_INT ?  x : -x;
+					f_ptr[0] = nx;
+					f_ptr[1] = y;
+					f_ptr[2] = z;
+					f_ptr[3] = 1.0;
+
+					i_ptr[0] = nx;
+					i_ptr[1] = y;
+					i_ptr[2] = z;
+					i_ptr[3] = 1;
+
+					u_ptr[0] = nx;
+					u_ptr[1] = y;
+					u_ptr[2] = z;
+					u_ptr[3] = 1;
+
+					compute_divisors(l, divisors);
+
+					expected_ptr[0] = f_ptr[0]/divisors[0];
+					expected_ptr[1] = f_ptr[1]/divisors[1];
+					expected_ptr[2] = f_ptr[2]/divisors[2];
+					expected_ptr[3] = 1.0;
+
+					f_ptr += 4;
+					i_ptr += 4;
+					u_ptr += 4;
+					expected_ptr += 4;
+				}
+			}
+		}
+
+		switch (tex_data_type) {
+		case GL_FLOAT:
+			level_image = f_level;
+			break;
+		case GL_UNSIGNED_INT:
+			level_image = u_level;
+			break;
+		case GL_INT:
+			level_image = i_level;
+			break;
+		}
+
+		switch (sampler->gl_target) {
+		case GL_TEXTURE_1D: {
+			glTexImage1D(GL_TEXTURE_1D, l, internal_format,
+				     level_size[l][0],
+				     0, tex_format, tex_data_type, level_image);
+			break;
+		}
+		case GL_TEXTURE_2D:
+			glTexImage2D(GL_TEXTURE_2D, l, internal_format,
+				     level_size[l][0], level_size[l][1],
+				     0, tex_format, tex_data_type, level_image);
+			break;
+		case GL_TEXTURE_3D:
+			glTexImage3D(GL_TEXTURE_3D, l, internal_format,
+				     level_size[l][0],
+				     level_size[l][1],
+				     level_size[l][2],
+				     0, tex_format, tex_data_type, level_image);
+			break;
+		case GL_TEXTURE_1D_ARRAY:
+			glTexImage2D(GL_TEXTURE_1D_ARRAY, l, internal_format,
+				     level_size[l][0], level_size[l][2],
+				     0, tex_format, tex_data_type, level_image);
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			glTexImage3D(GL_TEXTURE_2D_ARRAY, l, internal_format,
+				     level_size[l][0],
+				     level_size[l][1],
+				     level_size[l][2],
+				     0, tex_format, tex_data_type, level_image);
+			break;
+		}
+	}
+}
+
+/**
+ * Compute the number of miplevels, as well as the dimensions (width, height,
+ * depth/number of array slices) of each level.
+ */
+void
+compute_miplevel_info()
+{
+	int i, l;
+	bool is_array = sampler->gl_target == GL_TEXTURE_1D_ARRAY ||
+			sampler->gl_target == GL_TEXTURE_2D_ARRAY;
+
+	/* Compute the number of miplevels */
+	miplevels = (int) log2f(max3(sampler->width, sampler->height, sampler->depth))+1;
+
+	/* Compute the size of each miplevel */
+	level_size = malloc(miplevels * sizeof(int *));
+
+	level_size[0] = malloc(3 * sizeof(int));
+	level_size[0][0] = sampler->width;
+	level_size[0][1] = sampler->height;
+	level_size[0][2] = sampler->depth;
+	for (l = 1; l < miplevels; l++) {
+		level_size[l] = malloc(3 * sizeof(int));
+
+		for (i = 0; i < 3 - is_array; i++)
+			level_size[l][i] = max2(level_size[l-1][i] / 2, 1);
+
+		if (is_array)
+			level_size[l][2] = sampler->depth;
+	}
+}
+
+/**
+ * Generate, compile, and link the GLSL shaders.
+ */
+int
+generate_GLSL(enum shader_target test_stage)
+{
+	int vs, fs, prog;
+
+	/* Use statically sized buffers to avoid non-standard asprintf */
+	#define BS 500
+	static char vs_code[BS];
+	static char fs_code[BS];
+
+	switch (test_stage) {
+	case VS:
+		snprintf(vs_code, BS,
+			 "#version 130\n"
+			 "#define ivec1 int\n"
+			 "flat out %s color;\n"
+			 "in vec4 pos;\n"
+			 "in ivec4 texcoord;\n"
+			 "uniform %s tex;\n"
+			 "void main()\n"
+			 "{\n"
+			 "    color = texelFetch(tex, ivec%d(texcoord),\n"
+			 "                       texcoord.w);\n"
+			 "    gl_Position = gl_ModelViewProjectionMatrix*pos;\n"
+			 "}\n",
+			 color_type, sampler_name, sampler->coord_dim);
+		snprintf(fs_code, BS,
+			 "#version 130\n"
+			 "flat in %s color;\n"
+			 "uniform vec4 divisor;\n"
+			 "void main()\n"
+			 "{\n"
+			 "    gl_FragColor = vec4(color)/divisor;\n"
+			 "}\n",
+			 color_type);
+		break;
+	case FS:
+		snprintf(vs_code, BS,
+			 "#version 130\n"
+			 "#define ivec1 int\n"
+			 "in vec4 pos;\n"
+			 "in ivec4 texcoord;\n"
+			 "flat out ivec4 tc;\n"
+			 "void main()\n"
+			 "{\n"
+			 "    tc = texcoord;\n"
+			 "    gl_Position = gl_ModelViewProjectionMatrix*pos;\n"
+			 "}\n");
+		snprintf(fs_code, BS,
+			 "#version 130\n"
+			 "#define ivec1 int\n"
+			 "flat in ivec4 tc;\n"
+			 "uniform vec4 divisor;\n"
+			 "uniform %s tex;\n"
+			 "void main()\n"
+			 "{\n"
+			 "    vec4 color = texelFetch(tex, ivec%d(tc), tc.w);\n"
+			 "    gl_FragColor = color/divisor;\n"
+			 "}\n",
+			 sampler_name, sampler->coord_dim);
+		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);
+	prog = piglit_CreateProgram();
+	piglit_AttachShader(prog, vs);
+	piglit_AttachShader(prog, fs);
+
+	glBindAttribLocation(prog, pos_loc, "pos");
+	glBindAttribLocation(prog, texcoord_loc, "texcoord");
+
+	piglit_LinkProgram(prog);
+	piglit_link_check_status(prog);
+
+	return prog;
+}
+
+/**
+ * Check if a given command line argument is a valid GLSL sampler type.
+ * If so, infer dimensionality and data format based on the name.
+ */
+void
+select_sampler(char *full_name)
+{
+	int i;
+	const char *name = full_name;
+	static const struct sampler_info samplers[] =
+	{
+		{ "sampler1D",      1, GL_TEXTURE_1D,       65,  1,  1 },
+		{ "sampler2D",      2, GL_TEXTURE_2D,       65, 32,  1 },
+		{ "sampler3D",      3, GL_TEXTURE_3D,       65, 32,  5 },
+		{ "sampler1DArray", 2, GL_TEXTURE_1D_ARRAY, 65,  1,  5 },
+		{ "sampler2DArray", 3, GL_TEXTURE_2D_ARRAY, 65, 32,  5 },
+	};
+
+	assert(sampler == NULL);
+
+	if (full_name[0] == 'i' || full_name[0] == 'u')
+		name++; /* ignore sampler data type for now */
+
+	/* See if this is a valid sampler name */
+	for (i = 0; i < ARRAY_SIZE(samplers); i++) {
+		if (strcmp(samplers[i].name, name) == 0) {
+			sampler = &samplers[i];
+			break;
+		}
+	}
+
+	if (sampler == NULL)
+		return;
+
+	/* Found a valid sampler.  Set texture format related data. */
+	sampler_name = full_name;
+	if (full_name[0] == 'i') {
+		piglit_require_extension("GL_EXT_texture_integer");
+		color_type = "ivec4";
+		internal_format = GL_RGBA32I;
+		tex_format = GL_RGBA_INTEGER;
+		tex_data_type = GL_INT;
+	} else if (full_name[0] == 'u') {
+		piglit_require_extension("GL_EXT_texture_integer");
+		color_type = "uvec4";
+		internal_format = GL_RGBA32UI;
+		tex_format = GL_RGBA_INTEGER;
+		tex_data_type = GL_UNSIGNED_INT;
+	} else {
+		piglit_require_extension("GL_ARB_texture_float");
+		color_type = "vec4";
+		internal_format = GL_RGBA32F;
+		tex_format = GL_RGBA;
+		tex_data_type = GL_FLOAT;
+	}
+}
+
+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;
+
+	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? */
+			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");
+	divisor_loc = piglit_GetUniformLocation(prog, "divisor");
+
+	piglit_UseProgram(prog);
+
+	piglit_Uniform1i(tex_location, 0);
+
+	compute_miplevel_info();
+	generate_texture();
+	generate_VBOs();
+}
-- 
1.7.7.3



More information about the Piglit mailing list