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