1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Rbo state query tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fShaderStateQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es3fApiCase.hpp"
27 #include "gluRenderContext.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "deRandom.hpp"
31 #include "deMath.h"
32 #include "deString.h"
33
34 using namespace glw; // GLint and other GL types
35 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
36
37 namespace deqp
38 {
39 namespace gles3
40 {
41 namespace Functional
42 {
43 namespace
44 {
45
46 static const char *commonTestVertSource = "#version 300 es\n"
47 "void main (void)\n"
48 "{\n"
49 " gl_Position = vec4(0.0);\n"
50 "}\n\0";
51 static const char *commonTestFragSource = "#version 300 es\n"
52 "layout(location = 0) out mediump vec4 fragColor;\n"
53 "void main (void)\n"
54 "{\n"
55 " fragColor = vec4(0.0);\n"
56 "}\n\0";
57
58 static const char *brokenShader = "#version 300 es\n"
59 "broken, this should not compile!\n"
60 "\n\0";
61
62 // rounds x.1 to x+1
63 template <typename T>
roundGLfloatToNearestIntegerUp(GLfloat val)64 T roundGLfloatToNearestIntegerUp(GLfloat val)
65 {
66 return (T)(ceil(val));
67 }
68
69 // rounds x.9 to x
70 template <typename T>
roundGLfloatToNearestIntegerDown(GLfloat val)71 T roundGLfloatToNearestIntegerDown(GLfloat val)
72 {
73 return (T)(floor(val));
74 }
75
checkIntEquals(tcu::TestContext & testCtx,GLint got,GLint expected)76 bool checkIntEquals(tcu::TestContext &testCtx, GLint got, GLint expected)
77 {
78 using tcu::TestLog;
79
80 if (got != expected)
81 {
82 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got
83 << TestLog::EndMessage;
84 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
85 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
86 return false;
87 }
88 return true;
89 }
90
checkPointerEquals(tcu::TestContext & testCtx,const void * got,const void * expected)91 void checkPointerEquals(tcu::TestContext &testCtx, const void *got, const void *expected)
92 {
93 using tcu::TestLog;
94
95 if (got != expected)
96 {
97 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got
98 << TestLog::EndMessage;
99 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
100 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
101 }
102 }
103
verifyShaderParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint shader,GLenum pname,GLenum reference)104 void verifyShaderParam(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint shader, GLenum pname,
105 GLenum reference)
106 {
107 StateQueryMemoryWriteGuard<GLint> state;
108 gl.glGetShaderiv(shader, pname, &state);
109
110 if (state.verifyValidity(testCtx))
111 checkIntEquals(testCtx, state, reference);
112 }
113
verifyProgramParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLenum pname,GLenum reference)114 bool verifyProgramParam(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLenum pname,
115 GLenum reference)
116 {
117 StateQueryMemoryWriteGuard<GLint> state;
118 gl.glGetProgramiv(program, pname, &state);
119
120 return state.verifyValidity(testCtx) && checkIntEquals(testCtx, state, reference);
121 }
122
verifyActiveUniformParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLuint index,GLenum pname,GLenum reference)123 void verifyActiveUniformParam(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLuint index,
124 GLenum pname, GLenum reference)
125 {
126 StateQueryMemoryWriteGuard<GLint> state;
127 gl.glGetActiveUniformsiv(program, 1, &index, pname, &state);
128
129 if (state.verifyValidity(testCtx))
130 checkIntEquals(testCtx, state, reference);
131 }
132
verifyActiveUniformBlockParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLuint blockIndex,GLenum pname,GLenum reference)133 void verifyActiveUniformBlockParam(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program,
134 GLuint blockIndex, GLenum pname, GLenum reference)
135 {
136 StateQueryMemoryWriteGuard<GLint> state;
137 gl.glGetActiveUniformBlockiv(program, blockIndex, pname, &state);
138
139 if (state.verifyValidity(testCtx))
140 checkIntEquals(testCtx, state, reference);
141 }
142
verifyCurrentVertexAttribf(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)143 void verifyCurrentVertexAttribf(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLint index, GLfloat x, GLfloat y,
144 GLfloat z, GLfloat w)
145 {
146 using tcu::TestLog;
147
148 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
149 gl.glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
150
151 attribValue.verifyValidity(testCtx);
152
153 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w)
154 {
155 testCtx.getLog() << TestLog::Message << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];"
156 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << ","
157 << attribValue[3] << "]" << TestLog::EndMessage;
158 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
159 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
160 }
161 }
162
verifyCurrentVertexAttribIi(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLint x,GLint y,GLint z,GLint w)163 void verifyCurrentVertexAttribIi(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLint index, GLint x, GLint y,
164 GLint z, GLint w)
165 {
166 using tcu::TestLog;
167
168 StateQueryMemoryWriteGuard<GLint[4]> attribValue;
169 gl.glGetVertexAttribIiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
170
171 attribValue.verifyValidity(testCtx);
172
173 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w)
174 {
175 testCtx.getLog() << TestLog::Message << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];"
176 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << ","
177 << attribValue[3] << "]" << TestLog::EndMessage;
178 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
179 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
180 }
181 }
182
verifyCurrentVertexAttribIui(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLuint x,GLuint y,GLuint z,GLuint w)183 void verifyCurrentVertexAttribIui(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLint index, GLuint x, GLuint y,
184 GLuint z, GLuint w)
185 {
186 using tcu::TestLog;
187
188 StateQueryMemoryWriteGuard<GLuint[4]> attribValue;
189 gl.glGetVertexAttribIuiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
190
191 attribValue.verifyValidity(testCtx);
192
193 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w)
194 {
195 testCtx.getLog() << TestLog::Message << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];"
196 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << ","
197 << attribValue[3] << "]" << TestLog::EndMessage;
198 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
199 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
200 }
201 }
202
verifyCurrentVertexAttribConversion(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)203 void verifyCurrentVertexAttribConversion(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLint index, GLfloat x,
204 GLfloat y, GLfloat z, GLfloat w)
205 {
206 using tcu::TestLog;
207
208 StateQueryMemoryWriteGuard<GLint[4]> attribValue;
209 gl.glGetVertexAttribiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
210
211 attribValue.verifyValidity(testCtx);
212
213 const GLint referenceAsGLintMin[] = {
214 roundGLfloatToNearestIntegerDown<GLint>(x), roundGLfloatToNearestIntegerDown<GLint>(y),
215 roundGLfloatToNearestIntegerDown<GLint>(z), roundGLfloatToNearestIntegerDown<GLint>(w)};
216 const GLint referenceAsGLintMax[] = {
217 roundGLfloatToNearestIntegerUp<GLint>(x), roundGLfloatToNearestIntegerUp<GLint>(y),
218 roundGLfloatToNearestIntegerUp<GLint>(z), roundGLfloatToNearestIntegerUp<GLint>(w)};
219
220 if (attribValue[0] < referenceAsGLintMin[0] || attribValue[0] > referenceAsGLintMax[0] ||
221 attribValue[1] < referenceAsGLintMin[1] || attribValue[1] > referenceAsGLintMax[1] ||
222 attribValue[2] < referenceAsGLintMin[2] || attribValue[2] > referenceAsGLintMax[2] ||
223 attribValue[3] < referenceAsGLintMin[3] || attribValue[3] > referenceAsGLintMax[3])
224 {
225 testCtx.getLog() << TestLog::Message << "// ERROR: expected in range "
226 << "[" << referenceAsGLintMin[0] << " " << referenceAsGLintMax[0] << "], "
227 << "[" << referenceAsGLintMin[1] << " " << referenceAsGLintMax[1] << "], "
228 << "[" << referenceAsGLintMin[2] << " " << referenceAsGLintMax[2] << "], "
229 << "[" << referenceAsGLintMin[3] << " " << referenceAsGLintMax[3] << "]"
230 << "; got " << attribValue[0] << ", " << attribValue[1] << ", " << attribValue[2] << ", "
231 << attribValue[3] << " "
232 << "; Input=" << x << "; " << y << "; " << z << "; " << w << " " << TestLog::EndMessage;
233
234 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
235 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid attribute value");
236 }
237 }
238
verifyVertexAttrib(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLenum pname,GLenum reference)239 void verifyVertexAttrib(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLint index, GLenum pname, GLenum reference)
240 {
241 StateQueryMemoryWriteGuard<GLint> state;
242 gl.glGetVertexAttribIiv(index, pname, &state);
243
244 if (state.verifyValidity(testCtx))
245 checkIntEquals(testCtx, state, reference);
246 }
247
verifyUniformValue1f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x)248 void verifyUniformValue1f(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, float x)
249 {
250 using tcu::TestLog;
251
252 StateQueryMemoryWriteGuard<GLfloat[1]> state;
253 gl.glGetUniformfv(program, location, state);
254
255 if (!state.verifyValidity(testCtx))
256 return;
257
258 if (state[0] != x)
259 {
260 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << "]; got [" << state[0] << "]"
261 << TestLog::EndMessage;
262
263 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
264 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
265 }
266 }
267
verifyUniformValue2f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x,float y)268 void verifyUniformValue2f(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, float x,
269 float y)
270 {
271 using tcu::TestLog;
272
273 StateQueryMemoryWriteGuard<GLfloat[2]> state;
274 gl.glGetUniformfv(program, location, state);
275
276 if (!state.verifyValidity(testCtx))
277 return;
278
279 if (state[0] != x || state[1] != y)
280 {
281 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << "]; got [" << state[0]
282 << ", " << state[1] << "]" << TestLog::EndMessage;
283
284 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
285 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
286 }
287 }
288
verifyUniformValue3f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x,float y,float z)289 void verifyUniformValue3f(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, float x,
290 float y, float z)
291 {
292 using tcu::TestLog;
293
294 StateQueryMemoryWriteGuard<GLfloat[3]> state;
295 gl.glGetUniformfv(program, location, state);
296
297 if (!state.verifyValidity(testCtx))
298 return;
299
300 if (state[0] != x || state[1] != y || state[2] != z)
301 {
302 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << ", " << z << "]; got ["
303 << state[0] << ", " << state[1] << ", " << state[2] << "]" << TestLog::EndMessage;
304
305 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
306 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
307 }
308 }
309
verifyUniformValue4f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x,float y,float z,float w)310 void verifyUniformValue4f(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, float x,
311 float y, float z, float w)
312 {
313 using tcu::TestLog;
314
315 StateQueryMemoryWriteGuard<GLfloat[4]> state;
316 gl.glGetUniformfv(program, location, state);
317
318 if (!state.verifyValidity(testCtx))
319 return;
320
321 if (state[0] != x || state[1] != y || state[2] != z || state[3] != w)
322 {
323 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << ", " << z << ", " << w
324 << "]; got [" << state[0] << ", " << state[1] << ", " << state[2] << ", " << state[3] << "]"
325 << TestLog::EndMessage;
326
327 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
328 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
329 }
330 }
331
verifyUniformValue1i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x)332 void verifyUniformValue1i(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLint x)
333 {
334 using tcu::TestLog;
335
336 StateQueryMemoryWriteGuard<GLint[1]> state;
337 gl.glGetUniformiv(program, location, state);
338
339 if (!state.verifyValidity(testCtx))
340 return;
341
342 if (state[0] != x)
343 {
344 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << "]; got [" << state[0] << "]"
345 << TestLog::EndMessage;
346
347 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
348 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
349 }
350 }
351
verifyUniformValue2i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x,GLint y)352 void verifyUniformValue2i(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLint x,
353 GLint y)
354 {
355 using tcu::TestLog;
356
357 StateQueryMemoryWriteGuard<GLint[2]> state;
358 gl.glGetUniformiv(program, location, state);
359
360 if (!state.verifyValidity(testCtx))
361 return;
362
363 if (state[0] != x || state[1] != y)
364 {
365 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << "]; got [" << state[0]
366 << ", " << state[1] << "]" << TestLog::EndMessage;
367
368 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
369 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
370 }
371 }
372
verifyUniformValue3i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x,GLint y,GLint z)373 void verifyUniformValue3i(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLint x,
374 GLint y, GLint z)
375 {
376 using tcu::TestLog;
377
378 StateQueryMemoryWriteGuard<GLint[3]> state;
379 gl.glGetUniformiv(program, location, state);
380
381 if (!state.verifyValidity(testCtx))
382 return;
383
384 if (state[0] != x || state[1] != y || state[2] != z)
385 {
386 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << ", " << z << "]; got ["
387 << state[0] << ", " << state[1] << ", " << state[2] << "]" << TestLog::EndMessage;
388
389 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
390 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
391 }
392 }
393
verifyUniformValue4i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x,GLint y,GLint z,GLint w)394 void verifyUniformValue4i(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLint x,
395 GLint y, GLint z, GLint w)
396 {
397 using tcu::TestLog;
398
399 StateQueryMemoryWriteGuard<GLint[4]> state;
400 gl.glGetUniformiv(program, location, state);
401
402 if (!state.verifyValidity(testCtx))
403 return;
404
405 if (state[0] != x || state[1] != y || state[2] != z || state[3] != w)
406 {
407 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << ", " << z << ", " << w
408 << "]; got [" << state[0] << ", " << state[1] << ", " << state[2] << ", " << state[3] << "]"
409 << TestLog::EndMessage;
410
411 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
412 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
413 }
414 }
415
verifyUniformValue1ui(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLuint x)416 void verifyUniformValue1ui(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLuint x)
417 {
418 using tcu::TestLog;
419
420 StateQueryMemoryWriteGuard<GLuint[1]> state;
421 gl.glGetUniformuiv(program, location, state);
422
423 if (!state.verifyValidity(testCtx))
424 return;
425
426 if (state[0] != x)
427 {
428 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << "]; got [" << state[0] << "]"
429 << TestLog::EndMessage;
430
431 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
432 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
433 }
434 }
435
verifyUniformValue2ui(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLuint x,GLuint y)436 void verifyUniformValue2ui(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLuint x,
437 GLuint y)
438 {
439 using tcu::TestLog;
440
441 StateQueryMemoryWriteGuard<GLuint[2]> state;
442 gl.glGetUniformuiv(program, location, state);
443
444 if (!state.verifyValidity(testCtx))
445 return;
446
447 if (state[0] != x || state[1] != y)
448 {
449 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << "]; got [" << state[0]
450 << ", " << state[1] << "]" << TestLog::EndMessage;
451
452 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
453 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
454 }
455 }
456
verifyUniformValue3ui(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLuint x,GLuint y,GLuint z)457 void verifyUniformValue3ui(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLuint x,
458 GLuint y, GLuint z)
459 {
460 using tcu::TestLog;
461
462 StateQueryMemoryWriteGuard<GLuint[3]> state;
463 gl.glGetUniformuiv(program, location, state);
464
465 if (!state.verifyValidity(testCtx))
466 return;
467
468 if (state[0] != x || state[1] != y || state[2] != z)
469 {
470 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << ", " << z << "]; got ["
471 << state[0] << ", " << state[1] << ", " << state[2] << "]" << TestLog::EndMessage;
472
473 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
474 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
475 }
476 }
477
verifyUniformValue4ui(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLuint x,GLuint y,GLuint z,GLuint w)478 void verifyUniformValue4ui(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location, GLuint x,
479 GLuint y, GLuint z, GLuint w)
480 {
481 using tcu::TestLog;
482
483 StateQueryMemoryWriteGuard<GLuint[4]> state;
484 gl.glGetUniformuiv(program, location, state);
485
486 if (!state.verifyValidity(testCtx))
487 return;
488
489 if (state[0] != x || state[1] != y || state[2] != z || state[3] != w)
490 {
491 testCtx.getLog() << TestLog::Message << "// ERROR: expected [" << x << ", " << y << ", " << z << ", " << w
492 << "]; got [" << state[0] << ", " << state[1] << ", " << state[2] << ", " << state[3] << "]"
493 << TestLog::EndMessage;
494
495 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
496 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
497 }
498 }
499
500 template <int Count>
verifyUniformValues(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,const GLfloat * values)501 void verifyUniformValues(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location,
502 const GLfloat *values)
503 {
504 using tcu::TestLog;
505
506 StateQueryMemoryWriteGuard<GLfloat[Count]> state;
507 gl.glGetUniformfv(program, location, state);
508
509 if (!state.verifyValidity(testCtx))
510 return;
511
512 for (int ndx = 0; ndx < Count; ++ndx)
513 {
514 if (values[ndx] != state[ndx])
515 {
516 testCtx.getLog() << TestLog::Message << "// ERROR: at index " << ndx << " expected " << values[ndx]
517 << "; got " << state[ndx] << TestLog::EndMessage;
518
519 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
520 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
521 }
522 }
523 }
524
525 template <int N>
verifyUniformMatrixValues(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,const GLfloat * values,bool transpose)526 void verifyUniformMatrixValues(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLuint program, GLint location,
527 const GLfloat *values, bool transpose)
528 {
529 using tcu::TestLog;
530
531 StateQueryMemoryWriteGuard<GLfloat[N * N]> state;
532 gl.glGetUniformfv(program, location, state);
533
534 if (!state.verifyValidity(testCtx))
535 return;
536
537 for (int y = 0; y < N; ++y)
538 for (int x = 0; x < N; ++x)
539 {
540 const int refIndex = y * N + x;
541 const int stateIndex = transpose ? (x * N + y) : (y * N + x);
542
543 if (values[refIndex] != state[stateIndex])
544 {
545 testCtx.getLog() << TestLog::Message << "// ERROR: at index [" << y << "][" << x << "] expected "
546 << values[refIndex] << "; got " << state[stateIndex] << TestLog::EndMessage;
547
548 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
549 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
550 }
551 }
552 }
553
554 class ShaderTypeCase : public ApiCase
555 {
556 public:
ShaderTypeCase(Context & context,const char * name,const char * description)557 ShaderTypeCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
558 {
559 }
560
test(void)561 void test(void)
562 {
563 const GLenum shaderTypes[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER};
564 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
565 {
566 const GLuint shader = glCreateShader(shaderTypes[ndx]);
567 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_TYPE, shaderTypes[ndx]);
568 glDeleteShader(shader);
569 }
570 }
571 };
572
573 class ShaderCompileStatusCase : public ApiCase
574 {
575 public:
ShaderCompileStatusCase(Context & context,const char * name,const char * description)576 ShaderCompileStatusCase(Context &context, const char *name, const char *description)
577 : ApiCase(context, name, description)
578 {
579 }
580
test(void)581 void test(void)
582 {
583 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
584 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
585
586 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_FALSE);
587 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE);
588
589 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
590 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
591
592 glCompileShader(shaderVert);
593 glCompileShader(shaderFrag);
594 expectError(GL_NO_ERROR);
595
596 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
597 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
598
599 glDeleteShader(shaderVert);
600 glDeleteShader(shaderFrag);
601 expectError(GL_NO_ERROR);
602 }
603 };
604
605 class ShaderInfoLogCase : public ApiCase
606 {
607 public:
ShaderInfoLogCase(Context & context,const char * name,const char * description)608 ShaderInfoLogCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
609 {
610 }
611
test(void)612 void test(void)
613 {
614 using tcu::TestLog;
615
616 // INFO_LOG_LENGTH is 0 by default and it includes null-terminator
617 const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
618 verifyShaderParam(m_testCtx, *this, shader, GL_INFO_LOG_LENGTH, 0);
619
620 glShaderSource(shader, 1, &brokenShader, DE_NULL);
621 glCompileShader(shader);
622 expectError(GL_NO_ERROR);
623
624 // check the log length
625 StateQueryMemoryWriteGuard<GLint> logLength;
626 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
627 if (!logLength.verifyValidity(m_testCtx))
628 {
629 glDeleteShader(shader);
630 return;
631 }
632 if (logLength == 0)
633 {
634 glDeleteShader(shader);
635 return;
636 }
637
638 // check normal case
639 {
640 char buffer[2048] = {'x'}; // non-zero initialization
641
642 GLint written = 0; // written does not include null terminator
643 glGetShaderInfoLog(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
644
645 // check lengths are consistent
646 if (logLength <= DE_LENGTH_OF_ARRAY(buffer))
647 {
648 if (written != logLength - 1)
649 {
650 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << logLength - 1 << "; got "
651 << written << TestLog::EndMessage;
652 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
653 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
654 }
655 }
656
657 // check null-terminator, either at end of buffer or at buffer[written]
658 const char *terminator = &buffer[DE_LENGTH_OF_ARRAY(buffer) - 1];
659 if (logLength < DE_LENGTH_OF_ARRAY(buffer))
660 terminator = &buffer[written];
661
662 if (*terminator != '\0')
663 {
664 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)*terminator
665 << TestLog::EndMessage;
666 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
667 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
668 }
669 }
670
671 // check with too small buffer
672 {
673 char buffer[2048] = {'x'}; // non-zero initialization
674
675 // check string always ends with \0, even with small buffers
676 GLint written = 0;
677 glGetShaderInfoLog(shader, 1, &written, buffer);
678 if (written != 0)
679 {
680 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length 0; got " << written
681 << TestLog::EndMessage;
682 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
683 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
684 }
685 if (buffer[0] != '\0')
686 {
687 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)buffer[0]
688 << TestLog::EndMessage;
689 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
690 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
691 }
692 }
693
694 glDeleteShader(shader);
695 expectError(GL_NO_ERROR);
696 }
697 };
698
699 class ShaderSourceCase : public ApiCase
700 {
701 public:
ShaderSourceCase(Context & context,const char * name,const char * description)702 ShaderSourceCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
703 {
704 }
705
test(void)706 void test(void)
707 {
708 using tcu::TestLog;
709
710 // SHADER_SOURCE_LENGTH does include 0-terminator
711 const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
712 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_SOURCE_LENGTH, 0);
713
714 // check the SHADER_SOURCE_LENGTH
715 {
716 glShaderSource(shader, 1, &brokenShader, DE_NULL);
717 expectError(GL_NO_ERROR);
718
719 StateQueryMemoryWriteGuard<GLint> sourceLength;
720 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);
721
722 sourceLength.verifyValidity(m_testCtx);
723
724 const GLint referenceLength =
725 (GLint)std::string(brokenShader).length() + 1; // including the null terminator
726 if (sourceLength != referenceLength)
727 {
728 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got "
729 << sourceLength << TestLog::EndMessage;
730 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
731 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
732 }
733 }
734
735 // check the concat source SHADER_SOURCE_LENGTH
736 {
737 const char *shaders[] = {brokenShader, brokenShader};
738 glShaderSource(shader, 2, shaders, DE_NULL);
739 expectError(GL_NO_ERROR);
740
741 StateQueryMemoryWriteGuard<GLint> sourceLength;
742 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);
743
744 sourceLength.verifyValidity(m_testCtx);
745
746 const GLint referenceLength =
747 2 * (GLint)std::string(brokenShader).length() + 1; // including the null terminator
748 if (sourceLength != referenceLength)
749 {
750 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got "
751 << sourceLength << TestLog::EndMessage;
752 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
753 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
754 }
755 }
756
757 // check the string length
758 {
759 char buffer[2048] = {'x'};
760 DE_ASSERT(DE_LENGTH_OF_ARRAY(buffer) > 2 * (int)std::string(brokenShader).length());
761
762 GLint written = 0; // not inluding null-terminator
763 glGetShaderSource(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
764
765 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length();
766 if (written != referenceLength)
767 {
768 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length " << referenceLength
769 << "; got " << written << TestLog::EndMessage;
770 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
771 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
772 }
773 // check null pointer at
774 else
775 {
776 if (buffer[referenceLength] != '\0')
777 {
778 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at "
779 << referenceLength << TestLog::EndMessage;
780 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
781 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "did not get a null terminator");
782 }
783 }
784 }
785
786 // check with small buffer
787 {
788 char buffer[2048] = {'x'};
789
790 GLint written = 0;
791 glGetShaderSource(shader, 1, &written, buffer);
792
793 if (written != 0)
794 {
795 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written
796 << TestLog::EndMessage;
797 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
798 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
799 }
800 if (buffer[0] != '\0')
801 {
802 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator; got=" << int(buffer[0])
803 << ", char=" << buffer[0] << TestLog::EndMessage;
804 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
805 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid terminator");
806 }
807 }
808
809 glDeleteShader(shader);
810 expectError(GL_NO_ERROR);
811 }
812 };
813
814 class DeleteStatusCase : public ApiCase
815 {
816 public:
DeleteStatusCase(Context & context,const char * name,const char * description)817 DeleteStatusCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
818 {
819 }
820
test(void)821 void test(void)
822 {
823 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
824 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
825
826 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
827 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
828
829 glCompileShader(shaderVert);
830 glCompileShader(shaderFrag);
831 expectError(GL_NO_ERROR);
832
833 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
834 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
835
836 GLuint shaderProg = glCreateProgram();
837 glAttachShader(shaderProg, shaderVert);
838 glAttachShader(shaderProg, shaderFrag);
839 glLinkProgram(shaderProg);
840 expectError(GL_NO_ERROR);
841
842 verifyProgramParam(m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE);
843
844 verifyShaderParam(m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_FALSE);
845 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_FALSE);
846 verifyProgramParam(m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_FALSE);
847 expectError(GL_NO_ERROR);
848
849 glUseProgram(shaderProg);
850
851 glDeleteShader(shaderVert);
852 glDeleteShader(shaderFrag);
853 glDeleteProgram(shaderProg);
854 expectError(GL_NO_ERROR);
855
856 verifyShaderParam(m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_TRUE);
857 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_TRUE);
858 verifyProgramParam(m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_TRUE);
859 expectError(GL_NO_ERROR);
860
861 glUseProgram(0);
862 expectError(GL_NO_ERROR);
863 }
864 };
865
866 class CurrentVertexAttribInitialCase : public ApiCase
867 {
868 public:
CurrentVertexAttribInitialCase(Context & context,const char * name,const char * description)869 CurrentVertexAttribInitialCase(Context &context, const char *name, const char *description)
870 : ApiCase(context, name, description)
871 {
872 }
873
test(void)874 void test(void)
875 {
876 using tcu::TestLog;
877
878 int attribute_count = 16;
879 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
880
881 // initial
882
883 for (int index = 0; index < attribute_count; ++index)
884 {
885 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
886 glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
887 attribValue.verifyValidity(m_testCtx);
888
889 if (attribValue[0] != 0.0f || attribValue[1] != 0.0f || attribValue[2] != 0.0f || attribValue[3] != 1.0f)
890 {
891 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected [0, 0, 0, 1];"
892 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << ","
893 << attribValue[3] << "]" << TestLog::EndMessage;
894 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
895 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
896 }
897 }
898 }
899 };
900
901 class CurrentVertexAttribFloatCase : public ApiCase
902 {
903 public:
CurrentVertexAttribFloatCase(Context & context,const char * name,const char * description)904 CurrentVertexAttribFloatCase(Context &context, const char *name, const char *description)
905 : ApiCase(context, name, description)
906 {
907 }
908
test(void)909 void test(void)
910 {
911 using tcu::TestLog;
912
913 de::Random rnd(0xabcdef);
914
915 int attribute_count = 16;
916 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
917
918 // test write float/read float
919
920 for (int index = 0; index < attribute_count; ++index)
921 {
922 const GLfloat x = rnd.getFloat(-64000, 64000);
923 const GLfloat y = rnd.getFloat(-64000, 64000);
924 const GLfloat z = rnd.getFloat(-64000, 64000);
925 const GLfloat w = rnd.getFloat(-64000, 64000);
926
927 glVertexAttrib4f(index, x, y, z, w);
928 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
929 }
930 for (int index = 0; index < attribute_count; ++index)
931 {
932 const GLfloat x = rnd.getFloat(-64000, 64000);
933 const GLfloat y = rnd.getFloat(-64000, 64000);
934 const GLfloat z = rnd.getFloat(-64000, 64000);
935 const GLfloat w = 1.0f;
936
937 glVertexAttrib3f(index, x, y, z);
938 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
939 }
940 for (int index = 0; index < attribute_count; ++index)
941 {
942 const GLfloat x = rnd.getFloat(-64000, 64000);
943 const GLfloat y = rnd.getFloat(-64000, 64000);
944 const GLfloat z = 0.0f;
945 const GLfloat w = 1.0f;
946
947 glVertexAttrib2f(index, x, y);
948 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
949 }
950 for (int index = 0; index < attribute_count; ++index)
951 {
952 const GLfloat x = rnd.getFloat(-64000, 64000);
953 const GLfloat y = 0.0f;
954 const GLfloat z = 0.0f;
955 const GLfloat w = 1.0f;
956
957 glVertexAttrib1f(index, x);
958 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
959 }
960 }
961 };
962
963 class CurrentVertexAttribIntCase : public ApiCase
964 {
965 public:
CurrentVertexAttribIntCase(Context & context,const char * name,const char * description)966 CurrentVertexAttribIntCase(Context &context, const char *name, const char *description)
967 : ApiCase(context, name, description)
968 {
969 }
970
test(void)971 void test(void)
972 {
973 using tcu::TestLog;
974
975 de::Random rnd(0xabcdef);
976
977 int attribute_count = 16;
978 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
979
980 // test write float/read float
981
982 for (int index = 0; index < attribute_count; ++index)
983 {
984 const GLint x = rnd.getInt(-64000, 64000);
985 const GLint y = rnd.getInt(-64000, 64000);
986 const GLint z = rnd.getInt(-64000, 64000);
987 const GLint w = rnd.getInt(-64000, 64000);
988
989 glVertexAttribI4i(index, x, y, z, w);
990 verifyCurrentVertexAttribIi(m_testCtx, *this, index, x, y, z, w);
991 }
992 }
993 };
994
995 class CurrentVertexAttribUintCase : public ApiCase
996 {
997 public:
CurrentVertexAttribUintCase(Context & context,const char * name,const char * description)998 CurrentVertexAttribUintCase(Context &context, const char *name, const char *description)
999 : ApiCase(context, name, description)
1000 {
1001 }
1002
test(void)1003 void test(void)
1004 {
1005 using tcu::TestLog;
1006
1007 de::Random rnd(0xabcdef);
1008
1009 int attribute_count = 16;
1010 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
1011
1012 // test write float/read float
1013
1014 for (int index = 0; index < attribute_count; ++index)
1015 {
1016 const GLuint x = rnd.getInt(0, 64000);
1017 const GLuint y = rnd.getInt(0, 64000);
1018 const GLuint z = rnd.getInt(0, 64000);
1019 const GLuint w = rnd.getInt(0, 64000);
1020
1021 glVertexAttribI4ui(index, x, y, z, w);
1022 verifyCurrentVertexAttribIui(m_testCtx, *this, index, x, y, z, w);
1023 }
1024 }
1025 };
1026
1027 class CurrentVertexAttribConversionCase : public ApiCase
1028 {
1029 public:
CurrentVertexAttribConversionCase(Context & context,const char * name,const char * description)1030 CurrentVertexAttribConversionCase(Context &context, const char *name, const char *description)
1031 : ApiCase(context, name, description)
1032 {
1033 }
1034
test(void)1035 void test(void)
1036 {
1037 using tcu::TestLog;
1038
1039 de::Random rnd(0xabcdef);
1040
1041 int attribute_count = 16;
1042 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
1043
1044 // test write float/read float
1045
1046 for (int index = 0; index < attribute_count; ++index)
1047 {
1048 const GLfloat x = rnd.getFloat(-64000, 64000);
1049 const GLfloat y = rnd.getFloat(-64000, 64000);
1050 const GLfloat z = rnd.getFloat(-64000, 64000);
1051 const GLfloat w = rnd.getFloat(-64000, 64000);
1052
1053 glVertexAttrib4f(index, x, y, z, w);
1054 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
1055 }
1056 for (int index = 0; index < attribute_count; ++index)
1057 {
1058 const GLfloat x = rnd.getFloat(-64000, 64000);
1059 const GLfloat y = rnd.getFloat(-64000, 64000);
1060 const GLfloat z = rnd.getFloat(-64000, 64000);
1061 const GLfloat w = 1.0f;
1062
1063 glVertexAttrib3f(index, x, y, z);
1064 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
1065 }
1066 for (int index = 0; index < attribute_count; ++index)
1067 {
1068 const GLfloat x = rnd.getFloat(-64000, 64000);
1069 const GLfloat y = rnd.getFloat(-64000, 64000);
1070 const GLfloat z = 0.0f;
1071 const GLfloat w = 1.0f;
1072
1073 glVertexAttrib2f(index, x, y);
1074 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
1075 }
1076 for (int index = 0; index < attribute_count; ++index)
1077 {
1078 const GLfloat x = rnd.getFloat(-64000, 64000);
1079 const GLfloat y = 0.0f;
1080 const GLfloat z = 0.0f;
1081 const GLfloat w = 1.0f;
1082
1083 glVertexAttrib1f(index, x);
1084 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
1085 }
1086 }
1087 };
1088
1089 class ProgramInfoLogCase : public ApiCase
1090 {
1091 public:
1092 enum BuildErrorType
1093 {
1094 BUILDERROR_COMPILE = 0,
1095 BUILDERROR_LINK
1096 };
1097
ProgramInfoLogCase(Context & context,const char * name,const char * description,BuildErrorType buildErrorType)1098 ProgramInfoLogCase(Context &context, const char *name, const char *description, BuildErrorType buildErrorType)
1099 : ApiCase(context, name, description)
1100 , m_buildErrorType(buildErrorType)
1101 {
1102 }
1103
test(void)1104 void test(void)
1105 {
1106 using tcu::TestLog;
1107
1108 enum
1109 {
1110 BUF_SIZE = 2048
1111 };
1112
1113 static const char *const linkErrorVtxSource = "#version 300 es\n"
1114 "in highp vec4 a_pos;\n"
1115 "uniform highp vec4 u_uniform;\n"
1116 "void main ()\n"
1117 "{\n"
1118 " gl_Position = a_pos + u_uniform;\n"
1119 "}\n";
1120 static const char *const linkErrorFrgSource = "#version 300 es\n"
1121 "in highp vec4 v_missingVar;\n"
1122 "uniform highp int u_uniform;\n"
1123 "layout(location = 0) out mediump vec4 fragColor;\n"
1124 "void main ()\n"
1125 "{\n"
1126 " fragColor = v_missingVar + vec4(float(u_uniform));\n"
1127 "}\n";
1128
1129 const char *vtxSource = (m_buildErrorType == BUILDERROR_COMPILE) ? (brokenShader) : (linkErrorVtxSource);
1130 const char *frgSource = (m_buildErrorType == BUILDERROR_COMPILE) ? (brokenShader) : (linkErrorFrgSource);
1131
1132 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1133 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1134
1135 glShaderSource(shaderVert, 1, &vtxSource, DE_NULL);
1136 glShaderSource(shaderFrag, 1, &frgSource, DE_NULL);
1137
1138 glCompileShader(shaderVert);
1139 glCompileShader(shaderFrag);
1140 expectError(GL_NO_ERROR);
1141
1142 GLuint program = glCreateProgram();
1143 glAttachShader(program, shaderVert);
1144 glAttachShader(program, shaderFrag);
1145 glLinkProgram(program);
1146
1147 StateQueryMemoryWriteGuard<GLint> logLength;
1148 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
1149 logLength.verifyValidity(m_testCtx);
1150
1151 // check INFO_LOG_LENGTH == GetProgramInfoLog len
1152 {
1153 const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryLarge", "Query to large buffer");
1154 char buffer[BUF_SIZE] = {'x'};
1155 GLint written = 0;
1156
1157 glGetProgramInfoLog(program, BUF_SIZE, &written, buffer);
1158
1159 if (logLength != 0 && written + 1 != logLength) // INFO_LOG_LENGTH contains 0-terminator
1160 {
1161 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written + 1
1162 << "; got " << logLength << TestLog::EndMessage;
1163 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1164 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
1165 }
1166 else if (logLength != 0 && buffer[written] != '\0')
1167 {
1168 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at index " << written
1169 << TestLog::EndMessage;
1170 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1171 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing null terminator");
1172 }
1173 }
1174
1175 // check query to just correct sized buffer
1176 if (BUF_SIZE > logLength)
1177 {
1178 const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryAll",
1179 "Query all to exactly right sized buffer");
1180 char buffer[BUF_SIZE] = {'x'};
1181 GLint written = 0;
1182
1183 glGetProgramInfoLog(program, logLength, &written, buffer);
1184
1185 if (logLength != 0 && written + 1 != logLength) // INFO_LOG_LENGTH contains 0-terminator
1186 {
1187 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written + 1
1188 << "; got " << logLength << TestLog::EndMessage;
1189 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1190 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
1191 }
1192 else if (logLength != 0 && buffer[written] != '\0')
1193 {
1194 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at index " << written
1195 << TestLog::EndMessage;
1196 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1197 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing null terminator");
1198 }
1199 }
1200
1201 // check GetProgramInfoLog works with too small buffer
1202 {
1203 const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryNone", "Query none");
1204 char buffer[BUF_SIZE] = {'x'};
1205 GLint written = 0;
1206
1207 glGetProgramInfoLog(program, 1, &written, buffer);
1208
1209 if (written != 0)
1210 {
1211 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written
1212 << TestLog::EndMessage;
1213 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1214 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
1215 }
1216 }
1217
1218 glDeleteShader(shaderVert);
1219 glDeleteShader(shaderFrag);
1220 glDeleteProgram(program);
1221 expectError(GL_NO_ERROR);
1222 }
1223
1224 const BuildErrorType m_buildErrorType;
1225 };
1226
1227 class ProgramValidateStatusCase : public ApiCase
1228 {
1229 public:
ProgramValidateStatusCase(Context & context,const char * name,const char * description)1230 ProgramValidateStatusCase(Context &context, const char *name, const char *description)
1231 : ApiCase(context, name, description)
1232 {
1233 }
1234
test(void)1235 void test(void)
1236 {
1237 // test validate ok
1238 {
1239 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1240 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1241
1242 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1243 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
1244
1245 glCompileShader(shaderVert);
1246 glCompileShader(shaderFrag);
1247 expectError(GL_NO_ERROR);
1248
1249 GLuint program = glCreateProgram();
1250 glAttachShader(program, shaderVert);
1251 glAttachShader(program, shaderFrag);
1252 glLinkProgram(program);
1253 expectError(GL_NO_ERROR);
1254
1255 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1256 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
1257 verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE);
1258
1259 glValidateProgram(program);
1260 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_TRUE);
1261
1262 glDeleteShader(shaderVert);
1263 glDeleteShader(shaderFrag);
1264 glDeleteProgram(program);
1265 expectError(GL_NO_ERROR);
1266 }
1267
1268 // test with broken shader
1269 {
1270 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1271 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1272
1273 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1274 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL);
1275
1276 glCompileShader(shaderVert);
1277 glCompileShader(shaderFrag);
1278 expectError(GL_NO_ERROR);
1279
1280 GLuint program = glCreateProgram();
1281 glAttachShader(program, shaderVert);
1282 glAttachShader(program, shaderFrag);
1283 glLinkProgram(program);
1284 expectError(GL_NO_ERROR);
1285
1286 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1287 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE);
1288 verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_FALSE);
1289
1290 glValidateProgram(program);
1291 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_FALSE);
1292
1293 glDeleteShader(shaderVert);
1294 glDeleteShader(shaderFrag);
1295 glDeleteProgram(program);
1296 expectError(GL_NO_ERROR);
1297 }
1298 }
1299 };
1300
1301 class ProgramAttachedShadersCase : public ApiCase
1302 {
1303 public:
ProgramAttachedShadersCase(Context & context,const char * name,const char * description)1304 ProgramAttachedShadersCase(Context &context, const char *name, const char *description)
1305 : ApiCase(context, name, description)
1306 {
1307 }
1308
test(void)1309 void test(void)
1310 {
1311 using tcu::TestLog;
1312
1313 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1314 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1315
1316 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1317 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
1318
1319 glCompileShader(shaderVert);
1320 glCompileShader(shaderFrag);
1321 expectError(GL_NO_ERROR);
1322
1323 // check ATTACHED_SHADERS
1324
1325 GLuint program = glCreateProgram();
1326 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 0);
1327 expectError(GL_NO_ERROR);
1328
1329 glAttachShader(program, shaderVert);
1330 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 1);
1331 expectError(GL_NO_ERROR);
1332
1333 glAttachShader(program, shaderFrag);
1334 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 2);
1335 expectError(GL_NO_ERROR);
1336
1337 // check GetAttachedShaders
1338 {
1339 GLuint shaders[2] = {0, 0};
1340 GLint count = 0;
1341 glGetAttachedShaders(program, DE_LENGTH_OF_ARRAY(shaders), &count, shaders);
1342
1343 if (count != 2)
1344 {
1345 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 2; got " << count << TestLog::EndMessage;
1346 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1347 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1348 }
1349 // shaders are the attached shaders?
1350 if (!((shaders[0] == shaderVert && shaders[1] == shaderFrag) ||
1351 (shaders[0] == shaderFrag && shaders[1] == shaderVert)))
1352 {
1353 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << shaderVert << ", " << shaderFrag
1354 << "}; got {" << shaders[0] << ", " << shaders[1] << "}" << TestLog::EndMessage;
1355 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1356 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1357 }
1358 }
1359
1360 // check GetAttachedShaders with too small buffer
1361 {
1362 GLuint shaders[2] = {0, 0};
1363 GLint count = 0;
1364
1365 glGetAttachedShaders(program, 0, &count, shaders);
1366 if (count != 0)
1367 {
1368 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << count << TestLog::EndMessage;
1369 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1370 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1371 }
1372
1373 count = 0;
1374 glGetAttachedShaders(program, 1, &count, shaders);
1375 if (count != 1)
1376 {
1377 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 1; got " << count << TestLog::EndMessage;
1378 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1379 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1380 }
1381 }
1382
1383 glDeleteShader(shaderVert);
1384 glDeleteShader(shaderFrag);
1385 glDeleteProgram(program);
1386 expectError(GL_NO_ERROR);
1387 }
1388 };
1389
1390 class ProgramActiveUniformNameCase : public ApiCase
1391 {
1392 public:
ProgramActiveUniformNameCase(Context & context,const char * name,const char * description)1393 ProgramActiveUniformNameCase(Context &context, const char *name, const char *description)
1394 : ApiCase(context, name, description)
1395 {
1396 }
1397
test(void)1398 void test(void)
1399 {
1400 using tcu::TestLog;
1401
1402 static const char *testVertSource = "#version 300 es\n"
1403 "uniform highp float uniformNameWithLength23;\n"
1404 "uniform highp vec2 uniformVec2;\n"
1405 "uniform highp mat4 uniformMat4;\n"
1406 "void main (void)\n"
1407 "{\n"
1408 " gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + "
1409 "vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n"
1410 "}\n\0";
1411 static const char *testFragSource = "#version 300 es\n"
1412 "layout(location = 0) out mediump vec4 fragColor;"
1413 "void main (void)\n"
1414 "{\n"
1415 " fragColor = vec4(0.0);\n"
1416 "}\n\0";
1417
1418 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1419 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1420
1421 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
1422 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
1423
1424 glCompileShader(shaderVert);
1425 glCompileShader(shaderFrag);
1426 expectError(GL_NO_ERROR);
1427
1428 GLuint program = glCreateProgram();
1429 glAttachShader(program, shaderVert);
1430 glAttachShader(program, shaderFrag);
1431 glLinkProgram(program);
1432 expectError(GL_NO_ERROR);
1433
1434 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORMS, 3);
1435 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_MAX_LENGTH,
1436 (GLint)std::string("uniformNameWithLength23").length() + 1); // including a null terminator
1437 expectError(GL_NO_ERROR);
1438
1439 const char *uniformNames[] = {"uniformNameWithLength23", "uniformVec2", "uniformMat4"};
1440 StateQueryMemoryWriteGuard<GLuint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformIndices;
1441 glGetUniformIndices(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformNames, uniformIndices);
1442 uniformIndices.verifyValidity(m_testCtx);
1443
1444 // check name lengths
1445 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx)
1446 {
1447 const GLuint uniformIndex = uniformIndices[ndx];
1448
1449 StateQueryMemoryWriteGuard<GLint> uniformNameLen;
1450 glGetActiveUniformsiv(program, 1, &uniformIndex, GL_UNIFORM_NAME_LENGTH, &uniformNameLen);
1451
1452 uniformNameLen.verifyValidity(m_testCtx);
1453
1454 const GLint referenceLength = (GLint)std::string(uniformNames[ndx]).length() + 1;
1455 if (referenceLength != uniformNameLen) // uniformNameLen is with null terminator
1456 {
1457 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << referenceLength << "got "
1458 << uniformNameLen << TestLog::EndMessage;
1459 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1460 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
1461 }
1462 }
1463
1464 // check names
1465 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx)
1466 {
1467 char buffer[2048] = {'x'};
1468
1469 const GLuint uniformIndex = uniformIndices[ndx];
1470
1471 GLint written = 0; // null terminator not included
1472 GLint size = 0;
1473 GLenum type = 0;
1474 glGetActiveUniform(program, uniformIndex, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
1475
1476 const GLint referenceLength = (GLint)std::string(uniformNames[ndx]).length();
1477 if (referenceLength != written)
1478 {
1479 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << referenceLength << "got " << written
1480 << TestLog::EndMessage;
1481 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1482 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
1483 }
1484
1485 // and with too small buffer
1486 written = 0;
1487 glGetActiveUniform(program, uniformIndex, 1, &written, &size, &type, buffer);
1488
1489 if (written != 0)
1490 {
1491 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0 got " << written << TestLog::EndMessage;
1492 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1493 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
1494 }
1495 }
1496
1497 glDeleteShader(shaderVert);
1498 glDeleteShader(shaderFrag);
1499 glDeleteProgram(program);
1500 expectError(GL_NO_ERROR);
1501 }
1502 };
1503
1504 class ProgramUniformCase : public ApiCase
1505 {
1506 public:
ProgramUniformCase(Context & context,const char * name,const char * description)1507 ProgramUniformCase(Context &context, const char *name, const char *description)
1508 : ApiCase(context, name, description)
1509 {
1510 }
1511
test(void)1512 void test(void)
1513 {
1514 const struct UniformType
1515 {
1516 const char *declaration;
1517 const char *postDeclaration;
1518 const char *precision;
1519 const char *layout;
1520 const char *getter;
1521 GLenum type;
1522 GLint size;
1523 GLint isRowMajor;
1524 } uniformTypes[] = {
1525 {"float", "", "highp", "", "uniformValue", GL_FLOAT, 1, GL_FALSE},
1526 {"float[2]", "", "highp", "", "uniformValue[1]", GL_FLOAT, 2, GL_FALSE},
1527 {"vec2", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC2, 1, GL_FALSE},
1528 {"vec3", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC3, 1, GL_FALSE},
1529 {"vec4", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC4, 1, GL_FALSE},
1530 {"int", "", "highp", "", "float(uniformValue)", GL_INT, 1, GL_FALSE},
1531 {"ivec2", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC2, 1, GL_FALSE},
1532 {"ivec3", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC3, 1, GL_FALSE},
1533 {"ivec4", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC4, 1, GL_FALSE},
1534 {"uint", "", "highp", "", "float(uniformValue)", GL_UNSIGNED_INT, 1, GL_FALSE},
1535 {"uvec2", "", "highp", "", "float(uniformValue.x)", GL_UNSIGNED_INT_VEC2, 1, GL_FALSE},
1536 {"uvec3", "", "highp", "", "float(uniformValue.x)", GL_UNSIGNED_INT_VEC3, 1, GL_FALSE},
1537 {"uvec4", "", "highp", "", "float(uniformValue.x)", GL_UNSIGNED_INT_VEC4, 1, GL_FALSE},
1538 {"bool", "", "", "", "float(uniformValue)", GL_BOOL, 1, GL_FALSE},
1539 {"bvec2", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC2, 1, GL_FALSE},
1540 {"bvec3", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC3, 1, GL_FALSE},
1541 {"bvec4", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC4, 1, GL_FALSE},
1542 {"mat2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2, 1, GL_FALSE},
1543 {"mat3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3, 1, GL_FALSE},
1544 {"mat4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4, 1, GL_FALSE},
1545 {"mat2x3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2x3, 1, GL_FALSE},
1546 {"mat2x4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2x4, 1, GL_FALSE},
1547 {"mat3x2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3x2, 1, GL_FALSE},
1548 {"mat3x4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3x4, 1, GL_FALSE},
1549 {"mat4x2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4x2, 1, GL_FALSE},
1550 {"mat4x3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4x3, 1, GL_FALSE},
1551 {"sampler2D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_2D, 1, GL_FALSE},
1552 {"sampler3D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_3D, 1, GL_FALSE},
1553 {"samplerCube", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_CUBE, 1, GL_FALSE},
1554 {"sampler2DShadow", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_2D_SHADOW, 1,
1555 GL_FALSE},
1556 {"sampler2DArray", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_2D_ARRAY, 1,
1557 GL_FALSE},
1558 {"sampler2DArrayShadow", "", "highp", "", "float(textureSize(uniformValue,0).r)",
1559 GL_SAMPLER_2D_ARRAY_SHADOW, 1, GL_FALSE},
1560 {"samplerCubeShadow", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_SAMPLER_CUBE_SHADOW, 1,
1561 GL_FALSE},
1562 {"isampler2D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_2D, 1, GL_FALSE},
1563 {"isampler3D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_3D, 1, GL_FALSE},
1564 {"isamplerCube", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_CUBE, 1, GL_FALSE},
1565 {"isampler2DArray", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_INT_SAMPLER_2D_ARRAY, 1,
1566 GL_FALSE},
1567 {"usampler2D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_UNSIGNED_INT_SAMPLER_2D, 1,
1568 GL_FALSE},
1569 {"usampler3D", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_UNSIGNED_INT_SAMPLER_3D, 1,
1570 GL_FALSE},
1571 {"usamplerCube", "", "highp", "", "float(textureSize(uniformValue,0).r)", GL_UNSIGNED_INT_SAMPLER_CUBE, 1,
1572 GL_FALSE},
1573 {"usampler2DArray", "", "highp", "", "float(textureSize(uniformValue,0).r)",
1574 GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, 1, GL_FALSE},
1575 };
1576
1577 static const char *vertSource = "#version 300 es\n"
1578 "void main (void)\n"
1579 "{\n"
1580 " gl_Position = vec4(0.0);\n"
1581 "}\n\0";
1582
1583 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1584 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1585 GLuint program = glCreateProgram();
1586
1587 glAttachShader(program, shaderVert);
1588 glAttachShader(program, shaderFrag);
1589
1590 glShaderSource(shaderVert, 1, &vertSource, DE_NULL);
1591 glCompileShader(shaderVert);
1592 expectError(GL_NO_ERROR);
1593
1594 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformTypes); ++ndx)
1595 {
1596 tcu::ScopedLogSection(m_log, uniformTypes[ndx].declaration,
1597 std::string("Verify type of ") + uniformTypes[ndx].declaration + " variable" +
1598 uniformTypes[ndx].postDeclaration);
1599
1600 // gen fragment shader
1601
1602 std::ostringstream frag;
1603 frag << "#version 300 es\n";
1604 frag << uniformTypes[ndx].layout << "uniform " << uniformTypes[ndx].precision << " "
1605 << uniformTypes[ndx].declaration << " uniformValue" << uniformTypes[ndx].postDeclaration << ";\n";
1606 frag << "layout(location = 0) out mediump vec4 fragColor;\n";
1607 frag << "void main (void)\n";
1608 frag << "{\n";
1609 frag << " fragColor = vec4(" << uniformTypes[ndx].getter << ");\n";
1610 frag << "}\n";
1611
1612 {
1613 std::string fragmentSource = frag.str();
1614 const char *fragmentSourceCStr = fragmentSource.c_str();
1615 glShaderSource(shaderFrag, 1, &fragmentSourceCStr, DE_NULL);
1616 }
1617
1618 // compile & link
1619
1620 glCompileShader(shaderFrag);
1621 glLinkProgram(program);
1622
1623 // test
1624 if (verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE))
1625 {
1626 const char *uniformNames[] = {"uniformValue"};
1627 StateQueryMemoryWriteGuard<GLuint> uniformIndex;
1628 glGetUniformIndices(program, 1, uniformNames, &uniformIndex);
1629 uniformIndex.verifyValidity(m_testCtx);
1630
1631 verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_TYPE,
1632 uniformTypes[ndx].type);
1633 verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_SIZE,
1634 uniformTypes[ndx].size);
1635 verifyActiveUniformParam(m_testCtx, *this, program, uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
1636 uniformTypes[ndx].isRowMajor);
1637 }
1638 }
1639
1640 glDeleteShader(shaderVert);
1641 glDeleteShader(shaderFrag);
1642 glDeleteProgram(program);
1643 expectError(GL_NO_ERROR);
1644 }
1645 };
1646
1647 class ProgramActiveUniformBlocksCase : public ApiCase
1648 {
1649 public:
ProgramActiveUniformBlocksCase(Context & context,const char * name,const char * description)1650 ProgramActiveUniformBlocksCase(Context &context, const char *name, const char *description)
1651 : ApiCase(context, name, description)
1652 {
1653 }
1654
test(void)1655 void test(void)
1656 {
1657 using tcu::TestLog;
1658
1659 static const char *testVertSource =
1660 "#version 300 es\n"
1661 "uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n"
1662 "uniform shortUniformBlockName {highp vec2 vector2;highp vec4 vector4;} shortUniformInstanceName;\n"
1663 "void main (void)\n"
1664 "{\n"
1665 " gl_Position = shortUniformInstanceName.vector4 + vec4(longlongUniformInstanceName.vector2.x) + "
1666 "vec4(shortUniformInstanceName.vector2.x);\n"
1667 "}\n\0";
1668 static const char *testFragSource =
1669 "#version 300 es\n"
1670 "uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n"
1671 "layout(location = 0) out mediump vec4 fragColor;"
1672 "void main (void)\n"
1673 "{\n"
1674 " fragColor = vec4(longlongUniformInstanceName.vector2.y);\n"
1675 "}\n\0";
1676
1677 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1678 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1679
1680 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
1681 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
1682
1683 glCompileShader(shaderVert);
1684 glCompileShader(shaderFrag);
1685 expectError(GL_NO_ERROR);
1686
1687 GLuint program = glCreateProgram();
1688 glAttachShader(program, shaderVert);
1689 glAttachShader(program, shaderFrag);
1690 glLinkProgram(program);
1691 expectError(GL_NO_ERROR);
1692
1693 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1694 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
1695 verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE);
1696
1697 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_BLOCKS, 2);
1698 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH,
1699 (GLint)std::string("longlongUniformBlockName").length() + 1); // including a null terminator
1700 expectError(GL_NO_ERROR);
1701
1702 GLint longlongUniformBlockIndex = glGetUniformBlockIndex(program, "longlongUniformBlockName");
1703 GLint shortUniformBlockIndex = glGetUniformBlockIndex(program, "shortUniformBlockName");
1704
1705 const char *uniformNames[] = {"longlongUniformBlockName.vector2", "shortUniformBlockName.vector2",
1706 "shortUniformBlockName.vector4"};
1707
1708 // test UNIFORM_BLOCK_INDEX
1709
1710 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(uniformNames) == 3);
1711
1712 StateQueryMemoryWriteGuard<GLuint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformIndices;
1713 StateQueryMemoryWriteGuard<GLint[DE_LENGTH_OF_ARRAY(uniformNames)]> uniformsBlockIndices;
1714
1715 glGetUniformIndices(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformNames, uniformIndices);
1716 uniformIndices.verifyValidity(m_testCtx);
1717 expectError(GL_NO_ERROR);
1718
1719 glGetActiveUniformsiv(program, DE_LENGTH_OF_ARRAY(uniformNames), uniformIndices, GL_UNIFORM_BLOCK_INDEX,
1720 uniformsBlockIndices);
1721 uniformsBlockIndices.verifyValidity(m_testCtx);
1722 expectError(GL_NO_ERROR);
1723
1724 if (uniformsBlockIndices[0] != longlongUniformBlockIndex || uniformsBlockIndices[1] != shortUniformBlockIndex ||
1725 uniformsBlockIndices[2] != shortUniformBlockIndex)
1726 {
1727 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected [" << longlongUniformBlockIndex << ", "
1728 << shortUniformBlockIndex << ", " << shortUniformBlockIndex << "];"
1729 << "got [" << uniformsBlockIndices[0] << ", " << uniformsBlockIndices[1] << ", "
1730 << uniformsBlockIndices[2] << "]" << TestLog::EndMessage;
1731 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1732 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform block index");
1733 }
1734
1735 // test UNIFORM_BLOCK_NAME_LENGTH
1736
1737 verifyActiveUniformBlockParam(
1738 m_testCtx, *this, program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_NAME_LENGTH,
1739 (GLint)std::string("longlongUniformBlockName").length() + 1); // including null-terminator
1740 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex, GL_UNIFORM_BLOCK_NAME_LENGTH,
1741 (GLint)std::string("shortUniformBlockName").length() +
1742 1); // including null-terminator
1743 expectError(GL_NO_ERROR);
1744
1745 // test UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER & UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER
1746
1747 verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex,
1748 GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, GL_TRUE);
1749 verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex,
1750 GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, GL_TRUE);
1751 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex,
1752 GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, GL_TRUE);
1753 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex,
1754 GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, GL_FALSE);
1755 expectError(GL_NO_ERROR);
1756
1757 // test UNIFORM_BLOCK_ACTIVE_UNIFORMS
1758
1759 verifyActiveUniformBlockParam(m_testCtx, *this, program, longlongUniformBlockIndex,
1760 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, 1);
1761 verifyActiveUniformBlockParam(m_testCtx, *this, program, shortUniformBlockIndex,
1762 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, 2);
1763 expectError(GL_NO_ERROR);
1764
1765 // test UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
1766
1767 {
1768 StateQueryMemoryWriteGuard<GLint> longlongUniformBlockUniforms;
1769 glGetActiveUniformBlockiv(program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
1770 &longlongUniformBlockUniforms);
1771 longlongUniformBlockUniforms.verifyValidity(m_testCtx);
1772
1773 if (longlongUniformBlockUniforms == 2)
1774 {
1775 StateQueryMemoryWriteGuard<GLint[2]> longlongUniformBlockUniformIndices;
1776 glGetActiveUniformBlockiv(program, longlongUniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
1777 longlongUniformBlockUniformIndices);
1778 longlongUniformBlockUniformIndices.verifyValidity(m_testCtx);
1779
1780 if ((GLuint(longlongUniformBlockUniformIndices[0]) != uniformIndices[0] ||
1781 GLuint(longlongUniformBlockUniformIndices[1]) != uniformIndices[1]) &&
1782 (GLuint(longlongUniformBlockUniformIndices[1]) != uniformIndices[0] ||
1783 GLuint(longlongUniformBlockUniformIndices[0]) != uniformIndices[1]))
1784 {
1785 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << uniformIndices[0] << ", "
1786 << uniformIndices[1] << "};"
1787 << "got {" << longlongUniformBlockUniformIndices[0] << ", "
1788 << longlongUniformBlockUniformIndices[1] << "}" << TestLog::EndMessage;
1789
1790 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1791 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform indices");
1792 }
1793 }
1794 }
1795
1796 // check block names
1797
1798 {
1799 char buffer[2048] = {'x'};
1800 GLint written = 0;
1801 glGetActiveUniformBlockName(program, longlongUniformBlockIndex, DE_LENGTH_OF_ARRAY(buffer), &written,
1802 buffer);
1803 checkIntEquals(m_testCtx, written, (GLint)std::string("longlongUniformBlockName").length());
1804
1805 written = 0;
1806 glGetActiveUniformBlockName(program, shortUniformBlockIndex, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
1807 checkIntEquals(m_testCtx, written, (GLint)std::string("shortUniformBlockName").length());
1808
1809 // and one with too small buffer
1810 written = 0;
1811 glGetActiveUniformBlockName(program, longlongUniformBlockIndex, 1, &written, buffer);
1812 checkIntEquals(m_testCtx, written, 0);
1813 }
1814
1815 expectError(GL_NO_ERROR);
1816 glDeleteShader(shaderVert);
1817 glDeleteShader(shaderFrag);
1818 glDeleteProgram(program);
1819 expectError(GL_NO_ERROR);
1820 }
1821 };
1822
1823 class ProgramBinaryCase : public ApiCase
1824 {
1825 public:
ProgramBinaryCase(Context & context,const char * name,const char * description)1826 ProgramBinaryCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
1827 {
1828 }
1829
test(void)1830 void test(void)
1831 {
1832 using tcu::TestLog;
1833
1834 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1835 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1836
1837 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1838 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
1839
1840 glCompileShader(shaderVert);
1841 glCompileShader(shaderFrag);
1842 expectError(GL_NO_ERROR);
1843
1844 GLuint program = glCreateProgram();
1845 glAttachShader(program, shaderVert);
1846 glAttachShader(program, shaderFrag);
1847 glLinkProgram(program);
1848 expectError(GL_NO_ERROR);
1849
1850 // test PROGRAM_BINARY_RETRIEVABLE_HINT
1851 verifyProgramParam(m_testCtx, *this, program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_FALSE);
1852
1853 glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
1854 expectError(GL_NO_ERROR);
1855
1856 glLinkProgram(program);
1857 expectError(GL_NO_ERROR);
1858
1859 verifyProgramParam(m_testCtx, *this, program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
1860
1861 // test PROGRAM_BINARY_LENGTH does something
1862
1863 StateQueryMemoryWriteGuard<GLint> programLength;
1864 glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &programLength);
1865 expectError(GL_NO_ERROR);
1866 programLength.verifyValidity(m_testCtx);
1867
1868 glDeleteShader(shaderVert);
1869 glDeleteShader(shaderFrag);
1870 glDeleteProgram(program);
1871 expectError(GL_NO_ERROR);
1872 }
1873 };
1874
1875 class TransformFeedbackCase : public ApiCase
1876 {
1877 public:
TransformFeedbackCase(Context & context,const char * name,const char * description)1878 TransformFeedbackCase(Context &context, const char *name, const char *description)
1879 : ApiCase(context, name, description)
1880 {
1881 }
1882
test(void)1883 void test(void)
1884 {
1885 using tcu::TestLog;
1886
1887 static const char *transformFeedbackTestVertSource = "#version 300 es\n"
1888 "out highp vec4 tfOutput2withLongName;\n"
1889 "void main (void)\n"
1890 "{\n"
1891 " gl_Position = vec4(0.0);\n"
1892 " tfOutput2withLongName = vec4(0.0);\n"
1893 "}\n";
1894 static const char *transformFeedbackTestFragSource = "#version 300 es\n"
1895 "layout(location = 0) out highp vec4 fragColor;\n"
1896 "void main (void)\n"
1897 "{\n"
1898 " fragColor = vec4(0.0);\n"
1899 "}\n";
1900
1901 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1902 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1903 GLuint shaderProg = glCreateProgram();
1904
1905 verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, GL_INTERLEAVED_ATTRIBS);
1906
1907 glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL);
1908 glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL);
1909
1910 glCompileShader(shaderVert);
1911 glCompileShader(shaderFrag);
1912
1913 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1914 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
1915
1916 glAttachShader(shaderProg, shaderVert);
1917 glAttachShader(shaderProg, shaderFrag);
1918
1919 // check TRANSFORM_FEEDBACK_BUFFER_MODE
1920
1921 const char *transform_feedback_outputs[] = {"gl_Position", "tfOutput2withLongName"};
1922 const char *longest_output = transform_feedback_outputs[1];
1923 const GLenum bufferModes[] = {GL_SEPARATE_ATTRIBS, GL_INTERLEAVED_ATTRIBS};
1924
1925 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferModes); ++ndx)
1926 {
1927 glTransformFeedbackVaryings(shaderProg, DE_LENGTH_OF_ARRAY(transform_feedback_outputs),
1928 transform_feedback_outputs, bufferModes[ndx]);
1929 glLinkProgram(shaderProg);
1930 expectError(GL_NO_ERROR);
1931
1932 verifyProgramParam(m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE);
1933 verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, bufferModes[ndx]);
1934 }
1935
1936 // TRANSFORM_FEEDBACK_VARYINGS
1937 verifyProgramParam(m_testCtx, *this, shaderProg, GL_TRANSFORM_FEEDBACK_VARYINGS, 2);
1938
1939 // TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
1940 {
1941 StateQueryMemoryWriteGuard<GLint> maxOutputLen;
1942 glGetProgramiv(shaderProg, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &maxOutputLen);
1943
1944 maxOutputLen.verifyValidity(m_testCtx);
1945
1946 const GLint referenceLength = (GLint)std::string(longest_output).length() + 1;
1947 checkIntEquals(m_testCtx, maxOutputLen, referenceLength);
1948 }
1949
1950 // check varyings
1951 {
1952 StateQueryMemoryWriteGuard<GLint> varyings;
1953 glGetProgramiv(shaderProg, GL_TRANSFORM_FEEDBACK_VARYINGS, &varyings);
1954
1955 if (!varyings.isUndefined())
1956 for (int index = 0; index < varyings; ++index)
1957 {
1958 char buffer[2048] = {'x'};
1959
1960 GLint written = 0;
1961 GLint size = 0;
1962 GLenum type = 0;
1963 glGetTransformFeedbackVarying(shaderProg, index, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type,
1964 buffer);
1965
1966 if (written < DE_LENGTH_OF_ARRAY(buffer) && buffer[written] != '\0')
1967 {
1968 m_testCtx.getLog()
1969 << TestLog::Message << "// ERROR: Expected null terminator" << TestLog::EndMessage;
1970 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1971 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid string terminator");
1972 }
1973
1974 // check with too small buffer
1975 written = 0;
1976 glGetTransformFeedbackVarying(shaderProg, index, 1, &written, &size, &type, buffer);
1977 if (written != 0)
1978 {
1979 m_testCtx.getLog()
1980 << TestLog::Message << "// ERROR: Expected 0; got " << written << TestLog::EndMessage;
1981 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1982 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid write length");
1983 }
1984 }
1985 }
1986
1987 glDeleteShader(shaderVert);
1988 glDeleteShader(shaderFrag);
1989 glDeleteProgram(shaderProg);
1990 expectError(GL_NO_ERROR);
1991 }
1992 };
1993
1994 class ActiveAttributesCase : public ApiCase
1995 {
1996 public:
ActiveAttributesCase(Context & context,const char * name,const char * description)1997 ActiveAttributesCase(Context &context, const char *name, const char *description)
1998 : ApiCase(context, name, description)
1999 {
2000 }
2001
test(void)2002 void test(void)
2003 {
2004 using tcu::TestLog;
2005
2006 static const char *testVertSource = "#version 300 es\n"
2007 "in highp vec2 longInputAttributeName;\n"
2008 "in highp vec2 shortName;\n"
2009 "void main (void)\n"
2010 "{\n"
2011 " gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n"
2012 "}\n\0";
2013 static const char *testFragSource = "#version 300 es\n"
2014 "layout(location = 0) out mediump vec4 fragColor;"
2015 "void main (void)\n"
2016 "{\n"
2017 " fragColor = vec4(0.0);\n"
2018 "}\n\0";
2019
2020 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
2021 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
2022
2023 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
2024 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
2025
2026 glCompileShader(shaderVert);
2027 glCompileShader(shaderFrag);
2028 expectError(GL_NO_ERROR);
2029
2030 GLuint program = glCreateProgram();
2031 glAttachShader(program, shaderVert);
2032 glAttachShader(program, shaderFrag);
2033 glLinkProgram(program);
2034 expectError(GL_NO_ERROR);
2035
2036 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTES, 2);
2037 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
2038 (GLint)std::string("longInputAttributeName").length() + 1); // does include null-terminator
2039
2040 // check names
2041 for (int attributeNdx = 0; attributeNdx < 2; ++attributeNdx)
2042 {
2043 char buffer[2048] = {'x'};
2044
2045 GLint written = 0;
2046 GLint size = 0;
2047 GLenum type = 0;
2048 glGetActiveAttrib(program, attributeNdx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
2049 expectError(GL_NO_ERROR);
2050
2051 if (deStringBeginsWith(buffer, "longInputAttributeName"))
2052 {
2053 checkIntEquals(
2054 m_testCtx, written,
2055 (GLint)std::string("longInputAttributeName").length()); // does NOT include null-terminator
2056 }
2057 else if (deStringBeginsWith(buffer, "shortName"))
2058 {
2059 checkIntEquals(m_testCtx, written,
2060 (GLint)std::string("shortName").length()); // does NOT include null-terminator
2061 }
2062 else
2063 {
2064 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unexpected attribute name."
2065 << TestLog::EndMessage;
2066 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
2067 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected name");
2068 }
2069 }
2070
2071 // and with too short buffer
2072 {
2073 char buffer[2048] = {'x'};
2074
2075 GLint written = 0;
2076 GLint size = 0;
2077 GLenum type = 0;
2078
2079 glGetActiveAttrib(program, 0, 1, &written, &size, &type, buffer);
2080 expectError(GL_NO_ERROR);
2081 checkIntEquals(m_testCtx, written, 0);
2082 }
2083
2084 glDeleteShader(shaderVert);
2085 glDeleteShader(shaderFrag);
2086 glDeleteProgram(program);
2087 expectError(GL_NO_ERROR);
2088 }
2089 };
2090
2091 struct PointerData
2092 {
2093 GLint size;
2094 GLenum type;
2095 GLint stride;
2096 GLboolean normalized;
2097 const void *pointer;
2098 };
2099
2100 class VertexAttributeSizeCase : public ApiCase
2101 {
2102 public:
VertexAttributeSizeCase(Context & context,const char * name,const char * description)2103 VertexAttributeSizeCase(Context &context, const char *name, const char *description)
2104 : ApiCase(context, name, description)
2105 {
2106 }
2107
test(void)2108 void test(void)
2109 {
2110 GLfloat vertexData[4] = {0.0f}; // never accessed
2111
2112 const PointerData pointers[] = {
2113 // size test
2114 {4, GL_FLOAT, 0, GL_FALSE, vertexData}, {3, GL_FLOAT, 0, GL_FALSE, vertexData},
2115 {2, GL_FLOAT, 0, GL_FALSE, vertexData}, {1, GL_FLOAT, 0, GL_FALSE, vertexData},
2116 {4, GL_INT, 0, GL_FALSE, vertexData}, {3, GL_INT, 0, GL_FALSE, vertexData},
2117 {2, GL_INT, 0, GL_FALSE, vertexData}, {1, GL_INT, 0, GL_FALSE, vertexData},
2118 };
2119
2120 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2121 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2122
2123 // Test with default VAO
2124 if (!isCoreGL45)
2125 {
2126 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2127
2128 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2129 {
2130 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized,
2131 pointers[ndx].stride, pointers[ndx].pointer);
2132 expectError(GL_NO_ERROR);
2133
2134 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size);
2135 }
2136 }
2137
2138 // Test with multiple VAOs
2139 {
2140 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2141
2142 GLuint buf = 0;
2143 GLuint vaos[2] = {0};
2144
2145 glGenVertexArrays(2, vaos);
2146 glGenBuffers(1, &buf);
2147 glBindBuffer(GL_ARRAY_BUFFER, buf);
2148 expectError(GL_NO_ERROR);
2149
2150 // initial
2151 glBindVertexArray(vaos[0]);
2152 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, 4);
2153 expectError(GL_NO_ERROR);
2154
2155 // set vao 0 to some value
2156 glVertexAttribPointer(0, pointers[0].size, pointers[0].type, pointers[0].normalized, pointers[0].stride,
2157 DE_NULL);
2158 expectError(GL_NO_ERROR);
2159
2160 // set vao 1 to some other value
2161 glBindVertexArray(vaos[1]);
2162 glVertexAttribPointer(0, pointers[1].size, pointers[1].type, pointers[1].normalized, pointers[1].stride,
2163 DE_NULL);
2164 expectError(GL_NO_ERROR);
2165
2166 // verify vao 1 state
2167 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[1].size);
2168 expectError(GL_NO_ERROR);
2169
2170 // verify vao 0 state
2171 glBindVertexArray(vaos[0]);
2172 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[0].size);
2173 expectError(GL_NO_ERROR);
2174
2175 glDeleteVertexArrays(2, vaos);
2176 glDeleteBuffers(1, &buf);
2177 expectError(GL_NO_ERROR);
2178 }
2179 }
2180 };
2181
2182 class VertexAttributeTypeCase : public ApiCase
2183 {
2184 public:
VertexAttributeTypeCase(Context & context,const char * name,const char * description)2185 VertexAttributeTypeCase(Context &context, const char *name, const char *description)
2186 : ApiCase(context, name, description)
2187 {
2188 }
2189
test(void)2190 void test(void)
2191 {
2192 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2193 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2194
2195 // Test with default VAO
2196 if (!isCoreGL45)
2197 {
2198 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2199
2200 const GLfloat vertexData[4] = {0.0f}; // never accessed
2201
2202 // test VertexAttribPointer
2203 {
2204 const PointerData pointers[] = {
2205 {1, GL_BYTE, 0, GL_FALSE, vertexData},
2206 {1, GL_SHORT, 0, GL_FALSE, vertexData},
2207 {1, GL_INT, 0, GL_FALSE, vertexData},
2208 {1, GL_FIXED, 0, GL_FALSE, vertexData},
2209 {1, GL_FLOAT, 0, GL_FALSE, vertexData},
2210 {1, GL_HALF_FLOAT, 0, GL_FALSE, vertexData},
2211 {1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData},
2212 {1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData},
2213 {1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData},
2214 {4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData},
2215 {4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData},
2216 };
2217
2218 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2219 {
2220 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized,
2221 pointers[ndx].stride, pointers[ndx].pointer);
2222 expectError(GL_NO_ERROR);
2223
2224 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
2225 }
2226 }
2227
2228 // test glVertexAttribIPointer
2229 {
2230 const PointerData pointers[] = {
2231 {1, GL_BYTE, 0, GL_FALSE, vertexData},
2232 {1, GL_SHORT, 0, GL_FALSE, vertexData},
2233 {1, GL_INT, 0, GL_FALSE, vertexData},
2234 {1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData},
2235 {1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData},
2236 {1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData},
2237 };
2238
2239 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2240 {
2241 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride,
2242 pointers[ndx].pointer);
2243 expectError(GL_NO_ERROR);
2244
2245 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
2246 }
2247 }
2248 }
2249
2250 // Test with multiple VAOs
2251 {
2252 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2253
2254 GLuint buf = 0;
2255 GLuint vaos[2] = {0};
2256
2257 glGenVertexArrays(2, vaos);
2258 glGenBuffers(1, &buf);
2259 glBindBuffer(GL_ARRAY_BUFFER, buf);
2260 expectError(GL_NO_ERROR);
2261
2262 // initial
2263 glBindVertexArray(vaos[0]);
2264 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT);
2265 expectError(GL_NO_ERROR);
2266
2267 // set vao 0 to some value
2268 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2269 expectError(GL_NO_ERROR);
2270
2271 // set vao 1 to some other value
2272 glBindVertexArray(vaos[1]);
2273 glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 0, DE_NULL);
2274 expectError(GL_NO_ERROR);
2275
2276 // verify vao 1 state
2277 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_SHORT);
2278 expectError(GL_NO_ERROR);
2279
2280 // verify vao 0 state
2281 glBindVertexArray(vaos[0]);
2282 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT);
2283 expectError(GL_NO_ERROR);
2284
2285 glDeleteVertexArrays(2, vaos);
2286 glDeleteBuffers(1, &buf);
2287 expectError(GL_NO_ERROR);
2288 }
2289 }
2290 };
2291
2292 class VertexAttributeStrideCase : public ApiCase
2293 {
2294 public:
VertexAttributeStrideCase(Context & context,const char * name,const char * description)2295 VertexAttributeStrideCase(Context &context, const char *name, const char *description)
2296 : ApiCase(context, name, description)
2297 {
2298 }
2299
test(void)2300 void test(void)
2301 {
2302 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2303 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2304
2305 // Test with default VAO
2306 if (!isCoreGL45)
2307 {
2308 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2309
2310 const GLfloat vertexData[4] = {0.0f}; // never accessed
2311
2312 struct StridePointerData
2313 {
2314 GLint size;
2315 GLenum type;
2316 GLint stride;
2317 const void *pointer;
2318 };
2319
2320 // test VertexAttribPointer
2321 {
2322 const StridePointerData pointers[] = {
2323 {1, GL_FLOAT, 0, vertexData}, {1, GL_FLOAT, 1, vertexData},
2324 {1, GL_FLOAT, 4, vertexData}, {1, GL_HALF_FLOAT, 0, vertexData},
2325 {1, GL_HALF_FLOAT, 1, vertexData}, {1, GL_HALF_FLOAT, 4, vertexData},
2326 {1, GL_FIXED, 0, vertexData}, {1, GL_FIXED, 1, vertexData},
2327 {1, GL_FIXED, 4, vertexData},
2328 };
2329
2330 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2331 {
2332 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride,
2333 pointers[ndx].pointer);
2334 expectError(GL_NO_ERROR);
2335
2336 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
2337 }
2338 }
2339
2340 // test glVertexAttribIPointer
2341 {
2342 const StridePointerData pointers[] = {
2343 {1, GL_INT, 0, vertexData}, {1, GL_INT, 1, vertexData},
2344 {1, GL_INT, 4, vertexData}, {4, GL_UNSIGNED_BYTE, 0, vertexData},
2345 {4, GL_UNSIGNED_BYTE, 1, vertexData}, {4, GL_UNSIGNED_BYTE, 4, vertexData},
2346 {2, GL_SHORT, 0, vertexData}, {2, GL_SHORT, 1, vertexData},
2347 {2, GL_SHORT, 4, vertexData},
2348 };
2349
2350 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2351 {
2352 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride,
2353 pointers[ndx].pointer);
2354 expectError(GL_NO_ERROR);
2355
2356 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
2357 }
2358 }
2359 }
2360
2361 // Test with multiple VAOs
2362 {
2363 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2364
2365 GLuint buf = 0;
2366 GLuint vaos[2] = {0};
2367
2368 glGenVertexArrays(2, vaos);
2369 glGenBuffers(1, &buf);
2370 glBindBuffer(GL_ARRAY_BUFFER, buf);
2371 expectError(GL_NO_ERROR);
2372
2373 // initial
2374 glBindVertexArray(vaos[0]);
2375 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0);
2376 expectError(GL_NO_ERROR);
2377
2378 // set vao 0 to some value
2379 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 4, DE_NULL);
2380 expectError(GL_NO_ERROR);
2381
2382 // set vao 1 to some other value
2383 glBindVertexArray(vaos[1]);
2384 glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 8, DE_NULL);
2385 expectError(GL_NO_ERROR);
2386
2387 // verify vao 1 state
2388 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 8);
2389 expectError(GL_NO_ERROR);
2390
2391 // verify vao 0 state
2392 glBindVertexArray(vaos[0]);
2393 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 4);
2394 expectError(GL_NO_ERROR);
2395
2396 glDeleteVertexArrays(2, vaos);
2397 glDeleteBuffers(1, &buf);
2398 expectError(GL_NO_ERROR);
2399 }
2400 }
2401 };
2402
2403 class VertexAttributeNormalizedCase : public ApiCase
2404 {
2405 public:
VertexAttributeNormalizedCase(Context & context,const char * name,const char * description)2406 VertexAttributeNormalizedCase(Context &context, const char *name, const char *description)
2407 : ApiCase(context, name, description)
2408 {
2409 }
2410
test(void)2411 void test(void)
2412 {
2413 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2414 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2415
2416 // Test with default VAO
2417 if (!isCoreGL45)
2418 {
2419 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2420
2421 const GLfloat vertexData[4] = {0.0f}; // never accessed
2422
2423 // test VertexAttribPointer
2424 {
2425 const PointerData pointers[] = {
2426 {1, GL_BYTE, 0, GL_FALSE, vertexData},
2427 {1, GL_SHORT, 0, GL_FALSE, vertexData},
2428 {1, GL_INT, 0, GL_FALSE, vertexData},
2429 {1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData},
2430 {1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData},
2431 {1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData},
2432 {4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData},
2433 {4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData},
2434 {1, GL_BYTE, 0, GL_TRUE, vertexData},
2435 {1, GL_SHORT, 0, GL_TRUE, vertexData},
2436 {1, GL_INT, 0, GL_TRUE, vertexData},
2437 {1, GL_UNSIGNED_BYTE, 0, GL_TRUE, vertexData},
2438 {1, GL_UNSIGNED_SHORT, 0, GL_TRUE, vertexData},
2439 {1, GL_UNSIGNED_INT, 0, GL_TRUE, vertexData},
2440 {4, GL_INT_2_10_10_10_REV, 0, GL_TRUE, vertexData},
2441 {4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_TRUE, vertexData},
2442 };
2443
2444 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2445 {
2446 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized,
2447 pointers[ndx].stride, pointers[ndx].pointer);
2448 expectError(GL_NO_ERROR);
2449
2450 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED,
2451 pointers[ndx].normalized);
2452 }
2453 }
2454
2455 // test glVertexAttribIPointer
2456 {
2457 const PointerData pointers[] = {
2458 {1, GL_BYTE, 0, GL_FALSE, vertexData},
2459 {1, GL_SHORT, 0, GL_FALSE, vertexData},
2460 {1, GL_INT, 0, GL_FALSE, vertexData},
2461 {1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData},
2462 {1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData},
2463 {1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData},
2464 };
2465
2466 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2467 {
2468 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride,
2469 pointers[ndx].pointer);
2470 expectError(GL_NO_ERROR);
2471
2472 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
2473 }
2474 }
2475 }
2476
2477 // Test with multiple VAOs
2478 {
2479 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2480
2481 GLuint buf = 0;
2482 GLuint vaos[2] = {0};
2483
2484 glGenVertexArrays(2, vaos);
2485 glGenBuffers(1, &buf);
2486 glBindBuffer(GL_ARRAY_BUFFER, buf);
2487 expectError(GL_NO_ERROR);
2488
2489 // initial
2490 glBindVertexArray(vaos[0]);
2491 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
2492 expectError(GL_NO_ERROR);
2493
2494 // set vao 0 to some value
2495 glVertexAttribPointer(0, 1, GL_INT, GL_TRUE, 0, DE_NULL);
2496 expectError(GL_NO_ERROR);
2497
2498 // set vao 1 to some other value
2499 glBindVertexArray(vaos[1]);
2500 glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, DE_NULL);
2501 expectError(GL_NO_ERROR);
2502
2503 // verify vao 1 state
2504 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
2505 expectError(GL_NO_ERROR);
2506
2507 // verify vao 0 state
2508 glBindVertexArray(vaos[0]);
2509 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_TRUE);
2510 expectError(GL_NO_ERROR);
2511
2512 glDeleteVertexArrays(2, vaos);
2513 glDeleteBuffers(1, &buf);
2514 expectError(GL_NO_ERROR);
2515 }
2516 }
2517 };
2518
2519 class VertexAttributeIntegerCase : public ApiCase
2520 {
2521 public:
VertexAttributeIntegerCase(Context & context,const char * name,const char * description)2522 VertexAttributeIntegerCase(Context &context, const char *name, const char *description)
2523 : ApiCase(context, name, description)
2524 {
2525 }
2526
test(void)2527 void test(void)
2528 {
2529 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2530 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2531
2532 // Test with default VAO
2533 if (!isCoreGL45)
2534 {
2535 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2536
2537 const GLfloat vertexData[4] = {0.0f}; // never accessed
2538
2539 // test VertexAttribPointer
2540 {
2541 const PointerData pointers[] = {
2542 {1, GL_BYTE, 0, GL_FALSE, vertexData},
2543 {1, GL_SHORT, 0, GL_FALSE, vertexData},
2544 {1, GL_INT, 0, GL_FALSE, vertexData},
2545 {1, GL_FIXED, 0, GL_FALSE, vertexData},
2546 {1, GL_FLOAT, 0, GL_FALSE, vertexData},
2547 {1, GL_HALF_FLOAT, 0, GL_FALSE, vertexData},
2548 {1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData},
2549 {1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData},
2550 {1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData},
2551 {4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData},
2552 {4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData},
2553 };
2554
2555 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2556 {
2557 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized,
2558 pointers[ndx].stride, pointers[ndx].pointer);
2559 expectError(GL_NO_ERROR);
2560
2561 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
2562 }
2563 }
2564
2565 // test glVertexAttribIPointer
2566 {
2567 const PointerData pointers[] = {
2568 {1, GL_BYTE, 0, GL_FALSE, vertexData},
2569 {1, GL_SHORT, 0, GL_FALSE, vertexData},
2570 {1, GL_INT, 0, GL_FALSE, vertexData},
2571 {1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData},
2572 {1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData},
2573 {1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData},
2574 };
2575
2576 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2577 {
2578 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride,
2579 pointers[ndx].pointer);
2580 expectError(GL_NO_ERROR);
2581
2582 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE);
2583 }
2584 }
2585 }
2586
2587 // Test with multiple VAOs
2588 {
2589 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2590
2591 GLuint buf = 0;
2592 GLuint vaos[2] = {0};
2593
2594 glGenVertexArrays(2, vaos);
2595 glGenBuffers(1, &buf);
2596 glBindBuffer(GL_ARRAY_BUFFER, buf);
2597 expectError(GL_NO_ERROR);
2598
2599 // initial
2600 glBindVertexArray(vaos[0]);
2601 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
2602 expectError(GL_NO_ERROR);
2603
2604 // set vao 0 to some value
2605 glVertexAttribIPointer(0, 1, GL_INT, 0, DE_NULL);
2606 expectError(GL_NO_ERROR);
2607
2608 // set vao 1 to some other value
2609 glBindVertexArray(vaos[1]);
2610 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2611 expectError(GL_NO_ERROR);
2612
2613 // verify vao 1 state
2614 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
2615 expectError(GL_NO_ERROR);
2616
2617 // verify vao 0 state
2618 glBindVertexArray(vaos[0]);
2619 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE);
2620 expectError(GL_NO_ERROR);
2621
2622 glDeleteVertexArrays(2, vaos);
2623 glDeleteBuffers(1, &buf);
2624 expectError(GL_NO_ERROR);
2625 }
2626 }
2627 };
2628
2629 class VertexAttributeEnabledCase : public ApiCase
2630 {
2631 public:
VertexAttributeEnabledCase(Context & context,const char * name,const char * description)2632 VertexAttributeEnabledCase(Context &context, const char *name, const char *description)
2633 : ApiCase(context, name, description)
2634 {
2635 }
2636
test(void)2637 void test(void)
2638 {
2639 // VERTEX_ATTRIB_ARRAY_ENABLED
2640
2641 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2642 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2643
2644 // Test with default VAO
2645 if (!isCoreGL45)
2646 {
2647 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2648
2649 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
2650 glEnableVertexAttribArray(0);
2651 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
2652 glDisableVertexAttribArray(0);
2653 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
2654 }
2655
2656 // Test with multiple VAOs
2657 {
2658 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2659
2660 GLuint vaos[2] = {0};
2661
2662 glGenVertexArrays(2, vaos);
2663 expectError(GL_NO_ERROR);
2664
2665 // set vao 0 to some value
2666 glBindVertexArray(vaos[0]);
2667 glEnableVertexAttribArray(0);
2668 expectError(GL_NO_ERROR);
2669
2670 // set vao 1 to some other value
2671 glBindVertexArray(vaos[1]);
2672 glDisableVertexAttribArray(0);
2673 expectError(GL_NO_ERROR);
2674
2675 // verify vao 1 state
2676 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
2677 expectError(GL_NO_ERROR);
2678
2679 // verify vao 0 state
2680 glBindVertexArray(vaos[0]);
2681 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
2682 expectError(GL_NO_ERROR);
2683
2684 glDeleteVertexArrays(2, vaos);
2685 expectError(GL_NO_ERROR);
2686 }
2687 }
2688 };
2689
2690 class VertexAttributeDivisorCase : public ApiCase
2691 {
2692 public:
VertexAttributeDivisorCase(Context & context,const char * name,const char * description)2693 VertexAttributeDivisorCase(Context &context, const char *name, const char *description)
2694 : ApiCase(context, name, description)
2695 {
2696 }
2697
test(void)2698 void test(void)
2699 {
2700 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2701 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2702
2703 // Test with default VAO
2704 if (!isCoreGL45)
2705 {
2706 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2707
2708 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0);
2709 glVertexAttribDivisor(0, 1);
2710 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1);
2711 glVertexAttribDivisor(0, 5);
2712 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5);
2713 }
2714
2715 // Test with multiple VAOs
2716 {
2717 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2718
2719 GLuint vaos[2] = {0};
2720
2721 glGenVertexArrays(2, vaos);
2722 expectError(GL_NO_ERROR);
2723
2724 // set vao 0 to some value
2725 glBindVertexArray(vaos[0]);
2726 glVertexAttribDivisor(0, 1);
2727 expectError(GL_NO_ERROR);
2728
2729 // set vao 1 to some other value
2730 glBindVertexArray(vaos[1]);
2731 glVertexAttribDivisor(0, 5);
2732 expectError(GL_NO_ERROR);
2733
2734 // verify vao 1 state
2735 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5);
2736 expectError(GL_NO_ERROR);
2737
2738 // verify vao 0 state
2739 glBindVertexArray(vaos[0]);
2740 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1);
2741 expectError(GL_NO_ERROR);
2742
2743 glDeleteVertexArrays(2, vaos);
2744 expectError(GL_NO_ERROR);
2745 }
2746 }
2747 };
2748
2749 class VertexAttributeBufferBindingCase : public ApiCase
2750 {
2751 public:
VertexAttributeBufferBindingCase(Context & context,const char * name,const char * description)2752 VertexAttributeBufferBindingCase(Context &context, const char *name, const char *description)
2753 : ApiCase(context, name, description)
2754 {
2755 }
2756
test(void)2757 void test(void)
2758 {
2759 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2760 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2761
2762 // Test with default VAO
2763 if (!isCoreGL45)
2764 {
2765 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2766
2767 // initial
2768 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0);
2769
2770 GLuint bufferID;
2771 glGenBuffers(1, &bufferID);
2772 glBindBuffer(GL_ARRAY_BUFFER, bufferID);
2773 expectError(GL_NO_ERROR);
2774
2775 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2776 expectError(GL_NO_ERROR);
2777
2778 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID);
2779
2780 glDeleteBuffers(1, &bufferID);
2781 expectError(GL_NO_ERROR);
2782 }
2783
2784 // Test with multiple VAOs
2785 {
2786 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2787
2788 GLuint vaos[2] = {0};
2789 GLuint bufs[2] = {0};
2790
2791 glGenBuffers(2, bufs);
2792 expectError(GL_NO_ERROR);
2793
2794 glGenVertexArrays(2, vaos);
2795 expectError(GL_NO_ERROR);
2796
2797 // set vao 0 to some value
2798 glBindVertexArray(vaos[0]);
2799 glBindBuffer(GL_ARRAY_BUFFER, bufs[0]);
2800 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2801 expectError(GL_NO_ERROR);
2802
2803 // set vao 1 to some other value
2804 glBindVertexArray(vaos[1]);
2805 glBindBuffer(GL_ARRAY_BUFFER, bufs[1]);
2806 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2807 expectError(GL_NO_ERROR);
2808
2809 // verify vao 1 state
2810 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[1]);
2811 expectError(GL_NO_ERROR);
2812
2813 // verify vao 0 state
2814 glBindVertexArray(vaos[0]);
2815 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[0]);
2816 expectError(GL_NO_ERROR);
2817
2818 glDeleteVertexArrays(2, vaos);
2819 glDeleteBuffers(2, bufs);
2820 expectError(GL_NO_ERROR);
2821 }
2822 }
2823 };
2824
2825 class VertexAttributePointerCase : public ApiCase
2826 {
2827 public:
VertexAttributePointerCase(Context & context,const char * name,const char * description)2828 VertexAttributePointerCase(Context &context, const char *name, const char *description)
2829 : ApiCase(context, name, description)
2830 {
2831 }
2832
test(void)2833 void test(void)
2834 {
2835 const glu::ContextType &contextType = m_context.getRenderContext().getType();
2836 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2837
2838 // Test with default VAO
2839 if (!isCoreGL45)
2840 {
2841 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2842
2843 StateQueryMemoryWriteGuard<GLvoid *> initialState;
2844 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState);
2845 initialState.verifyValidity(m_testCtx);
2846 checkPointerEquals(m_testCtx, initialState, 0);
2847
2848 const GLfloat vertexData[4] = {0.0f}; // never accessed
2849 const PointerData pointers[] = {
2850 {1, GL_BYTE, 0, GL_FALSE, &vertexData[2]}, {1, GL_SHORT, 0, GL_FALSE, &vertexData[1]},
2851 {1, GL_INT, 0, GL_FALSE, &vertexData[2]}, {1, GL_FIXED, 0, GL_FALSE, &vertexData[2]},
2852 {1, GL_FIXED, 0, GL_FALSE, &vertexData[1]}, {1, GL_FLOAT, 0, GL_FALSE, &vertexData[0]},
2853 {1, GL_FLOAT, 0, GL_FALSE, &vertexData[3]}, {1, GL_FLOAT, 0, GL_FALSE, &vertexData[2]},
2854 {1, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[0]}, {4, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[1]},
2855 {4, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[2]},
2856 };
2857
2858 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2859 {
2860 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized,
2861 pointers[ndx].stride, pointers[ndx].pointer);
2862 expectError(GL_NO_ERROR);
2863
2864 StateQueryMemoryWriteGuard<GLvoid *> state;
2865 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
2866 state.verifyValidity(m_testCtx);
2867 checkPointerEquals(m_testCtx, state, pointers[ndx].pointer);
2868 }
2869 }
2870
2871 // Test with multiple VAOs
2872 {
2873 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2874
2875 GLuint vaos[2] = {0};
2876 GLuint bufs[2] = {0};
2877
2878 glGenBuffers(2, bufs);
2879 expectError(GL_NO_ERROR);
2880
2881 glGenVertexArrays(2, vaos);
2882 expectError(GL_NO_ERROR);
2883
2884 // set vao 0 to some value
2885 glBindVertexArray(vaos[0]);
2886 glBindBuffer(GL_ARRAY_BUFFER, bufs[0]);
2887 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, glu::BufferOffsetAsPointer(8));
2888 expectError(GL_NO_ERROR);
2889
2890 // set vao 1 to some other value
2891 glBindVertexArray(vaos[1]);
2892 glBindBuffer(GL_ARRAY_BUFFER, bufs[1]);
2893 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, glu::BufferOffsetAsPointer(4));
2894 expectError(GL_NO_ERROR);
2895
2896 // verify vao 1 state
2897 {
2898 StateQueryMemoryWriteGuard<GLvoid *> state;
2899 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
2900 state.verifyValidity(m_testCtx);
2901 checkPointerEquals(m_testCtx, state, glu::BufferOffsetAsPointer(4));
2902 }
2903 expectError(GL_NO_ERROR);
2904
2905 // verify vao 0 state
2906 glBindVertexArray(vaos[0]);
2907 {
2908 StateQueryMemoryWriteGuard<GLvoid *> state;
2909 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
2910 state.verifyValidity(m_testCtx);
2911 checkPointerEquals(m_testCtx, state, glu::BufferOffsetAsPointer(8));
2912 }
2913 expectError(GL_NO_ERROR);
2914
2915 glDeleteVertexArrays(2, vaos);
2916 glDeleteBuffers(2, bufs);
2917 expectError(GL_NO_ERROR);
2918 }
2919 }
2920 };
2921
2922 class UniformValueFloatCase : public ApiCase
2923 {
2924 public:
UniformValueFloatCase(Context & context,const char * name,const char * description)2925 UniformValueFloatCase(Context &context, const char *name, const char *description)
2926 : ApiCase(context, name, description)
2927 {
2928 }
2929
test(void)2930 void test(void)
2931 {
2932 static const char *testVertSource =
2933 "#version 300 es\n"
2934 "uniform highp float floatUniform;\n"
2935 "uniform highp vec2 float2Uniform;\n"
2936 "uniform highp vec3 float3Uniform;\n"
2937 "uniform highp vec4 float4Uniform;\n"
2938 "void main (void)\n"
2939 "{\n"
2940 " gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n"
2941 "}\n";
2942 static const char *testFragSource = "#version 300 es\n"
2943 "layout(location = 0) out mediump vec4 fragColor;"
2944 "void main (void)\n"
2945 "{\n"
2946 " fragColor = vec4(0.0);\n"
2947 "}\n";
2948
2949 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
2950 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
2951
2952 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
2953 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
2954
2955 glCompileShader(shaderVert);
2956 glCompileShader(shaderFrag);
2957 expectError(GL_NO_ERROR);
2958
2959 GLuint program = glCreateProgram();
2960 glAttachShader(program, shaderVert);
2961 glAttachShader(program, shaderFrag);
2962 glLinkProgram(program);
2963 glUseProgram(program);
2964 expectError(GL_NO_ERROR);
2965
2966 GLint location;
2967
2968 location = glGetUniformLocation(program, "floatUniform");
2969 glUniform1f(location, 1.0f);
2970 verifyUniformValue1f(m_testCtx, *this, program, location, 1.0f);
2971
2972 location = glGetUniformLocation(program, "float2Uniform");
2973 glUniform2f(location, 1.0f, 2.0f);
2974 verifyUniformValue2f(m_testCtx, *this, program, location, 1.0f, 2.0f);
2975
2976 location = glGetUniformLocation(program, "float3Uniform");
2977 glUniform3f(location, 1.0f, 2.0f, 3.0f);
2978 verifyUniformValue3f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f);
2979
2980 location = glGetUniformLocation(program, "float4Uniform");
2981 glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f);
2982 verifyUniformValue4f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f, 4.0f);
2983
2984 glUseProgram(0);
2985 glDeleteShader(shaderVert);
2986 glDeleteShader(shaderFrag);
2987 glDeleteProgram(program);
2988 expectError(GL_NO_ERROR);
2989 }
2990 };
2991
2992 class UniformValueIntCase : public ApiCase
2993 {
2994 public:
UniformValueIntCase(Context & context,const char * name,const char * description)2995 UniformValueIntCase(Context &context, const char *name, const char *description)
2996 : ApiCase(context, name, description)
2997 {
2998 }
2999
test(void)3000 void test(void)
3001 {
3002 static const char *testVertSource =
3003 "#version 300 es\n"
3004 "uniform highp int intUniform;\n"
3005 "uniform highp ivec2 int2Uniform;\n"
3006 "uniform highp ivec3 int3Uniform;\n"
3007 "uniform highp ivec4 int4Uniform;\n"
3008 "void main (void)\n"
3009 "{\n"
3010 " gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n"
3011 "}\n";
3012 static const char *testFragSource = "#version 300 es\n"
3013 "layout(location = 0) out mediump vec4 fragColor;"
3014 "void main (void)\n"
3015 "{\n"
3016 " fragColor = vec4(0.0);\n"
3017 "}\n";
3018
3019 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3020 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3021
3022 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3023 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3024
3025 glCompileShader(shaderVert);
3026 glCompileShader(shaderFrag);
3027 expectError(GL_NO_ERROR);
3028
3029 GLuint program = glCreateProgram();
3030 glAttachShader(program, shaderVert);
3031 glAttachShader(program, shaderFrag);
3032 glLinkProgram(program);
3033 glUseProgram(program);
3034 expectError(GL_NO_ERROR);
3035
3036 GLint location;
3037
3038 location = glGetUniformLocation(program, "intUniform");
3039 glUniform1i(location, 1);
3040 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3041
3042 location = glGetUniformLocation(program, "int2Uniform");
3043 glUniform2i(location, 1, 2);
3044 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 2);
3045
3046 location = glGetUniformLocation(program, "int3Uniform");
3047 glUniform3i(location, 1, 2, 3);
3048 verifyUniformValue3i(m_testCtx, *this, program, location, 1, 2, 3);
3049
3050 location = glGetUniformLocation(program, "int4Uniform");
3051 glUniform4i(location, 1, 2, 3, 4);
3052 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 2, 3, 4);
3053
3054 glUseProgram(0);
3055 glDeleteShader(shaderVert);
3056 glDeleteShader(shaderFrag);
3057 glDeleteProgram(program);
3058 expectError(GL_NO_ERROR);
3059 }
3060 };
3061
3062 class UniformValueUintCase : public ApiCase
3063 {
3064 public:
UniformValueUintCase(Context & context,const char * name,const char * description)3065 UniformValueUintCase(Context &context, const char *name, const char *description)
3066 : ApiCase(context, name, description)
3067 {
3068 }
3069
test(void)3070 void test(void)
3071 {
3072 static const char *testVertSource =
3073 "#version 300 es\n"
3074 "uniform highp uint uintUniform;\n"
3075 "uniform highp uvec2 uint2Uniform;\n"
3076 "uniform highp uvec3 uint3Uniform;\n"
3077 "uniform highp uvec4 uint4Uniform;\n"
3078 "void main (void)\n"
3079 "{\n"
3080 " gl_Position = vec4(float(uintUniform + uint2Uniform.x + uint3Uniform.x + uint4Uniform.x));\n"
3081 "}\n";
3082 static const char *testFragSource = "#version 300 es\n"
3083 "layout(location = 0) out mediump vec4 fragColor;"
3084 "void main (void)\n"
3085 "{\n"
3086 " fragColor = vec4(0.0);\n"
3087 "}\n";
3088
3089 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3090 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3091
3092 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3093 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3094
3095 glCompileShader(shaderVert);
3096 glCompileShader(shaderFrag);
3097 expectError(GL_NO_ERROR);
3098
3099 GLuint program = glCreateProgram();
3100 glAttachShader(program, shaderVert);
3101 glAttachShader(program, shaderFrag);
3102 glLinkProgram(program);
3103 glUseProgram(program);
3104 expectError(GL_NO_ERROR);
3105
3106 GLint location;
3107
3108 location = glGetUniformLocation(program, "uintUniform");
3109 glUniform1ui(location, 1);
3110 verifyUniformValue1ui(m_testCtx, *this, program, location, 1);
3111
3112 location = glGetUniformLocation(program, "uint2Uniform");
3113 glUniform2ui(location, 1, 2);
3114 verifyUniformValue2ui(m_testCtx, *this, program, location, 1, 2);
3115
3116 location = glGetUniformLocation(program, "uint3Uniform");
3117 glUniform3ui(location, 1, 2, 3);
3118 verifyUniformValue3ui(m_testCtx, *this, program, location, 1, 2, 3);
3119
3120 location = glGetUniformLocation(program, "uint4Uniform");
3121 glUniform4ui(location, 1, 2, 3, 4);
3122 verifyUniformValue4ui(m_testCtx, *this, program, location, 1, 2, 3, 4);
3123
3124 glUseProgram(0);
3125 glDeleteShader(shaderVert);
3126 glDeleteShader(shaderFrag);
3127 glDeleteProgram(program);
3128 expectError(GL_NO_ERROR);
3129 }
3130 };
3131
3132 class UniformValueBooleanCase : public ApiCase
3133 {
3134 public:
UniformValueBooleanCase(Context & context,const char * name,const char * description)3135 UniformValueBooleanCase(Context &context, const char *name, const char *description)
3136 : ApiCase(context, name, description)
3137 {
3138 }
3139
test(void)3140 void test(void)
3141 {
3142 static const char *testVertSource = "#version 300 es\n"
3143 "uniform bool boolUniform;\n"
3144 "uniform bvec2 bool2Uniform;\n"
3145 "uniform bvec3 bool3Uniform;\n"
3146 "uniform bvec4 bool4Uniform;\n"
3147 "void main (void)\n"
3148 "{\n"
3149 " gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + "
3150 "float(bool3Uniform.x) + float(bool4Uniform.x));\n"
3151 "}\n";
3152 static const char *testFragSource = "#version 300 es\n"
3153 "layout(location = 0) out mediump vec4 fragColor;"
3154 "void main (void)\n"
3155 "{\n"
3156 " fragColor = vec4(0.0);\n"
3157 "}\n";
3158
3159 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3160 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3161
3162 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3163 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3164
3165 glCompileShader(shaderVert);
3166 glCompileShader(shaderFrag);
3167 expectError(GL_NO_ERROR);
3168
3169 GLuint program = glCreateProgram();
3170 glAttachShader(program, shaderVert);
3171 glAttachShader(program, shaderFrag);
3172 glLinkProgram(program);
3173 glUseProgram(program);
3174 expectError(GL_NO_ERROR);
3175
3176 GLint location;
3177
3178 // int conversion
3179
3180 location = glGetUniformLocation(program, "boolUniform");
3181 glUniform1i(location, 1);
3182 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3183
3184 location = glGetUniformLocation(program, "bool2Uniform");
3185 glUniform2i(location, 1, 2);
3186 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1);
3187
3188 location = glGetUniformLocation(program, "bool3Uniform");
3189 glUniform3i(location, 0, 1, 2);
3190 verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1);
3191
3192 location = glGetUniformLocation(program, "bool4Uniform");
3193 glUniform4i(location, 1, 0, 1, -1);
3194 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1);
3195
3196 // float conversion
3197
3198 location = glGetUniformLocation(program, "boolUniform");
3199 glUniform1f(location, 1.0f);
3200 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3201
3202 location = glGetUniformLocation(program, "bool2Uniform");
3203 glUniform2f(location, 1.0f, 0.1f);
3204 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1);
3205
3206 location = glGetUniformLocation(program, "bool3Uniform");
3207 glUniform3f(location, 0.0f, 0.1f, -0.1f);
3208 verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1);
3209
3210 location = glGetUniformLocation(program, "bool4Uniform");
3211 glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f);
3212 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1);
3213
3214 glUseProgram(0);
3215 glDeleteShader(shaderVert);
3216 glDeleteShader(shaderFrag);
3217 glDeleteProgram(program);
3218 expectError(GL_NO_ERROR);
3219 }
3220 };
3221
3222 class UniformValueSamplerCase : public ApiCase
3223 {
3224 public:
UniformValueSamplerCase(Context & context,const char * name,const char * description)3225 UniformValueSamplerCase(Context &context, const char *name, const char *description)
3226 : ApiCase(context, name, description)
3227 {
3228 }
3229
test(void)3230 void test(void)
3231 {
3232 static const char *testVertSource = "#version 300 es\n"
3233 "void main (void)\n"
3234 "{\n"
3235 " gl_Position = vec4(0.0);\n"
3236 "}\n";
3237 static const char *testFragSource = "#version 300 es\n"
3238 "uniform highp sampler2D uniformSampler;\n"
3239 "layout(location = 0) out mediump vec4 fragColor;"
3240 "void main (void)\n"
3241 "{\n"
3242 " fragColor = vec4(textureSize(uniformSampler, 0).x);\n"
3243 "}\n";
3244
3245 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3246 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3247
3248 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3249 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3250
3251 glCompileShader(shaderVert);
3252 glCompileShader(shaderFrag);
3253 expectError(GL_NO_ERROR);
3254
3255 GLuint program = glCreateProgram();
3256 glAttachShader(program, shaderVert);
3257 glAttachShader(program, shaderFrag);
3258 glLinkProgram(program);
3259 glUseProgram(program);
3260 expectError(GL_NO_ERROR);
3261
3262 GLint location;
3263
3264 location = glGetUniformLocation(program, "uniformSampler");
3265 glUniform1i(location, 1);
3266 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3267
3268 glUseProgram(0);
3269 glDeleteShader(shaderVert);
3270 glDeleteShader(shaderFrag);
3271 glDeleteProgram(program);
3272 expectError(GL_NO_ERROR);
3273 }
3274 };
3275
3276 class UniformValueArrayCase : public ApiCase
3277 {
3278 public:
UniformValueArrayCase(Context & context,const char * name,const char * description)3279 UniformValueArrayCase(Context &context, const char *name, const char *description)
3280 : ApiCase(context, name, description)
3281 {
3282 }
3283
test(void)3284 void test(void)
3285 {
3286 static const char *testVertSource = "#version 300 es\n"
3287 "uniform highp float arrayUniform[5];"
3288 "uniform highp vec2 array2Uniform[5];"
3289 "uniform highp vec3 array3Uniform[5];"
3290 "uniform highp vec4 array4Uniform[5];"
3291 "void main (void)\n"
3292 "{\n"
3293 " gl_Position = \n"
3294 " + vec4(arrayUniform[0] + arrayUniform[1] + "
3295 "arrayUniform[2] + arrayUniform[3] + arrayUniform[4])\n"
3296 " + vec4(array2Uniform[0].x + array2Uniform[1].x + "
3297 "array2Uniform[2].x + array2Uniform[3].x + array2Uniform[4].x)\n"
3298 " + vec4(array3Uniform[0].x + array3Uniform[1].x + "
3299 "array3Uniform[2].x + array3Uniform[3].x + array3Uniform[4].x)\n"
3300 " + vec4(array4Uniform[0].x + array4Uniform[1].x + "
3301 "array4Uniform[2].x + array4Uniform[3].x + array4Uniform[4].x);\n"
3302 "}\n";
3303 static const char *testFragSource = "#version 300 es\n"
3304 "layout(location = 0) out mediump vec4 fragColor;"
3305 "void main (void)\n"
3306 "{\n"
3307 " fragColor = vec4(0.0);\n"
3308 "}\n";
3309
3310 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3311 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3312
3313 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3314 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3315
3316 glCompileShader(shaderVert);
3317 glCompileShader(shaderFrag);
3318 expectError(GL_NO_ERROR);
3319
3320 GLuint program = glCreateProgram();
3321 glAttachShader(program, shaderVert);
3322 glAttachShader(program, shaderFrag);
3323 glLinkProgram(program);
3324 glUseProgram(program);
3325 expectError(GL_NO_ERROR);
3326
3327 GLint location;
3328
3329 float uniformValue[5 * 4] = {-1.0f, 0.1f, 4.0f, 800.0f, 13.0f, 55.0f, 12.0f, 91.0f, -55.1f, 1.1f,
3330 98.0f, 19.0f, 41.0f, 65.0f, 4.0f, 12.2f, 95.0f, 77.0f, 32.0f, 48.0f};
3331
3332 location = glGetUniformLocation(program, "arrayUniform");
3333 glUniform1fv(location, 5, uniformValue);
3334 expectError(GL_NO_ERROR);
3335
3336 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program, "arrayUniform[0]"),
3337 uniformValue[0]);
3338 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program, "arrayUniform[1]"),
3339 uniformValue[1]);
3340 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program, "arrayUniform[2]"),
3341 uniformValue[2]);
3342 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program, "arrayUniform[3]"),
3343 uniformValue[3]);
3344 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program, "arrayUniform[4]"),
3345 uniformValue[4]);
3346 expectError(GL_NO_ERROR);
3347
3348 location = glGetUniformLocation(program, "array2Uniform");
3349 glUniform2fv(location, 5, uniformValue);
3350 expectError(GL_NO_ERROR);
3351
3352 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program, "array2Uniform[0]"),
3353 uniformValue[2 * 0], uniformValue[(2 * 0) + 1]);
3354 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program, "array2Uniform[1]"),
3355 uniformValue[2 * 1], uniformValue[(2 * 1) + 1]);
3356 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program, "array2Uniform[2]"),
3357 uniformValue[2 * 2], uniformValue[(2 * 2) + 1]);
3358 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program, "array2Uniform[3]"),
3359 uniformValue[2 * 3], uniformValue[(2 * 3) + 1]);
3360 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program, "array2Uniform[4]"),
3361 uniformValue[2 * 4], uniformValue[(2 * 4) + 1]);
3362 expectError(GL_NO_ERROR);
3363
3364 location = glGetUniformLocation(program, "array3Uniform");
3365 glUniform3fv(location, 5, uniformValue);
3366 expectError(GL_NO_ERROR);
3367
3368 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program, "array3Uniform[0]"),
3369 uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]);
3370 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program, "array3Uniform[1]"),
3371 uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]);
3372 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program, "array3Uniform[2]"),
3373 uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]);
3374 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program, "array3Uniform[3]"),
3375 uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]);
3376 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program, "array3Uniform[4]"),
3377 uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]);
3378 expectError(GL_NO_ERROR);
3379
3380 location = glGetUniformLocation(program, "array4Uniform");
3381 glUniform4fv(location, 5, uniformValue);
3382 expectError(GL_NO_ERROR);
3383
3384 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program, "array4Uniform[0]"),
3385 uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2],
3386 uniformValue[(4 * 0) + 3]);
3387 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program, "array4Uniform[1]"),
3388 uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2],
3389 uniformValue[(4 * 1) + 3]);
3390 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program, "array4Uniform[2]"),
3391 uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2],
3392 uniformValue[(4 * 2) + 3]);
3393 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program, "array4Uniform[3]"),
3394 uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2],
3395 uniformValue[(4 * 3) + 3]);
3396 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program, "array4Uniform[4]"),
3397 uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2],
3398 uniformValue[(4 * 4) + 3]);
3399 expectError(GL_NO_ERROR);
3400
3401 glUseProgram(0);
3402 glDeleteShader(shaderVert);
3403 glDeleteShader(shaderFrag);
3404 glDeleteProgram(program);
3405 expectError(GL_NO_ERROR);
3406 }
3407 };
3408
3409 class UniformValueMatrixCase : public ApiCase
3410 {
3411 public:
UniformValueMatrixCase(Context & context,const char * name,const char * description)3412 UniformValueMatrixCase(Context &context, const char *name, const char *description)
3413 : ApiCase(context, name, description)
3414 {
3415 }
3416
test(void)3417 void test(void)
3418 {
3419 static const char *testVertSource =
3420 "#version 300 es\n"
3421 "uniform highp mat2 mat2Uniform;"
3422 "uniform highp mat3 mat3Uniform;"
3423 "uniform highp mat4 mat4Uniform;"
3424 "void main (void)\n"
3425 "{\n"
3426 " gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n"
3427 "}\n";
3428 static const char *testFragSource = "#version 300 es\n"
3429 "layout(location = 0) out mediump vec4 fragColor;"
3430 "void main (void)\n"
3431 "{\n"
3432 " fragColor = vec4(0.0);\n"
3433 "}\n";
3434
3435 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3436 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3437
3438 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3439 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3440
3441 glCompileShader(shaderVert);
3442 glCompileShader(shaderFrag);
3443 expectError(GL_NO_ERROR);
3444
3445 GLuint program = glCreateProgram();
3446 glAttachShader(program, shaderVert);
3447 glAttachShader(program, shaderFrag);
3448 glLinkProgram(program);
3449 glUseProgram(program);
3450 expectError(GL_NO_ERROR);
3451
3452 GLint location;
3453
3454 float matrixValues[4 * 4] = {
3455 -1.0f, 0.1f, 4.0f, 800.0f, 13.0f, 55.0f, 12.0f, 91.0f,
3456 -55.1f, 1.1f, 98.0f, 19.0f, 41.0f, 65.0f, 4.0f, 12.2f,
3457 };
3458
3459 // the values of the matrix are returned in column major order but they can be given in either order
3460
3461 location = glGetUniformLocation(program, "mat2Uniform");
3462 glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues);
3463 verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, false);
3464 glUniformMatrix2fv(location, 1, GL_TRUE, matrixValues);
3465 verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, true);
3466
3467 location = glGetUniformLocation(program, "mat3Uniform");
3468 glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues);
3469 verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, false);
3470 glUniformMatrix3fv(location, 1, GL_TRUE, matrixValues);
3471 verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, true);
3472
3473 location = glGetUniformLocation(program, "mat4Uniform");
3474 glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues);
3475 verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, false);
3476 glUniformMatrix4fv(location, 1, GL_TRUE, matrixValues);
3477 verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, true);
3478
3479 glUseProgram(0);
3480 glDeleteShader(shaderVert);
3481 glDeleteShader(shaderFrag);
3482 glDeleteProgram(program);
3483 expectError(GL_NO_ERROR);
3484 }
3485 };
3486
3487 class PrecisionFormatCase : public ApiCase
3488 {
3489 public:
3490 struct RequiredFormat
3491 {
3492 int negativeRange;
3493 int positiveRange;
3494 int precision;
3495 };
3496
PrecisionFormatCase(Context & context,const char * name,const char * description,glw::GLenum shaderType,glw::GLenum precisionType)3497 PrecisionFormatCase(Context &context, const char *name, const char *description, glw::GLenum shaderType,
3498 glw::GLenum precisionType)
3499 : ApiCase(context, name, description)
3500 , m_shaderType(shaderType)
3501 , m_precisionType(precisionType)
3502 {
3503 }
3504
3505 private:
test(void)3506 void test(void)
3507 {
3508 const RequiredFormat expected = getRequiredFormat();
3509 bool error = false;
3510 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> shaderCompiler;
3511 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]> range;
3512 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> precision;
3513
3514 // query values
3515 glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision);
3516 expectError(GL_NO_ERROR);
3517
3518 if (!range.verifyValidity(m_testCtx))
3519 return;
3520 if (!precision.verifyValidity(m_testCtx))
3521 return;
3522
3523 m_log << tcu::TestLog::Message << "range[0] = " << range[0] << "\n"
3524 << "range[1] = " << range[1] << "\n"
3525 << "precision = " << precision << tcu::TestLog::EndMessage;
3526
3527 // verify values
3528
3529 if (m_precisionType == GL_HIGH_FLOAT)
3530 {
3531 // highp float must be IEEE 754 single
3532
3533 if (range[0] != expected.negativeRange || range[1] != expected.positiveRange ||
3534 precision != expected.precision)
3535 {
3536 m_log << tcu::TestLog::Message << "// ERROR: Invalid precision format, expected:\n"
3537 << "\trange[0] = " << expected.negativeRange << "\n"
3538 << "\trange[1] = " << expected.positiveRange << "\n"
3539 << "\tprecision = " << expected.precision << tcu::TestLog::EndMessage;
3540 error = true;
3541 }
3542 }
3543 else
3544 {
3545 if (range[0] < expected.negativeRange)
3546 {
3547 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to "
3548 << expected.negativeRange << tcu::TestLog::EndMessage;
3549 error = true;
3550 }
3551
3552 if (range[1] < expected.positiveRange)
3553 {
3554 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to "
3555 << expected.positiveRange << tcu::TestLog::EndMessage;
3556 error = true;
3557 }
3558
3559 if (precision < expected.precision)
3560 {
3561 m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to "
3562 << expected.precision << tcu::TestLog::EndMessage;
3563 error = true;
3564 }
3565 }
3566
3567 if (error)
3568 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range");
3569 }
3570
getRequiredFormat(void) const3571 RequiredFormat getRequiredFormat(void) const
3572 {
3573 // Precisions for different types.
3574 const RequiredFormat requirements[] = {
3575 {0, 0, 8}, //!< lowp float
3576 {13, 13, 10}, //!< mediump float
3577 {127, 127, 23}, //!< highp float
3578 {8, 7, 0}, //!< lowp int
3579 {15, 14, 0}, //!< mediump int
3580 {31, 30, 0}, //!< highp int
3581 };
3582 const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT;
3583
3584 DE_ASSERT(ndx >= 0);
3585 DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements));
3586 return requirements[ndx];
3587 }
3588
3589 const glw::GLenum m_shaderType;
3590 const glw::GLenum m_precisionType;
3591 };
3592
3593 } // namespace
3594
ShaderStateQueryTests(Context & context)3595 ShaderStateQueryTests::ShaderStateQueryTests(Context &context)
3596 : TestCaseGroup(context, "shader", "Shader State Query tests")
3597 {
3598 }
3599
init(void)3600 void ShaderStateQueryTests::init(void)
3601 {
3602 // shader
3603 addChild(new ShaderTypeCase(m_context, "shader_type", "SHADER_TYPE"));
3604 addChild(new ShaderCompileStatusCase(m_context, "shader_compile_status", "COMPILE_STATUS"));
3605 addChild(new ShaderInfoLogCase(m_context, "shader_info_log_length", "INFO_LOG_LENGTH"));
3606 addChild(new ShaderSourceCase(m_context, "shader_source_length", "SHADER_SOURCE_LENGTH"));
3607
3608 // shader and program
3609 addChild(new DeleteStatusCase(m_context, "delete_status", "DELETE_STATUS"));
3610
3611 // vertex-attrib
3612 addChild(new CurrentVertexAttribInitialCase(m_context, "current_vertex_attrib_initial", "CURRENT_VERTEX_ATTRIB"));
3613 addChild(new CurrentVertexAttribFloatCase(m_context, "current_vertex_attrib_float", "CURRENT_VERTEX_ATTRIB"));
3614 addChild(new CurrentVertexAttribIntCase(m_context, "current_vertex_attrib_int", "CURRENT_VERTEX_ATTRIB"));
3615 addChild(new CurrentVertexAttribUintCase(m_context, "current_vertex_attrib_uint", "CURRENT_VERTEX_ATTRIB"));
3616 addChild(new CurrentVertexAttribConversionCase(m_context, "current_vertex_attrib_float_to_int",
3617 "CURRENT_VERTEX_ATTRIB"));
3618
3619 // program
3620 addChild(new ProgramInfoLogCase(m_context, "program_info_log_length", "INFO_LOG_LENGTH",
3621 ProgramInfoLogCase::BUILDERROR_COMPILE));
3622 addChild(new ProgramInfoLogCase(m_context, "program_info_log_length_link_error", "INFO_LOG_LENGTH",
3623 ProgramInfoLogCase::BUILDERROR_LINK));
3624 addChild(new ProgramValidateStatusCase(m_context, "program_validate_status", "VALIDATE_STATUS"));
3625 addChild(new ProgramAttachedShadersCase(m_context, "program_attached_shaders", "ATTACHED_SHADERS"));
3626
3627 addChild(new ProgramActiveUniformNameCase(m_context, "program_active_uniform_name",
3628 "ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH"));
3629 addChild(new ProgramUniformCase(m_context, "program_active_uniform_types",
3630 "UNIFORM_TYPE, UNIFORM_SIZE, and UNIFORM_IS_ROW_MAJOR"));
3631 addChild(new ProgramActiveUniformBlocksCase(m_context, "program_active_uniform_blocks", "ACTIVE_UNIFORM_BLOCK_x"));
3632 addChild(new ProgramBinaryCase(m_context, "program_binary",
3633 "PROGRAM_BINARY_LENGTH and PROGRAM_BINARY_RETRIEVABLE_HINT"));
3634
3635 // transform feedback
3636 addChild(new TransformFeedbackCase(
3637 m_context, "transform_feedback",
3638 "TRANSFORM_FEEDBACK_BUFFER_MODE, TRANSFORM_FEEDBACK_VARYINGS, TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH"));
3639
3640 // attribute related
3641 addChild(
3642 new ActiveAttributesCase(m_context, "active_attributes", "ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH"));
3643 addChild(new VertexAttributeSizeCase(m_context, "vertex_attrib_size", "VERTEX_ATTRIB_ARRAY_SIZE"));
3644 addChild(new VertexAttributeTypeCase(m_context, "vertex_attrib_type", "VERTEX_ATTRIB_ARRAY_TYPE"));
3645 addChild(new VertexAttributeStrideCase(m_context, "vertex_attrib_stride", "VERTEX_ATTRIB_ARRAY_STRIDE"));
3646 addChild(
3647 new VertexAttributeNormalizedCase(m_context, "vertex_attrib_normalized", "VERTEX_ATTRIB_ARRAY_NORMALIZED"));
3648 addChild(new VertexAttributeIntegerCase(m_context, "vertex_attrib_integer", "VERTEX_ATTRIB_ARRAY_INTEGER"));
3649 addChild(new VertexAttributeEnabledCase(m_context, "vertex_attrib_array_enabled", "VERTEX_ATTRIB_ARRAY_ENABLED"));
3650 addChild(new VertexAttributeDivisorCase(m_context, "vertex_attrib_array_divisor", "VERTEX_ATTRIB_ARRAY_DIVISOR"));
3651 addChild(new VertexAttributeBufferBindingCase(m_context, "vertex_attrib_array_buffer_binding",
3652 "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"));
3653 addChild(new VertexAttributePointerCase(m_context, "vertex_attrib_pointerv", "GetVertexAttribPointerv"));
3654
3655 // uniform values
3656 addChild(new UniformValueFloatCase(m_context, "uniform_value_float", "GetUniform*"));
3657 addChild(new UniformValueIntCase(m_context, "uniform_value_int", "GetUniform*"));
3658 addChild(new UniformValueUintCase(m_context, "uniform_value_uint", "GetUniform*"));
3659 addChild(new UniformValueBooleanCase(m_context, "uniform_value_boolean", "GetUniform*"));
3660 addChild(new UniformValueSamplerCase(m_context, "uniform_value_sampler", "GetUniform*"));
3661 addChild(new UniformValueArrayCase(m_context, "uniform_value_array", "GetUniform*"));
3662 addChild(new UniformValueMatrixCase(m_context, "uniform_value_matrix", "GetUniform*"));
3663
3664 // precision format query
3665 addChild(new PrecisionFormatCase(m_context, "precision_vertex_lowp_float", "GetShaderPrecisionFormat",
3666 GL_VERTEX_SHADER, GL_LOW_FLOAT));
3667 addChild(new PrecisionFormatCase(m_context, "precision_vertex_mediump_float", "GetShaderPrecisionFormat",
3668 GL_VERTEX_SHADER, GL_MEDIUM_FLOAT));
3669 addChild(new PrecisionFormatCase(m_context, "precision_vertex_highp_float", "GetShaderPrecisionFormat",
3670 GL_VERTEX_SHADER, GL_HIGH_FLOAT));
3671 addChild(new PrecisionFormatCase(m_context, "precision_vertex_lowp_int", "GetShaderPrecisionFormat",
3672 GL_VERTEX_SHADER, GL_LOW_INT));
3673 addChild(new PrecisionFormatCase(m_context, "precision_vertex_mediump_int", "GetShaderPrecisionFormat",
3674 GL_VERTEX_SHADER, GL_MEDIUM_INT));
3675 addChild(new PrecisionFormatCase(m_context, "precision_vertex_highp_int", "GetShaderPrecisionFormat",
3676 GL_VERTEX_SHADER, GL_HIGH_INT));
3677 addChild(new PrecisionFormatCase(m_context, "precision_fragment_lowp_float", "GetShaderPrecisionFormat",
3678 GL_FRAGMENT_SHADER, GL_LOW_FLOAT));
3679 addChild(new PrecisionFormatCase(m_context, "precision_fragment_mediump_float", "GetShaderPrecisionFormat",
3680 GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT));
3681 addChild(new PrecisionFormatCase(m_context, "precision_fragment_highp_float", "GetShaderPrecisionFormat",
3682 GL_FRAGMENT_SHADER, GL_HIGH_FLOAT));
3683 addChild(new PrecisionFormatCase(m_context, "precision_fragment_lowp_int", "GetShaderPrecisionFormat",
3684 GL_FRAGMENT_SHADER, GL_LOW_INT));
3685 addChild(new PrecisionFormatCase(m_context, "precision_fragment_mediump_int", "GetShaderPrecisionFormat",
3686 GL_FRAGMENT_SHADER, GL_MEDIUM_INT));
3687 addChild(new PrecisionFormatCase(m_context, "precision_fragment_highp_int", "GetShaderPrecisionFormat",
3688 GL_FRAGMENT_SHADER, GL_HIGH_INT));
3689 }
3690
3691 } // namespace Functional
3692 } // namespace gles3
3693 } // namespace deqp
3694