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
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 DEALINGS
25 * \file change-objects-while-paused.c
26 * Verify behavior of changing XFB objects while XFB is paused.
28 * The test methodology is:
30 * - Bind an XFB object, start XFB, draw something, pause XFB.
32 * - Bind a different XFB object, start XFB, draw something, pause XFB.
34 * - Rebind the first XFB object, resume XFB, draw something, end XFB.
36 * - Rebind the second XFB object, resume XFB, draw something, end XFB.
38 * - Verify that all the expected data has landed in the expected places.
41 #include "piglit-util-gl.h"
43 PIGLIT_GL_TEST_CONFIG_BEGIN
45 #ifdef PIGLIT_USE_OPENGL
46 config
.supports_gl_compat_version
= 10;
47 #elif defined PIGLIT_USE_OPENGL_ES3
48 config
.supports_gl_es_version
= 30;
50 #error "Cannot build this."
52 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
;
53 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
55 PIGLIT_GL_TEST_CONFIG_END
63 static const float data
[] = {
78 static const char vstext
[] =
79 #if defined PIGLIT_USE_OPENGL_ES3
84 "in vec4 piglit_vertex;\n"
89 " gl_Position = piglit_vertex;\n"
90 " x = piglit_vertex.x;\n"
94 static const char fstext
[] =
95 #if defined PIGLIT_USE_OPENGL_ES3
100 "out highp vec4 color;\n"
101 "void main() { color = vec4(0); }\n"
105 check_results(unsigned test
, unsigned expect_written
, const float *expect_data
,
106 GLuint q0
, GLuint q1
)
113 glGetQueryObjectuiv(q0
, GL_QUERY_RESULT
, &written
[0]);
114 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
116 glGetQueryObjectuiv(q0
, GL_QUERY_RESULT
, &written
[1]);
117 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
119 total
= written
[0] + written
[1];
120 if (total
!= expect_written
) {
122 "XFB %d GL_PRIMITIVES_WRITTEN: "
123 "Expected %d, got %d\n",
124 test
, expect_written
, total
);
128 data
= glMapBufferRange(GL_ARRAY_BUFFER
, 0, 512, GL_MAP_READ_BIT
);
129 if (!piglit_check_gl_error(GL_NO_ERROR
) || data
== NULL
) {
130 fprintf(stderr
, "XFB %d: Could not map results buffer.\n",
136 for (i
= 0; i
< expect_written
; i
++) {
137 if (data
[i
] != expect_data
[i
]) {
140 "Expected %f, got %f\n",
141 test
, i
, expect_data
[i
], data
[i
]);
146 glUnmapBuffer(GL_ARRAY_BUFFER
);
152 void piglit_init(int argc
, char **argv
)
154 static const char *varyings
[] = {"x"};
162 #ifdef PIGLIT_USE_OPENGL
163 piglit_require_transform_feedback();
164 piglit_require_GLSL_version(130);
165 piglit_require_extension("GL_ARB_vertex_array_object");
166 piglit_require_extension("GL_ARB_transform_feedback2");
169 /* This is all just the boot-strap work for the test.
171 glGenTransformFeedbacks(ARRAY_SIZE(xfb
), xfb
);
172 glGenBuffers(ARRAY_SIZE(buffers
), buffers
);
174 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
, buffers
[0]);
175 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER
, 1024, NULL
, GL_STREAM_READ
);
177 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
, buffers
[1]);
178 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER
, 1024, NULL
, GL_STREAM_READ
);
180 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
, 0);
182 glGenVertexArrays(1, &vao
);
183 glBindVertexArray(vao
);
184 glBindBuffer(GL_ARRAY_BUFFER
, buffers
[2]);
185 glBufferData(GL_ARRAY_BUFFER
, sizeof(data
), data
, GL_STATIC_DRAW
);
186 glVertexAttribPointer(0, 1, GL_FLOAT
, GL_FALSE
, 1 * sizeof(GLfloat
), 0);
187 glEnableVertexAttribArray(0);
189 glGenQueries(ARRAY_SIZE(queries
), queries
);
191 prog
= piglit_build_simple_program_unlinked(vstext
, fstext
);
193 glTransformFeedbackVaryings(prog
, 1, varyings
, GL_INTERLEAVED_ATTRIBS
);
195 if (!piglit_link_check_status(prog
)) {
201 glEnable(GL_RASTERIZER_DISCARD
);
203 /* Here's the actual test.
205 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK
, xfb
[0]);
206 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER
, 0, buffers
[0]);
207 glBeginTransformFeedback(GL_POINTS
);
209 glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
, queries
[0]);
210 glDrawArrays(GL_POINTS
, 0, 4);
211 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
);
213 glPauseTransformFeedback();
215 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
217 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK
, xfb
[1]);
218 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER
, 0, buffers
[1]);
219 glBeginTransformFeedback(GL_POINTS
);
221 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
223 glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
, queries
[1]);
224 glDrawArrays(GL_POINTS
, 4, 2);
225 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
);
227 glPauseTransformFeedback();
229 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
231 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK
, xfb
[0]);
232 glResumeTransformFeedback();
234 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
236 glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
, queries
[2]);
237 glDrawArrays(GL_POINTS
, 6, 4);
238 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
);
240 glEndTransformFeedback();
242 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
244 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK
, xfb
[1]);
245 glResumeTransformFeedback();
247 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
249 glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
, queries
[3]);
250 glDrawArrays(GL_POINTS
, 10, 2);
251 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
);
253 glEndTransformFeedback();
255 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
257 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK
, 0);
258 glBindVertexArray(0);
260 /* The first XFB should have 8 primitives generated, and the buffer
261 * object should contain the values {1.0, 2.0, 3.0, 4.0, 7.0, 8.0,
265 static const float expected_xfb_data
[] = {
266 1.0, 2.0, 3.0, 4.0, 7.0, 8.0, 9.0, 10.0
269 glBindBuffer(GL_ARRAY_BUFFER
, buffers
[0]);
270 pass
= check_results(1, ARRAY_SIZE(expected_xfb_data
),
272 queries
[0], queries
[2])
276 /* The second XFB should have 4 primitives generated, and the buffer
277 * object should contain the values {5.0, 6.0, 11.0, 12.0}.
280 static const float expected_xfb_data
[] = {
284 glBindBuffer(GL_ARRAY_BUFFER
, buffers
[1]);
285 pass
= check_results(2, ARRAY_SIZE(expected_xfb_data
),
287 queries
[1], queries
[3])
291 glBindBuffer(GL_ARRAY_BUFFER
, 0);
294 glBindVertexArray(0);
295 glDeleteVertexArrays(1, &vao
);
296 glDeleteBuffers(ARRAY_SIZE(buffers
), buffers
);
297 glDeleteQueries(ARRAY_SIZE(queries
), queries
);
298 glDeleteTransformFeedbacks(ARRAY_SIZE(xfb
), xfb
);
301 glDeleteProgram(prog
);
303 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);