perf/pixel-rate: new pixel throughput microbenchmark
[piglit.git] / tests / spec / ext_transform_feedback / geometry-shaders-basic.c
blob140de9b743f47ffc6cc591d151e552722579f0e5
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 geometry-shaders-basic.c
27 * Verify basic functionality of transform feedback when a geometry
28 * shader is in use.
30 * This test checks that:
32 * - The number of primitives counted by GL_PRIMITIVES_GENERATED and
33 * GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN is based on the number
34 * of geometry shader output vertices (rather than the number of
35 * primitives sent down the pipeline).
37 * - Data output by the geometry shader is properly recorded in the
38 * transform feedback buffer.
41 #include "piglit-util-gl.h"
43 #define GEOM_OUT_VERTS 10
44 #define DRAW_COUNT 10
46 PIGLIT_GL_TEST_CONFIG_BEGIN
47 config.supports_gl_compat_version = 32;
48 config.supports_gl_core_version = 32;
49 config.khr_no_error_support = PIGLIT_NO_ERRORS;
50 PIGLIT_GL_TEST_CONFIG_END
52 static const char *vstext =
53 "#version 150\n"
54 "in int vertex_count;\n"
55 "out int vertex_count_to_gs;\n"
56 "\n"
57 "void main()\n"
58 "{\n"
59 " vertex_count_to_gs = vertex_count;\n"
60 "}\n";
62 static const char *gstext =
63 "#version 150\n"
64 "layout(points) in;\n"
65 "layout(points, max_vertices=10) out;\n"
66 "in int vertex_count_to_gs[1];\n"
67 "out int vertex_id;\n"
68 "\n"
69 "void main()\n"
70 "{\n"
71 " for (int i = 0; i < vertex_count_to_gs[0]; i++) {\n"
72 " vertex_id = i;\n"
73 " EmitVertex();\n"
74 " }\n"
75 "}\n";
77 static const char *varyings[] = { "vertex_id" };
79 void
80 piglit_init(int argc, char **argv)
82 GLint vertex_data[1] = { GEOM_OUT_VERTS };
83 bool pass = true;
84 GLuint vs, gs, prog, array_buf, query_result, xfb_buf, generated_query,
85 written_query, vao;
86 GLint vertex_count_loc;
87 const GLint *readback;
88 int i;
90 vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
91 gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gstext);
92 prog = glCreateProgram();
93 glAttachShader(prog, vs);
94 glAttachShader(prog, gs);
95 glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS);
96 glLinkProgram(prog);
97 if (!piglit_link_check_status(prog)) {
98 glDeleteProgram(prog);
99 piglit_report_result(PIGLIT_FAIL);
101 glUseProgram(prog);
103 /* Setup inputs */
104 glGenVertexArrays(1, &vao);
105 glBindVertexArray(vao);
106 glGenBuffers(1, &array_buf);
107 glBindBuffer(GL_ARRAY_BUFFER, array_buf);
108 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), &vertex_data,
109 GL_STATIC_DRAW);
110 vertex_count_loc = glGetAttribLocation(prog, "vertex_count");
111 glVertexAttribIPointer(vertex_count_loc, 1, GL_INT, sizeof(GLint), 0);
112 glEnableVertexAttribArray(vertex_count_loc);
114 /* Setup transform feedback buffer */
115 glGenBuffers(1, &xfb_buf);
116 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
117 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
118 DRAW_COUNT * GEOM_OUT_VERTS * sizeof(GLint), NULL, GL_STREAM_READ);
119 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 0,
120 DRAW_COUNT * GEOM_OUT_VERTS * sizeof(GLint));
122 /* Setup queries */
123 glGenQueries(1, &generated_query);
124 glGenQueries(1, &written_query);
125 glBeginQuery(GL_PRIMITIVES_GENERATED, generated_query);
126 glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, written_query);
128 /* Do drawing */
129 glBeginTransformFeedback(GL_POINTS);
130 for (i = 0; i < DRAW_COUNT; i++) {
131 glDrawArrays(GL_POINTS, 0, 1);
132 glPauseTransformFeedback();
133 glResumeTransformFeedback();
135 glEndTransformFeedback();
137 /* Check query results */
138 glEndQuery(GL_PRIMITIVES_GENERATED);
139 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
140 glGetQueryObjectuiv(generated_query, GL_QUERY_RESULT, &query_result);
141 if (query_result != DRAW_COUNT * GEOM_OUT_VERTS) {
142 printf("GL_PRIMITIVES_GENERATED query failed."
143 " Expected %d, got %d.\n", GEOM_OUT_VERTS,
144 query_result);
145 pass = false;
147 glGetQueryObjectuiv(written_query, GL_QUERY_RESULT, &query_result);
148 if (query_result != DRAW_COUNT * GEOM_OUT_VERTS) {
149 printf("GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query failed."
150 " Expected %d, got %d.\n", GEOM_OUT_VERTS,
151 query_result);
152 pass = false;
155 /* Check transform feedback data */
156 readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
157 for (i = 0; i < DRAW_COUNT * GEOM_OUT_VERTS; i++) {
158 GLint expected = i % DRAW_COUNT;
159 GLint got = readback[i];
160 if (got != expected) {
161 printf("Incorrect data for vertex %d."
162 " Expected %d, got %d.", i, expected, got);
163 pass = false;
166 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
168 /* Check for errors */
169 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
171 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
174 enum piglit_result
175 piglit_display(void)
177 /* Should never be reached */
178 return PIGLIT_FAIL;