/* * 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. * * From the ARB_geometry_shader4 spec section 2.6.1: * "If a geometry shader is not active, the "adjacent" vertices are ignored." */ #include "piglit-util-gl.h" struct primitive { GLenum type; int count; unsigned short indices[12]; }; static const struct primitives { struct primitive adjacency, base; } tests[] = { { {GL_LINES_ADJACENCY, 8, {4, 5, 6, 7, 8, 9, 10, 11} }, {GL_LINES, 4, {5, 6, 9, 10} } }, { {GL_LINE_STRIP_ADJACENCY, 6, {4, 5, 6, 10, 9, 8} }, {GL_LINE_STRIP, 4, {5, 6, 10, 9} } }, { {GL_TRIANGLES_ADJACENCY, 12, {9, 4, 5, 6, 10, 14, 6, 11, 10, 9, 5, 1} }, {GL_TRIANGLES, 6, {9, 5, 10, 6, 10, 5} } }, { {GL_TRIANGLE_STRIP_ADJACENCY, 8, {9, 4, 5, 14, 10, 1, 6, 11} }, {GL_TRIANGLE_STRIP, 4, {9, 5, 10, 6} } } }; static const float vertex_data[] = { -1, 1, -1/3., 1, 1/3., 1, 1, 1, 0, 1/3., -1/3., 1/3., 1/3., 1/3., 1, 1/3., 0, -1/3., -1/3., -1/3., 1/3., -1/3., 1, -1/3., 0, 0, -1/3., 0, 1/3., 0, 1, 0, }; static const char vs_text[] = "attribute vec4 vertex;\n" "void main()\n" "{\n" " gl_Position = vertex;\n" "}\n"; static const char fs_text[] = "uniform vec4 color;\n" "void main()\n" "{\n" " gl_FragColor = color;\n" "}\n"; static const struct primitives *test; static bool indexed = false; static bool use_core = false; static void parse_cmd_line(int argc, char **argv); PIGLIT_GL_TEST_CONFIG_BEGIN parse_cmd_line(argc, argv); if (!use_core) { config.supports_gl_compat_version = 20; config.supports_gl_core_version = 31; } else { config.supports_gl_compat_version = 32; config.supports_gl_core_version = 32; } config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA; PIGLIT_GL_TEST_CONFIG_END GLuint color_uniform; /* Parse command line arguments. * * Recognized command line arguments are: * * The primitive type with adjacency to test (one of GL_LINES_ADJACENCY, * GL_LINE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY or * GL_TRIANGLE_STRIP_ADJACENCY). * * The optional argument "indexed" to use indexed drawing. * * The optional argument "core" to use GLSL 1.50 */ static void parse_cmd_line(int argc, char **argv) { int i, j; for (i = 1; i < argc; i++) { for (j = 0; j < ARRAY_SIZE(tests); j++) { if (strcmp(argv[i], piglit_get_prim_name(tests[j].adjacency.type)) == 0) test = &tests[j]; } if (strcmp(argv[i], "indexed") == 0) indexed = true; else if (strcmp(argv[i], "core") == 0) use_core = true; } if (test == NULL) { fprintf(stderr, "Please specify the adjacent primitive type " "to test on the command line\n"); piglit_report_result(PIGLIT_FAIL); } } void piglit_init(int argc, char **argv) { GLuint array_bufs[2]; GLuint array; GLuint prog; if (!use_core) piglit_require_extension("GL_ARB_geometry_shader4"); /* Bind Vertex Data */ glGenVertexArrays(1, &array); glBindVertexArray(array); glGenBuffers(2, array_bufs); glBindBuffer(GL_ARRAY_BUFFER, array_bufs[0]); if (indexed) glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STREAM_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, array_bufs[1]); /* Create shader. */ prog = piglit_build_simple_program(vs_text, fs_text); glBindAttribLocation(prog, 0, "vertex"); glLinkProgram(prog); color_uniform = glGetUniformLocation(prog, "color"); glUseProgram(prog); /* Enable blending. */ glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); } static void draw(const struct primitive prim) { if (indexed) { /* Upload index data and draw. */ glBufferData(GL_ELEMENT_ARRAY_BUFFER, prim.count * 2, prim.indices, GL_STREAM_DRAW); glDrawElements(prim.type, prim.count, GL_UNSIGNED_SHORT, NULL); } else { int i; float data[24]; /* Build vertex data, upload it and draw. */ for (i = 0; i < prim.count; ++i) { data[2 * i + 0] = vertex_data[2 * prim.indices[i] + 0]; data[2 * i + 1] = vertex_data[2 * prim.indices[i] + 1]; } glBufferData(GL_ARRAY_BUFFER, prim.count * 2 * 4, data, GL_STREAM_DRAW); glDrawArrays(prim.type, 0, prim.count); } } enum piglit_result piglit_display(void) { bool pass = true; const float black[] = {0, 0, 0, 1}; const float red[] = {1, 0, 0, 1}; const float green[] = {0, 1, 0, 1}; const float yellow[] = {1, 1, 0, 1}; glClear(GL_COLOR_BUFFER_BIT); /* Draw adjacency primitive red. */ glUniform4fv(color_uniform, 1, red); draw(test->adjacency); /* Draw normal primitive green. */ glUniform4fv(color_uniform, 1, green); draw(test->base); pass = piglit_probe_rect_two_rgb(0, 0, piglit_width, piglit_height, black, yellow) && pass; pass = piglit_check_gl_error(GL_NO_ERROR) && pass; if (!piglit_automatic) piglit_present_results(); return (pass ? PIGLIT_PASS : PIGLIT_FAIL); }