[Piglit] [PATCH 06/11] shader_runner: Add "active uniform" command

Ian Romanick idr at freedesktop.org
Mon Sep 8 14:34:51 PDT 2014


From: Ian Romanick <ian.d.romanick at intel.com>

This enables querying various aspects of a uniform using
glActiveUniformsiv.  Future commits will use this feature to test UBO
layouts.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 tests/shaders/shader_runner.c | 218 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 217 insertions(+), 1 deletion(-)

diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c
index 3d77db9..310b2d4 100644
--- a/tests/shaders/shader_runner.c
+++ b/tests/shaders/shader_runner.c
@@ -80,6 +80,8 @@ struct component_version {
 	char _string[100];
 };
 
+#define ENUM_STRING(e) { #e, e }
+
 struct string_to_enum {
 	const char *name;
 	GLenum token;
@@ -1614,6 +1616,219 @@ set_uniform(const char *line, int ubo_array_index)
 	return;
 }
 
+/**
+ * Query a uniform using glGetActiveUniformsiv
+ *
+ * Format of the command:
+ *
+ *     active uniform uniform_name GL_PNAME_ENUM integer
+ *
+ * or
+ *
+ *     active uniform uniform_name GL_PNAME_ENUM GL_TYPE_ENUM
+ */
+void
+active_uniform(const char *line)
+{
+	static const struct string_to_enum all_pnames[] = {
+		ENUM_STRING(GL_UNIFORM_TYPE),
+		ENUM_STRING(GL_UNIFORM_SIZE),
+		ENUM_STRING(GL_UNIFORM_NAME_LENGTH),
+		ENUM_STRING(GL_UNIFORM_BLOCK_INDEX),
+		ENUM_STRING(GL_UNIFORM_OFFSET),
+		ENUM_STRING(GL_UNIFORM_ARRAY_STRIDE),
+		ENUM_STRING(GL_UNIFORM_MATRIX_STRIDE),
+		ENUM_STRING(GL_UNIFORM_IS_ROW_MAJOR),
+		ENUM_STRING(GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX),
+		{ NULL, 0 }
+	};
+
+	static const struct string_to_enum all_types[] = {
+		ENUM_STRING(GL_FLOAT),
+		ENUM_STRING(GL_FLOAT_VEC2),
+		ENUM_STRING(GL_FLOAT_VEC3),
+		ENUM_STRING(GL_FLOAT_VEC4),
+		ENUM_STRING(GL_DOUBLE),
+		ENUM_STRING(GL_DOUBLE_VEC2),
+		ENUM_STRING(GL_DOUBLE_VEC3),
+		ENUM_STRING(GL_DOUBLE_VEC4),
+		ENUM_STRING(GL_INT),
+		ENUM_STRING(GL_INT_VEC2),
+		ENUM_STRING(GL_INT_VEC3),
+		ENUM_STRING(GL_INT_VEC4),
+		ENUM_STRING(GL_UNSIGNED_INT),
+		ENUM_STRING(GL_UNSIGNED_INT_VEC2),
+		ENUM_STRING(GL_UNSIGNED_INT_VEC3),
+		ENUM_STRING(GL_UNSIGNED_INT_VEC4),
+		ENUM_STRING(GL_BOOL),
+		ENUM_STRING(GL_BOOL_VEC2),
+		ENUM_STRING(GL_BOOL_VEC3),
+		ENUM_STRING(GL_BOOL_VEC4),
+		ENUM_STRING(GL_FLOAT_MAT2),
+		ENUM_STRING(GL_FLOAT_MAT3),
+		ENUM_STRING(GL_FLOAT_MAT4),
+		ENUM_STRING(GL_FLOAT_MAT2x3),
+		ENUM_STRING(GL_FLOAT_MAT2x4),
+		ENUM_STRING(GL_FLOAT_MAT3x2),
+		ENUM_STRING(GL_FLOAT_MAT3x4),
+		ENUM_STRING(GL_FLOAT_MAT4x2),
+		ENUM_STRING(GL_FLOAT_MAT4x3),
+		ENUM_STRING(GL_DOUBLE_MAT2),
+		ENUM_STRING(GL_DOUBLE_MAT3),
+		ENUM_STRING(GL_DOUBLE_MAT4),
+		ENUM_STRING(GL_DOUBLE_MAT2x3),
+		ENUM_STRING(GL_DOUBLE_MAT2x4),
+		ENUM_STRING(GL_DOUBLE_MAT3x2),
+		ENUM_STRING(GL_DOUBLE_MAT3x4),
+		ENUM_STRING(GL_DOUBLE_MAT4x2),
+		ENUM_STRING(GL_DOUBLE_MAT4x3),
+		ENUM_STRING(GL_SAMPLER_1D),
+		ENUM_STRING(GL_SAMPLER_2D),
+		ENUM_STRING(GL_SAMPLER_3D),
+		ENUM_STRING(GL_SAMPLER_CUBE),
+		ENUM_STRING(GL_SAMPLER_1D_SHADOW),
+		ENUM_STRING(GL_SAMPLER_2D_SHADOW),
+		ENUM_STRING(GL_SAMPLER_1D_ARRAY),
+		ENUM_STRING(GL_SAMPLER_2D_ARRAY),
+		ENUM_STRING(GL_SAMPLER_1D_ARRAY_SHADOW),
+		ENUM_STRING(GL_SAMPLER_2D_ARRAY_SHADOW),
+		ENUM_STRING(GL_SAMPLER_2D_MULTISAMPLE),
+		ENUM_STRING(GL_SAMPLER_2D_MULTISAMPLE_ARRAY),
+		ENUM_STRING(GL_SAMPLER_CUBE_SHADOW),
+		ENUM_STRING(GL_SAMPLER_BUFFER),
+		ENUM_STRING(GL_SAMPLER_2D_RECT),
+		ENUM_STRING(GL_SAMPLER_2D_RECT_SHADOW),
+		ENUM_STRING(GL_INT_SAMPLER_1D),
+		ENUM_STRING(GL_INT_SAMPLER_2D),
+		ENUM_STRING(GL_INT_SAMPLER_3D),
+		ENUM_STRING(GL_INT_SAMPLER_CUBE),
+		ENUM_STRING(GL_INT_SAMPLER_1D_ARRAY),
+		ENUM_STRING(GL_INT_SAMPLER_2D_ARRAY),
+		ENUM_STRING(GL_INT_SAMPLER_2D_MULTISAMPLE),
+		ENUM_STRING(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY),
+		ENUM_STRING(GL_INT_SAMPLER_BUFFER),
+		ENUM_STRING(GL_INT_SAMPLER_2D_RECT),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_1D),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_3D),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_CUBE),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_BUFFER),
+		ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_RECT),
+		{ NULL, 0 }
+	};
+
+	char name[512];
+	char name_buf[512];
+	char pname_string[512];
+	GLenum pname;
+	GLint expected;
+	int i;
+	int num_active_uniforms;
+
+	line = strcpy_to_space(name, eat_whitespace(line));
+
+	strcpy_to_space(pname_string, eat_whitespace(line));
+	pname = lookup_enum_string(all_pnames, &line, "glGetUniformsiv pname");
+
+	line = eat_whitespace(line);
+	if (isdigit(line[0])) {
+		expected = strtol(line, NULL, 0);
+	} else {
+		expected = lookup_enum_string(all_types, &line, "type enum");
+	}
+
+	glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_active_uniforms);
+	for (i = 0; i < num_active_uniforms; i++) {
+		GLint got;
+		GLint size;
+		GLenum type;
+		GLsizei name_len;
+		bool pass = true;
+
+		glGetActiveUniform(prog, i, sizeof(name_buf), &name_len,
+				   &size, &type, name_buf);
+
+		if (!piglit_check_gl_error(GL_NO_ERROR)) {
+			fprintf(stderr, "glGetActiveUniform error\n");
+			piglit_report_result(PIGLIT_FAIL);
+		}
+
+		if (strcmp(name, name_buf) != 0)
+			continue;
+
+		/* If the requested pname is one of the values that
+		 * glGetActiveUniform happens to return, check the value
+		 * returned by that function too.
+		 */
+		switch (pname) {
+		case GL_UNIFORM_TYPE:
+			got = (GLint) type;
+			break;
+
+		case GL_UNIFORM_SIZE:
+			got = size;
+			break;
+
+		case GL_UNIFORM_NAME_LENGTH:
+			got = name_len;
+			break;
+
+		default:
+			/* This ensures the check below will pass when the
+			 * requested enum is not one of the values already
+			 * returned by glGetActiveUniform.
+			 */
+			got = expected;
+			break;
+		}
+
+		if (got != expected) {
+			fprintf(stderr,
+				"glGetActiveUniform(%s, %s): "
+				"expected %d (0x%04x), got %d (0x%04x)\n",
+				name, pname_string,
+				expected, expected, got, got);
+			pass = false;
+		}
+
+		/* Set 'got' to some value in case glGetActiveUniformsiv
+		 * doesn't write to it.  That should only be able to occur
+		 * when the function raises a GL error, but "should" is kind
+		 * of a funny word.
+		 */
+		got = ~expected;
+		glGetActiveUniformsiv(prog, 1, (GLuint *) &i, pname, &got);
+
+		if (!piglit_check_gl_error(GL_NO_ERROR)) {
+			fprintf(stderr, "glGetActiveUniformsiv error\n");
+			piglit_report_result(PIGLIT_FAIL);
+		}
+
+		if (got != expected) {
+			fprintf(stderr,
+				"glGetActiveUniformsiv(%s, %s): "
+				"expected %d, got %d\n",
+				name, pname_string,
+				expected, got);
+			pass = false;
+		}
+
+		if (!pass)
+			piglit_report_result(PIGLIT_FAIL);
+
+		return;
+	}
+
+
+	fprintf(stderr, "No active uniform named \"%s\"\n", name);
+	piglit_report_result(PIGLIT_FAIL);
+	return;
+}
+
 void
 set_parameter(const char *line)
 {
@@ -1712,7 +1927,6 @@ do_enable_disable(const char *line, bool enable_flag)
 		glDisable(value);
 }
 
-#define ENUM_STRING(e) { #e, e }
 static const struct string_to_enum hint_target_table[] = {
 	ENUM_STRING(GL_LINE_SMOOTH_HINT),
 	ENUM_STRING(GL_POLYGON_SMOOTH_HINT),
@@ -2375,6 +2589,8 @@ piglit_display(void)
 			program_must_be_in_use();
 		} else if (string_match("ubo array index ", line)) {
 			get_ints(line + strlen("ubo array index "), &ubo_array_index, 1);
+		} else if (string_match("active uniform ", line)) {
+			active_uniform(line + strlen("active uniform "));
 		} else if ((line[0] != '\n') && (line[0] != '\0')
 			   && (line[0] != '#')) {
 			printf("unknown command \"%s\"\n", line);
-- 
1.8.1.4



More information about the Piglit mailing list