[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