fix the spelling in whole piglit
[piglit.git] / tests / spec / ext_transform_feedback / tessellation.c
blob43af5ef39ed3dc233cea712008af1c0160337e51
1 /*
2 * Copyright © 2011 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 /**
25 * \file tessellation.c
27 * Verify that transform feedback properly converts primitives of
28 * types GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLE_STRIP,
29 * GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, and GL_POLYGON into
30 * primitives of type GL_LINES or GL_TRIANGLES, as appropriate.
32 * According to the OpenGL 3.0 spec (section 2.15: Transform Feedback):
34 * "When quads and polygons are provided to transform feedback
35 * with a primitive mode of TRIANGLES, they will be tessellated
36 * and recorded as triangles (the order of tessellation within a
37 * primitive is undefined). Individual lines or triangles of a
38 * strip or fan primitive will be extracted and recorded
39 * separately."
41 * Although it is not stated explicitly, it is clear from context that
42 * individual lines of a LINE_LOOP primitive are also expected to be
43 * extracted and recorded separately. Also, the spec does not place
44 * any requirement on the order in which vertices are output when
45 * extracting individual lines or triangles of a strip, fan, or
46 * LINE_LOOP primitive.
48 * Because the spec allows variability in how these primitives are
49 * tessellated and extracted, we can't verify correct operation by
50 * examining the vertices themselves. However, we can check that if
51 * the transform feedback output is fed back into the GL pipeline
52 * (using GL_TRIANGLES or GL_LINES, as appropriate), the same image
53 * will be rendered.
55 * This test operates by first rendering an image without transform
56 * feedback, then rendering the same image with transform feedback,
57 * then rendering the transform feedback output. Then it checks that
58 * the 3 generated images match exactly.
60 * In addition, the test verifies that the expected number of vertices
61 * was output by transform feedback.
63 * The images are rendered using a fragment shader that attenuates the
64 * color of back-facing primitives, so that the test will verify that
65 * tessellation preserves winding order properly.
67 * The test can be run in four different coloring modes:
69 * - "monochrome", meaning that all vertices are assigned the same
70 * color. A failure in this mode means that the tessellated image
71 * did not have the correct shape.
73 * - "wireframe", meaning that all vertices are assigned the same
74 * color, but the image is drawn using
75 * glPolygonMode(GL_FRONT_AND_BACK, GL_LINE). This test only makes
76 * sense for shapes that would normally be filled (e.g. polygons).
77 * Since we don't expect a tessellated polygon to have the same
78 * appearance as the original image (since additional edges are
79 * added), in this mode we merely check that the correct number of
80 * vertices are output and that the image renders the same with
81 * transform feedback active as with transform feedback inactive.
83 * - "smooth", meaning that all vertices are assigned different
84 * colors, and the primitives are drawn with smooth interpolation.
85 * A failure in this mode means that the tessellation performed by
86 * transform feedback failed to match the tessellation performed by
87 * the GL pipeline under normal operation.
89 * - "flat_last" or "flat_first", meaning that all vertices are
90 * assigned different colors, and the primitives are flatshaded. In
91 * the "flat_last" case, they are flatshaded using the GL standard
92 * "last vertex" convention to select the provoking vertex. In the
93 * "flat_first" case, they are flatshaded using the alternative
94 * "first vertex" convention provided by GL_EXT_provoking_vertex or
95 * GL_ARB_provoking_vertex. A failure in one of these modes means
96 * that within at least one of the tessellated primitives, transform
97 * feedback failed to output the vertices in the correct order for
98 * proper flatshading.
100 * Note: the test can also be run on primitive types "points",
101 * "lines", and "triangles". Although these primitive types are not
102 * subject to tessellation, the test is still useful for verifying
103 * that correct transform feedback output is generated.
105 * Note: some OpenGL implementations do not pass the "flat_first" and
106 * "flat_last" tests when rendering quads or polygons. That is, they
107 * produce a tessellation which contains the correct vertices, but not
108 * in the order required to preserve flat shaded colors. This is
109 * unlikely to cause problems for client programs, since client
110 * programs that use new features like transform feedback are unlikely
111 * to also use deprecated features like quads and polygons. Also, it
112 * is a matter of interpretation whether these tests are expected to
113 * pass at all--after all, the spec does say that "the order of
114 * tessellation within a primitive is undefined". Accordingly, these
115 * failures, should they occur, are flagged as warnings rather than
116 * failures.
119 #include "piglit-util-gl.h"
121 #define BUFFER_SIZE 20
123 PIGLIT_GL_TEST_CONFIG_BEGIN
125 config.supports_gl_compat_version = 10;
127 config.window_width = 256;
128 config.window_height = 256;
129 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
130 config.khr_no_error_support = PIGLIT_NO_ERRORS;
132 PIGLIT_GL_TEST_CONFIG_END
134 /* Test parameters */
135 static GLenum draw_mode;
136 static GLenum xfb_mode;
137 static unsigned num_input_vertices;
138 static unsigned expected_num_output_vertices;
139 static unsigned expected_num_output_primitives;
140 static float (*vertex_positions)[2];
141 static GLboolean monochrome;
142 static GLboolean use_flat_color;
143 static GLboolean wireframe;
144 static GLboolean is_deprecated_draw_mode;
146 /* Other globals */
147 static GLuint normal_prog;
148 static GLuint xfb_prog;
149 static GLuint xfb_buf;
150 static GLuint xfb_generated_query;
151 static GLuint xfb_written_query;
152 static float vertex_colors[][4] = {
153 { 0.00, 0.00, 0.00, 0.00 },
154 { 1.00, 0.25, 0.25, 1.00 },
155 { 0.15, 0.37, 0.98, 1.00 },
156 { 0.50, 0.93, 0.07, 1.00 },
157 { 0.85, 0.02, 0.63, 1.00 },
158 { 0.0, 0.75, 0.75, 1.00 },
159 { 0.85, 0.63, 0.02, 1.00 },
160 { 0.5, 0.07, 0.93, 1.00 },
161 { 0.15, 0.98, 0.37, 1.00 }
164 static struct vertex_data {
165 float vertex[2];
166 float smooth_color[4];
167 float flat_color[4];
168 } verts[BUFFER_SIZE];
170 /* Note: vertices are chosen to be on pixel centers to minimize the
171 * risk that rounding errors change the image.
173 static float points_vertices[][2] = {
174 { 2.5, 62.5 },
175 { 62.5, 62.5 },
176 { 2.5, 2.5 },
177 { 62.5, 2.5 }
180 /* Note: vertices are chosen to be on pixel centers to minimize the
181 * risk that rounding errors change the image.
183 static float lines_vertices[][2] = {
184 { 2.5, 62.5 },
185 { 62.5, 62.5 },
186 { 2.5, 2.5 },
187 { 62.5, 2.5 }
190 /* Note: vertices are chosen to be on pixel centers to minimize the
191 * risk that rounding errors change the image.
193 static float line_loop_vertices[][2] = {
194 { 2.5, 2.5 },
195 { 2.5, 62.5 },
196 { 62.5, 62.5 },
197 { 62.5, 2.5 }
200 /* Note: vertices are chosen to be on pixel centers to minimize the
201 * risk that rounding errors change the image.
203 static float line_strip_vertices[][2] = {
204 { 2.5, 2.5 },
205 { 2.5, 32.5 },
206 { 32.5, 32.5 },
207 { 32.5, 62.5 }
210 static float triangles_vertices[][2] = {
211 { 2, 2 },
212 { 2, 62 },
213 { 42, 2 },
214 { 62, 2 },
215 { 62, 62 },
216 { 102, 2 }
219 static float triangle_strip_vertices[][2] = {
220 { 2, 2 },
221 { 2, 62 },
222 { 42, 2 },
223 { 42, 62 },
224 { 82, 2 }
227 static float triangle_fan_vertices[][2] = {
228 { 2, 2 },
229 { 2, 62 },
230 { 32, 47 },
231 { 52, 27 },
232 { 57, 12 }
235 static float quads_vertices[][2] = {
236 { 2, 2 },
237 { 2, 62 },
238 { 62, 62 },
239 { 62, 2 },
240 { 102, 2 },
241 { 102, 62 },
242 { 162, 62 },
243 { 162, 2 }
246 static float quad_strip_vertices[][2] = {
247 { 2, 2 },
248 { 2, 62 },
249 { 62, 2 },
250 { 62, 62 },
251 { 122, 2 },
252 { 122, 62 }
255 static float polygon_vertices[][2] = {
256 { 12, 2 },
257 { 2, 42 },
258 { 32, 62 },
259 { 62, 42 },
260 { 52, 2 }
263 static const char *vstext =
264 "#version 130\n"
265 "uniform vec2 vertex_offset;\n"
266 "in vec2 vertex;\n"
267 "in vec4 smooth_color;\n"
268 "in vec4 flat_color;\n"
269 "out vec2 vertex_varying;\n"
270 "out vec4 smooth_color_varying;\n"
271 "flat out vec4 flat_color_varying;\n"
272 "\n"
273 "void main()\n"
274 "{\n"
275 " gl_Position = vec4(vertex + vertex_offset, 0, 128.0);\n"
276 " vertex_varying = vertex;\n"
277 " smooth_color_varying = smooth_color;\n"
278 " flat_color_varying = flat_color;\n"
279 "}\n";
281 static const char *fstext =
282 "#version 130\n"
283 "uniform bool use_flat_color;\n"
284 "in vec4 smooth_color_varying;\n"
285 "flat in vec4 flat_color_varying;\n"
286 "\n"
287 "void main()\n"
288 "{\n"
289 " vec4 color = use_flat_color ? flat_color_varying\n"
290 " : smooth_color_varying;\n"
291 " if (!gl_FrontFacing)\n"
292 " color *= 0.5;\n"
293 " gl_FragColor = color;\n"
294 "}\n";
296 static const char *varyings[] = {
297 "vertex_varying", "smooth_color_varying", "flat_color_varying"
300 static void
301 initialize_shader_and_xfb()
303 GLuint vs, fs;
305 piglit_require_GLSL_version(130);
306 piglit_require_transform_feedback();
307 vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
308 fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fstext);
309 normal_prog = glCreateProgram();
310 glAttachShader(normal_prog, vs);
311 glAttachShader(normal_prog, fs);
312 glLinkProgram(normal_prog);
313 if (!piglit_link_check_status(normal_prog)) {
314 piglit_report_result(PIGLIT_FAIL);
316 xfb_prog = glCreateProgram();
317 glAttachShader(xfb_prog, vs);
318 glAttachShader(xfb_prog, fs);
319 glTransformFeedbackVaryings(xfb_prog, 3, varyings,
320 GL_INTERLEAVED_ATTRIBS);
321 glLinkProgram(xfb_prog);
322 if (!piglit_link_check_status(xfb_prog)) {
323 piglit_report_result(PIGLIT_FAIL);
325 glGenBuffers(1, &xfb_buf);
326 glGenQueries(1, &xfb_generated_query);
327 glGenQueries(1, &xfb_written_query);
328 glFrontFace(GL_CW);
329 if (!piglit_check_gl_error(0))
330 piglit_report_result(PIGLIT_FAIL);
333 static void
334 setup_vertex_shader_inputs(GLuint prog)
336 GLint vertex_index = glGetAttribLocation(prog, "vertex");
337 GLint smooth_color_index = glGetAttribLocation(prog, "smooth_color");
338 GLint flat_color_index = glGetAttribLocation(prog, "flat_color");
340 glVertexAttribPointer(vertex_index, 2, GL_FLOAT, GL_FALSE,
341 sizeof(verts[0]), &verts[0].vertex);
342 glVertexAttribPointer(smooth_color_index, 4, GL_FLOAT, GL_FALSE,
343 sizeof(verts[0]), &verts[0].smooth_color);
344 glVertexAttribPointer(flat_color_index, 4, GL_FLOAT, GL_FALSE,
345 sizeof(verts[0]), &verts[0].flat_color);
346 glEnableVertexAttribArray(vertex_index);
347 glEnableVertexAttribArray(smooth_color_index);
348 glEnableVertexAttribArray(flat_color_index);
349 if (!piglit_check_gl_error(0))
350 piglit_report_result(PIGLIT_FAIL);
353 static void
354 initialize_vertex_shader_inputs()
356 unsigned i;
358 if (monochrome) {
359 for (i = 1; i < ARRAY_SIZE(vertex_colors); ++i) {
360 vertex_colors[i][0] = 1.0;
361 vertex_colors[i][1] = 1.0;
362 vertex_colors[i][2] = 1.0;
363 vertex_colors[i][3] = 1.0;
367 for (i = 0; i < num_input_vertices; ++i) {
368 memcpy(verts[i].vertex, vertex_positions[i],
369 sizeof(verts[i].vertex));
370 memcpy(verts[i].smooth_color, vertex_colors[i+1],
371 sizeof(verts[i].smooth_color));
372 memcpy(verts[i].flat_color, vertex_colors[i+1],
373 sizeof(verts[i].flat_color));
378 * Determine how many vertices were output by transform feedback by
379 * seeing which elements of the transform feedback buffer have been
380 * changed from their zero-initialized value.
382 static unsigned
383 count_output_vertices(struct vertex_data *vertices)
385 struct vertex_data zero_initialized;
386 unsigned i;
388 memset(&zero_initialized, 0, sizeof(zero_initialized));
390 for (i = 0; i < BUFFER_SIZE; ++i) {
391 if (memcmp(&vertices[i], &zero_initialized,
392 sizeof(zero_initialized)) == 0)
393 break;
395 return i;
399 * Check that two strips of the window match. Strips are numbered
400 * from the top from 0 to 3.
402 static GLboolean
403 match_strips(int reference, int compare)
405 GLfloat *reference_image =
406 malloc(piglit_width * (piglit_height / 4) * 4 * sizeof(float));
407 int reference_offset = (3 - reference) * (piglit_height / 4);
408 int compare_offset = (3 - compare) * (piglit_height / 4);
409 GLboolean result;
410 glReadPixels(0, reference_offset, piglit_width, piglit_height / 4,
411 GL_RGBA, GL_FLOAT, reference_image);
412 result = piglit_probe_image_rgba(0, compare_offset, piglit_width,
413 piglit_height / 4, reference_image);
414 free(reference_image);
415 return result;
418 static void
419 draw(GLuint prog, bool use_xfb, float y_offset, GLenum mode,
420 unsigned num_vertices)
422 float vertex_offset[2] = { -82.0, y_offset };
423 struct vertex_data buffer[BUFFER_SIZE];
425 glUseProgram(prog);
426 setup_vertex_shader_inputs(prog);
427 glUniform2fv(glGetUniformLocation(prog, "vertex_offset"),
428 1, vertex_offset);
429 glUniform1i(glGetUniformLocation(prog, "use_flat_color"),
430 use_flat_color);
431 glBindBuffer(GL_ARRAY_BUFFER, 0);
432 if (use_xfb) {
433 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
434 /* Initialize the buffer with 0 so that we will be
435 * able to identify membory that was not overwritten by
436 * the transform feedback.
438 memset(buffer, 0, sizeof(buffer));
439 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(buffer),
440 buffer, GL_STREAM_READ);
441 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf);
442 glBeginTransformFeedback(xfb_mode);
443 glBeginQuery(GL_PRIMITIVES_GENERATED, xfb_generated_query);
444 glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
445 xfb_written_query);
447 glDrawArrays(mode, 0, num_vertices);
448 if (use_xfb) {
449 glEndTransformFeedback();
450 glEndQuery(GL_PRIMITIVES_GENERATED);
451 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
453 if (!piglit_check_gl_error(0))
454 piglit_report_result(PIGLIT_FAIL);
457 static void
458 print_usage_and_exit(char *prog_name)
460 printf("Usage: %s <draw_mode> <shade_mode>\n"
461 " where <draw_mode> is one of:\n"
462 " points\n"
463 " lines\n"
464 " line_loop\n"
465 " line_strip\n"
466 " triangles\n"
467 " triangle_strip\n"
468 " triangle_fan\n"
469 " quads\n"
470 " quad_strip\n"
471 " polygon\n"
472 " and <shade_mode> is one of:\n"
473 " monochrome\n"
474 " smooth\n"
475 " flat_first\n"
476 " flat_last\n", prog_name);
477 exit(1);
480 void
481 piglit_init(int argc, char **argv)
483 /* Interpret command line args */
484 if (argc != 3)
485 print_usage_and_exit(argv[0]);
486 if (strcmp(argv[1], "points") == 0) {
487 draw_mode = GL_POINTS;
488 is_deprecated_draw_mode = GL_FALSE;
489 xfb_mode = GL_POINTS;
490 num_input_vertices = 4;
491 expected_num_output_vertices = 4;
492 expected_num_output_primitives = 4;
493 vertex_positions = points_vertices;
494 } else if (strcmp(argv[1], "lines") == 0) {
495 draw_mode = GL_LINES;
496 is_deprecated_draw_mode = GL_FALSE;
497 xfb_mode = GL_LINES;
498 num_input_vertices = 4;
499 expected_num_output_vertices = 4;
500 expected_num_output_primitives = 2;
501 vertex_positions = lines_vertices;
502 } else if (strcmp(argv[1], "line_loop") == 0) {
503 draw_mode = GL_LINE_LOOP;
504 is_deprecated_draw_mode = GL_FALSE;
505 xfb_mode = GL_LINES;
506 num_input_vertices = 4;
507 expected_num_output_vertices = 8;
508 expected_num_output_primitives = 4;
509 vertex_positions = line_loop_vertices;
510 } else if (strcmp(argv[1], "line_strip") == 0) {
511 draw_mode = GL_LINE_STRIP;
512 is_deprecated_draw_mode = GL_FALSE;
513 xfb_mode = GL_LINES;
514 num_input_vertices = 4;
515 expected_num_output_vertices = 6;
516 expected_num_output_primitives = 3;
517 vertex_positions = line_strip_vertices;
518 } else if (strcmp(argv[1], "triangles") == 0) {
519 draw_mode = GL_TRIANGLES;
520 is_deprecated_draw_mode = GL_FALSE;
521 xfb_mode = GL_TRIANGLES;
522 num_input_vertices = 6;
523 expected_num_output_vertices = 6;
524 expected_num_output_primitives = 2;
525 vertex_positions = triangles_vertices;
526 } else if (strcmp(argv[1], "triangle_strip") == 0) {
527 draw_mode = GL_TRIANGLE_STRIP;
528 is_deprecated_draw_mode = GL_FALSE;
529 xfb_mode = GL_TRIANGLES;
530 num_input_vertices = 5;
531 expected_num_output_vertices = 9;
532 expected_num_output_primitives = 3;
533 vertex_positions = triangle_strip_vertices;
534 } else if (strcmp(argv[1], "triangle_fan") == 0) {
535 draw_mode = GL_TRIANGLE_FAN;
536 is_deprecated_draw_mode = GL_FALSE;
537 xfb_mode = GL_TRIANGLES;
538 num_input_vertices = 5;
539 expected_num_output_vertices = 9;
540 expected_num_output_primitives = 3;
541 vertex_positions = triangle_fan_vertices;
542 } else if (strcmp(argv[1], "quads") == 0) {
543 draw_mode = GL_QUADS;
544 is_deprecated_draw_mode = GL_TRUE;
545 xfb_mode = GL_TRIANGLES;
546 num_input_vertices = 8;
547 expected_num_output_vertices = 12;
548 expected_num_output_primitives = 4;
549 vertex_positions = quads_vertices;
550 } else if (strcmp(argv[1], "quad_strip") == 0) {
551 draw_mode = GL_QUAD_STRIP;
552 is_deprecated_draw_mode = GL_TRUE;
553 xfb_mode = GL_TRIANGLES;
554 num_input_vertices = 6;
555 expected_num_output_vertices = 12;
556 expected_num_output_primitives = 4;
557 vertex_positions = quad_strip_vertices;
558 } else if (strcmp(argv[1], "polygon") == 0) {
559 draw_mode = GL_POLYGON;
560 is_deprecated_draw_mode = GL_TRUE;
561 xfb_mode = GL_TRIANGLES;
562 num_input_vertices = 5;
563 expected_num_output_vertices = 9;
564 expected_num_output_primitives = 3;
565 vertex_positions = polygon_vertices;
566 } else {
567 print_usage_and_exit(argv[0]);
569 if (strcmp(argv[2], "monochrome") == 0) {
570 monochrome = GL_TRUE;
571 use_flat_color = GL_FALSE;
572 wireframe = GL_FALSE;
573 } else if (strcmp(argv[2], "smooth") == 0) {
574 monochrome = GL_FALSE;
575 use_flat_color = GL_FALSE;
576 wireframe = GL_FALSE;
577 } else if (strcmp(argv[2], "flat_last") == 0) {
578 monochrome = GL_FALSE;
579 use_flat_color = GL_TRUE;
580 wireframe = GL_FALSE;
581 } else if (strcmp(argv[2], "flat_first") == 0) {
582 monochrome = GL_FALSE;
583 use_flat_color = GL_TRUE;
584 if (piglit_is_extension_supported("GL_EXT_provoking_vertex")) {
585 glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION);
586 } else if (piglit_is_extension_supported("GL_ARB_provoking_vertex")) {
587 glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
588 } else {
589 printf("Test requires GL_EXT_provoking_vertex "
590 "or GL_ARB_provoking_vertex\n");
591 piglit_report_result(PIGLIT_SKIP);
593 wireframe = GL_FALSE;
594 } else if (strcmp(argv[2], "wireframe") == 0) {
595 monochrome = GL_TRUE;
596 use_flat_color = GL_FALSE;
597 wireframe = GL_TRUE;
598 } else {
599 print_usage_and_exit(argv[0]);
602 initialize_shader_and_xfb();
605 enum piglit_result piglit_display(void)
607 struct vertex_data *readback;
608 unsigned num_output_vertices;
609 GLboolean pass = GL_TRUE;
610 GLboolean warn = GL_FALSE;
611 GLuint num_generated_primitives;
612 GLuint num_written_primitives;
614 initialize_vertex_shader_inputs();
616 glClear(GL_COLOR_BUFFER_BIT);
617 if (wireframe)
618 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
619 draw(normal_prog, false, 64.0, draw_mode, num_input_vertices);
620 draw(xfb_prog, true, 0.0, draw_mode, num_input_vertices);
622 pass = match_strips(0, 1) && pass;
624 readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
625 pass = piglit_check_gl_error(0) && pass;
627 num_output_vertices = count_output_vertices(readback);
628 if (num_output_vertices != expected_num_output_vertices) {
629 printf("Expected %u output vertices, but got %u\n",
630 expected_num_output_vertices, num_output_vertices);
631 pass = GL_FALSE;
633 glGetQueryObjectuiv(xfb_generated_query, GL_QUERY_RESULT,
634 &num_generated_primitives);
635 if (num_generated_primitives != expected_num_output_primitives) {
636 printf("Expected %u primitives generated, but got %u\n",
637 expected_num_output_primitives,
638 num_generated_primitives);
639 pass = GL_FALSE;
641 glGetQueryObjectuiv(xfb_written_query, GL_QUERY_RESULT,
642 &num_written_primitives);
643 if (num_written_primitives != expected_num_output_primitives) {
644 printf("Expected %u primitives written, but got %u\n",
645 expected_num_output_primitives, num_written_primitives);
646 pass = GL_FALSE;
649 memcpy(verts, readback, sizeof(verts));
650 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
652 draw(normal_prog, false, -64.0, xfb_mode, num_output_vertices);
654 if (!wireframe) {
655 if (use_flat_color && is_deprecated_draw_mode)
656 warn = (!match_strips(0, 2)) || warn;
657 else
658 pass = match_strips(0, 2) && pass;
661 piglit_present_results();
663 if (!pass)
664 return PIGLIT_FAIL;
665 else if (warn)
666 return PIGLIT_WARN;
667 else
668 return PIGLIT_PASS;