[Piglit] [PATCH] shaders: add a test counting builtin active uniforms

Dylan Baker baker.dylan.c at gmail.com
Thu May 28 11:50:54 PDT 2015


Hey Martin,

I know these have already landed, but I noticed that you added tests in
the shaders/ directory. I Just wanted to let you know that we're not
adding new tests in the shaders directory, in the future putting them in
the appropriate directory under the spec directory. We're also trying to
use descriptive names rather than <shortname>-<number>.

Dylan

On Tue, May 19, 2015 at 03:29:33PM +0300, Martin Peres wrote:
> The test will almost-always pass but it is a nice way to catch bugs
> in our implementation... More information inside the test!
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32403
> Signed-off-by: Martin Peres <martin.peres at linux.intel.com>
> ---
>  tests/all.py                    |   1 +
>  tests/shaders/CMakeLists.gl.txt |   1 +
>  tests/shaders/getuniform-03.c   | 305 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 307 insertions(+)
>  create mode 100755 tests/shaders/getuniform-03.c
> 
> diff --git a/tests/all.py b/tests/all.py
> index 5b87410..8159b9b 100755
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -484,6 +484,7 @@ with profile.group_manager(PiglitGLTest, 'shaders') as g:
>      g(['glsl-getattriblocation'])
>      g(['getuniform-01'])
>      g(['getuniform-02'])
> +    g(['getuniform-03'])
>      g(['glsl-invalid-asm-01'])
>      g(['glsl-invalid-asm-02'])
>      g(['glsl-novertexdata'])
> diff --git a/tests/shaders/CMakeLists.gl.txt b/tests/shaders/CMakeLists.gl.txt
> index 35b4c6c..192debb 100644
> --- a/tests/shaders/CMakeLists.gl.txt
> +++ b/tests/shaders/CMakeLists.gl.txt
> @@ -59,6 +59,7 @@ piglit_add_executable (glsl-getactiveuniform-count glsl-getactiveuniform-count.c
>  piglit_add_executable (glsl-getactiveuniform-length glsl-getactiveuniform-length.c)
>  piglit_add_executable (getuniform-01 getuniform-01.c)
>  piglit_add_executable (getuniform-02 getuniform-02.c)
> +piglit_add_executable (getuniform-03 getuniform-03.c)
>  piglit_add_executable (glsl-invalid-asm-01 glsl-invalid-asm-01.c)
>  piglit_add_executable (glsl-invalid-asm-02 glsl-invalid-asm-02.c)
>  piglit_add_executable (glsl-novertexdata glsl-novertexdata.c)
> diff --git a/tests/shaders/getuniform-03.c b/tests/shaders/getuniform-03.c
> new file mode 100755
> index 0000000..927a98f
> --- /dev/null
> +++ b/tests/shaders/getuniform-03.c
> @@ -0,0 +1,305 @@
> +/*
> + * Copyright 2015 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.
> + */
> +
> +#include "piglit-util-gl.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +
> +	config.supports_gl_compat_version = 21;
> +
> +	config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +struct builtin_uniform_t {
> +	const char *name;
> +	GLenum type;
> +	bool is_array;
> +	bool found;
> +} uniforms[] = {
> +	{ "gl_DepthRange.near", GL_FLOAT, false , false },
> +	{ "gl_DepthRange.far", GL_FLOAT, false , false },
> +	{ "gl_DepthRange.diff", GL_FLOAT, false , false },
> +	/* { "gl_NumSamples", GL_INT, false , false }, requires OGL 4.0 */
> +	{ "gl_ModelViewMatrix", GL_FLOAT_MAT4, false , false },
> +	{ "gl_ProjectionMatrix", GL_FLOAT_MAT4, false , false  },
> +	{ "gl_ModelViewProjectionMatrix", GL_FLOAT_MAT4, false , false },
> +	{ "gl_TextureMatrix", GL_FLOAT_MAT4, true , false  },
> +	{ "gl_NormalMatrix", GL_FLOAT_MAT3, false , false  },
> +	{ "gl_ModelViewMatrixInverse", GL_FLOAT_MAT4, false , false },
> +	{ "gl_ProjectionMatrixInverse", GL_FLOAT_MAT4, false , false  },
> +	{ "gl_TextureMatrixInverse", GL_FLOAT_MAT4, true , false  },
> +	{ "gl_ModelViewMatrixTranspose", GL_FLOAT_MAT4, false , false  },
> +	{ "gl_ProjectionMatrixTranspose", GL_FLOAT_MAT4, false , false },
> +	{ "gl_ModelViewProjectionMatrixTranspose", GL_FLOAT_MAT4, false , false },
> +	{ "gl_TextureMatrixTranspose", GL_FLOAT_MAT4, true , false  },
> +	{ "gl_ModelViewMatrixInverseTranspose", GL_FLOAT_MAT4, false , false  },
> +	{ "gl_ProjectionMatrixInverseTranspose", GL_FLOAT_MAT4, false , false },
> +	{ "gl_ModelViewProjectionMatrixInverseTranspose", GL_FLOAT_MAT4, false  },
> +	{ "gl_TextureMatrixInverseTranspose", GL_FLOAT_MAT4, true , false },
> +	{ "gl_NormalScale", GL_FLOAT, false , false },
> +	{ "gl_ClipPlane", GL_FLOAT_VEC4, true , false },
> +	{ "gl_Point.size", GL_FLOAT, false , false },
> +	{ "gl_Point.sizeMin", GL_FLOAT, false , false },
> +	{ "gl_Point.sizeMax", GL_FLOAT, false , false },
> +	{ "gl_Point.fadeThresholdSize", GL_FLOAT, false , false },
> +	{ "gl_Point.distanceConstantAttenuation", GL_FLOAT, false , false },
> +	{ "gl_Point.distanceLinearAttenuation", GL_FLOAT, false , false },
> +	{ "gl_Point.distanceQuadraticAttenuation", GL_FLOAT, false , false },
> +	{ "gl_FrontMaterial.emission", GL_FLOAT_VEC4, false , false },
> +	{ "gl_FrontMaterial.ambient", GL_FLOAT_VEC4, false , false },
> +	{ "gl_FrontMaterial.diffuse", GL_FLOAT_VEC4, false , false },
> +	{ "gl_FrontMaterial.specular", GL_FLOAT_VEC4, false , false },
> +	{ "gl_FrontMaterial.shininess", GL_FLOAT, false , false },
> +	{ "gl_BackMaterial.emission", GL_FLOAT_VEC4, false , false },
> +	{ "gl_BackMaterial.ambient", GL_FLOAT_VEC4, false , false },
> +	{ "gl_BackMaterial.diffuse", GL_FLOAT_VEC4, false , false },
> +	{ "gl_BackMaterial.specular", GL_FLOAT_VEC4, false , false },
> +	{ "gl_BackMaterial.shininess", GL_FLOAT, false , false },
> +	{ "gl_LightSource[0].ambient", GL_FLOAT_VEC4, false , false },
> +	{ "gl_LightSource[0].diffuse", GL_FLOAT_VEC4, false , false },
> +	{ "gl_LightSource[0].specular", GL_FLOAT_VEC4, false , false },
> +	{ "gl_LightSource[0].position", GL_FLOAT_VEC4, false , false },
> +	{ "gl_LightSource[0].halfVector", GL_FLOAT_VEC4, false , false },
> +	{ "gl_LightSource[0].spotDirection", GL_FLOAT_VEC3, false , false },
> +	{ "gl_LightSource[0].spotExponent", GL_FLOAT, false , false },
> +	{ "gl_LightSource[0].spotCutoff", GL_FLOAT, false , false },
> +	{ "gl_LightSource[0].spotCosCutoff", GL_FLOAT, false , false },
> +	{ "gl_LightSource[0].constantAttenuation", GL_FLOAT, false , false },
> +	{ "gl_LightSource[0].linearAttenuation", GL_FLOAT, false , false },
> +	{ "gl_LightSource[0].quadraticAttenuation", GL_FLOAT, false , false },
> +	{ "gl_LightModel.ambient", GL_FLOAT_VEC4, false , false },
> +	{ "gl_FrontLightModelProduct.sceneColor", GL_FLOAT_VEC4, false , false },
> +	{ "gl_BackLightModelProduct.sceneColor", GL_FLOAT_VEC4, false , false },
> +	{ "gl_FrontLightProduct[0].ambient", GL_FLOAT_VEC4, true , false },
> +	{ "gl_FrontLightProduct[0].diffuse", GL_FLOAT_VEC4, true , false },
> +	{ "gl_FrontLightProduct[0].specular", GL_FLOAT_VEC4, true , false },
> +	{ "gl_BackLightProduct[0].ambient", GL_FLOAT_VEC4, true , false },
> +	{ "gl_BackLightProduct[0].diffuse", GL_FLOAT_VEC4, true , false },
> +	{ "gl_BackLightProduct[0].specular", GL_FLOAT_VEC4, true , false },
> +	{ "gl_TextureEnvColor", GL_FLOAT_VEC4, true , false },
> +	{ "gl_EyePlaneS", GL_FLOAT_VEC4, true , false },
> +	{ "gl_EyePlaneT", GL_FLOAT_VEC4, true , false },
> +	{ "gl_EyePlaneR", GL_FLOAT_VEC4, true , false },
> +	{ "gl_EyePlaneQ", GL_FLOAT_VEC4, true , false },
> +	{ "gl_ObjectPlaneS", GL_FLOAT_VEC4, true , false },
> +	{ "gl_ObjectPlaneT", GL_FLOAT_VEC4, true , false },
> +	{ "gl_ObjectPlaneR", GL_FLOAT_VEC4, true , false },
> +	{ "gl_ObjectPlaneQ", GL_FLOAT_VEC4, true , false },
> +	{ "gl_Fog.color", GL_FLOAT_VEC4, false , false },
> +	{ "gl_Fog.density", GL_FLOAT, false , false },
> +	{ "gl_Fog.start", GL_FLOAT, false , false },
> +	{ "gl_Fog.end", GL_FLOAT, false , false },
> +	{ "gl_Fog.scale", GL_FLOAT, false , false },
> +};
> +
> +static const char vs_header[] =
> +   "void main()\n"
> +   "{\n"
> +   "  gl_Position = vec4(1);\n";
> +
> +static const char vs_footer[] =
> +   "}\n";
> +
> +char *
> +gen_vs_shader_all()
> +{
> +	/* strlen("  gl_Position += vec4(gl_ModelViewProjectionMatrixInverse
> +	 *        "Transpose[0]);\n") */
> +	size_t max_line_size = 64;
> +	size_t uniforms_count = ARRAY_SIZE(uniforms);
> +	size_t shader_len = strlen(vs_header) +
> +			    uniforms_count * max_line_size +
> +			    strlen(vs_footer) + 1;
> +	size_t i;
> +
> +	/* allocate the shader */
> +	char *vs_text = malloc(shader_len);
> +	memset(vs_text, 0, shader_len);
> +
> +	/* add the header */
> +	strcat(vs_text, vs_header);
> +
> +	/* add a reference to every uniform */
> +	for (i = 0; i < uniforms_count; i++) {
> +		strcat(vs_text, "  gl_Position += ");
> +		switch(uniforms[i].type) {
> +		case GL_FLOAT_VEC3:
> +			strcat(vs_text, "vec4(");
> +			strcat(vs_text, uniforms[i].name);
> +			strcat(vs_text, ", 1)");
> +			break;
> +		case GL_FLOAT_MAT4:
> +			strcat(vs_text, "vec4(");
> +			strcat(vs_text, uniforms[i].name);
> +			strcat(vs_text, "[0])");
> +			break;
> +		case GL_FLOAT_MAT3:
> +			strcat(vs_text, "vec4(");
> +			strcat(vs_text, uniforms[i].name);
> +			strcat(vs_text, ")");
> +			break;
> +		default:
> +			strcat(vs_text, uniforms[i].name);
> +			if (uniforms[i].is_array)
> +				strcat(vs_text, "[0]");
> +		}
> +		strcat(vs_text, ";\n");
> +	}
> +
> +	/* add the footer */
> +	strcat(vs_text, vs_footer);
> +
> +	/* Uncomment the following to view the generated shader */
> +	/*fprintf(stderr, "shader = '%s'\n", vs_text);*/
> +
> +	return vs_text;
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	/* never called */
> +	return PIGLIT_FAIL;
> +}
> +
> +static struct builtin_uniform_t *
> +find_uniform(const char *name)
> +{
> +	size_t i;
> +
> +	for (i = 0; i < ARRAY_SIZE(uniforms); i++) {
> +		/* OpenGL ES 3.0 and OpenGL 4.2 require that the "[0]" be
> +		 * appended to the name.  Earlier versions of the spec are
> +		 * ambiguous.  Accept either name.
> +		*/
> +		if (strcmp(uniforms[i].name, name) == 0 ||
> +		    (strcmp(name + strlen(name) - 3, "[0]") == 0 &&
> +		     strncmp(uniforms[i].name, name, strlen(name) - 3) == 0))
> +			return &uniforms[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	GLint numUniforms, i;
> +	bool pass = true;
> +	GLuint vs, prog;
> +	char *vs_text;
> +
> +	piglit_require_vertex_shader();
> +	piglit_require_fragment_shader();
> +
> +	vs_text = gen_vs_shader_all();
> +
> +	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
> +	prog = piglit_link_simple_program(vs, 0);
> +	if (!prog) {
> +		printf("Compilation error. Aborting...\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +
> +	glUseProgram(prog);
> +	free(vs_text);
> +
> +	glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &numUniforms);
> +	if (numUniforms != ARRAY_SIZE(uniforms)) {
> +		printf("Unexpected number of uniforms (found %d, expected "
> +		       "%lu)\n", numUniforms, ARRAY_SIZE(uniforms));
> +	}
> +
> +	/* check the types of the active uniforms and check which ones got
> +	 * references by glGetActiveUniform for later comparaison. */
> +	for (i = 0; i < numUniforms; i++) {
> +		struct builtin_uniform_t *uniform;
> +		GLcharARB name[100];
> +		GLsizei len;
> +		GLint size;
> +		GLenum type;
> +
> +		glGetActiveUniform(prog, i, sizeof(name), &len, &size, &type,
> +				   name);
> +
> +		uniform = find_uniform(name);
> +
> +		if (!uniform) {
> +			fprintf(stderr, "Cannot find uniform '%s'\n", name);
> +			pass = false;
> +			continue;
> +		}
> +
> +		uniform->found = true;
> +
> +		if (type != uniform->type) {
> +			printf("Wrong type for '%s' (found %s(0x%x)), "
> +			       "expected %s(0x%x))\n",
> +				name, piglit_get_gl_enum_name(type), type,
> +				piglit_get_gl_enum_name(uniform->type),
> +				uniform->type);
> +				pass = false;
> +		}
> +	}
> +
> +	/* check that no uniform got forgotten as there is the possibility that
> +	 * one got referenced twice!
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(uniforms); i++) {
> +		if (uniforms[i].found == false) {
> +			fprintf(stderr, "uniform '%s' is missing from the "
> +					"active uniform list!\n",
> +				uniforms[i].name);
> +
> +			/* A missing builtin is legal, as stated by page 80
> +			 * (page 94 of the PDF) of the OpenGL 2.1 spec:
> +			 *
> +			 * "The returned uniform name can be the name of
> +			 * built-in uniform state as well."
> +			 */
> +
> +			/* FIXME: verify that the missing uniform as not been
> +			 * forgotten by the implementation. One way could have
> +			 * been to count the number of components used by the
> +			 * uniforms and add more components until reaching
> +			 * shader then adding other uniforms to reach
> +			 * GL_MAX_VERTEX_UNIFORM_COMPONENTS. If the shader still
> +			 * compiles, and assuming that
> +			 * GL_MAX_VERTEX_UNIFORM_COMPONENTS reports a good value
> +			 * then we can assume that the compiler just replaced
> +			 * the uniform with something else. If it does not
> +			 * compile, then it probably lied somewhere!
> +			 *
> +			 * The problem with this approach is that counting the
> +			 * number of components used for some types such as
> +			 * matrices is implementation-dependent...
> +			 *
> +			 * Until we have such a way to verify, let's not fail
> +			 * the test!
> +			 */
> +		}
> +	}
> +
> +	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
> +}
> -- 
> 2.4.0
> 
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/piglit/attachments/20150528/363bf7f3/attachment-0001.sig>


More information about the Piglit mailing list