[Piglit] [PATCH] Primitive restart: Test in every possible draw mode.

Brian Paul brianp at vmware.com
Thu Apr 25 16:58:12 PDT 2013


On 04/25/2013 12:54 PM, Paul Berry wrote:
> Some implementations (i965 in particular) treat primitive restart
> differently depending what type of primitive is being drawn.  This
> test verifies that primitive restart works correctly for all primitive
> types.
> ---
>   tests/all.tests                             |   5 +
>   tests/general/CMakeLists.gl.txt             |   1 +
>   tests/general/primitive-restart-draw-mode.c | 275 ++++++++++++++++++++++++++++
>   3 files changed, 281 insertions(+)
>   create mode 100644 tests/general/primitive-restart-draw-mode.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index 7e5bd03..9791e9a 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -2244,6 +2244,11 @@ add_single_param_test_set(
>       "DISABLE_VBO",
>       "VBO_VERTEX_ONLY", "VBO_INDEX_ONLY",
>       "VBO_SEPARATE_VERTEX_AND_INDEX", "VBO_COMBINED_VERTEX_AND_INDEX")
> +add_single_param_test_set(
> +        nv_primitive_restart,
> +        'primitive-restart-draw-mode',
> +        'points', 'lines', 'line_loop', 'line_strip', 'triangles',
> +        'triangle_strip', 'triangle_fan', 'quads', 'quad_strip', 'polygon')
>
>   ext_provoking_vertex = Group()
>   spec['EXT_provoking_vertex'] = ext_provoking_vertex
> diff --git a/tests/general/CMakeLists.gl.txt b/tests/general/CMakeLists.gl.txt
> index 0e87baa..98e3271 100644
> --- a/tests/general/CMakeLists.gl.txt
> +++ b/tests/general/CMakeLists.gl.txt
> @@ -94,6 +94,7 @@ piglit_add_executable (point-line-no-cull point-line-no-cull.c)
>   piglit_add_executable (polygon-mode-offset polygon-mode-offset.c)
>   piglit_add_executable (polygon-mode polygon-mode.c)
>   piglit_add_executable (primitive-restart primitive-restart.c)
> +piglit_add_executable (primitive-restart-draw-mode primitive-restart-draw-mode.c)
>   piglit_add_executable (provoking-vertex provoking-vertex.c)
>   piglit_add_executable (push-pop-texture-state push-pop-texture-state.c)
>   piglit_add_executable (oes-read-format oes-read-format.c)
> diff --git a/tests/general/primitive-restart-draw-mode.c b/tests/general/primitive-restart-draw-mode.c
> new file mode 100644
> index 0000000..311fd81
> --- /dev/null
> +++ b/tests/general/primitive-restart-draw-mode.c
> @@ -0,0 +1,275 @@
> +/*
> + * Copyright © 2013 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 primitive-restart-draw-mode.c
> + *
> + * Test proper functioning of primitive restart in all draw modes.  In
> + * particular, verify that dangling vertices are properly discarded.
> + *
> + * The test operates as follows:
> + *
> + * - Choose a pattern of 8 vertices which will allow easy visual
> + *   inspection of the rendered image.  For some primitive types, we
> + *   arrange the 8 vertices in an octagon.  For others, we arrange
> + *   them in two rows, with vertices alternating between the two rows.
> + *
> + * - Construct an index buffer consisting of the values 0 through 7,
> + *   interrupted at some location by the primitive restart index, and
> + *   draw using the resulting index buffer using glDrawElements().
> + *   Seven images are drawn in a vertical array, one for each possible
> + *   place where the primitive restart index might interrupt the
> + *   indices.
> + *
> + * - To the right of each of the above images, use a pair of calls to
> + *   glDrawArrays() to simulate the expected behaviour of primitive
> + *   restart.
> + *
> + * - Compare the left and right halves of the resulting window to make
> + *   sure they match.
> + *
> + * Note: for easier visual inspection of the result, the image under
> + * test is drawn in blue, and the vertices are drawn in white using
> + * GL_POINTS.
> + */
> +
> +#include "piglit-util-gl-common.h"
> +
> +
> +#define NUM_VERTICES 8
> +#define NUM_ROWS (NUM_VERTICES - 1)
> +#define NUM_COLS 2
> +#define PATTERN_SIZE 75
> +#define VERTEX_ATTR 0
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +	config.supports_gl_compat_version = 10;
> +	config.window_width = PATTERN_SIZE * NUM_COLS;
> +	config.window_height = PATTERN_SIZE * NUM_ROWS;
> +	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +
> +enum vertex_pattern
> +{
> +	VERTEX_PATTERN_OCTAGON,
> +	VERTEX_PATTERN_2_ROWS,
> +	VERTEX_PATTERN_COUNT,
> +};
> +
> +
> +static const struct xy_coords
> +{
> +	GLfloat x;
> +	GLfloat y;
> +} vertex_patterns[VERTEX_PATTERN_COUNT][NUM_VERTICES] = {
> +	/* VERTEX_PATTERN_OCTAGON */
> +	{
> +		{ 27, 69 },
> +		{ 48, 69 },
> +		{ 69, 48 },
> +		{ 69, 27 },
> +		{ 48,  6 },
> +		{ 27,  6 },
> +		{  6, 27 },
> +		{  6, 48 },
> +	},
> +	/* VERTEX_PATTERN_2_ROWS */
> +	{
> +		{ 20, 63 },
> +		{ 55, 63 },
> +		{ 20, 46 },
> +		{ 55, 46 },
> +		{ 20, 29 },
> +		{ 55, 29 },
> +		{ 20, 12 },
> +		{ 55, 12 },
> +	},
> +};
> +
> +
> +static const struct test_desc
> +{
> +	const char *name;
> +	GLenum prim_type;
> +	enum vertex_pattern pattern;
> +} tests[] = {
> +	{ "points",         GL_POINTS,         VERTEX_PATTERN_OCTAGON },
> +	{ "lines",          GL_LINES,          VERTEX_PATTERN_OCTAGON },
> +	{ "line_loop",      GL_LINE_LOOP,      VERTEX_PATTERN_OCTAGON },
> +	{ "line_strip",     GL_LINE_STRIP,     VERTEX_PATTERN_OCTAGON },
> +	{ "triangles",      GL_TRIANGLES,      VERTEX_PATTERN_2_ROWS  },
> +	{ "triangle_strip", GL_TRIANGLE_STRIP, VERTEX_PATTERN_2_ROWS  },
> +	{ "triangle_fan",   GL_TRIANGLE_FAN,   VERTEX_PATTERN_OCTAGON },
> +	{ "quads",          GL_QUADS,          VERTEX_PATTERN_OCTAGON },
> +	{ "quad_strip",     GL_QUAD_STRIP,     VERTEX_PATTERN_2_ROWS  },
> +	{ "polygon",        GL_POLYGON,        VERTEX_PATTERN_OCTAGON },
> +};
> +
> +static const struct test_desc *test = NULL;
> +
> +
> +static const char vs_text[] =
> +	"#version 110\n"
> +	"attribute vec2 vertex;\n"
> +	"uniform vec2 offset;\n"
> +	"uniform vec2 window_size;\n"
> +	"uniform vec4 color;\n"
> +	"void main()\n"
> +	"{\n"
> +	"  gl_Position = vec4((vertex + offset) / window_size * 2.0 - 1.0,\n"
> +	"                     0.0, 1.0);\n"
> +	"  gl_FrontColor = color;\n"
> +	"}\n";
> +
> +
> +static GLuint prog;
> +static GLint window_size_loc;
> +static GLint offset_loc;
> +static GLint color_loc;
> +
> +
> +static void
> +print_usage_and_exit(const char *prog_name)
> +{
> +	int i;
> +	printf("Usage: %s<subtest>\n"
> +	       "  where<subtest>  is one of the following:\n", prog_name);
> +	for (i = 0; i<  ARRAY_SIZE(tests); i++)
> +		printf("    %s\n", tests[i].name);
> +	piglit_report_result(PIGLIT_FAIL);
> +}
> +
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	int i;
> +	GLuint vs;
> +
> +	/* Parse params */
> +	if (argc != 2)
> +		print_usage_and_exit(argv[0]);
> +	for (i = 0; i<  ARRAY_SIZE(tests); i++) {
> +		if (strcmp(argv[1], tests[i].name) == 0) {
> +			test =&tests[i];
> +			break;
> +		}
> +	}
> +	if (test == NULL)
> +		print_usage_and_exit(argv[0]);
> +
> +	piglit_require_GLSL_version(110);
> +	if (!piglit_is_extension_supported("GL_NV_primitive_restart")&&
> +	    piglit_get_gl_version()<  31) {
> +		printf("GL_NV_primitive_restart or GL 3.1 required\n");
> +		piglit_report_result(PIGLIT_SKIP);
> +	}
> +
> +	prog = glCreateProgram();
> +	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
> +	glAttachShader(prog, vs);
> +	glDeleteShader(vs);
> +	glBindAttribLocation(prog, VERTEX_ATTR, "vertex");
> +	glLinkProgram(prog);

I think you could use piglit_link_simple_program(vs, fs=0)


> +	if (!piglit_link_check_status(prog) ||
> +	    !piglit_check_gl_error(GL_NO_ERROR)) {
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +	window_size_loc = glGetUniformLocation(prog, "window_size");
> +	offset_loc = glGetUniformLocation(prog, "offset");
> +	color_loc = glGetUniformLocation(prog, "color");
> +}
> +
> +
> +static void
> +draw_pattern(int restart_pos, bool use_primitive_restart)
> +{
> +	/* Draw test pattern in blue */
> +	glUniform4f(color_loc, 0.25, 0.25, 1.0, 1.0);
> +	if (use_primitive_restart) {
> +		GLubyte index_buffer[NUM_VERTICES + 1];
> +		int i;
> +
> +		for (i = 0; i<  restart_pos; i++) {
> +			index_buffer[i] = i;
> +		}
> +		index_buffer[restart_pos] = 0xff;
> +		for (i = restart_pos + 1; i<  ARRAY_SIZE(index_buffer); i++) {
> +			index_buffer[i] = i - 1;
> +		}
> +		if (piglit_get_gl_version()>= 31) {
> +			glEnable(GL_PRIMITIVE_RESTART);
> +			glPrimitiveRestartIndex(0xff);
> +		} else {
> +			glEnableClientState(GL_PRIMITIVE_RESTART_NV);
> +			glPrimitiveRestartIndexNV(0xff);
> +		}
> +		glDrawElements(test->prim_type, ARRAY_SIZE(index_buffer),
> +			       GL_UNSIGNED_BYTE, index_buffer);
> +		if (piglit_get_gl_version()>= 31)
> +			glDisable(GL_PRIMITIVE_RESTART);
> +		else
> +			glDisableClientState(GL_PRIMITIVE_RESTART_NV);
> +	} else {
> +		glDrawArrays(test->prim_type, 0, restart_pos);
> +		glDrawArrays(test->prim_type, restart_pos,
> +			     NUM_VERTICES - restart_pos);
> +	}
> +
> +	if (test->prim_type != GL_POINTS) {
> +		/* Draw vertices in white */
> +		glUniform4f(color_loc, 1.0, 1.0, 1.0, 1.0);
> +		glDrawArrays(GL_POINTS, 0, NUM_VERTICES);
> +	}
> +}
> +
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	int row, col;
> +	bool pass = true;
> +
> +	glClear(GL_COLOR_BUFFER_BIT);
> +	glUseProgram(prog);
> +	glUniform2f(window_size_loc, piglit_width, piglit_height);
> +	glVertexAttribPointer(VERTEX_ATTR, 2, GL_FLOAT, GL_FALSE,
> +			      sizeof(vertex_patterns[test->pattern][0]),
> +			      vertex_patterns[test->pattern]);
> +	glEnableVertexAttribArray(VERTEX_ATTR);
> +
> +	for (col = 0; col<  NUM_COLS; col++) {
> +		for (row = 0; row<  NUM_ROWS; row++) {
> +			glUniform2f(offset_loc, col * PATTERN_SIZE,
> +				    (NUM_ROWS - 1 - row) * PATTERN_SIZE);
> +			draw_pattern(row + 1, col == 0);
> +		}
> +	}
> +
> +	pass = piglit_probe_rect_halves_equal_rgba(0, 0, piglit_width,
> +						   piglit_height)&&  pass;
> +	pass = piglit_check_gl_error(GL_NO_ERROR)&&  pass;
> +	piglit_present_results();
> +	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}

Otherwise LGTM.

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



More information about the Piglit mailing list