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
21 * DEALINGS IN THE SOFTWARE.
25 * \file geometry-shaders-basic.c
27 * Verify basic functionality of transform feedback when a geometry
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
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
=
54 "in int vertex_count;\n"
55 "out int vertex_count_to_gs;\n"
59 " vertex_count_to_gs = vertex_count;\n"
62 static const char *gstext
=
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"
71 " for (int i = 0; i < vertex_count_to_gs[0]; i++) {\n"
77 static const char *varyings
[] = { "vertex_id" };
80 piglit_init(int argc
, char **argv
)
82 GLint vertex_data
[1] = { GEOM_OUT_VERTS
};
84 GLuint vs
, gs
, prog
, array_buf
, query_result
, xfb_buf
, generated_query
,
86 GLint vertex_count_loc
;
87 const GLint
*readback
;
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
);
97 if (!piglit_link_check_status(prog
)) {
98 glDeleteProgram(prog
);
99 piglit_report_result(PIGLIT_FAIL
);
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
,
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
));
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
);
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
,
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
,
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
);
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
);
177 /* Should never be reached */