perf/pixel-rate: new pixel throughput microbenchmark
[piglit.git] / tests / spec / arb_indirect_parameters / tf-count-arrays.c
blob037d2e931b8c520651a1b20bd3fc4683882790fc
1 /*
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
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 #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 =
35 "#version 140\n"
36 "out int tf;\n"
37 "uniform int tf_val;\n"
38 "void main() { gl_Position = vec4(0); tf = tf_val; }\n";
40 static const char *vs_draw =
41 "#version 140\n"
42 "out vec4 color;\n"
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 =
47 "#version 140\n"
48 "out vec4 c;\n"
49 "in vec4 color;\n"
50 "void main() { c = color; }\n";
52 static GLint tf_prog, draw_prog;
53 static GLint tf_val;
54 static GLuint tf_vao, draw_vao;
56 void
57 piglit_init(int argc, char **argv)
59 static const char *varying = "tf";
60 static const unsigned cmds[] = {
61 4, 1, 0, 0,
62 4, 1, 4, 0,
63 4, 1, 8, 0,
65 static const struct {
66 float vertex_array[12 * 2];
67 float colors[12 * 4];
68 } geometry = {
70 -1, -1,
71 0, -1,
72 0, 1,
73 -1, 1,
75 0, -1,
76 1, -1,
77 1, 1,
78 0, 1,
80 -1, -1,
81 1, -1,
82 1, 1,
83 -1, 1,
86 0, 1, 0, 1,
87 0, 1, 0, 1,
88 0, 1, 0, 1,
89 0, 1, 0, 1,
91 0, 1, 1, 1,
92 0, 1, 1, 1,
93 0, 1, 1, 1,
94 0, 1, 1, 1,
96 1, 0, 0, 0,
97 1, 0, 0, 0,
98 1, 0, 0, 0,
99 1, 0, 0, 0,
103 GLuint vbo, dbo;
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);
139 enum piglit_result
140 piglit_display(void)
142 GLuint xfb_buf;
143 bool pass = true;
144 unsigned *map;
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(
181 GL_TRIANGLE_FAN,
182 0, 0, 2, 0);
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,
188 gb);
189 if (!pass) {
190 printf("first draw failed\n");
191 goto end;
194 /* Overdraw with the red quad, except count = 0 */
195 glMultiDrawArraysIndirectCountARB(
196 GL_TRIANGLE_FAN,
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,
203 gb);
204 if (!pass)
205 printf("second draw did something when it shouldn't have.\n");
207 end:
208 piglit_present_results();
209 map = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
210 if (map[0] != 2) {
211 printf("map[0] != 2\n");
212 pass = false;
214 if (map[1] != 0) {
215 printf("map[1] != 0\n");
216 pass = false;
218 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
219 glDeleteBuffers(1, &xfb_buf);
220 return pass ? PIGLIT_PASS : PIGLIT_FAIL;