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 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2193 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2194
2195 // Test with default VAO
2196 if (!isCoreGL45)
2197 {
2198 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2199
2200 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2201 {
2202 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
2203 expectError(GL_NO_ERROR);
2204
2205 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size);
2206 }
2207 }
2208
2209 // Test with multiple VAOs
2210 {
2211 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2212
2213 GLuint buf = 0;
2214 GLuint vaos[2] = {0};
2215
2216 glGenVertexArrays(2, vaos);
2217 glGenBuffers(1, &buf);
2218 glBindBuffer(GL_ARRAY_BUFFER, buf);
2219 expectError(GL_NO_ERROR);
2220
2221 // initial
2222 glBindVertexArray(vaos[0]);
2223 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, 4);
2224 expectError(GL_NO_ERROR);
2225
2226 // set vao 0 to some value
2227 glVertexAttribPointer(0, pointers[0].size, pointers[0].type, pointers[0].normalized, pointers[0].stride, DE_NULL);
2228 expectError(GL_NO_ERROR);
2229
2230 // set vao 1 to some other value
2231 glBindVertexArray(vaos[1]);
2232 glVertexAttribPointer(0, pointers[1].size, pointers[1].type, pointers[1].normalized, pointers[1].stride, DE_NULL);
2233 expectError(GL_NO_ERROR);
2234
2235 // verify vao 1 state
2236 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[1].size);
2237 expectError(GL_NO_ERROR);
2238
2239 // verify vao 0 state
2240 glBindVertexArray(vaos[0]);
2241 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[0].size);
2242 expectError(GL_NO_ERROR);
2243
2244 glDeleteVertexArrays(2, vaos);
2245 glDeleteBuffers(1, &buf);
2246 expectError(GL_NO_ERROR);
2247 }
2248 }
2249 };
2250
2251 class VertexAttributeTypeCase : public ApiCase
2252 {
2253 public:
VertexAttributeTypeCase(Context & context,const char * name,const char * description)2254 VertexAttributeTypeCase (Context& context, const char* name, const char* description)
2255 : ApiCase(context, name, description)
2256 {
2257 }
2258
test(void)2259 void test (void)
2260 {
2261 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2262 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2263
2264 // Test with default VAO
2265 if (!isCoreGL45)
2266 {
2267 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2268
2269 const GLfloat vertexData[4] = {0.0f}; // never accessed
2270
2271 // test VertexAttribPointer
2272 {
2273 const PointerData pointers[] =
2274 {
2275 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
2276 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
2277 { 1, GL_INT, 0, GL_FALSE, vertexData },
2278 { 1, GL_FIXED, 0, GL_FALSE, vertexData },
2279 { 1, GL_FLOAT, 0, GL_FALSE, vertexData },
2280 { 1, GL_HALF_FLOAT, 0, GL_FALSE, vertexData },
2281 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
2282 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
2283 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData },
2284 { 4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData },
2285 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData },
2286 };
2287
2288 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2289 {
2290 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
2291 expectError(GL_NO_ERROR);
2292
2293 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
2294 }
2295 }
2296
2297 // test glVertexAttribIPointer
2298 {
2299 const PointerData pointers[] =
2300 {
2301 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
2302 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
2303 { 1, GL_INT, 0, GL_FALSE, vertexData },
2304 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
2305 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
2306 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData },
2307 };
2308
2309 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2310 {
2311 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
2312 expectError(GL_NO_ERROR);
2313
2314 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
2315 }
2316 }
2317 }
2318
2319 // Test with multiple VAOs
2320 {
2321 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2322
2323 GLuint buf = 0;
2324 GLuint vaos[2] = {0};
2325
2326 glGenVertexArrays(2, vaos);
2327 glGenBuffers(1, &buf);
2328 glBindBuffer(GL_ARRAY_BUFFER, buf);
2329 expectError(GL_NO_ERROR);
2330
2331 // initial
2332 glBindVertexArray(vaos[0]);
2333 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT);
2334 expectError(GL_NO_ERROR);
2335
2336 // set vao 0 to some value
2337 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2338 expectError(GL_NO_ERROR);
2339
2340 // set vao 1 to some other value
2341 glBindVertexArray(vaos[1]);
2342 glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 0, DE_NULL);
2343 expectError(GL_NO_ERROR);
2344
2345 // verify vao 1 state
2346 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_SHORT);
2347 expectError(GL_NO_ERROR);
2348
2349 // verify vao 0 state
2350 glBindVertexArray(vaos[0]);
2351 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_FLOAT);
2352 expectError(GL_NO_ERROR);
2353
2354 glDeleteVertexArrays(2, vaos);
2355 glDeleteBuffers(1, &buf);
2356 expectError(GL_NO_ERROR);
2357 }
2358 }
2359 };
2360
2361 class VertexAttributeStrideCase : public ApiCase
2362 {
2363 public:
VertexAttributeStrideCase(Context & context,const char * name,const char * description)2364 VertexAttributeStrideCase (Context& context, const char* name, const char* description)
2365 : ApiCase(context, name, description)
2366 {
2367 }
2368
test(void)2369 void test (void)
2370 {
2371 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2372 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2373
2374 // Test with default VAO
2375 if (!isCoreGL45)
2376 {
2377 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2378
2379 const GLfloat vertexData[4] = {0.0f}; // never accessed
2380
2381 struct StridePointerData
2382 {
2383 GLint size;
2384 GLenum type;
2385 GLint stride;
2386 const void* pointer;
2387 };
2388
2389 // test VertexAttribPointer
2390 {
2391 const StridePointerData pointers[] =
2392 {
2393 { 1, GL_FLOAT, 0, vertexData },
2394 { 1, GL_FLOAT, 1, vertexData },
2395 { 1, GL_FLOAT, 4, vertexData },
2396 { 1, GL_HALF_FLOAT, 0, vertexData },
2397 { 1, GL_HALF_FLOAT, 1, vertexData },
2398 { 1, GL_HALF_FLOAT, 4, vertexData },
2399 { 1, GL_FIXED, 0, vertexData },
2400 { 1, GL_FIXED, 1, vertexData },
2401 { 1, GL_FIXED, 4, vertexData },
2402 };
2403
2404 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2405 {
2406 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride, pointers[ndx].pointer);
2407 expectError(GL_NO_ERROR);
2408
2409 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
2410 }
2411 }
2412
2413 // test glVertexAttribIPointer
2414 {
2415 const StridePointerData pointers[] =
2416 {
2417 { 1, GL_INT, 0, vertexData },
2418 { 1, GL_INT, 1, vertexData },
2419 { 1, GL_INT, 4, vertexData },
2420 { 4, GL_UNSIGNED_BYTE, 0, vertexData },
2421 { 4, GL_UNSIGNED_BYTE, 1, vertexData },
2422 { 4, GL_UNSIGNED_BYTE, 4, vertexData },
2423 { 2, GL_SHORT, 0, vertexData },
2424 { 2, GL_SHORT, 1, vertexData },
2425 { 2, GL_SHORT, 4, vertexData },
2426 };
2427
2428 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2429 {
2430 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
2431 expectError(GL_NO_ERROR);
2432
2433 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
2434 }
2435 }
2436 }
2437
2438 // Test with multiple VAOs
2439 {
2440 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2441
2442 GLuint buf = 0;
2443 GLuint vaos[2] = {0};
2444
2445 glGenVertexArrays(2, vaos);
2446 glGenBuffers(1, &buf);
2447 glBindBuffer(GL_ARRAY_BUFFER, buf);
2448 expectError(GL_NO_ERROR);
2449
2450 // initial
2451 glBindVertexArray(vaos[0]);
2452 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0);
2453 expectError(GL_NO_ERROR);
2454
2455 // set vao 0 to some value
2456 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 4, DE_NULL);
2457 expectError(GL_NO_ERROR);
2458
2459 // set vao 1 to some other value
2460 glBindVertexArray(vaos[1]);
2461 glVertexAttribPointer(0, 1, GL_SHORT, GL_FALSE, 8, DE_NULL);
2462 expectError(GL_NO_ERROR);
2463
2464 // verify vao 1 state
2465 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 8);
2466 expectError(GL_NO_ERROR);
2467
2468 // verify vao 0 state
2469 glBindVertexArray(vaos[0]);
2470 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 4);
2471 expectError(GL_NO_ERROR);
2472
2473 glDeleteVertexArrays(2, vaos);
2474 glDeleteBuffers(1, &buf);
2475 expectError(GL_NO_ERROR);
2476 }
2477 }
2478 };
2479
2480 class VertexAttributeNormalizedCase : public ApiCase
2481 {
2482 public:
VertexAttributeNormalizedCase(Context & context,const char * name,const char * description)2483 VertexAttributeNormalizedCase (Context& context, const char* name, const char* description)
2484 : ApiCase(context, name, description)
2485 {
2486 }
2487
test(void)2488 void test (void)
2489 {
2490 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2491 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2492
2493 // Test with default VAO
2494 if (!isCoreGL45)
2495 {
2496 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2497
2498 const GLfloat vertexData[4] = {0.0f}; // never accessed
2499
2500 // test VertexAttribPointer
2501 {
2502 const PointerData pointers[] =
2503 {
2504 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
2505 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
2506 { 1, GL_INT, 0, GL_FALSE, vertexData },
2507 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
2508 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
2509 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData },
2510 { 4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData },
2511 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData },
2512 { 1, GL_BYTE, 0, GL_TRUE, vertexData },
2513 { 1, GL_SHORT, 0, GL_TRUE, vertexData },
2514 { 1, GL_INT, 0, GL_TRUE, vertexData },
2515 { 1, GL_UNSIGNED_BYTE, 0, GL_TRUE, vertexData },
2516 { 1, GL_UNSIGNED_SHORT, 0, GL_TRUE, vertexData },
2517 { 1, GL_UNSIGNED_INT, 0, GL_TRUE, vertexData },
2518 { 4, GL_INT_2_10_10_10_REV, 0, GL_TRUE, vertexData },
2519 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_TRUE, vertexData },
2520 };
2521
2522 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2523 {
2524 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
2525 expectError(GL_NO_ERROR);
2526
2527 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx].normalized);
2528 }
2529 }
2530
2531 // test glVertexAttribIPointer
2532 {
2533 const PointerData pointers[] =
2534 {
2535 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
2536 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
2537 { 1, GL_INT, 0, GL_FALSE, vertexData },
2538 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
2539 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
2540 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData },
2541 };
2542
2543 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2544 {
2545 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
2546 expectError(GL_NO_ERROR);
2547
2548 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
2549 }
2550 }
2551 }
2552
2553 // Test with multiple VAOs
2554 {
2555 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2556
2557 GLuint buf = 0;
2558 GLuint vaos[2] = {0};
2559
2560 glGenVertexArrays(2, vaos);
2561 glGenBuffers(1, &buf);
2562 glBindBuffer(GL_ARRAY_BUFFER, buf);
2563 expectError(GL_NO_ERROR);
2564
2565 // initial
2566 glBindVertexArray(vaos[0]);
2567 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
2568 expectError(GL_NO_ERROR);
2569
2570 // set vao 0 to some value
2571 glVertexAttribPointer(0, 1, GL_INT, GL_TRUE, 0, DE_NULL);
2572 expectError(GL_NO_ERROR);
2573
2574 // set vao 1 to some other value
2575 glBindVertexArray(vaos[1]);
2576 glVertexAttribPointer(0, 1, GL_INT, GL_FALSE, 0, DE_NULL);
2577 expectError(GL_NO_ERROR);
2578
2579 // verify vao 1 state
2580 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE);
2581 expectError(GL_NO_ERROR);
2582
2583 // verify vao 0 state
2584 glBindVertexArray(vaos[0]);
2585 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_TRUE);
2586 expectError(GL_NO_ERROR);
2587
2588 glDeleteVertexArrays(2, vaos);
2589 glDeleteBuffers(1, &buf);
2590 expectError(GL_NO_ERROR);
2591 }
2592 }
2593 };
2594
2595 class VertexAttributeIntegerCase : public ApiCase
2596 {
2597 public:
VertexAttributeIntegerCase(Context & context,const char * name,const char * description)2598 VertexAttributeIntegerCase (Context& context, const char* name, const char* description)
2599 : ApiCase(context, name, description)
2600 {
2601 }
2602
test(void)2603 void test (void)
2604 {
2605 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2606 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2607
2608 // Test with default VAO
2609 if (!isCoreGL45)
2610 {
2611 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2612
2613 const GLfloat vertexData[4] = {0.0f}; // never accessed
2614
2615 // test VertexAttribPointer
2616 {
2617 const PointerData pointers[] =
2618 {
2619 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
2620 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
2621 { 1, GL_INT, 0, GL_FALSE, vertexData },
2622 { 1, GL_FIXED, 0, GL_FALSE, vertexData },
2623 { 1, GL_FLOAT, 0, GL_FALSE, vertexData },
2624 { 1, GL_HALF_FLOAT, 0, GL_FALSE, vertexData },
2625 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
2626 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
2627 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData },
2628 { 4, GL_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData },
2629 { 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, GL_FALSE, vertexData },
2630 };
2631
2632 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2633 {
2634 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
2635 expectError(GL_NO_ERROR);
2636
2637 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
2638 }
2639 }
2640
2641 // test glVertexAttribIPointer
2642 {
2643 const PointerData pointers[] =
2644 {
2645 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
2646 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
2647 { 1, GL_INT, 0, GL_FALSE, vertexData },
2648 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
2649 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
2650 { 1, GL_UNSIGNED_INT, 0, GL_FALSE, vertexData },
2651 };
2652
2653 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2654 {
2655 glVertexAttribIPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].stride, pointers[ndx].pointer);
2656 expectError(GL_NO_ERROR);
2657
2658 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE);
2659 }
2660 }
2661 }
2662
2663 // Test with multiple VAOs
2664 {
2665 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2666
2667 GLuint buf = 0;
2668 GLuint vaos[2] = {0};
2669
2670 glGenVertexArrays(2, vaos);
2671 glGenBuffers(1, &buf);
2672 glBindBuffer(GL_ARRAY_BUFFER, buf);
2673 expectError(GL_NO_ERROR);
2674
2675 // initial
2676 glBindVertexArray(vaos[0]);
2677 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
2678 expectError(GL_NO_ERROR);
2679
2680 // set vao 0 to some value
2681 glVertexAttribIPointer(0, 1, GL_INT, 0, DE_NULL);
2682 expectError(GL_NO_ERROR);
2683
2684 // set vao 1 to some other value
2685 glBindVertexArray(vaos[1]);
2686 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2687 expectError(GL_NO_ERROR);
2688
2689 // verify vao 1 state
2690 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE);
2691 expectError(GL_NO_ERROR);
2692
2693 // verify vao 0 state
2694 glBindVertexArray(vaos[0]);
2695 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_TRUE);
2696 expectError(GL_NO_ERROR);
2697
2698 glDeleteVertexArrays(2, vaos);
2699 glDeleteBuffers(1, &buf);
2700 expectError(GL_NO_ERROR);
2701 }
2702 }
2703 };
2704
2705 class VertexAttributeEnabledCase : public ApiCase
2706 {
2707 public:
VertexAttributeEnabledCase(Context & context,const char * name,const char * description)2708 VertexAttributeEnabledCase (Context& context, const char* name, const char* description)
2709 : ApiCase(context, name, description)
2710 {
2711 }
2712
test(void)2713 void test (void)
2714 {
2715 // VERTEX_ATTRIB_ARRAY_ENABLED
2716
2717 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2718 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2719
2720 // Test with default VAO
2721 if (!isCoreGL45)
2722 {
2723 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2724
2725 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
2726 glEnableVertexAttribArray(0);
2727 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
2728 glDisableVertexAttribArray(0);
2729 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
2730 }
2731
2732 // Test with multiple VAOs
2733 {
2734 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2735
2736 GLuint vaos[2] = {0};
2737
2738 glGenVertexArrays(2, vaos);
2739 expectError(GL_NO_ERROR);
2740
2741 // set vao 0 to some value
2742 glBindVertexArray(vaos[0]);
2743 glEnableVertexAttribArray(0);
2744 expectError(GL_NO_ERROR);
2745
2746 // set vao 1 to some other value
2747 glBindVertexArray(vaos[1]);
2748 glDisableVertexAttribArray(0);
2749 expectError(GL_NO_ERROR);
2750
2751 // verify vao 1 state
2752 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
2753 expectError(GL_NO_ERROR);
2754
2755 // verify vao 0 state
2756 glBindVertexArray(vaos[0]);
2757 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
2758 expectError(GL_NO_ERROR);
2759
2760 glDeleteVertexArrays(2, vaos);
2761 expectError(GL_NO_ERROR);
2762 }
2763 }
2764 };
2765
2766 class VertexAttributeDivisorCase : public ApiCase
2767 {
2768 public:
VertexAttributeDivisorCase(Context & context,const char * name,const char * description)2769 VertexAttributeDivisorCase (Context& context, const char* name, const char* description)
2770 : ApiCase(context, name, description)
2771 {
2772 }
2773
test(void)2774 void test (void)
2775 {
2776 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2777 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2778
2779 // Test with default VAO
2780 if (!isCoreGL45)
2781 {
2782 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2783
2784 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0);
2785 glVertexAttribDivisor(0, 1);
2786 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1);
2787 glVertexAttribDivisor(0, 5);
2788 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5);
2789 }
2790
2791 // Test with multiple VAOs
2792 {
2793 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2794
2795 GLuint vaos[2] = {0};
2796
2797 glGenVertexArrays(2, vaos);
2798 expectError(GL_NO_ERROR);
2799
2800 // set vao 0 to some value
2801 glBindVertexArray(vaos[0]);
2802 glVertexAttribDivisor(0, 1);
2803 expectError(GL_NO_ERROR);
2804
2805 // set vao 1 to some other value
2806 glBindVertexArray(vaos[1]);
2807 glVertexAttribDivisor(0, 5);
2808 expectError(GL_NO_ERROR);
2809
2810 // verify vao 1 state
2811 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 5);
2812 expectError(GL_NO_ERROR);
2813
2814 // verify vao 0 state
2815 glBindVertexArray(vaos[0]);
2816 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1);
2817 expectError(GL_NO_ERROR);
2818
2819 glDeleteVertexArrays(2, vaos);
2820 expectError(GL_NO_ERROR);
2821 }
2822 }
2823 };
2824
2825 class VertexAttributeBufferBindingCase : public ApiCase
2826 {
2827 public:
VertexAttributeBufferBindingCase(Context & context,const char * name,const char * description)2828 VertexAttributeBufferBindingCase (Context& context, const char* name, const char* description)
2829 : ApiCase(context, name, description)
2830 {
2831 }
2832
test(void)2833 void test (void)
2834 {
2835 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2836 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2837
2838 // Test with default VAO
2839 if (!isCoreGL45)
2840 {
2841 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2842
2843 // initial
2844 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0);
2845
2846 GLuint bufferID;
2847 glGenBuffers(1, &bufferID);
2848 glBindBuffer(GL_ARRAY_BUFFER, bufferID);
2849 expectError(GL_NO_ERROR);
2850
2851 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2852 expectError(GL_NO_ERROR);
2853
2854 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID);
2855
2856 glDeleteBuffers(1, &bufferID);
2857 expectError(GL_NO_ERROR);
2858 }
2859
2860 // Test with multiple VAOs
2861 {
2862 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2863
2864 GLuint vaos[2] = {0};
2865 GLuint bufs[2] = {0};
2866
2867 glGenBuffers(2, bufs);
2868 expectError(GL_NO_ERROR);
2869
2870 glGenVertexArrays(2, vaos);
2871 expectError(GL_NO_ERROR);
2872
2873 // set vao 0 to some value
2874 glBindVertexArray(vaos[0]);
2875 glBindBuffer(GL_ARRAY_BUFFER, bufs[0]);
2876 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2877 expectError(GL_NO_ERROR);
2878
2879 // set vao 1 to some other value
2880 glBindVertexArray(vaos[1]);
2881 glBindBuffer(GL_ARRAY_BUFFER, bufs[1]);
2882 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2883 expectError(GL_NO_ERROR);
2884
2885 // verify vao 1 state
2886 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[1]);
2887 expectError(GL_NO_ERROR);
2888
2889 // verify vao 0 state
2890 glBindVertexArray(vaos[0]);
2891 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufs[0]);
2892 expectError(GL_NO_ERROR);
2893
2894 glDeleteVertexArrays(2, vaos);
2895 glDeleteBuffers(2, bufs);
2896 expectError(GL_NO_ERROR);
2897 }
2898 }
2899 };
2900
2901 class VertexAttributePointerCase : public ApiCase
2902 {
2903 public:
VertexAttributePointerCase(Context & context,const char * name,const char * description)2904 VertexAttributePointerCase (Context& context, const char* name, const char* description)
2905 : ApiCase(context, name, description)
2906 {
2907 }
2908
test(void)2909 void test (void)
2910 {
2911 const glu::ContextType& contextType = m_context.getRenderContext().getType();
2912 const bool isCoreGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2913
2914 // Test with default VAO
2915 if (!isCoreGL45)
2916 {
2917 const tcu::ScopedLogSection section(m_log, "DefaultVAO", "Test with default VAO");
2918
2919 StateQueryMemoryWriteGuard<GLvoid*> initialState;
2920 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState);
2921 initialState.verifyValidity(m_testCtx);
2922 checkPointerEquals(m_testCtx, initialState, 0);
2923
2924 const GLfloat vertexData[4] = {0.0f}; // never accessed
2925 const PointerData pointers[] =
2926 {
2927 { 1, GL_BYTE, 0, GL_FALSE, &vertexData[2] },
2928 { 1, GL_SHORT, 0, GL_FALSE, &vertexData[1] },
2929 { 1, GL_INT, 0, GL_FALSE, &vertexData[2] },
2930 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[2] },
2931 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[1] },
2932 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[0] },
2933 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[3] },
2934 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[2] },
2935 { 1, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[0] },
2936 { 4, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[1] },
2937 { 4, GL_HALF_FLOAT, 0, GL_FALSE, &vertexData[2] },
2938 };
2939
2940 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
2941 {
2942 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
2943 expectError(GL_NO_ERROR);
2944
2945 StateQueryMemoryWriteGuard<GLvoid*> state;
2946 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
2947 state.verifyValidity(m_testCtx);
2948 checkPointerEquals(m_testCtx, state, pointers[ndx].pointer);
2949 }
2950 }
2951
2952 // Test with multiple VAOs
2953 {
2954 const tcu::ScopedLogSection section(m_log, "WithVAO", "Test with VAO");
2955
2956 GLuint vaos[2] = {0};
2957 GLuint bufs[2] = {0};
2958
2959 glGenBuffers(2, bufs);
2960 expectError(GL_NO_ERROR);
2961
2962 glGenVertexArrays(2, vaos);
2963 expectError(GL_NO_ERROR);
2964
2965 // set vao 0 to some value
2966 glBindVertexArray(vaos[0]);
2967 glBindBuffer(GL_ARRAY_BUFFER, bufs[0]);
2968 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, glu::BufferOffsetAsPointer(8));
2969 expectError(GL_NO_ERROR);
2970
2971 // set vao 1 to some other value
2972 glBindVertexArray(vaos[1]);
2973 glBindBuffer(GL_ARRAY_BUFFER, bufs[1]);
2974 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, glu::BufferOffsetAsPointer(4));
2975 expectError(GL_NO_ERROR);
2976
2977 // verify vao 1 state
2978 {
2979 StateQueryMemoryWriteGuard<GLvoid*> state;
2980 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
2981 state.verifyValidity(m_testCtx);
2982 checkPointerEquals(m_testCtx, state, glu::BufferOffsetAsPointer(4));
2983 }
2984 expectError(GL_NO_ERROR);
2985
2986 // verify vao 0 state
2987 glBindVertexArray(vaos[0]);
2988 {
2989 StateQueryMemoryWriteGuard<GLvoid*> state;
2990 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
2991 state.verifyValidity(m_testCtx);
2992 checkPointerEquals(m_testCtx, state, glu::BufferOffsetAsPointer(8));
2993 }
2994 expectError(GL_NO_ERROR);
2995
2996 glDeleteVertexArrays(2, vaos);
2997 glDeleteBuffers(2, bufs);
2998 expectError(GL_NO_ERROR);
2999 }
3000 }
3001 };
3002
3003 class UniformValueFloatCase : public ApiCase
3004 {
3005 public:
UniformValueFloatCase(Context & context,const char * name,const char * description)3006 UniformValueFloatCase (Context& context, const char* name, const char* description)
3007 : ApiCase(context, name, description)
3008 {
3009 }
3010
test(void)3011 void test (void)
3012 {
3013 static const char* testVertSource =
3014 "#version 300 es\n"
3015 "uniform highp float floatUniform;\n"
3016 "uniform highp vec2 float2Uniform;\n"
3017 "uniform highp vec3 float3Uniform;\n"
3018 "uniform highp vec4 float4Uniform;\n"
3019 "void main (void)\n"
3020 "{\n"
3021 " gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n"
3022 "}\n";
3023 static const char* testFragSource =
3024 "#version 300 es\n"
3025 "layout(location = 0) out mediump vec4 fragColor;"
3026 "void main (void)\n"
3027 "{\n"
3028 " fragColor = vec4(0.0);\n"
3029 "}\n";
3030
3031 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3032 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3033
3034 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3035 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3036
3037 glCompileShader(shaderVert);
3038 glCompileShader(shaderFrag);
3039 expectError(GL_NO_ERROR);
3040
3041 GLuint program = glCreateProgram();
3042 glAttachShader(program, shaderVert);
3043 glAttachShader(program, shaderFrag);
3044 glLinkProgram(program);
3045 glUseProgram(program);
3046 expectError(GL_NO_ERROR);
3047
3048 GLint location;
3049
3050 location = glGetUniformLocation(program,"floatUniform");
3051 glUniform1f(location, 1.0f);
3052 verifyUniformValue1f(m_testCtx, *this, program, location, 1.0f);
3053
3054 location = glGetUniformLocation(program,"float2Uniform");
3055 glUniform2f(location, 1.0f, 2.0f);
3056 verifyUniformValue2f(m_testCtx, *this, program, location, 1.0f, 2.0f);
3057
3058 location = glGetUniformLocation(program,"float3Uniform");
3059 glUniform3f(location, 1.0f, 2.0f, 3.0f);
3060 verifyUniformValue3f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f);
3061
3062 location = glGetUniformLocation(program,"float4Uniform");
3063 glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f);
3064 verifyUniformValue4f(m_testCtx, *this, program, location, 1.0f, 2.0f, 3.0f, 4.0f);
3065
3066 glUseProgram(0);
3067 glDeleteShader(shaderVert);
3068 glDeleteShader(shaderFrag);
3069 glDeleteProgram(program);
3070 expectError(GL_NO_ERROR);
3071 }
3072 };
3073
3074 class UniformValueIntCase : public ApiCase
3075 {
3076 public:
UniformValueIntCase(Context & context,const char * name,const char * description)3077 UniformValueIntCase (Context& context, const char* name, const char* description)
3078 : ApiCase(context, name, description)
3079 {
3080 }
3081
test(void)3082 void test (void)
3083 {
3084 static const char* testVertSource =
3085 "#version 300 es\n"
3086 "uniform highp int intUniform;\n"
3087 "uniform highp ivec2 int2Uniform;\n"
3088 "uniform highp ivec3 int3Uniform;\n"
3089 "uniform highp ivec4 int4Uniform;\n"
3090 "void main (void)\n"
3091 "{\n"
3092 " gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n"
3093 "}\n";
3094 static const char* testFragSource =
3095 "#version 300 es\n"
3096 "layout(location = 0) out mediump vec4 fragColor;"
3097 "void main (void)\n"
3098 "{\n"
3099 " fragColor = vec4(0.0);\n"
3100 "}\n";
3101
3102 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3103 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3104
3105 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3106 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3107
3108 glCompileShader(shaderVert);
3109 glCompileShader(shaderFrag);
3110 expectError(GL_NO_ERROR);
3111
3112 GLuint program = glCreateProgram();
3113 glAttachShader(program, shaderVert);
3114 glAttachShader(program, shaderFrag);
3115 glLinkProgram(program);
3116 glUseProgram(program);
3117 expectError(GL_NO_ERROR);
3118
3119 GLint location;
3120
3121 location = glGetUniformLocation(program,"intUniform");
3122 glUniform1i(location, 1);
3123 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3124
3125 location = glGetUniformLocation(program,"int2Uniform");
3126 glUniform2i(location, 1, 2);
3127 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 2);
3128
3129 location = glGetUniformLocation(program,"int3Uniform");
3130 glUniform3i(location, 1, 2, 3);
3131 verifyUniformValue3i(m_testCtx, *this, program, location, 1, 2, 3);
3132
3133 location = glGetUniformLocation(program,"int4Uniform");
3134 glUniform4i(location, 1, 2, 3, 4);
3135 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 2, 3, 4);
3136
3137 glUseProgram(0);
3138 glDeleteShader(shaderVert);
3139 glDeleteShader(shaderFrag);
3140 glDeleteProgram(program);
3141 expectError(GL_NO_ERROR);
3142 }
3143 };
3144
3145 class UniformValueUintCase : public ApiCase
3146 {
3147 public:
UniformValueUintCase(Context & context,const char * name,const char * description)3148 UniformValueUintCase (Context& context, const char* name, const char* description)
3149 : ApiCase(context, name, description)
3150 {
3151 }
3152
test(void)3153 void test (void)
3154 {
3155 static const char* testVertSource =
3156 "#version 300 es\n"
3157 "uniform highp uint uintUniform;\n"
3158 "uniform highp uvec2 uint2Uniform;\n"
3159 "uniform highp uvec3 uint3Uniform;\n"
3160 "uniform highp uvec4 uint4Uniform;\n"
3161 "void main (void)\n"
3162 "{\n"
3163 " gl_Position = vec4(float(uintUniform + uint2Uniform.x + uint3Uniform.x + uint4Uniform.x));\n"
3164 "}\n";
3165 static const char* testFragSource =
3166 "#version 300 es\n"
3167 "layout(location = 0) out mediump vec4 fragColor;"
3168 "void main (void)\n"
3169 "{\n"
3170 " fragColor = vec4(0.0);\n"
3171 "}\n";
3172
3173 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3174 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3175
3176 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3177 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3178
3179 glCompileShader(shaderVert);
3180 glCompileShader(shaderFrag);
3181 expectError(GL_NO_ERROR);
3182
3183 GLuint program = glCreateProgram();
3184 glAttachShader(program, shaderVert);
3185 glAttachShader(program, shaderFrag);
3186 glLinkProgram(program);
3187 glUseProgram(program);
3188 expectError(GL_NO_ERROR);
3189
3190 GLint location;
3191
3192 location = glGetUniformLocation(program,"uintUniform");
3193 glUniform1ui(location, 1);
3194 verifyUniformValue1ui(m_testCtx, *this, program, location, 1);
3195
3196 location = glGetUniformLocation(program,"uint2Uniform");
3197 glUniform2ui(location, 1, 2);
3198 verifyUniformValue2ui(m_testCtx, *this, program, location, 1, 2);
3199
3200 location = glGetUniformLocation(program,"uint3Uniform");
3201 glUniform3ui(location, 1, 2, 3);
3202 verifyUniformValue3ui(m_testCtx, *this, program, location, 1, 2, 3);
3203
3204 location = glGetUniformLocation(program,"uint4Uniform");
3205 glUniform4ui(location, 1, 2, 3, 4);
3206 verifyUniformValue4ui(m_testCtx, *this, program, location, 1, 2, 3, 4);
3207
3208 glUseProgram(0);
3209 glDeleteShader(shaderVert);
3210 glDeleteShader(shaderFrag);
3211 glDeleteProgram(program);
3212 expectError(GL_NO_ERROR);
3213 }
3214 };
3215
3216
3217 class UniformValueBooleanCase : public ApiCase
3218 {
3219 public:
UniformValueBooleanCase(Context & context,const char * name,const char * description)3220 UniformValueBooleanCase (Context& context, const char* name, const char* description)
3221 : ApiCase(context, name, description)
3222 {
3223 }
3224
test(void)3225 void test (void)
3226 {
3227 static const char* testVertSource =
3228 "#version 300 es\n"
3229 "uniform bool boolUniform;\n"
3230 "uniform bvec2 bool2Uniform;\n"
3231 "uniform bvec3 bool3Uniform;\n"
3232 "uniform bvec4 bool4Uniform;\n"
3233 "void main (void)\n"
3234 "{\n"
3235 " gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n"
3236 "}\n";
3237 static const char* testFragSource =
3238 "#version 300 es\n"
3239 "layout(location = 0) out mediump vec4 fragColor;"
3240 "void main (void)\n"
3241 "{\n"
3242 " fragColor = vec4(0.0);\n"
3243 "}\n";
3244
3245 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3246 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3247
3248 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3249 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3250
3251 glCompileShader(shaderVert);
3252 glCompileShader(shaderFrag);
3253 expectError(GL_NO_ERROR);
3254
3255 GLuint program = glCreateProgram();
3256 glAttachShader(program, shaderVert);
3257 glAttachShader(program, shaderFrag);
3258 glLinkProgram(program);
3259 glUseProgram(program);
3260 expectError(GL_NO_ERROR);
3261
3262 GLint location;
3263
3264 // int conversion
3265
3266 location = glGetUniformLocation(program,"boolUniform");
3267 glUniform1i(location, 1);
3268 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3269
3270 location = glGetUniformLocation(program,"bool2Uniform");
3271 glUniform2i(location, 1, 2);
3272 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1);
3273
3274 location = glGetUniformLocation(program,"bool3Uniform");
3275 glUniform3i(location, 0, 1, 2);
3276 verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1);
3277
3278 location = glGetUniformLocation(program,"bool4Uniform");
3279 glUniform4i(location, 1, 0, 1, -1);
3280 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1);
3281
3282 // float conversion
3283
3284 location = glGetUniformLocation(program,"boolUniform");
3285 glUniform1f(location, 1.0f);
3286 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3287
3288 location = glGetUniformLocation(program,"bool2Uniform");
3289 glUniform2f(location, 1.0f, 0.1f);
3290 verifyUniformValue2i(m_testCtx, *this, program, location, 1, 1);
3291
3292 location = glGetUniformLocation(program,"bool3Uniform");
3293 glUniform3f(location, 0.0f, 0.1f, -0.1f);
3294 verifyUniformValue3i(m_testCtx, *this, program, location, 0, 1, 1);
3295
3296 location = glGetUniformLocation(program,"bool4Uniform");
3297 glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f);
3298 verifyUniformValue4i(m_testCtx, *this, program, location, 1, 0, 1, 1);
3299
3300 glUseProgram(0);
3301 glDeleteShader(shaderVert);
3302 glDeleteShader(shaderFrag);
3303 glDeleteProgram(program);
3304 expectError(GL_NO_ERROR);
3305 }
3306 };
3307
3308 class UniformValueSamplerCase : public ApiCase
3309 {
3310 public:
UniformValueSamplerCase(Context & context,const char * name,const char * description)3311 UniformValueSamplerCase (Context& context, const char* name, const char* description)
3312 : ApiCase(context, name, description)
3313 {
3314 }
3315
test(void)3316 void test (void)
3317 {
3318 static const char* testVertSource =
3319 "#version 300 es\n"
3320 "void main (void)\n"
3321 "{\n"
3322 " gl_Position = vec4(0.0);\n"
3323 "}\n";
3324 static const char* testFragSource =
3325 "#version 300 es\n"
3326 "uniform highp sampler2D uniformSampler;\n"
3327 "layout(location = 0) out mediump vec4 fragColor;"
3328 "void main (void)\n"
3329 "{\n"
3330 " fragColor = vec4(textureSize(uniformSampler, 0).x);\n"
3331 "}\n";
3332
3333 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3334 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3335
3336 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3337 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3338
3339 glCompileShader(shaderVert);
3340 glCompileShader(shaderFrag);
3341 expectError(GL_NO_ERROR);
3342
3343 GLuint program = glCreateProgram();
3344 glAttachShader(program, shaderVert);
3345 glAttachShader(program, shaderFrag);
3346 glLinkProgram(program);
3347 glUseProgram(program);
3348 expectError(GL_NO_ERROR);
3349
3350 GLint location;
3351
3352 location = glGetUniformLocation(program,"uniformSampler");
3353 glUniform1i(location, 1);
3354 verifyUniformValue1i(m_testCtx, *this, program, location, 1);
3355
3356 glUseProgram(0);
3357 glDeleteShader(shaderVert);
3358 glDeleteShader(shaderFrag);
3359 glDeleteProgram(program);
3360 expectError(GL_NO_ERROR);
3361 }
3362 };
3363
3364 class UniformValueArrayCase : public ApiCase
3365 {
3366 public:
UniformValueArrayCase(Context & context,const char * name,const char * description)3367 UniformValueArrayCase (Context& context, const char* name, const char* description)
3368 : ApiCase(context, name, description)
3369 {
3370 }
3371
test(void)3372 void test (void)
3373 {
3374 static const char* testVertSource =
3375 "#version 300 es\n"
3376 "uniform highp float arrayUniform[5];"
3377 "uniform highp vec2 array2Uniform[5];"
3378 "uniform highp vec3 array3Uniform[5];"
3379 "uniform highp vec4 array4Uniform[5];"
3380 "void main (void)\n"
3381 "{\n"
3382 " gl_Position = \n"
3383 " + vec4(arrayUniform[0] + arrayUniform[1] + arrayUniform[2] + arrayUniform[3] + arrayUniform[4])\n"
3384 " + vec4(array2Uniform[0].x + array2Uniform[1].x + array2Uniform[2].x + array2Uniform[3].x + array2Uniform[4].x)\n"
3385 " + vec4(array3Uniform[0].x + array3Uniform[1].x + array3Uniform[2].x + array3Uniform[3].x + array3Uniform[4].x)\n"
3386 " + vec4(array4Uniform[0].x + array4Uniform[1].x + array4Uniform[2].x + array4Uniform[3].x + array4Uniform[4].x);\n"
3387 "}\n";
3388 static const char* testFragSource =
3389 "#version 300 es\n"
3390 "layout(location = 0) out mediump vec4 fragColor;"
3391 "void main (void)\n"
3392 "{\n"
3393 " fragColor = vec4(0.0);\n"
3394 "}\n";
3395
3396 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3397 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3398
3399 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3400 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3401
3402 glCompileShader(shaderVert);
3403 glCompileShader(shaderFrag);
3404 expectError(GL_NO_ERROR);
3405
3406 GLuint program = glCreateProgram();
3407 glAttachShader(program, shaderVert);
3408 glAttachShader(program, shaderFrag);
3409 glLinkProgram(program);
3410 glUseProgram(program);
3411 expectError(GL_NO_ERROR);
3412
3413 GLint location;
3414
3415 float uniformValue[5 * 4] =
3416 {
3417 -1.0f, 0.1f, 4.0f, 800.0f,
3418 13.0f, 55.0f, 12.0f, 91.0f,
3419 -55.1f, 1.1f, 98.0f, 19.0f,
3420 41.0f, 65.0f, 4.0f, 12.2f,
3421 95.0f, 77.0f, 32.0f, 48.0f
3422 };
3423
3424 location = glGetUniformLocation(program,"arrayUniform");
3425 glUniform1fv(location, 5, uniformValue);
3426 expectError(GL_NO_ERROR);
3427
3428 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[0]"), uniformValue[0]);
3429 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[1]"), uniformValue[1]);
3430 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[2]"), uniformValue[2]);
3431 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[3]"), uniformValue[3]);
3432 verifyUniformValue1f(m_testCtx, *this, program, glGetUniformLocation(program,"arrayUniform[4]"), uniformValue[4]);
3433 expectError(GL_NO_ERROR);
3434
3435 location = glGetUniformLocation(program,"array2Uniform");
3436 glUniform2fv(location, 5, uniformValue);
3437 expectError(GL_NO_ERROR);
3438
3439 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[0]"), uniformValue[2 * 0], uniformValue[(2 * 0) + 1]);
3440 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[1]"), uniformValue[2 * 1], uniformValue[(2 * 1) + 1]);
3441 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[2]"), uniformValue[2 * 2], uniformValue[(2 * 2) + 1]);
3442 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[3]"), uniformValue[2 * 3], uniformValue[(2 * 3) + 1]);
3443 verifyUniformValue2f(m_testCtx, *this, program, glGetUniformLocation(program,"array2Uniform[4]"), uniformValue[2 * 4], uniformValue[(2 * 4) + 1]);
3444 expectError(GL_NO_ERROR);
3445
3446 location = glGetUniformLocation(program,"array3Uniform");
3447 glUniform3fv(location, 5, uniformValue);
3448 expectError(GL_NO_ERROR);
3449
3450 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[0]"), uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]);
3451 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[1]"), uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]);
3452 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[2]"), uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]);
3453 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[3]"), uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]);
3454 verifyUniformValue3f(m_testCtx, *this, program, glGetUniformLocation(program,"array3Uniform[4]"), uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]);
3455 expectError(GL_NO_ERROR);
3456
3457 location = glGetUniformLocation(program,"array4Uniform");
3458 glUniform4fv(location, 5, uniformValue);
3459 expectError(GL_NO_ERROR);
3460
3461 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[0]"), uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]);
3462 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[1]"), uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]);
3463 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[2]"), uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]);
3464 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[3]"), uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]);
3465 verifyUniformValue4f(m_testCtx, *this, program, glGetUniformLocation(program,"array4Uniform[4]"), uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]);
3466 expectError(GL_NO_ERROR);
3467
3468 glUseProgram(0);
3469 glDeleteShader(shaderVert);
3470 glDeleteShader(shaderFrag);
3471 glDeleteProgram(program);
3472 expectError(GL_NO_ERROR);
3473 }
3474 };
3475
3476 class UniformValueMatrixCase : public ApiCase
3477 {
3478 public:
UniformValueMatrixCase(Context & context,const char * name,const char * description)3479 UniformValueMatrixCase (Context& context, const char* name, const char* description)
3480 : ApiCase(context, name, description)
3481 {
3482 }
3483
test(void)3484 void test (void)
3485 {
3486 static const char* testVertSource =
3487 "#version 300 es\n"
3488 "uniform highp mat2 mat2Uniform;"
3489 "uniform highp mat3 mat3Uniform;"
3490 "uniform highp mat4 mat4Uniform;"
3491 "void main (void)\n"
3492 "{\n"
3493 " gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n"
3494 "}\n";
3495 static const char* testFragSource =
3496 "#version 300 es\n"
3497 "layout(location = 0) out mediump vec4 fragColor;"
3498 "void main (void)\n"
3499 "{\n"
3500 " fragColor = vec4(0.0);\n"
3501 "}\n";
3502
3503 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
3504 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
3505
3506 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
3507 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
3508
3509 glCompileShader(shaderVert);
3510 glCompileShader(shaderFrag);
3511 expectError(GL_NO_ERROR);
3512
3513 GLuint program = glCreateProgram();
3514 glAttachShader(program, shaderVert);
3515 glAttachShader(program, shaderFrag);
3516 glLinkProgram(program);
3517 glUseProgram(program);
3518 expectError(GL_NO_ERROR);
3519
3520 GLint location;
3521
3522 float matrixValues[4 * 4] =
3523 {
3524 -1.0f, 0.1f, 4.0f, 800.0f,
3525 13.0f, 55.0f, 12.0f, 91.0f,
3526 -55.1f, 1.1f, 98.0f, 19.0f,
3527 41.0f, 65.0f, 4.0f, 12.2f,
3528 };
3529
3530 // the values of the matrix are returned in column major order but they can be given in either order
3531
3532 location = glGetUniformLocation(program,"mat2Uniform");
3533 glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues);
3534 verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, false);
3535 glUniformMatrix2fv(location, 1, GL_TRUE, matrixValues);
3536 verifyUniformMatrixValues<2>(m_testCtx, *this, program, location, matrixValues, true);
3537
3538 location = glGetUniformLocation(program,"mat3Uniform");
3539 glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues);
3540 verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, false);
3541 glUniformMatrix3fv(location, 1, GL_TRUE, matrixValues);
3542 verifyUniformMatrixValues<3>(m_testCtx, *this, program, location, matrixValues, true);
3543
3544 location = glGetUniformLocation(program,"mat4Uniform");
3545 glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues);
3546 verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, false);
3547 glUniformMatrix4fv(location, 1, GL_TRUE, matrixValues);
3548 verifyUniformMatrixValues<4>(m_testCtx, *this, program, location, matrixValues, true);
3549
3550 glUseProgram(0);
3551 glDeleteShader(shaderVert);
3552 glDeleteShader(shaderFrag);
3553 glDeleteProgram(program);
3554 expectError(GL_NO_ERROR);
3555 }
3556 };
3557
3558 class PrecisionFormatCase : public ApiCase
3559 {
3560 public:
3561 struct RequiredFormat
3562 {
3563 int negativeRange;
3564 int positiveRange;
3565 int precision;
3566 };
3567
PrecisionFormatCase(Context & context,const char * name,const char * description,glw::GLenum shaderType,glw::GLenum precisionType)3568 PrecisionFormatCase (Context& context, const char* name, const char* description, glw::GLenum shaderType, glw::GLenum precisionType)
3569 : ApiCase (context, name, description)
3570 , m_shaderType (shaderType)
3571 , m_precisionType (precisionType)
3572 {
3573 }
3574
3575 private:
test(void)3576 void test (void)
3577 {
3578 const RequiredFormat expected = getRequiredFormat();
3579 bool error = false;
3580 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> shaderCompiler;
3581 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]> range;
3582 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> precision;
3583
3584 // query values
3585 glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision);
3586 expectError(GL_NO_ERROR);
3587
3588 if (!range.verifyValidity(m_testCtx))
3589 return;
3590 if (!precision.verifyValidity(m_testCtx))
3591 return;
3592
3593 m_log
3594 << tcu::TestLog::Message
3595 << "range[0] = " << range[0] << "\n"
3596 << "range[1] = " << range[1] << "\n"
3597 << "precision = " << precision
3598 << tcu::TestLog::EndMessage;
3599
3600 // verify values
3601
3602 if (m_precisionType == GL_HIGH_FLOAT)
3603 {
3604 // highp float must be IEEE 754 single
3605
3606 if (range[0] != expected.negativeRange ||
3607 range[1] != expected.positiveRange ||
3608 precision != expected.precision)
3609 {
3610 m_log
3611 << tcu::TestLog::Message
3612 << "// ERROR: Invalid precision format, expected:\n"
3613 << "\trange[0] = " << expected.negativeRange << "\n"
3614 << "\trange[1] = " << expected.positiveRange << "\n"
3615 << "\tprecision = " << expected.precision
3616 << tcu::TestLog::EndMessage;
3617 error = true;
3618 }
3619 }
3620 else
3621 {
3622 if (range[0] < expected.negativeRange)
3623 {
3624 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to " << expected.negativeRange << tcu::TestLog::EndMessage;
3625 error = true;
3626 }
3627
3628 if (range[1] < expected.positiveRange)
3629 {
3630 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to " << expected.positiveRange << tcu::TestLog::EndMessage;
3631 error = true;
3632 }
3633
3634 if (precision < expected.precision)
3635 {
3636 m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to " << expected.precision << tcu::TestLog::EndMessage;
3637 error = true;
3638 }
3639 }
3640
3641 if (error)
3642 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range");
3643 }
3644
getRequiredFormat(void) const3645 RequiredFormat getRequiredFormat (void) const
3646 {
3647 // Precisions for different types.
3648 const RequiredFormat requirements[] =
3649 {
3650 { 0, 0, 8 }, //!< lowp float
3651 { 13, 13, 10 }, //!< mediump float
3652 { 127, 127, 23 }, //!< highp float
3653 { 8, 7, 0 }, //!< lowp int
3654 { 15, 14, 0 }, //!< mediump int
3655 { 31, 30, 0 }, //!< highp int
3656 };
3657 const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT;
3658
3659 DE_ASSERT(ndx >= 0);
3660 DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements));
3661 return requirements[ndx];
3662 }
3663
3664 const glw::GLenum m_shaderType;
3665 const glw::GLenum m_precisionType;
3666 };
3667
3668 } // anonymous
3669
3670
ShaderStateQueryTests(Context & context)3671 ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
3672 : TestCaseGroup(context, "shader", "Shader State Query tests")
3673 {
3674 }
3675
init(void)3676 void ShaderStateQueryTests::init (void)
3677 {
3678 // shader
3679 addChild(new ShaderTypeCase (m_context, "shader_type", "SHADER_TYPE"));
3680 addChild(new ShaderCompileStatusCase (m_context, "shader_compile_status", "COMPILE_STATUS"));
3681 addChild(new ShaderInfoLogCase (m_context, "shader_info_log_length", "INFO_LOG_LENGTH"));
3682 addChild(new ShaderSourceCase (m_context, "shader_source_length", "SHADER_SOURCE_LENGTH"));
3683
3684 // shader and program
3685 addChild(new DeleteStatusCase (m_context, "delete_status", "DELETE_STATUS"));
3686
3687 // vertex-attrib
3688 addChild(new CurrentVertexAttribInitialCase (m_context, "current_vertex_attrib_initial", "CURRENT_VERTEX_ATTRIB"));
3689 addChild(new CurrentVertexAttribFloatCase (m_context, "current_vertex_attrib_float", "CURRENT_VERTEX_ATTRIB"));
3690 addChild(new CurrentVertexAttribIntCase (m_context, "current_vertex_attrib_int", "CURRENT_VERTEX_ATTRIB"));
3691 addChild(new CurrentVertexAttribUintCase (m_context, "current_vertex_attrib_uint", "CURRENT_VERTEX_ATTRIB"));
3692 addChild(new CurrentVertexAttribConversionCase (m_context, "current_vertex_attrib_float_to_int", "CURRENT_VERTEX_ATTRIB"));
3693
3694 // program
3695 addChild(new ProgramInfoLogCase (m_context, "program_info_log_length", "INFO_LOG_LENGTH", ProgramInfoLogCase::BUILDERROR_COMPILE));
3696 addChild(new ProgramInfoLogCase (m_context, "program_info_log_length_link_error", "INFO_LOG_LENGTH", ProgramInfoLogCase::BUILDERROR_LINK));
3697 addChild(new ProgramValidateStatusCase (m_context, "program_validate_status", "VALIDATE_STATUS"));
3698 addChild(new ProgramAttachedShadersCase (m_context, "program_attached_shaders", "ATTACHED_SHADERS"));
3699
3700 addChild(new ProgramActiveUniformNameCase (m_context, "program_active_uniform_name", "ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH"));
3701 addChild(new ProgramUniformCase (m_context, "program_active_uniform_types", "UNIFORM_TYPE, UNIFORM_SIZE, and UNIFORM_IS_ROW_MAJOR"));
3702 addChild(new ProgramActiveUniformBlocksCase (m_context, "program_active_uniform_blocks", "ACTIVE_UNIFORM_BLOCK_x"));
3703 addChild(new ProgramBinaryCase (m_context, "program_binary", "PROGRAM_BINARY_LENGTH and PROGRAM_BINARY_RETRIEVABLE_HINT"));
3704
3705 // transform feedback
3706 addChild(new TransformFeedbackCase (m_context, "transform_feedback", "TRANSFORM_FEEDBACK_BUFFER_MODE, TRANSFORM_FEEDBACK_VARYINGS, TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH"));
3707
3708 // attribute related
3709 addChild(new ActiveAttributesCase (m_context, "active_attributes", "ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH"));
3710 addChild(new VertexAttributeSizeCase (m_context, "vertex_attrib_size", "VERTEX_ATTRIB_ARRAY_SIZE"));
3711 addChild(new VertexAttributeTypeCase (m_context, "vertex_attrib_type", "VERTEX_ATTRIB_ARRAY_TYPE"));
3712 addChild(new VertexAttributeStrideCase (m_context, "vertex_attrib_stride", "VERTEX_ATTRIB_ARRAY_STRIDE"));
3713 addChild(new VertexAttributeNormalizedCase (m_context, "vertex_attrib_normalized", "VERTEX_ATTRIB_ARRAY_NORMALIZED"));
3714 addChild(new VertexAttributeIntegerCase (m_context, "vertex_attrib_integer", "VERTEX_ATTRIB_ARRAY_INTEGER"));
3715 addChild(new VertexAttributeEnabledCase (m_context, "vertex_attrib_array_enabled", "VERTEX_ATTRIB_ARRAY_ENABLED"));
3716 addChild(new VertexAttributeDivisorCase (m_context, "vertex_attrib_array_divisor", "VERTEX_ATTRIB_ARRAY_DIVISOR"));
3717 addChild(new VertexAttributeBufferBindingCase (m_context, "vertex_attrib_array_buffer_binding", "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"));
3718 addChild(new VertexAttributePointerCase (m_context, "vertex_attrib_pointerv", "GetVertexAttribPointerv"));
3719
3720 // uniform values
3721 addChild(new UniformValueFloatCase (m_context, "uniform_value_float", "GetUniform*"));
3722 addChild(new UniformValueIntCase (m_context, "uniform_value_int", "GetUniform*"));
3723 addChild(new UniformValueUintCase (m_context, "uniform_value_uint", "GetUniform*"));
3724 addChild(new UniformValueBooleanCase (m_context, "uniform_value_boolean", "GetUniform*"));
3725 addChild(new UniformValueSamplerCase (m_context, "uniform_value_sampler", "GetUniform*"));
3726 addChild(new UniformValueArrayCase (m_context, "uniform_value_array", "GetUniform*"));
3727 addChild(new UniformValueMatrixCase (m_context, "uniform_value_matrix", "GetUniform*"));
3728
3729 // precision format query
3730 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_FLOAT));
3731 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_FLOAT));
3732 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_FLOAT));
3733 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_INT));
3734 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_INT));
3735 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_INT));
3736 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_FLOAT));
3737 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT));
3738 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_FLOAT));
3739 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_INT));
3740 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_INT));
3741 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_INT));
3742 }
3743
3744 } // Functional
3745 } // gles3
3746 } // deqp
3747