ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_direct_state_access / gettransformfeedback.c
blob879a65ceffa59287a2898ecdb3b643657948294c
1 /*
2 * Copyright © 2015 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 /** @file gettransformfeedback.c
25 * Simple transform feedback test drawing GL_POINTS and checking that all the
26 * state is well reported by the GetTransformFeedback*() functions.
28 * Greatly inspired from ext_transform_feedback/points.c.
30 * From OpenGL 4.5, section 22.4 "Transform Feedback State Queries", page 552:
32 * "void GetTransformFeedbackiv(uint xfb, enum pname, int *param);
33 * void GetTransformFeedbacki v(uint xfb, enum pname, uint index, int *param);
34 * void GetTransformFeedbacki64 v(uint xfb, enum pname,uint index,
35 * int64 *param);
37 * xfb must be zero, indicating the default transform feedback object, or the
38 * name of an existing transform feedback object. pname must be one of the
39 * tokens listed in table 23.48, depending on the command name as shown in the
40 * errors section below. For indexed state, index is the index of the transform
41 * feedback stream. param is the address of a variable to receive the result of
42 * the query.
44 * Errors
45 * An INVALID_OPERATION error is generated by GetTransformFeedback* if xfb is
46 * not zero or the name of an existing transform feedback object.
47 * An INVALID_ENUM error is generated by GetTransformFeedbackiv if pname is not
48 * TRANSFORM_FEEDBACK_PAUSED or TRANSFORM_FEEDBACK_ACTIVE.
49 * An INVALID_ENUM error is generated by GetTransformFeedbacki v if pname is
50 * not TRANSFORM_FEEDBACK_BUFFER_BINDING.
51 * An INVALID_ENUM error is generated by GetTransformFeedbacki64 v if pname is
52 * not TRANSFORM_FEEDBACK_BUFFER_START or TRANSFORM_FEEDBACK_BUFFER_SIZE.
53 * An INVALID_VALUE error is generated by GetTransformFeedbacki v and
54 * GetTransformFeedbacki64 v if index is greater than or equal to the number
55 * of binding points for transform feedback, as described in section 6.7.1."
58 #include "piglit-util-gl.h"
59 #include "dsa-utils.h"
61 PIGLIT_GL_TEST_CONFIG_BEGIN
62 config.supports_gl_core_version = 31;
63 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
64 config.khr_no_error_support = PIGLIT_NO_ERRORS;
65 PIGLIT_GL_TEST_CONFIG_END
68 static GLuint prog;
69 static GLuint xfb_buf[3], input_buf, vao;
70 static bool pass = true;
72 static const char *vstext = {
73 "#version 140\n"
74 "in float valIn;"
75 "out float valOut1;"
76 "out float valOut2;"
77 "void main() {"
78 " valOut1 = valIn + 1;"
79 " valOut2 = valIn * 2;"
80 "}"
83 #define NUM_INPUTS 4
84 static const GLfloat inputs[NUM_INPUTS] = {-1.0, 0.0, 1.0, 3.0};
86 struct context_t {
87 struct tbo_state_t {
88 GLuint binding;
89 GLint64 start;
90 GLint64 size;
91 } bo_state[3];
92 bool active;
93 bool paused;
94 } ctx;
96 void
97 check_active_paused_state(const char *test_name)
99 GLint param;
101 glGetTransformFeedbackiv(0, GL_TRANSFORM_FEEDBACK_PAUSED, &param);
102 piglit_check_gl_error(GL_NO_ERROR);
103 PIGLIT_SUBTEST_CONDITION(param == ctx.paused, pass, "%s: paused state "
104 "valid", test_name);
106 glGetTransformFeedbackiv(0, GL_TRANSFORM_FEEDBACK_ACTIVE, &param);
107 piglit_check_gl_error(GL_NO_ERROR);
108 PIGLIT_SUBTEST_CONDITION(param == ctx.active, pass, "%s: active state "
109 "valid", test_name);
112 void
113 check_binding_state(const char *test_name)
115 GLint64 param64;
116 GLint param;
117 int i;
119 for (i = 0; i < 3; i++) {
120 glGetTransformFeedbacki_v(0,
121 GL_TRANSFORM_FEEDBACK_BUFFER_BINDING,
122 i, &param);
123 piglit_check_gl_error(GL_NO_ERROR);
124 PIGLIT_SUBTEST_CONDITION(param == ctx.bo_state[i].binding, pass,
125 "%s: bound buffer %i valid", test_name, i);
127 glGetTransformFeedbacki64_v(0,
128 GL_TRANSFORM_FEEDBACK_BUFFER_START,
129 i, &param64);
130 piglit_check_gl_error(GL_NO_ERROR);
131 PIGLIT_SUBTEST_CONDITION(param64 == ctx.bo_state[i].start, pass,
132 "%s: bound buffer %i start valid", test_name,
135 glGetTransformFeedbacki64_v(0,
136 GL_TRANSFORM_FEEDBACK_BUFFER_SIZE,
137 i, &param64);
138 piglit_check_gl_error(GL_NO_ERROR);
139 PIGLIT_SUBTEST_CONDITION(param64 == ctx.bo_state[i].size, pass,
140 "%s: bound buffer %i size valid", test_name,
145 void
146 check_invalid_queries()
148 GLint64 param64;
149 GLint param;
151 if (piglit_khr_no_error)
152 return;
154 glGetTransformFeedbackiv(0, GL_TRANSFORM_FEEDBACK_BINDING, &param);
155 PIGLIT_SUBTEST_ERROR(GL_INVALID_ENUM, pass,
156 "glGetTransformFeedbackiv: fetch invalid attribute");
158 glGetTransformFeedbacki_v(0, GL_TRANSFORM_FEEDBACK_ACTIVE, 0, &param);
159 PIGLIT_SUBTEST_ERROR(GL_INVALID_ENUM, pass,
160 "glGetTransformFeedbacki_v: fetch invalid attribute");
162 glGetTransformFeedbacki64_v(0, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING,
163 0, &param64);
164 PIGLIT_SUBTEST_ERROR(GL_INVALID_ENUM, pass,
165 "glGetTransformFeedbacki64_v: fetch invalid attribute");
168 void
169 piglit_init(int argc, char **argv)
171 static const char *varyings[] = { "valOut1", "valOut2" };
172 GLuint size, start;
173 GLint inAttrib;
174 int i;
176 /* Check the driver. */
177 piglit_require_extension("GL_ARB_transform_feedback3");
178 piglit_require_extension("GL_ARB_direct_state_access");
180 /* Create shaders. */
181 prog = piglit_build_simple_program_unlinked(vstext, NULL);
182 glTransformFeedbackVaryings(prog, 2, varyings,
183 GL_SEPARATE_ATTRIBS);
184 glLinkProgram(prog);
185 if (!piglit_link_check_status(prog)) {
186 glDeleteProgram(prog);
187 piglit_report_result(PIGLIT_FAIL);
189 glUseProgram(prog);
191 /* Set up the Vertex Array Buffer */
192 glEnable(GL_VERTEX_ARRAY);
193 glGenVertexArrays(1, &vao);
194 glBindVertexArray(vao);
196 /* Set up the input data buffer */
197 glGenBuffers(1, &input_buf);
198 glBindBuffer(GL_ARRAY_BUFFER, input_buf);
199 glBufferData(GL_ARRAY_BUFFER, sizeof(inputs), inputs, GL_STATIC_DRAW);
200 inAttrib = glGetAttribLocation(prog, "valIn");
201 piglit_check_gl_error(GL_NO_ERROR);
202 glVertexAttribPointer(inAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0);
203 glEnableVertexAttribArray(inAttrib);
205 /* set the initial state */
206 ctx.active = false;
207 ctx.paused = false;
208 for (i = 0; i < 3; i++) {
209 ctx.bo_state[i].binding = 0;
210 ctx.bo_state[i].start = 0;
211 ctx.bo_state[i].size = 0;
213 check_active_paused_state("initial state");
214 check_binding_state("initial state");
216 /* Set up the transform feedback buffer */
217 glGenBuffers(3, xfb_buf);
218 for (i = 0; i < 2; i++) {
219 start = rand() & 0xFC;
220 size = 0x100 + (rand() & 0xFFC);
222 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[i]);
223 piglit_check_gl_error(GL_NO_ERROR);
224 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
225 start + size, NULL, GL_STREAM_READ);
226 piglit_check_gl_error(GL_NO_ERROR);
227 glTransformFeedbackBufferRange(0, i, xfb_buf[i], start, size);
228 piglit_check_gl_error(GL_NO_ERROR);
230 ctx.bo_state[i].binding = xfb_buf[i];
231 ctx.bo_state[i].start = start;
232 ctx.bo_state[i].size = size;
235 check_binding_state("post-binding state");
238 enum piglit_result
239 piglit_display(void)
241 check_invalid_queries();
243 glClear(GL_COLOR_BUFFER_BIT);
245 glBeginTransformFeedback(GL_POINTS);
247 ctx.active = true;
248 check_active_paused_state("TransformFeedback started");
250 glPauseTransformFeedback();
252 ctx.paused = true;
253 check_active_paused_state("TransformFeedback paused");
255 glResumeTransformFeedback();
257 ctx.paused = false;
258 check_active_paused_state("TransformFeedback resumed");
260 glEndTransformFeedback();
262 ctx.active = false;
263 check_active_paused_state("TransformFeedback ended");
265 /* clean-up everything */
266 glDeleteBuffers(3, xfb_buf);
267 glDeleteBuffers(1, &input_buf);
268 glDeleteVertexArrays(1, &vao);
269 glDeleteProgram(prog);
271 return pass ? PIGLIT_PASS : PIGLIT_FAIL;