[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