From: Nicolai Hähnle <nicolai.haeh...@amd.com>

---
 tests/spec/gl-3.2/adj-prims.c | 144 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 128 insertions(+), 16 deletions(-)

diff --git a/tests/spec/gl-3.2/adj-prims.c b/tests/spec/gl-3.2/adj-prims.c
index f4479c708..6faff74d2 100644
--- a/tests/spec/gl-3.2/adj-prims.c
+++ b/tests/spec/gl-3.2/adj-prims.c
@@ -135,25 +135,28 @@ static GLuint triangles_adj_vao;
 static GLuint triangle_strip_adj_vao;
 
 static GLenum polygon_mode = GL_FILL;
 static GLenum cull_mode = GL_NONE;
 static GLenum provoking_vertex = GL_LAST_VERTEX_CONVENTION;
 
 static GLuint gs_lines_program;
 static GLuint gs_line_strip_program;
 static GLuint gs_triangles_program;
 static GLuint gs_triangle_strip_program;
+static GLuint xfb_buf;
+static GLuint element_buf;
 static GLuint ref_program;
 static GLint colorUniform, modelViewProjUniform;
 
 // if false, draw without GS, also draw the 'extra' lines/tris.  For debugging.
 static bool draw_with_gs = true;
+static bool draw_elements = false;
 
 
 /**
  * Given a primitive type (adjacency type only), and the first/last provoking
  * vertex mode, and a primitive (line, triangle) index, return the index of
  * the vertex which will specify the primitive's flat-shaded color.
  */
 static unsigned
 provoking_vertex_index(GLenum prim_mode, GLenum pv_mode, unsigned prim_index)
 {
@@ -304,42 +307,47 @@ num_gs_prims(GLenum prim_mode, unsigned num_verts)
 static bool
 probe_prims(GLenum prim_mode, const float verts[][2], unsigned num_verts,
            unsigned vp_pos)
 {
        const int vp_w = piglit_width / 4;
        const unsigned num_prims = num_gs_prims(prim_mode, num_verts);
        unsigned prim;
 
        for (prim = 0; prim < num_prims; prim++) {
                bool pass = false;
-               const float *expected_color = NULL;
-               float bad_color[4];
+               float expected_color[4];
+               float bad_color[4] = { -1 };
                bool bad_color_found = false;
                int x, y, i;
 
                compute_probe_location(prim_mode, prim, verts,
                                       vp_pos * vp_w, 0, &x, &y);
 
                if (cull_mode == GL_FRONT &&
                    (prim_mode == GL_TRIANGLES_ADJACENCY ||
                     prim_mode == GL_TRIANGLE_STRIP_ADJACENCY)) {
                        // All triangles should be front facing.
                        // With front culling, all should be discarded.
                        // Region should be black.
                        if (piglit_probe_rect_rgba(x-1, y-1, 3, 3, black)) {
                                pass = true;
                        }
                } else {
                        GLfloat buf[9][4];
                        unsigned pvi = provoking_vertex_index(prim_mode,
                                                     provoking_vertex, prim);
-                       expected_color = colors[pvi];
+                       memcpy(&expected_color, colors[pvi], 
sizeof(expected_color));
+                       if (prim_mode == GL_TRIANGLES_ADJACENCY ||
+                           prim_mode == GL_TRIANGLE_STRIP_ADJACENCY) {
+                               expected_color[2] = pvi * (1.0 / 255);
+                               expected_color[3] = provoking_vertex == 
GL_FIRST_VERTEX_CONVENTION ? 0.0 : 1.0;
+                       }
 
                        // Read a 3x3 region for line probing
                        glReadPixels(x-1, y-1, 3, 3, GL_RGBA, GL_FLOAT, buf);
 
                        // look for non-black pixel
                        for (i = 0; i < 9; i++) {
                                if (buf[i][0] != 0 || buf[i][1] != 0 ||
                                    buf[i][2] != 0 || buf[i][3] != 0) {
                                        // check for expected color
                                        if (colors_match(expected_color, 
buf[i]))
@@ -352,57 +360,100 @@ probe_prims(GLenum prim_mode, const float verts[][2], 
unsigned num_verts,
                                                bad_color[3] = buf[i][3];
                                        }
                                }
                        }
                }
 
                if (!pass) {
                        printf("Failure for %s, "
                               "prim %u wrong color at (%d,%d)\n",
                               piglit_get_prim_name(prim_mode), prim, x, y);
-                       if (expected_color && bad_color_found) {
-                               printf("Expected %.1g, %.1g, %.1g, %.1g\n",
+                       if (bad_color_found) {
+                               printf("Expected %g, %g, %g, %g\n",
                                       expected_color[0],
                                       expected_color[1],
                                       expected_color[2],
                                       expected_color[3]);
-                               printf("Found %.1g, %.1g, %.1g, %.1g\n",
+                               printf("Found %g, %g, %g, %g\n",
                                       bad_color[0],
                                       bad_color[1],
                                       bad_color[2],
                                       bad_color[3]);
                        }
 
                        return false;
                }
        }
 
        return true;
 }
 
+static bool
+probe_xfb(GLenum prim_mode, unsigned num_verts)
+{
+       bool pass = true;
+       const unsigned num_prims = num_gs_prims(prim_mode, num_verts);
+       const float *xfb_data = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 
GL_READ_ONLY);
+
+       for (unsigned prim = 0; prim < num_prims; prim++) {
+               const float *found_color;
+               float expected_color[4];
+               unsigned pvi = provoking_vertex_index(prim_mode,
+                                               provoking_vertex, prim);
+
+               memcpy(&expected_color, colors[pvi], sizeof(expected_color));
+               expected_color[2] = pvi * (1.0 / 255);
+               expected_color[3] = provoking_vertex == 
GL_FIRST_VERTEX_CONVENTION ? 0.0 : 1.0;
+
+               found_color = xfb_data + 4 * (3 * prim + (provoking_vertex == 
GL_FIRST_VERTEX_CONVENTION ? 0 : 2));
+
+               if (!colors_match(expected_color, found_color)) {
+                       printf("Transform Feedback Failure for %s, prim %u 
wrong color\n",
+                              piglit_get_prim_name(prim_mode), prim);
+                       printf("Expected %g, %g, %g, %g\n",
+                              expected_color[0],
+                              expected_color[1],
+                              expected_color[2],
+                              expected_color[3]);
+                       printf("Found %g, %g, %g, %g\n",
+                              found_color[0],
+                              found_color[1],
+                              found_color[2],
+                              found_color[3]);
+
+                       pass = false;
+               }
+       }
+
+       glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+
+       return pass;
+}
 
 
 static GLuint
 make_gs_program(GLenum input_prim)
 {
        static const char *vs_text =
                "#version 150 \n"
                "in vec4 vertex; \n"
                "in vec4 color; \n"
                "uniform mat4 modelViewProj; \n"
                "out vec4 pos;\n"
                "out vec4 vs_gs_color; \n"
+               "out int vs_gs_vertex_id; \n"
                "void main() \n"
                "{ \n"
                "   gl_Position = vertex * modelViewProj; \n"
                "   pos = vertex * modelViewProj; \n"
                "   vs_gs_color = color; \n"
+               "   vs_gs_vertex_id = gl_VertexID; \n"
                "} \n";
        static const char *gs_text_lines =
                "#version 150 \n"
                "layout(lines_adjacency) in;\n"
                "layout(line_strip, max_vertices = 2) out;\n"
                "in vec4 pos[]; \n"
                "in vec4 vs_gs_color[4]; \n"
                "flat out vec4 gs_fs_color; \n"
                "void main() \n"
                "{ \n"
@@ -413,41 +464,49 @@ make_gs_program(GLenum input_prim)
                "   gl_Position = pos[2]; \n"
                "   EmitVertex(); \n"
                "   EndPrimitive(); \n"
                "} \n";
        static const char *gs_text_triangles =
                "#version 150 \n"
                "layout(triangles_adjacency) in;\n"
                "layout(triangle_strip, max_vertices = 3) out;\n"
                "in vec4 pos[]; \n"
                "in vec4 vs_gs_color[6]; \n"
+               "in int vs_gs_vertex_id[6]; \n"
                "flat out vec4 gs_fs_color; \n"
                "void main() \n"
                "{ \n"
                "   gs_fs_color = vs_gs_color[0]; \n"
+               "   gs_fs_color.b = vs_gs_vertex_id[0] * (1. / 255.); \n"
+               "   gs_fs_color.a = 0.0; \n"
                "   gl_Position = pos[0]; \n"
                "   EmitVertex(); \n"
                "   gs_fs_color = vs_gs_color[2]; \n"
+               "   gs_fs_color.b = vs_gs_vertex_id[2] * (1. / 255.); \n"
+               "   gs_fs_color.a = 0.5; \n"
                "   gl_Position = pos[2]; \n"
                "   EmitVertex(); \n"
                "   gs_fs_color = vs_gs_color[4]; \n"
+               "   gs_fs_color.b = vs_gs_vertex_id[4] * (1. / 255.); \n"
+               "   gs_fs_color.a = 1.0; \n"
                "   gl_Position = pos[4]; \n"
                "   EmitVertex(); \n"
                "   //EndPrimitive(); \n"
                "} \n";
        static const char *fs_text =
                "#version 150 \n"
                "flat in vec4 gs_fs_color; \n"
                "void main() \n"
                "{ \n"
                "   gl_FragColor = gs_fs_color; \n"
                "} \n";
+       static const char *gs_xfb_varyings[] = { "gs_fs_color" };
        const char *gs_text;
        GLuint program;
 
        switch (input_prim) {
        case GL_LINES_ADJACENCY:
        case GL_LINE_STRIP_ADJACENCY:
                gs_text = gs_text_lines;
                break;
        case GL_TRIANGLES_ADJACENCY:
        case GL_TRIANGLE_STRIP_ADJACENCY:
@@ -462,20 +521,23 @@ make_gs_program(GLenum input_prim)
                GL_VERTEX_SHADER, vs_text,
                GL_GEOMETRY_SHADER, gs_text,
                GL_FRAGMENT_SHADER, fs_text,
                0);
 
        assert(program);
 
        glBindAttribLocation(program, 0, "vertex");
        glBindAttribLocation(program, 1, "color");
 
+       glTransformFeedbackVaryings(program, 1, &gs_xfb_varyings[0],
+                                   GL_INTERLEAVED_ATTRIBS);
+
        glLinkProgram(program);
 
        return program;
 }
 
 
 static GLuint
 make_ref_program(void)
 {
        static const char *vs_text =
@@ -661,51 +723,96 @@ use_program(GLuint program)
 
 static void
 set_viewport(unsigned pos)
 {
        int vp_w = piglit_width / 4;
        assert(pos < 4);
        glViewport(pos * vp_w, 0, vp_w, piglit_height);
 }
 
 
+static void
+draw_gs_triangles(GLenum prim_mode, GLuint vao, unsigned num_verts,
+                 unsigned vp_pos)
+{
+       size_t buffer_size;
+       void *zeros;
+
+       use_program(gs_triangles_program);
+       set_viewport(vp_pos);
+       glBindVertexArray(vao);
+
+       buffer_size =
+               12 * sizeof(float) *
+               num_gs_prims(prim_mode, num_verts);
+       zeros = calloc(1, buffer_size);
+
+       glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf);
+       glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, buffer_size,
+                       zeros, GL_STREAM_READ);
+
+       free(zeros);
+
+       glBeginTransformFeedback(GL_TRIANGLES);
+
+       if (draw_elements) {
+               GLushort* elements;
+
+               glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buf);
+               glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+                       sizeof(GLushort) * num_verts, NULL,
+                       GL_STATIC_DRAW);
+               elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+               for (unsigned i = 0; i < num_verts; i++) {
+                       elements[i] = i;
+               }
+               glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+               glDrawElements(prim_mode, num_verts, GL_UNSIGNED_SHORT, NULL);
+       } else {
+               glDrawArrays(prim_mode, 0, num_verts);
+       }
+
+       glEndTransformFeedback();
+}
+
 enum piglit_result
 piglit_display(void)
 {
        bool pass = true;
 
        glClear(GL_COLOR_BUFFER_BIT);
 
        if (draw_with_gs) {
                use_program(gs_lines_program);
                set_viewport(0);
                glBindVertexArray(lines_adj_vao);
                glDrawArrays(GL_LINES_ADJACENCY, 0,
                             NUM_VERTS(lines_adj_verts));
 
                use_program(gs_line_strip_program);
                set_viewport(1);
                glBindVertexArray(line_strip_adj_vao);
                glDrawArrays(GL_LINE_STRIP_ADJACENCY, 0,
                             NUM_VERTS(line_strip_adj_verts));
 
-               use_program(gs_triangles_program);
-               set_viewport(2);
-               glBindVertexArray(triangles_adj_vao);
-               glDrawArrays(GL_TRIANGLES_ADJACENCY, 0,
-                            NUM_VERTS(triangles_adj_verts));
+               draw_gs_triangles(GL_TRIANGLES_ADJACENCY, triangles_adj_vao,
+                                 NUM_VERTS(triangles_adj_verts), 2);
 
-               use_program(gs_triangle_strip_program);
-               set_viewport(3);
-               glBindVertexArray(triangle_strip_adj_vao);
-               glDrawArrays(GL_TRIANGLE_STRIP_ADJACENCY, 0,
-                            NUM_VERTS(triangle_strip_adj_verts));
+               pass = probe_xfb(GL_TRIANGLES_ADJACENCY,
+                                NUM_VERTS(triangles_adj_verts)) && pass;
+
+               draw_gs_triangles(GL_TRIANGLE_STRIP_ADJACENCY, 
triangle_strip_adj_vao,
+                                 NUM_VERTS(triangle_strip_adj_verts), 3);
+
+               pass = probe_xfb(GL_TRIANGLE_STRIP_ADJACENCY,
+                                NUM_VERTS(triangle_strip_adj_verts)) && pass;
        }
        else {
                /* This path is basically for debugging and visualizing the
                 * "extra" lines and tris in adjacency primitives.
                 */
                use_program(ref_program);
 
                set_viewport(0);
                draw_lines_adj(lines_adj_vao, 8);
 
@@ -780,32 +887,37 @@ piglit_init(int argc, char **argv)
                else if (strcmp(argv[i], "cull-back") == 0)
                        cull_mode = GL_BACK;
                else if (strcmp(argv[i], "cull-front") == 0)
                        cull_mode = GL_FRONT;
                else if (strcmp(argv[i], "ref") == 0)
                        draw_with_gs = GL_FALSE;
                else if (strcmp(argv[i], "pv-last") == 0)
                        provoking_vertex = GL_LAST_VERTEX_CONVENTION;
                else if (strcmp(argv[i], "pv-first") == 0)
                        provoking_vertex = GL_FIRST_VERTEX_CONVENTION;
+               else if (strcmp(argv[i], "elements") == 0)
+                       draw_elements = true;
                else
                        printf("Unexpected %s argument\n", argv[i]);
        }
 
        glPolygonMode(GL_FRONT_AND_BACK, polygon_mode);
        if (cull_mode != GL_NONE) {
                glCullFace(cull_mode);
                glEnable(GL_CULL_FACE);
                glFrontFace(GL_CW);
        }
        glProvokingVertex(provoking_vertex);
 
+       glGenBuffers(1, &xfb_buf);
+       glGenBuffers(1, &element_buf);
+
        lines_adj_vao = create_vao(lines_adj_verts,
                                   NUM_VERTS(lines_adj_verts));
 
        line_strip_adj_vao = create_vao(line_strip_adj_verts,
                                        NUM_VERTS(line_strip_adj_verts));
 
        triangles_adj_vao = create_vao(triangles_adj_verts,
                                       NUM_VERTS(triangles_adj_verts));
 
        triangle_strip_adj_vao = create_vao(triangle_strip_adj_verts,
-- 
2.15.1

_______________________________________________
Piglit mailing list
Piglit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to