framework/replay: disable AA accounting when comparing with no tolerance
[piglit.git] / tests / spec / gl-3.1 / primitive-restart-xfb.c
blobe700142cbdae82a8d8fa9d7a5744206f43039803
1 /*
2 * Copyright © 2013 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 primitive-restart-xfb.c
27 * Test interactions between primitive restart and transform feedback
28 * primitive counting behaviour.
30 * This test makes a single glDrawElements(GL_TRIANGLE_STRIP, 9, ...)
31 * draw call, where the index buffer specifies 4 normal vertices, the
32 * primitive restart index, and then 4 more normal vertices. It
33 * verifies that the implementation correctly counts this as drawing 4
34 * triangles (rather than 7, which would be the behaviour of if
35 * primitive restart were not in use).
37 * The test can be run in three ways (selectable by a command line
38 * argument):
40 * - "generated" verifies that the GL_PRIMITIVES_GENERATED query
41 * counts the primitives correctly.
43 * - "written" verifies that the
44 * GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query counts the
45 * primitives correctly.
47 * - "flush" verifies that if these 4 triangles are followed by a
48 * glFlush() and then more primitives further drawing, transform
49 * feedback for the latter primitives is placed at the correct
50 * location in the transform feedback buffer.
53 #include "piglit-util-gl.h"
55 PIGLIT_GL_TEST_CONFIG_BEGIN
56 config.supports_gl_core_version = 31;
57 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
58 config.khr_no_error_support = PIGLIT_NO_ERRORS;
59 PIGLIT_GL_TEST_CONFIG_END
62 enum test_mode_enum {
63 TEST_MODE_GENERATED,
64 TEST_MODE_WRITTEN,
65 TEST_MODE_FLUSH,
69 static const char vs_text[] =
70 "#version 130\n"
71 "in int x_in;\n"
72 "flat out int x_out;\n"
73 "void main()\n"
74 "{\n"
75 " gl_Position = vec4(0.0);\n"
76 " x_out = x_in;\n"
77 "}\n";
80 static const GLchar *varyings[] = { "x_out" };
83 /**
84 * Indices used for the test.
86 static const GLubyte indices[] = {
87 /* For the main draw call */
88 0, 1, 2, 3, 0xff, 4, 5, 6, 7,
90 /* After the glFlush() call (when in TEST_MODE_FLUSH) */
91 8, 9, 10, 11
95 static const GLint vertex_attrs[] = { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 };
98 /**
99 * Expected transform feedback result when in TEST_MODE_FLUSH:
100 * - 2 triangles with attribute 1 and 2 triangles with attribute value 2 (from
101 * the first draw call)
102 * - 2 triangles with attribute 3 (from the second draw call, after the flush)
104 static const GLint expected_xfb_result[] =
105 { 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3 };
108 static void
109 print_usage_and_exit(const char *prog_name)
111 printf("Usage: %s <subtest>\n"
112 " where <subtest> is one of the following:\n"
113 " generated\n"
114 " written\n"
115 " flush\n", prog_name);
116 piglit_report_result(PIGLIT_FAIL);
120 static bool
121 check_query_result(GLuint query, GLuint expected)
123 GLuint result;
125 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
126 if (result != expected) {
127 printf("Query result: %u, expected: %u\n", result, expected);
128 return false;
130 return true;
134 static bool
135 check_xfb_result()
137 bool pass = true;
138 int i;
139 const GLint *readback =
140 glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
141 sizeof(expected_xfb_result), GL_MAP_READ_BIT);
142 for (i = 0; i < ARRAY_SIZE(expected_xfb_result); i++) {
143 if (readback[i] != expected_xfb_result[i]) {
144 printf("XFB[%i] == %i, expected %i\n", i, readback[i],
145 expected_xfb_result[i]);
146 pass = false;
149 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
150 return pass;
154 void
155 piglit_init(int argc, char **argv)
157 GLuint buf;
158 void *initial_data;
159 bool pass = true;
160 enum test_mode_enum test_mode;
161 GLuint prog;
162 GLuint vao, vbo_attrs, vbo_indices;
163 GLuint query;
165 if (argc != 2)
166 print_usage_and_exit(argv[0]);
167 if (strcmp(argv[1], "generated") == 0)
168 test_mode = TEST_MODE_GENERATED;
169 else if (strcmp(argv[1], "written") == 0)
170 test_mode = TEST_MODE_WRITTEN;
171 else if (strcmp(argv[1], "flush") == 0)
172 test_mode = TEST_MODE_FLUSH;
173 else
174 print_usage_and_exit(argv[0]);
176 prog = piglit_build_simple_program_unlinked(vs_text, NULL);
177 glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS);
178 glBindAttribLocation(prog, 0, "x_in");
179 glLinkProgram(prog);
180 if (!piglit_link_check_status(prog) ||
181 !piglit_check_gl_error(GL_NO_ERROR)) {
182 piglit_report_result(PIGLIT_FAIL);
184 glUseProgram(prog);
186 /* Create transform feedback buffer and pre-load it with
187 * garbage.
189 glGenBuffers(1, &buf);
190 initial_data = malloc(sizeof(expected_xfb_result));
191 memset(initial_data, 0xcc, sizeof(expected_xfb_result));
192 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
193 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_xfb_result),
194 initial_data, GL_STREAM_READ);
195 free(initial_data);
197 /* Set up VAO/VBO */
198 glGenVertexArrays(1, &vao);
199 glBindVertexArray(vao);
200 glGenBuffers(1, &vbo_attrs);
201 glBindBuffer(GL_ARRAY_BUFFER, vbo_attrs);
202 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_attrs), vertex_attrs,
203 GL_STREAM_DRAW);
204 glVertexAttribIPointer(0, 1, GL_INT, 0, NULL);
205 glEnableVertexAttribArray(0);
206 glGenBuffers(1, &vbo_indices);
207 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
208 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,
209 GL_STREAM_DRAW);
211 /* Misc setup */
212 glEnable(GL_RASTERIZER_DISCARD);
213 glEnable(GL_PRIMITIVE_RESTART);
214 glPrimitiveRestartIndex(0xff);
215 glGenQueries(1, &query);
217 switch (test_mode) {
218 case TEST_MODE_GENERATED:
219 glBeginQuery(GL_PRIMITIVES_GENERATED, query);
220 glBeginTransformFeedback(GL_TRIANGLES);
221 glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL);
222 glEndTransformFeedback();
223 glEndQuery(GL_PRIMITIVES_GENERATED);
224 pass = check_query_result(query, 4);
225 break;
226 case TEST_MODE_WRITTEN:
227 glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
228 glBeginTransformFeedback(GL_TRIANGLES);
229 glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL);
230 glEndTransformFeedback();
231 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
232 pass = check_query_result(query, 4);
233 break;
234 case TEST_MODE_FLUSH:
235 glBeginTransformFeedback(GL_TRIANGLES);
236 glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL);
237 glFlush();
238 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE,
239 (void *) (9 * sizeof(GLubyte)));
240 glEndTransformFeedback();
241 pass = check_xfb_result();
242 break;
245 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
246 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
250 enum piglit_result
251 piglit_display(void)
253 /* Should never be reached */
254 return PIGLIT_FAIL;