2 * Copyright (C) 2016 Ilia Mirkin
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
21 * DEALINGS IN THE SOFTWARE.
24 #include "piglit-util-gl.h"
26 PIGLIT_GL_TEST_CONFIG_BEGIN
28 config
.supports_gl_core_version
= 31;
29 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
30 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
32 PIGLIT_GL_TEST_CONFIG_END
34 static const char *vs_tf
=
37 "uniform int tf_val;\n"
38 "void main() { gl_Position = vec4(0); tf = tf_val; }\n";
40 static const char *vs_draw
=
43 "in vec4 piglit_vertex, in_color;\n"
44 "void main() { gl_Position = piglit_vertex; color = in_color; }\n";
46 static const char *fs_draw
=
50 "void main() { c = color; }\n";
52 static GLint tf_prog
, draw_prog
;
54 static GLuint tf_vao
, draw_vao
;
57 piglit_init(int argc
, char **argv
)
59 static const char *varying
= "tf";
60 static const unsigned cmds
[] = {
66 float vertex_array
[12 * 2];
105 piglit_require_extension("GL_ARB_indirect_parameters");
107 tf_prog
= piglit_build_simple_program_unlinked(vs_tf
, NULL
);
108 draw_prog
= piglit_build_simple_program(vs_draw
, fs_draw
);
110 glTransformFeedbackVaryings(tf_prog
, 1, &varying
,
111 GL_INTERLEAVED_ATTRIBS
);
112 glLinkProgram(tf_prog
);
113 if (!piglit_link_check_status(tf_prog
))
114 piglit_report_result(PIGLIT_FAIL
);
115 tf_val
= glGetUniformLocation(tf_prog
, "tf_val");
117 glGenVertexArrays(1, &tf_vao
);
119 glGenVertexArrays(1, &draw_vao
);
120 glBindVertexArray(draw_vao
);
122 glGenBuffers(1, &vbo
);
123 glBindBuffer(GL_ARRAY_BUFFER
, vbo
);
124 glBufferData(GL_ARRAY_BUFFER
, sizeof(geometry
), &geometry
, GL_STATIC_DRAW
);
126 glVertexAttribPointer(0, 2, GL_FLOAT
, GL_FALSE
,
127 2 * sizeof(GLfloat
), NULL
);
129 glVertexAttribPointer(1, 4, GL_FLOAT
, GL_FALSE
,
130 4 * sizeof(GLfloat
), (void *)(12 * 2 * 4));
131 glEnableVertexAttribArray(0);
132 glEnableVertexAttribArray(1);
134 glGenBuffers(1, &dbo
);
135 glBindBuffer(GL_DRAW_INDIRECT_BUFFER
, dbo
);
136 glBufferData(GL_DRAW_INDIRECT_BUFFER
, sizeof(cmds
), cmds
, GL_STATIC_DRAW
);
146 static const float g
[] = {0, 1, 0, 1};
147 static const float gb
[] = {0, 1, 1, 1};
149 glClearColor(0.2, 0.2, 0.2, 0.2);
150 glClear(GL_COLOR_BUFFER_BIT
);
152 glGenBuffers(1, &xfb_buf
);
153 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
, xfb_buf
);
154 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER
, 8, NULL
, GL_STATIC_READ
);
156 glEnable(GL_RASTERIZER_DISCARD
);
157 glBindVertexArray(tf_vao
);
158 glUseProgram(tf_prog
);
160 /* write a 2 into xfb_buf[0] */
161 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER
, 0, xfb_buf
, 0, 4);
162 glUniform1i(tf_val
, 2);
163 glBeginTransformFeedback(GL_POINTS
);
164 glDrawArrays(GL_POINTS
, 0, 1);
165 glEndTransformFeedback();
167 /* write a 0 into xfb_buf[1] */
168 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER
, 0, xfb_buf
, 4, 4);
169 glUniform1i(tf_val
, 0);
170 glBeginTransformFeedback(GL_POINTS
);
171 glDrawArrays(GL_POINTS
, 0, 1);
172 glEndTransformFeedback();
174 glDisable(GL_RASTERIZER_DISCARD
);
175 glBindVertexArray(draw_vao
);
176 glUseProgram(draw_prog
);
178 /* Draw the g/gb halves */
179 glBindBuffer(GL_PARAMETER_BUFFER_ARB
, xfb_buf
);
180 glMultiDrawArraysIndirectCountARB(
184 pass
&= piglit_probe_rect_rgba(0, 0, piglit_width
/ 2, piglit_height
,
186 pass
&= piglit_probe_rect_rgba(piglit_width
/ 2, 0,
187 piglit_width
/ 2, piglit_height
,
190 printf("first draw failed\n");
194 /* Overdraw with the red quad, except count = 0 */
195 glMultiDrawArraysIndirectCountARB(
197 (const void *) (2 * 4 * 4), 4, 1, 0);
199 pass
&= piglit_probe_rect_rgba(0, 0, piglit_width
/ 2, piglit_height
,
201 pass
&= piglit_probe_rect_rgba(piglit_width
/ 2, 0,
202 piglit_width
/ 2, piglit_height
,
205 printf("second draw did something when it shouldn't have.\n");
208 piglit_present_results();
209 map
= glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
, GL_READ_ONLY
);
211 printf("map[0] != 2\n");
215 printf("map[1] != 0\n");
218 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
);
219 glDeleteBuffers(1, &xfb_buf
);
220 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;