[Piglit] [PATCH 12/18] arb_geometry_shader4: Test that adjacent vertices are ignored when no geometry shader is active.

Brian Paul brianp at vmware.com
Tue Jun 11 07:49:09 PDT 2013


On 05/24/2013 10:49 AM, Fabian Bieler wrote:
> Draw the adjacency version of a primitive in red and blend the normal version
> of that primitive in green on top of it. Check that the entire framebuffer is
> yellow or black.
>
> ARB_geometry_shader4 spec 2.6.1:
> "If a geometry shader is not active, the "adjacent" vertices are ignored."
> ---
>   tests/all.tests                                    |   2 +
>   .../execution/CMakeLists.gl.txt                    |  14 ++
>   .../execution/ignore-adjacent-vertices-indexed.c   | 223 +++++++++++++++++++++
>   .../execution/ignore-adjacent-vertices.c           | 218 ++++++++++++++++++++
>   4 files changed, 457 insertions(+)
>   create mode 100644 tests/spec/arb_geometry_shader4/execution/CMakeLists.gl.txt
>   create mode 100644 tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices-indexed.c
>   create mode 100644 tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index 785c864..294c2b6 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -2297,6 +2297,8 @@ spec['ARB_map_buffer_alignment'] = arb_map_buffer_alignment
>   add_plain_test(arb_map_buffer_alignment, 'arb_map_buffer_alignment-sanity_test')
>
>   arb_geometry_shader4 = Group()
> +add_concurrent_test(arb_geometry_shader4, 'ignore-adjacent-vertices')
> +add_concurrent_test(arb_geometry_shader4, 'ignore-adjacent-vertices-indexed')
>   add_concurrent_test(arb_geometry_shader4, 'program-parameter-input-type')
>   add_concurrent_test(arb_geometry_shader4, 'program-parameter-input-type-draw')
>   add_concurrent_test(arb_geometry_shader4, 'program-parameter-output-type')
> diff --git a/tests/spec/arb_geometry_shader4/execution/CMakeLists.gl.txt b/tests/spec/arb_geometry_shader4/execution/CMakeLists.gl.txt
> new file mode 100644
> index 0000000..8a370b9
> --- /dev/null
> +++ b/tests/spec/arb_geometry_shader4/execution/CMakeLists.gl.txt
> @@ -0,0 +1,14 @@
> +include_directories(
> +	${GLEXT_INCLUDE_DIR}
> +	${OPENGL_INCLUDE_PATH}
> +	${piglit_SOURCE_DIR}/tests/util
> +)
> +
> +link_libraries (
> +	piglitutil_${piglit_target_api}
> +	${OPENGL_gl_LIBRARY}
> +	${OPENGL_glu_LIBRARY}
> +)
> +
> +piglit_add_executable (ignore-adjacent-vertices ignore-adjacent-vertices.c)
> +piglit_add_executable (ignore-adjacent-vertices-indexed ignore-adjacent-vertices-indexed.c)
> diff --git a/tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices-indexed.c b/tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices-indexed.c
> new file mode 100644
> index 0000000..2ddee13
> --- /dev/null
> +++ b/tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices-indexed.c
> @@ -0,0 +1,223 @@
> +/*
> + * Copyright © 2013 The Piglit project
> + *
> + * 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 ignore-adjacent-vertices-indexed.c
> + *
> + * Test that adjacent vertices are ignored when no geometry shader is active.
> + * Draw the adjacency primitive in red and blend the non adjacency version in
> + * green on top of it. Then test that the entire framebuffer is either yellow
> + * or black.
> + */
> +
> +#include "piglit-util-gl-common.h"
> +
> +struct primitives {
> +	GLenum type_adjacency;
> +	int count_adjacency;
> +	GLenum type_base;
> +	int count_base;
> +};
> +
> +static const char vs_text[] =
> +	"void main()\n"
> +	"{\n"
> +	"	gl_Position = ftransform();\n"
> +	"}\n";
> +
> +static const char fs_text[] =
> +	"uniform vec4 color;\n"
> +	"void main()\n"
> +	"{\n"
> +	"	gl_FragColor = color;\n"
> +	"}\n";
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +	config.supports_gl_compat_version = 20;
> +	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +GLuint color_uniform;
> +
> +/* Check that the framebuffer is yellow and black. */
> +static bool
> +check_framebuffer(void)
> +{
> +	static uint32_t* buffer = 0;
> +	int y, x;
> +	if (!buffer) buffer = malloc(sizeof(uint32_t) * piglit_width * piglit_height);
> +
> +	glReadPixels(0, 0, piglit_width, piglit_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
> +
> +	for (y = 0; y < piglit_height; ++y) {
> +		for (x = 0; x < piglit_width; ++x) {
> +			uint32_t val = buffer[y * piglit_width + x] & 0xFFFFFF00;
> +
> +			if (val != 0 && val != 0xFFFF0000) {
> +				fprintf(stderr, "FAIL: Rendered primitives differ.\n");
> +				return false;
> +			}
> +		}
> +	}
> +
> +	return true;
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	GLuint array_bufs[2];
> +	GLuint array;
> +	GLuint vs, fs, prog;
> +	const int w = piglit_width;
> +	const int h = piglit_height;
> +	const float x_3 = (int)(w / 3.0) + 0.5;
> +	const float y_3 = (int)(h / 3.0) + 0.5;
> +	const float x2_3 = (int)(w * 2.0 / 3.0) + 0.5;
> +	const float y2_3 = (int)(h * 2.0 / 3.0) + 0.5;
> +	const float vertex_data[] = {
> +		0, h, x_3, h, x2_3, h, w, h,
> +		0, y2_3, x_3, y2_3, x2_3, y2_3, w, y2_3,
> +		0, y_3, x_3, y_3, x2_3, y_3, w, y_3,
> +		0, 0, x_3, 0, x2_3, 0, w, 0,
> +	};
> +	const unsigned short index_data[] = {
> +		/* lines_adjacency */
> +		4, 5, 6, 7, 8, 9, 10, 11,
> +
> +		/* lines */
> +		5, 6, 9, 10,
> +
> +		/* line_strip_adjacency */
> +		4, 5, 6, 10, 9, 8,
> +
> +		/* line_strip */
> +		5, 6, 10, 9,
> +
> +		/* triangles_adjacency */
> +		9, 4, 5, 6, 10, 14, 6, 11, 10, 9, 5, 1,
> +
> +		/* triangles */
> +		9, 5, 10, 6, 10, 5,
> +
> +		/* triangle_strip_adjacency */
> +		9, 4, 5, 14, 10, 1, 6, 11,
> +
> +		/* triangle_strip */
> +		9, 5, 10, 6,
> +	};
> +
> +	/* Bind Vertex Data */
> +	glGenVertexArrays(1, &array);
> +	glBindVertexArray(array);
> +	glGenBuffers(2, array_bufs);
> +	glBindBuffer(GL_ARRAY_BUFFER, array_bufs[0]);
> +	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
> +		     vertex_data, GL_STREAM_DRAW);
> +	glVertexPointer(2, GL_FLOAT, 0, NULL);
> +	glBindBuffer(GL_ARRAY_BUFFER, 0);
> +	glEnableClientState(GL_VERTEX_ARRAY);
> +
> +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, array_bufs[1]);
> +	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index_data),
> +		     index_data, GL_STREAM_DRAW);
> +
> +	/* Create shader. */
> +	prog = glCreateProgram();
> +	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
> +	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);
> +	glAttachShader(prog, vs);
> +	glAttachShader(prog, fs);
> +	glDeleteShader(vs);
> +	glDeleteShader(fs);
> +	glLinkProgram(prog);
> +	if (!piglit_link_check_status(prog) ||
> +	    !piglit_check_gl_error(GL_NO_ERROR)) {
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +	color_uniform = glGetUniformLocation(prog, "color");
> +	glUseProgram(prog);
> +
> +	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
> +
> +	/* Enable blending. */
> +	glEnable(GL_BLEND);
> +	glBlendEquation(GL_FUNC_ADD);
> +	glBlendFunc(GL_ONE, GL_ONE);
> +}
> +
> +static bool
> +run_test(const struct primitives test, int *first)
> +{
> +	const float red[] = {1, 0, 0, 1};
> +	const float green[] = {0, 1, 0, 1};
> +	bool pass = true;
> +
> +	printf("Testing %s and %s.\n", piglit_get_prim_name(test.type_adjacency),
> +			               piglit_get_prim_name(test.type_base));
> +
> +	glClear(GL_COLOR_BUFFER_BIT);
> +
> +	/* Draw adjacency primitive red. */
> +	glUniform4fv(color_uniform, 1, red);
> +	glDrawElements(test.type_adjacency, test.count_adjacency, GL_UNSIGNED_SHORT, NULL + *first * 2);
> +	*first += test.count_adjacency;
> +
> +	/* Draw normal primitive green. */
> +	glUniform4fv(color_uniform, 1, green);
> +	glDrawElements(test.type_base, test.count_base, GL_UNSIGNED_SHORT, NULL + *first * 2);
> +	*first += test.count_base;
> +
> +	pass = check_framebuffer() && pass;
> +	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
> +
> +	return pass;
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	bool pass = true;
> +	int first = 0;
> +	int i = 0;
> +	const struct primitives tests[] = {
> +		{GL_LINES_ADJACENCY, 8, GL_LINES, 4},
> +		{GL_LINE_STRIP_ADJACENCY, 6, GL_LINE_STRIP, 4},
> +		{GL_TRIANGLES_ADJACENCY, 12, GL_TRIANGLES, 6},
> +		{GL_TRIANGLE_STRIP_ADJACENCY, 8, GL_TRIANGLE_STRIP, 4},
> +	};
> +
> +	for (i = 0; i < ARRAY_SIZE(tests); i++) {
> +		pass = run_test(tests[i], &first) && pass;
> +
> +		if (!piglit_automatic && !pass) {
> +			piglit_present_results();
> +			return PIGLIT_FAIL;
> +		}
> +	}
> +
> +	if (!piglit_automatic)
> +		piglit_present_results();
> +
> +	return (pass ? PIGLIT_PASS : PIGLIT_FAIL);
> +}
> diff --git a/tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices.c b/tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices.c
> new file mode 100644
> index 0000000..6136151
> --- /dev/null
> +++ b/tests/spec/arb_geometry_shader4/execution/ignore-adjacent-vertices.c
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright © 2013 The Piglit project
> + *
> + * 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 ignore-adjacent-vertices.c
> + *
> + * Test that adjacent vertices are ignored when no geometry shader is active.
> + * Draw the adjacency primitive in red and blend the non adjacency version in
> + * green on top of it. Then test that the entire framebuffer is either yellow
> + * or black.
> + */
> +
> +#include "piglit-util-gl-common.h"
> +
> +struct primitives {
> +	GLenum type_adjacency;
> +	int count_adjacency;
> +	GLenum type_base;
> +	int count_base;
> +};
> +
> +static const char vs_text[] =
> +	"void main()\n"
> +	"{\n"
> +	"	gl_Position = ftransform();\n"
> +	"}\n";
> +
> +static const char fs_text[] =
> +	"uniform vec4 color;\n"
> +	"void main()\n"
> +	"{\n"
> +	"	gl_FragColor = color;\n"
> +	"}\n";
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +	config.supports_gl_compat_version = 20;
> +	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +GLuint color_uniform;
> +
> +/* Check that the framebuffer is yellow and black. */
> +static bool
> +check_framebuffer(void)
> +{
> +	static uint32_t* buffer = 0;
> +	int y, x;
> +	if (!buffer) buffer = malloc(sizeof(uint32_t) * piglit_width * piglit_height);

I think you could just use malloc/free per call here.


> +
> +	glReadPixels(0, 0, piglit_width, piglit_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
> +
> +	for (y = 0; y < piglit_height; ++y) {
> +		for (x = 0; x < piglit_width; ++x) {
> +			uint32_t val = buffer[y * piglit_width + x] & 0xFFFFFF00;
> +
> +			if (val != 0 && val != 0xFFFF0000) {
> +				fprintf(stderr, "FAIL: Rendered primitives differ.\n");
> +				return false;
> +			}
> +		}
> +	}
> +
> +	return true;
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	GLuint array_buf;
> +	GLuint array;
> +	GLuint vs, fs, prog;
> +	const int w = piglit_width;
> +	const int h = piglit_height;
> +	const float x_3 = (int)(w / 3.0) + 0.5;
> +	const float y_3 = (int)(h / 3.0) + 0.5;
> +	const float x2_3 = (int)(w * 2.0 / 3.0) + 0.5;
> +	const float y2_3 = (int)(h * 2.0 / 3.0) + 0.5;
> +	const float vertex_data[] = {
> +		/* lines_adjacency */
> +		0, y2_3, x_3, y2_3, x2_3, y2_3, w, y2_3,
> +		0, y_3, x_3, y_3, x2_3, y_3, w, y_3,
> +
> +		/* lines */
> +		x_3, y2_3, x2_3, y2_3,
> +		x_3, y_3, x2_3, y_3,
> +
> +		/* line_strip_adjacency */
> +		0, y2_3, x_3, y2_3, x2_3, y2_3,
> +		x2_3, y_3, x_3, y_3, 0, y_3,
> +
> +		/* line_strip */
> +		x_3, y2_3, x2_3, y2_3, x2_3, y_3, x_3, y_3,
> +
> +		/* triangles_adjacency */
> +		x_3, y_3, 0, y2_3, x_3, y2_3, x2_3, y2_3, x2_3, y_3, x2_3, 0,
> +		x2_3, y2_3, w, y_3, x2_3, y_3, x_3, y_3, x_3, y2_3, x_3, h,
> +
> +		/* triangles */
> +		x_3, y_3, x_3, y2_3, x2_3, y_3,
> +		x2_3, y2_3, x2_3, y_3, x_3, y2_3,
> +
> +		/* triangle_strip_adjacency */
> +		x_3, y_3, 0, y2_3, x_3, y2_3, x2_3, 0, x2_3, y_3, x_3, h, x2_3, y2_3, w, y_3,
> +
> +		/* triangle_strip */
> +		x_3, y_3, x_3, y2_3, x2_3, y_3, x2_3, y2_3,
> +	};
> +
> +	/* Bind Vertex Data */
> +	glGenVertexArrays(1, &array);
> +	glBindVertexArray(array);
> +	glGenBuffers(1, &array_buf);
> +	glBindBuffer(GL_ARRAY_BUFFER, array_buf);
> +	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
> +		     vertex_data, GL_STREAM_DRAW);
> +	glVertexPointer(2, GL_FLOAT, 0, NULL);
> +	glEnableClientState(GL_VERTEX_ARRAY);
> +	glBindBuffer(GL_ARRAY_BUFFER, 0);
> +
> +	/* Create shader. */
> +	prog = glCreateProgram();
> +	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
> +	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);
> +	glAttachShader(prog, vs);
> +	glAttachShader(prog, fs);
> +	glDeleteShader(vs);
> +	glDeleteShader(fs);
> +	glLinkProgram(prog);
> +	if (!piglit_link_check_status(prog) ||
> +	    !piglit_check_gl_error(GL_NO_ERROR)) {
> +		piglit_report_result(PIGLIT_FAIL);
> +	}

You could consolidate this shader setup code with 
piglit_build_simple_program().


> +	color_uniform = glGetUniformLocation(prog, "color");
> +	glUseProgram(prog);
> +
> +	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
> +
> +	/* Enable blending. */
> +	glEnable(GL_BLEND);
> +	glBlendEquation(GL_FUNC_ADD);
> +	glBlendFunc(GL_ONE, GL_ONE);
> +}
> +
> +static bool
> +run_test(const struct primitives test, int *first)
> +{
> +	const float red[] = {1, 0, 0, 1};
> +	const float green[] = {0, 1, 0, 1};
> +	bool pass = true;
> +
> +	printf("Testing %s and %s.\n", piglit_get_prim_name(test.type_adjacency),
> +			               piglit_get_prim_name(test.type_base));
> +
> +	glClear(GL_COLOR_BUFFER_BIT);
> +
> +	/* Draw adjacency primitive red. */
> +	glUniform4fv(color_uniform, 1, red);
> +	glDrawArrays(test.type_adjacency, *first, test.count_adjacency);
> +	*first += test.count_adjacency;
> +
> +	/* Draw normal primitive green. */
> +	glUniform4fv(color_uniform, 1, green);
> +	glDrawArrays(test.type_base, *first, test.count_base);
> +	*first += test.count_base;
> +
> +	pass = check_framebuffer() && pass;
> +	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
> +
> +	return pass;
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	bool pass = true;
> +	int first = 0;
> +	int i = 0;
> +	const struct primitives tests[] = {
> +		{GL_LINES_ADJACENCY, 8, GL_LINES, 4},
> +		{GL_LINE_STRIP_ADJACENCY, 6, GL_LINE_STRIP, 4},
> +		{GL_TRIANGLES_ADJACENCY, 12, GL_TRIANGLES, 6},
> +		{GL_TRIANGLE_STRIP_ADJACENCY, 8, GL_TRIANGLE_STRIP, 4},
> +	};
> +
> +	for (i = 0; i < ARRAY_SIZE(tests); i++) {
> +		pass = run_test(tests[i], &first) && pass;
> +
> +		if (!piglit_automatic && !pass) {
> +			piglit_present_results();
> +			return PIGLIT_FAIL;
> +		}
> +	}
> +
> +	if (!piglit_automatic)
> +		piglit_present_results();
> +
> +	return (pass ? PIGLIT_PASS : PIGLIT_FAIL);
> +}

One other thing, but not a big deal- this code is a bit fragile with 
respect to window resizing.  You have window size-related code in the 
init function.  Usually, the window size would be accounted for in the 
piglit_display() function.  But window resizing is not too common in piglit.

Reviewed-by: Brian Paul <brianp at vmware.com>




More information about the Piglit mailing list