[Piglit] [PATCH] Add test glsl-uniform-out-of-bounds-2.c

Frank Henigman fjhenigman at google.com
Thu Nov 15 12:22:06 PST 2012


v2
Reorganized code, new comments and messages to make clearer.
Adopt reviewer's suggestions re ARRAY_SIZE, formatting, piglit_check_gl_error,
window size.

Check behavior of glGetUniformLocation, glGetUniform and glUniform(Matrix)
when attempting to access inactive/non-existent array elements.
---
 tests/all.tests                              |    1 +
 tests/shaders/CMakeLists.gl.txt              |    1 +
 tests/shaders/glsl-uniform-out-of-bounds-2.c |  179 ++++++++++++++++++++++++++
 3 files changed, 181 insertions(+), 0 deletions(-)
 create mode 100644 tests/shaders/glsl-uniform-out-of-bounds-2.c

diff --git a/tests/all.tests b/tests/all.tests
index 36c5847..2cf1ef4 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -240,6 +240,7 @@ add_plain_test(shaders, 'glsl-novertexdata')
 add_plain_test(shaders, 'glsl-preprocessor-comments')
 add_plain_test(shaders, 'glsl-reload-source')
 add_plain_test(shaders, 'glsl-uniform-out-of-bounds')
+add_plain_test(shaders, 'glsl-uniform-out-of-bounds-2')
 add_plain_test(shaders, 'glsl-uniform-update')
 add_plain_test(shaders, 'glsl-unused-varying')
 add_plain_test(shaders, 'glsl-fs-bug25902')
diff --git a/tests/shaders/CMakeLists.gl.txt b/tests/shaders/CMakeLists.gl.txt
index 6ac0230..93cbf7b 100644
--- a/tests/shaders/CMakeLists.gl.txt
+++ b/tests/shaders/CMakeLists.gl.txt
@@ -66,6 +66,7 @@ piglit_add_executable (glsl-reload-source glsl-reload-source.c)
 piglit_add_executable (glsl-unused-varying glsl-unused-varying.c)
 piglit_add_executable (glsl-uniform-update glsl-uniform-update.c)
 piglit_add_executable (glsl-uniform-out-of-bounds glsl-uniform-out-of-bounds.c)
+piglit_add_executable (glsl-uniform-out-of-bounds-2 glsl-uniform-out-of-bounds-2.c)
 piglit_add_executable (glsl-fs-bug25902 glsl-fs-bug25902.c)
 piglit_add_executable (glsl-fs-color-matrix glsl-fs-color-matrix.c)
 piglit_add_executable (glsl-fs-exp2 glsl-fs-exp2.c)
diff --git a/tests/shaders/glsl-uniform-out-of-bounds-2.c b/tests/shaders/glsl-uniform-out-of-bounds-2.c
new file mode 100644
index 0000000..95210d8
--- /dev/null
+++ b/tests/shaders/glsl-uniform-out-of-bounds-2.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * \file glsl-uniform-out-of-bounds-2.c
+ *
+ * glGetUniformLocation should return:
+ * -1 for inactive array elements (as reported by glGetActiveUniform)
+ * not -1 for active array elements (as reported by glGetActiveUniform)
+ * -1 for non-existent array elements (indices outside the array)
+ *
+ * Write and read all active array elements and check that data out == data in.
+ *
+ * Write and read some invalid locations and check for GL_INVALID_OPERATION.
+ *
+ * \author Frank Henigman <fjhenigman at google.com>
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+
+	config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static GLint prog;
+
+enum piglit_result
+piglit_display(void)
+{
+	/* unreached */
+	return PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	GLint vs, fs;
+	int i, j, k;
+	bool pass = true;
+	GLint numActiveUniform;
+	GLint min = -1, max = -1;
+	GLfloat data[16] =
+		{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+	GLfloat v[16];
+	GLint bogus[99];
+	int nbogus = 0;
+
+	piglit_require_gl_version(20);
+
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER,
+		"attribute vec4 p;\n"
+		"void main() { gl_Position = p; }\n"
+	);
+	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER,
+		"uniform vec4 v[4];\n"
+		"uniform mat4 m[4];\n"
+		"void main() { gl_FragColor = v[1] + m[1][1]; }\n"
+	);
+
+	prog = piglit_link_simple_program(vs, fs);
+	glUseProgram(prog);
+	glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &numActiveUniform);
+	printf("active uniforms %d\n", numActiveUniform);
+
+	// for each array in shader
+	for (k = 0; k < numActiveUniform; ++k) {
+		GLchar name[99];
+		GLint numActiveElements;
+		GLenum type;
+		int size;
+		glGetActiveUniform(prog, k, ARRAY_SIZE(name), NULL,
+						   &numActiveElements, &type, name);
+		if (name[1] != 0)
+			continue;
+		if (name[0] == 'v')
+			size = 4;
+		else if (name[0] == 'm')
+			size = 16;
+		else
+			continue;
+		printf("array '%s' active elements %d\n", name, numActiveElements);
+
+		// for each index in array, plus some before and after
+		for (i = -2; i < 6; ++i) {
+			bool isActive = 0 <= i && i < numActiveElements;
+			GLchar element[9];
+			GLint loc;
+			sprintf(element, "%s[%d]", name, i);
+			loc = glGetUniformLocation(prog, element);
+
+			// check result of glGetUniformLocation
+			if (loc == -1) {
+				if (isActive) {
+					printf("FAIL: no location for active %s\n", element);
+					pass = false;
+				}
+			} else {
+				if (!isActive) {
+					printf("FAIL: got location for inactive %s\n", element);
+					pass = false;
+				}
+
+				// write location
+				if (size == 4) {
+					glUniform4fv(loc, 1, data);
+				} else {
+					glUniformMatrix4fv(loc, 1, GL_FALSE, data);
+				}
+				// read back
+				for (j = 0; j < size; ++j)
+					v[j] = 0;
+				glGetUniformfv(prog, loc, v);
+				// compare
+				for (j = 0; j < size; ++j) {
+					if (v[j] != data[j]) {
+						printf("FAIL: wrong value in %s\n", element);
+						pass = false;
+						break;
+					}
+				}
+
+				if (min == -1 || loc < min)
+					min = loc;
+				if (max == -1 || loc > max)
+					max = loc;
+			}
+		}
+	}
+
+	// make up some bogus locations
+	for (i = 1; i < 6; ++i) {
+		bogus[nbogus++] = min - i;
+		bogus[nbogus++] = max + i;
+		bogus[nbogus++] = max + (1<<16) + i - 3;
+	}
+
+	// test writing and reading bogus locations
+	for (i = 0; i < nbogus; ++i) {
+		if (bogus[i] == -1)
+			continue;
+		printf("trying bogus location %d\n", bogus[i]);
+		glUniform4fv(bogus[i], 1, v);
+		if (!piglit_check_gl_error(GL_INVALID_OPERATION)) {
+			printf("FAIL: wrote bogus location\n");
+			pass = false;
+		}
+		glUniformMatrix4fv(bogus[i], 1, GL_FALSE, v);
+		if (!piglit_check_gl_error(GL_INVALID_OPERATION)) {
+			printf("FAIL: wrote bogus location (matrix)\n");
+			pass = false;
+		}
+		glGetUniformfv(prog, bogus[i], v);
+		if (!piglit_check_gl_error(GL_INVALID_OPERATION)) {
+			printf("FAIL: read bogus location\n");
+			pass = false;
+		}
+	}
+
+	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
-- 
1.7.7.3



More information about the Piglit mailing list