1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.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 "es2fShaderStateQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es2fApiCase.hpp"
27 #include "gluRenderContext.hpp"
28 #include "gluShaderProgram.hpp"
29 #include "glwEnums.hpp"
30 #include "glwFunctions.hpp"
31 #include "deRandom.hpp"
32 #include "deMath.h"
33 #include "deString.h"
34
35 using namespace glw; // GLint and other GL types
36 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
37
38 namespace deqp
39 {
40 namespace gles2
41 {
42 namespace Functional
43 {
44 namespace
45 {
46
47 static const char* commonTestVertSource = "void main (void)\n"
48 "{\n"
49 " gl_Position = vec4(0.0);\n"
50 "}\n";
51 static const char* commonTestFragSource = "void main (void)\n"
52 "{\n"
53 " gl_FragColor = vec4(0.0);\n"
54 "}\n";
55
56 static const char* brokenShader = "broken, this should not compile!\n"
57 "\n";
58
59 // rounds x.1 to x+1
60 template <typename T>
roundGLfloatToNearestIntegerUp(GLfloat val)61 T roundGLfloatToNearestIntegerUp (GLfloat val)
62 {
63 return (T)(ceil(val));
64 }
65
66 // rounds x.9 to x
67 template <typename T>
roundGLfloatToNearestIntegerDown(GLfloat val)68 T roundGLfloatToNearestIntegerDown (GLfloat val)
69 {
70 return (T)(floor(val));
71 }
72
checkIntEquals(tcu::TestContext & testCtx,GLint got,GLint expected)73 bool checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
74 {
75 using tcu::TestLog;
76
77 if (got != expected)
78 {
79 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
80 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
81 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
82 return false;
83 }
84 return true;
85 }
86
checkPointerEquals(tcu::TestContext & testCtx,const void * got,const void * expected)87 void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected)
88 {
89 using tcu::TestLog;
90
91 if (got != expected)
92 {
93 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
94 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
95 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
96 }
97 }
98
verifyShaderParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint shader,GLenum pname,GLenum reference)99 void verifyShaderParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint shader, GLenum pname, GLenum reference)
100 {
101 StateQueryMemoryWriteGuard<GLint> state;
102 gl.glGetShaderiv(shader, pname, &state);
103
104 if (state.verifyValidity(testCtx))
105 checkIntEquals(testCtx, state, reference);
106 }
107
verifyProgramParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLenum pname,GLenum reference)108 bool verifyProgramParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLenum pname, GLenum reference)
109 {
110 StateQueryMemoryWriteGuard<GLint> state;
111 gl.glGetProgramiv(program, pname, &state);
112
113 if (state.verifyValidity(testCtx))
114 return checkIntEquals(testCtx, state, reference);
115 return false;
116 }
117
verifyCurrentVertexAttribf(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)118 void verifyCurrentVertexAttribf (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
119 {
120 using tcu::TestLog;
121
122 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
123 gl.glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
124
125 attribValue.verifyValidity(testCtx);
126
127 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w)
128 {
129 testCtx.getLog() << TestLog::Message
130 << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];"
131 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]"
132 << TestLog::EndMessage;
133 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
134 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
135 }
136 }
137
verifyCurrentVertexAttribConversion(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)138 void verifyCurrentVertexAttribConversion (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
139 {
140 using tcu::TestLog;
141
142 StateQueryMemoryWriteGuard<GLint[4]> attribValue;
143 gl.glGetVertexAttribiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
144
145 attribValue.verifyValidity(testCtx);
146
147 const GLint referenceAsGLintMin[] =
148 {
149 roundGLfloatToNearestIntegerDown<GLint>(x),
150 roundGLfloatToNearestIntegerDown<GLint>(y),
151 roundGLfloatToNearestIntegerDown<GLint>(z),
152 roundGLfloatToNearestIntegerDown<GLint>(w)
153 };
154 const GLint referenceAsGLintMax[] =
155 {
156 roundGLfloatToNearestIntegerUp<GLint>(x),
157 roundGLfloatToNearestIntegerUp<GLint>(y),
158 roundGLfloatToNearestIntegerUp<GLint>(z),
159 roundGLfloatToNearestIntegerUp<GLint>(w)
160 };
161
162 if (attribValue[0] < referenceAsGLintMin[0] || attribValue[0] > referenceAsGLintMax[0] ||
163 attribValue[1] < referenceAsGLintMin[1] || attribValue[1] > referenceAsGLintMax[1] ||
164 attribValue[2] < referenceAsGLintMin[2] || attribValue[2] > referenceAsGLintMax[2] ||
165 attribValue[3] < referenceAsGLintMin[3] || attribValue[3] > referenceAsGLintMax[3])
166 {
167 testCtx.getLog() << TestLog::Message
168 << "// ERROR: expected in range "
169 << "[" << referenceAsGLintMin[0] << " " << referenceAsGLintMax[0] << "], "
170 << "[" << referenceAsGLintMin[1] << " " << referenceAsGLintMax[1] << "], "
171 << "[" << referenceAsGLintMin[2] << " " << referenceAsGLintMax[2] << "], "
172 << "[" << referenceAsGLintMin[3] << " " << referenceAsGLintMax[3] << "]"
173 << "; got "
174 << attribValue[0] << ", "
175 << attribValue[1] << ", "
176 << attribValue[2] << ", "
177 << attribValue[3] << " "
178 << "; Input="
179 << x << "; "
180 << y << "; "
181 << z << "; "
182 << w << " " << TestLog::EndMessage;
183
184 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
185 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid attribute value");
186 }
187 }
188
verifyVertexAttrib(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLint index,GLenum pname,GLenum reference)189 void verifyVertexAttrib (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLenum pname, GLenum reference)
190 {
191 StateQueryMemoryWriteGuard<GLint> state;
192 gl.glGetVertexAttribiv(index, pname, &state);
193
194 if (state.verifyValidity(testCtx))
195 checkIntEquals(testCtx, state, reference);
196 }
197
verifyUniformValue1f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x)198 void verifyUniformValue1f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x)
199 {
200 using tcu::TestLog;
201
202 StateQueryMemoryWriteGuard<GLfloat[1]> state;
203 gl.glGetUniformfv(program, location, state);
204
205 if (!state.verifyValidity(testCtx))
206 return;
207
208 if (state[0] != x)
209 {
210 testCtx.getLog() << TestLog::Message
211 << "// ERROR: expected ["
212 << x
213 << "]; got ["
214 << state[0]
215 << "]"
216 << TestLog::EndMessage;
217
218 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
219 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
220 }
221 }
222
verifyUniformValue2f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x,float y)223 void verifyUniformValue2f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y)
224 {
225 using tcu::TestLog;
226
227 StateQueryMemoryWriteGuard<GLfloat[2]> state;
228 gl.glGetUniformfv(program, location, state);
229
230 if (!state.verifyValidity(testCtx))
231 return;
232
233 if (state[0] != x ||
234 state[1] != y)
235 {
236 testCtx.getLog() << TestLog::Message
237 << "// ERROR: expected ["
238 << x << ", "
239 << y
240 << "]; got ["
241 << state[0] << ", "
242 << state[1]
243 << "]"
244 << TestLog::EndMessage;
245
246 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
247 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
248 }
249 }
250
verifyUniformValue3f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x,float y,float z)251 void verifyUniformValue3f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z)
252 {
253 using tcu::TestLog;
254
255 StateQueryMemoryWriteGuard<GLfloat[3]> state;
256 gl.glGetUniformfv(program, location, state);
257
258 if (!state.verifyValidity(testCtx))
259 return;
260
261 if (state[0] != x ||
262 state[1] != y ||
263 state[2] != z)
264 {
265 testCtx.getLog() << TestLog::Message
266 << "// ERROR: expected ["
267 << x << ", "
268 << y << ", "
269 << z
270 << "]; got ["
271 << state[0] << ", "
272 << state[1] << ", "
273 << state[2]
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
verifyUniformValue4f(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,float x,float y,float z,float w)282 void verifyUniformValue4f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z, float w)
283 {
284 using tcu::TestLog;
285
286 StateQueryMemoryWriteGuard<GLfloat[4]> 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 state[2] != z ||
295 state[3] != w)
296 {
297 testCtx.getLog() << TestLog::Message
298 << "// ERROR: expected ["
299 << x << ", "
300 << y << ", "
301 << z << ", "
302 << w
303 << "]; got ["
304 << state[0] << ", "
305 << state[1] << ", "
306 << state[2] << ", "
307 << state[3]
308 << "]"
309 << TestLog::EndMessage;
310
311 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
312 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
313 }
314 }
315
verifyUniformValue1i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x)316 void verifyUniformValue1i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x)
317 {
318 using tcu::TestLog;
319
320 StateQueryMemoryWriteGuard<GLint[1]> state;
321 gl.glGetUniformiv(program, location, state);
322
323 if (!state.verifyValidity(testCtx))
324 return;
325
326 if (state[0] != x)
327 {
328 testCtx.getLog() << TestLog::Message
329 << "// ERROR: expected ["
330 << x
331 << "]; got ["
332 << state[0]
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
verifyUniformValue2i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x,GLint y)341 void verifyUniformValue2i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y)
342 {
343 using tcu::TestLog;
344
345 StateQueryMemoryWriteGuard<GLint[2]> state;
346 gl.glGetUniformiv(program, location, state);
347
348 if (!state.verifyValidity(testCtx))
349 return;
350
351 if (state[0] != x ||
352 state[1] != y)
353 {
354 testCtx.getLog() << TestLog::Message
355 << "// ERROR: expected ["
356 << x << ", "
357 << y
358 << "]; got ["
359 << state[0] << ", "
360 << state[1]
361 << "]"
362 << TestLog::EndMessage;
363
364 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
365 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
366 }
367 }
368
verifyUniformValue3i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x,GLint y,GLint z)369 void verifyUniformValue3i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z)
370 {
371 using tcu::TestLog;
372
373 StateQueryMemoryWriteGuard<GLint[3]> state;
374 gl.glGetUniformiv(program, location, state);
375
376 if (!state.verifyValidity(testCtx))
377 return;
378
379 if (state[0] != x ||
380 state[1] != y ||
381 state[2] != z)
382 {
383 testCtx.getLog() << TestLog::Message
384 << "// ERROR: expected ["
385 << x << ", "
386 << y << ", "
387 << z
388 << "]; got ["
389 << state[0] << ", "
390 << state[1] << ", "
391 << state[2]
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
verifyUniformValue4i(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,GLint x,GLint y,GLint z,GLint w)400 void verifyUniformValue4i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w)
401 {
402 using tcu::TestLog;
403
404 StateQueryMemoryWriteGuard<GLint[4]> 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 state[2] != z ||
413 state[3] != w)
414 {
415 testCtx.getLog() << TestLog::Message
416 << "// ERROR: expected ["
417 << x << ", "
418 << y << ", "
419 << z << ", "
420 << w
421 << "]; got ["
422 << state[0] << ", "
423 << state[1] << ", "
424 << state[2] << ", "
425 << state[3]
426 << "]"
427 << TestLog::EndMessage;
428
429 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
430 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
431 }
432 }
433
434 template <int Count>
verifyUniformValues(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,const GLfloat * values)435 void verifyUniformValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values)
436 {
437 using tcu::TestLog;
438
439 StateQueryMemoryWriteGuard<GLfloat[Count]> state;
440 gl.glGetUniformfv(program, location, state);
441
442 if (!state.verifyValidity(testCtx))
443 return;
444
445 for (int ndx = 0; ndx < Count; ++ndx)
446 {
447 if (values[ndx] != state[ndx])
448 {
449 testCtx.getLog() << TestLog::Message << "// ERROR: at index " << ndx << " expected " << values[ndx] << "; got " << state[ndx] << TestLog::EndMessage;
450
451 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
452 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
453 }
454 }
455 }
456
457 template <int N>
verifyUniformMatrixValues(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLuint program,GLint location,const GLfloat * values,bool transpose)458 void verifyUniformMatrixValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values, bool transpose)
459 {
460 using tcu::TestLog;
461
462 StateQueryMemoryWriteGuard<GLfloat[N*N]> state;
463 gl.glGetUniformfv(program, location, state);
464
465 if (!state.verifyValidity(testCtx))
466 return;
467
468 for (int y = 0; y < N; ++y)
469 for (int x = 0; x < N; ++x)
470 {
471 const int refIndex = y*N + x;
472 const int stateIndex = transpose ? (x*N + y) : (y*N + x);
473
474 if (values[refIndex] != state[stateIndex])
475 {
476 testCtx.getLog() << TestLog::Message << "// ERROR: at index [" << y << "][" << x << "] expected " << values[refIndex] << "; got " << state[stateIndex] << TestLog::EndMessage;
477
478 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
479 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
480 }
481 }
482 }
483
requireShaderCompiler(tcu::TestContext & testCtx,glu::CallLogWrapper & gl)484 void requireShaderCompiler (tcu::TestContext& testCtx, glu::CallLogWrapper& gl)
485 {
486 StateQueryMemoryWriteGuard<GLboolean> state;
487 gl.glGetBooleanv(GL_SHADER_COMPILER, &state);
488
489 if (!state.verifyValidity(testCtx) || state != GL_TRUE)
490 throw tcu::NotSupportedError("Test requires SHADER_COMPILER = TRUE");
491 }
492
493 class ShaderTypeCase : public ApiCase
494 {
495 public:
ShaderTypeCase(Context & context,const char * name,const char * description)496 ShaderTypeCase (Context& context, const char* name, const char* description)
497 : ApiCase(context, name, description)
498 {
499 }
500
test(void)501 void test (void)
502 {
503 const GLenum shaderTypes[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER};
504 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
505 {
506 const GLuint shader = glCreateShader(shaderTypes[ndx]);
507 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_TYPE, shaderTypes[ndx]);
508 glDeleteShader(shader);
509 }
510 }
511 };
512
513 class ShaderCompileStatusCase : public ApiCase
514 {
515 public:
ShaderCompileStatusCase(Context & context,const char * name,const char * description)516 ShaderCompileStatusCase (Context& context, const char* name, const char* description)
517 : ApiCase(context, name, description)
518 {
519 }
520
test(void)521 void test (void)
522 {
523 requireShaderCompiler(m_testCtx, *this);
524
525 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
526 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
527
528 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_FALSE);
529 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE);
530
531 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
532 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
533
534 glCompileShader(shaderVert);
535 glCompileShader(shaderFrag);
536 expectError(GL_NO_ERROR);
537
538 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
539 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
540
541 glDeleteShader(shaderVert);
542 glDeleteShader(shaderFrag);
543 expectError(GL_NO_ERROR);
544 }
545 };
546
547 class ShaderInfoLogCase : public ApiCase
548 {
549 public:
ShaderInfoLogCase(Context & context,const char * name,const char * description)550 ShaderInfoLogCase (Context& context, const char* name, const char* description)
551 : ApiCase(context, name, description)
552 {
553 }
554
test(void)555 void test (void)
556 {
557 requireShaderCompiler(m_testCtx, *this);
558
559 using tcu::TestLog;
560
561 // INFO_LOG_LENGTH is 0 by default and it includes null-terminator
562 const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
563 verifyShaderParam(m_testCtx, *this, shader, GL_INFO_LOG_LENGTH, 0);
564
565 glShaderSource(shader, 1, &brokenShader, DE_NULL);
566 glCompileShader(shader);
567 expectError(GL_NO_ERROR);
568
569 // check the log length
570 StateQueryMemoryWriteGuard<GLint> logLength;
571 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
572 if (!logLength.verifyValidity(m_testCtx))
573 {
574 glDeleteShader(shader);
575 return;
576 }
577 if (logLength == 0)
578 {
579 glDeleteShader(shader);
580 return;
581 }
582
583 // check normal case
584 {
585 char buffer[2048] = {'x'}; // non-zero initialization
586
587 GLint written = 0; // written does not include null terminator
588 glGetShaderInfoLog(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
589
590 // check lengths are consistent
591 if (logLength <= DE_LENGTH_OF_ARRAY(buffer))
592 {
593 if (written != logLength-1)
594 {
595 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << logLength-1 << "; got " << written << TestLog::EndMessage;
596 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
597 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
598 }
599 }
600
601 // check null-terminator, either at end of buffer or at buffer[written]
602 const char* terminator = &buffer[DE_LENGTH_OF_ARRAY(buffer) - 1];
603 if (logLength < DE_LENGTH_OF_ARRAY(buffer))
604 terminator = &buffer[written];
605
606 if (*terminator != '\0')
607 {
608 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)*terminator << TestLog::EndMessage;
609 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
610 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
611 }
612 }
613
614 // check with too small buffer
615 {
616 char buffer[2048] = {'x'}; // non-zero initialization
617
618 // check string always ends with \0, even with small buffers
619 GLint written = 0;
620 glGetShaderInfoLog(shader, 1, &written, buffer);
621 if (written != 0)
622 {
623 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length 0; got " << written << TestLog::EndMessage;
624 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
625 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
626 }
627 if (buffer[0] != '\0')
628 {
629 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)buffer[0] << TestLog::EndMessage;
630 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
631 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
632 }
633 }
634
635 glDeleteShader(shader);
636 expectError(GL_NO_ERROR);
637 }
638 };
639
640 class ShaderSourceCase : public ApiCase
641 {
642 public:
ShaderSourceCase(Context & context,const char * name,const char * description)643 ShaderSourceCase (Context& context, const char* name, const char* description)
644 : ApiCase(context, name, description)
645 {
646 }
647
test(void)648 void test (void)
649 {
650 requireShaderCompiler(m_testCtx, *this);
651
652 using tcu::TestLog;
653
654 // SHADER_SOURCE_LENGTH does include 0-terminator
655 const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
656 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_SOURCE_LENGTH, 0);
657
658 // check the SHADER_SOURCE_LENGTH
659 {
660 glShaderSource(shader, 1, &brokenShader, DE_NULL);
661 expectError(GL_NO_ERROR);
662
663 StateQueryMemoryWriteGuard<GLint> sourceLength;
664 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);
665
666 sourceLength.verifyValidity(m_testCtx);
667
668 const GLint referenceLength = (GLint)std::string(brokenShader).length() + 1; // including the null terminator
669 if (sourceLength != referenceLength)
670 {
671 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage;
672 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
673 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
674 }
675 }
676
677 // check the concat source SHADER_SOURCE_LENGTH
678 {
679 const char* shaders[] = {brokenShader, brokenShader};
680 glShaderSource(shader, 2, shaders, DE_NULL);
681 expectError(GL_NO_ERROR);
682
683 StateQueryMemoryWriteGuard<GLint> sourceLength;
684 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);
685
686 sourceLength.verifyValidity(m_testCtx);
687
688 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length() + 1; // including the null terminator
689 if (sourceLength != referenceLength)
690 {
691 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage;
692 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
693 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
694 }
695 }
696
697 // check the string length
698 {
699 char buffer[2048] = {'x'};
700 DE_ASSERT(DE_LENGTH_OF_ARRAY(buffer) > 2 * (int)std::string(brokenShader).length());
701
702 GLint written = 0; // not inluding null-terminator
703 glGetShaderSource(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
704
705 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length();
706 if (written != referenceLength)
707 {
708 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length " << referenceLength << "; got " << written << TestLog::EndMessage;
709 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
710 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
711 }
712 // check null pointer at
713 else
714 {
715 if (buffer[referenceLength] != '\0')
716 {
717 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at " << referenceLength << TestLog::EndMessage;
718 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
719 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "did not get a null terminator");
720 }
721 }
722 }
723
724 // check with small buffer
725 {
726 char buffer[2048] = {'x'};
727
728 GLint written = 0;
729 glGetShaderSource(shader, 1, &written, buffer);
730
731 if (written != 0)
732 {
733 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage;
734 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
735 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
736 }
737 if (buffer[0] != '\0')
738 {
739 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator; got=" << int(buffer[0]) << ", char=" << buffer[0] << TestLog::EndMessage;
740 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
741 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid terminator");
742 }
743 }
744
745 glDeleteShader(shader);
746 expectError(GL_NO_ERROR);
747 }
748 };
749
750 class DeleteStatusCase : public ApiCase
751 {
752 public:
DeleteStatusCase(Context & context,const char * name,const char * description)753 DeleteStatusCase (Context& context, const char* name, const char* description)
754 : ApiCase(context, name, description)
755 {
756 }
757
test(void)758 void test (void)
759 {
760 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
761 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
762
763 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
764 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
765
766 glCompileShader(shaderVert);
767 glCompileShader(shaderFrag);
768 expectError(GL_NO_ERROR);
769
770 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
771 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
772
773 GLuint shaderProg = glCreateProgram();
774 glAttachShader(shaderProg, shaderVert);
775 glAttachShader(shaderProg, shaderFrag);
776 glLinkProgram(shaderProg);
777 expectError(GL_NO_ERROR);
778
779 verifyProgramParam (m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE);
780
781 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_FALSE);
782 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_FALSE);
783 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_FALSE);
784 expectError(GL_NO_ERROR);
785
786 glUseProgram(shaderProg);
787
788 glDeleteShader(shaderVert);
789 glDeleteShader(shaderFrag);
790 glDeleteProgram(shaderProg);
791 expectError(GL_NO_ERROR);
792
793 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_TRUE);
794 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_TRUE);
795 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_TRUE);
796 expectError(GL_NO_ERROR);
797
798 glUseProgram(0);
799 expectError(GL_NO_ERROR);
800 }
801 };
802
803 class CurrentVertexAttribInitialCase : public ApiCase
804 {
805 public:
CurrentVertexAttribInitialCase(Context & context,const char * name,const char * description)806 CurrentVertexAttribInitialCase (Context& context, const char* name, const char* description)
807 : ApiCase(context, name, description)
808 {
809 }
810
test(void)811 void test (void)
812 {
813 using tcu::TestLog;
814
815 int attribute_count = 16;
816 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
817
818 // initial
819
820 for (int index = 0; index < attribute_count; ++index)
821 {
822 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
823 glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
824 attribValue.verifyValidity(m_testCtx);
825
826 if (attribValue[0] != 0.0f || attribValue[1] != 0.0f || attribValue[2] != 0.0f || attribValue[3] != 1.0f)
827 {
828 m_testCtx.getLog() << TestLog::Message
829 << "// ERROR: Expected [0, 0, 0, 1];"
830 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]"
831 << TestLog::EndMessage;
832 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
833 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
834 }
835 }
836 }
837 };
838
839 class CurrentVertexAttribFloatCase : public ApiCase
840 {
841 public:
CurrentVertexAttribFloatCase(Context & context,const char * name,const char * description)842 CurrentVertexAttribFloatCase (Context& context, const char* name, const char* description)
843 : ApiCase(context, name, description)
844 {
845 }
846
test(void)847 void test (void)
848 {
849 using tcu::TestLog;
850
851 de::Random rnd(0xabcdef);
852
853 int attribute_count = 16;
854 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
855
856 // test write float/read float
857
858 for (int index = 0; index < attribute_count; ++index)
859 {
860 const GLfloat x = rnd.getFloat(-64000, 64000);
861 const GLfloat y = rnd.getFloat(-64000, 64000);
862 const GLfloat z = rnd.getFloat(-64000, 64000);
863 const GLfloat w = rnd.getFloat(-64000, 64000);
864
865 glVertexAttrib4f(index, x, y, z, w);
866 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
867 }
868 for (int index = 0; index < attribute_count; ++index)
869 {
870 const GLfloat x = rnd.getFloat(-64000, 64000);
871 const GLfloat y = rnd.getFloat(-64000, 64000);
872 const GLfloat z = rnd.getFloat(-64000, 64000);
873 const GLfloat w = 1.0f;
874
875 glVertexAttrib3f(index, x, y, z);
876 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
877 }
878 for (int index = 0; index < attribute_count; ++index)
879 {
880 const GLfloat x = rnd.getFloat(-64000, 64000);
881 const GLfloat y = rnd.getFloat(-64000, 64000);
882 const GLfloat z = 0.0f;
883 const GLfloat w = 1.0f;
884
885 glVertexAttrib2f(index, x, y);
886 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
887 }
888 for (int index = 0; index < attribute_count; ++index)
889 {
890 const GLfloat x = rnd.getFloat(-64000, 64000);
891 const GLfloat y = 0.0f;
892 const GLfloat z = 0.0f;
893 const GLfloat w = 1.0f;
894
895 glVertexAttrib1f(index, x);
896 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
897 }
898 }
899 };
900
901 class CurrentVertexAttribConversionCase : public ApiCase
902 {
903 public:
CurrentVertexAttribConversionCase(Context & context,const char * name,const char * description)904 CurrentVertexAttribConversionCase (Context& context, const char* name, const char* description)
905 : ApiCase(context, name, description)
906 {
907 }
908
test(void)909 void test (void)
910 {
911 using tcu::TestLog;
912
913 de::Random rnd(0xabcdef);
914
915 int attribute_count = 16;
916 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
917
918 // test write float/read float
919
920 for (int index = 0; index < attribute_count; ++index)
921 {
922 const GLfloat x = rnd.getFloat(-64000, 64000);
923 const GLfloat y = rnd.getFloat(-64000, 64000);
924 const GLfloat z = rnd.getFloat(-64000, 64000);
925 const GLfloat w = rnd.getFloat(-64000, 64000);
926
927 glVertexAttrib4f(index, x, y, z, w);
928 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
929 }
930 for (int index = 0; index < attribute_count; ++index)
931 {
932 const GLfloat x = rnd.getFloat(-64000, 64000);
933 const GLfloat y = rnd.getFloat(-64000, 64000);
934 const GLfloat z = rnd.getFloat(-64000, 64000);
935 const GLfloat w = 1.0f;
936
937 glVertexAttrib3f(index, x, y, z);
938 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
939 }
940 for (int index = 0; index < attribute_count; ++index)
941 {
942 const GLfloat x = rnd.getFloat(-64000, 64000);
943 const GLfloat y = rnd.getFloat(-64000, 64000);
944 const GLfloat z = 0.0f;
945 const GLfloat w = 1.0f;
946
947 glVertexAttrib2f(index, x, y);
948 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
949 }
950 for (int index = 0; index < attribute_count; ++index)
951 {
952 const GLfloat x = rnd.getFloat(-64000, 64000);
953 const GLfloat y = 0.0f;
954 const GLfloat z = 0.0f;
955 const GLfloat w = 1.0f;
956
957 glVertexAttrib1f(index, x);
958 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
959 }
960 }
961 };
962
963 class ProgramInfoLogCase : public ApiCase
964 {
965 public:
ProgramInfoLogCase(Context & context,const char * name,const char * description)966 ProgramInfoLogCase (Context& context, const char* name, const char* description)
967 : ApiCase(context, name, description)
968 {
969 }
970
test(void)971 void test (void)
972 {
973 using tcu::TestLog;
974
975 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
976 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
977
978 glShaderSource(shaderVert, 1, &brokenShader, DE_NULL);
979 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL);
980
981 glCompileShader(shaderVert);
982 glCompileShader(shaderFrag);
983 expectError(GL_NO_ERROR);
984
985 GLuint program = glCreateProgram();
986 glAttachShader(program, shaderVert);
987 glAttachShader(program, shaderFrag);
988 glLinkProgram(program);
989
990 // check INFO_LOG_LENGTH == GetProgramInfoLog len
991 {
992 char buffer[2048] = {'x'};
993
994 GLint written = 0;
995 glGetProgramInfoLog(program, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
996
997 StateQueryMemoryWriteGuard<GLint> logLength;
998 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
999 logLength.verifyValidity(m_testCtx);
1000
1001 if (logLength != 0 && written+1 != logLength) // INFO_LOG_LENGTH contains 0-terminator
1002 {
1003 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written+1 << "; got " << logLength << TestLog::EndMessage;
1004 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1005 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
1006 }
1007 }
1008
1009 // check GetProgramInfoLog works with too small buffer
1010 {
1011 char buffer[2048] = {'x'};
1012
1013 GLint written = 0;
1014 glGetProgramInfoLog(program, 1, &written, buffer);
1015
1016 if (written != 0)
1017 {
1018 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage;
1019 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1020 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
1021 }
1022 }
1023
1024 glDeleteShader(shaderVert);
1025 glDeleteShader(shaderFrag);
1026 glDeleteProgram(program);
1027 expectError(GL_NO_ERROR);
1028 }
1029 };
1030
1031 class ProgramValidateStatusCase : public ApiCase
1032 {
1033 public:
ProgramValidateStatusCase(Context & context,const char * name,const char * description)1034 ProgramValidateStatusCase (Context& context, const char* name, const char* description)
1035 : ApiCase(context, name, description)
1036 {
1037 }
1038
test(void)1039 void test (void)
1040 {
1041 // test validate ok
1042 {
1043 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1044 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1045
1046 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1047 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
1048
1049 glCompileShader(shaderVert);
1050 glCompileShader(shaderFrag);
1051 expectError(GL_NO_ERROR);
1052
1053 GLuint program = glCreateProgram();
1054 glAttachShader(program, shaderVert);
1055 glAttachShader(program, shaderFrag);
1056 glLinkProgram(program);
1057 expectError(GL_NO_ERROR);
1058
1059 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1060 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
1061 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE);
1062
1063 glValidateProgram(program);
1064 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_TRUE);
1065
1066 glDeleteShader(shaderVert);
1067 glDeleteShader(shaderFrag);
1068 glDeleteProgram(program);
1069 expectError(GL_NO_ERROR);
1070 }
1071
1072 // test with broken shader
1073 {
1074 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1075 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1076
1077 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1078 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL);
1079
1080 glCompileShader(shaderVert);
1081 glCompileShader(shaderFrag);
1082 expectError(GL_NO_ERROR);
1083
1084 GLuint program = glCreateProgram();
1085 glAttachShader(program, shaderVert);
1086 glAttachShader(program, shaderFrag);
1087 glLinkProgram(program);
1088 expectError(GL_NO_ERROR);
1089
1090 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1091 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE);
1092 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_FALSE);
1093
1094 glValidateProgram(program);
1095 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_FALSE);
1096
1097 glDeleteShader(shaderVert);
1098 glDeleteShader(shaderFrag);
1099 glDeleteProgram(program);
1100 expectError(GL_NO_ERROR);
1101 }
1102 }
1103 };
1104
1105 class ProgramAttachedShadersCase : public ApiCase
1106 {
1107 public:
ProgramAttachedShadersCase(Context & context,const char * name,const char * description)1108 ProgramAttachedShadersCase (Context& context, const char* name, const char* description)
1109 : ApiCase(context, name, description)
1110 {
1111 }
1112
test(void)1113 void test (void)
1114 {
1115 using tcu::TestLog;
1116
1117 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1118 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1119
1120 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1121 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
1122
1123 glCompileShader(shaderVert);
1124 glCompileShader(shaderFrag);
1125 expectError(GL_NO_ERROR);
1126
1127 // check ATTACHED_SHADERS
1128
1129 GLuint program = glCreateProgram();
1130 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 0);
1131 expectError(GL_NO_ERROR);
1132
1133 glAttachShader(program, shaderVert);
1134 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 1);
1135 expectError(GL_NO_ERROR);
1136
1137 glAttachShader(program, shaderFrag);
1138 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 2);
1139 expectError(GL_NO_ERROR);
1140
1141 // check GetAttachedShaders
1142 {
1143 GLuint shaders[2] = {0, 0};
1144 GLint count = 0;
1145 glGetAttachedShaders(program, DE_LENGTH_OF_ARRAY(shaders), &count, shaders);
1146
1147 if (count != 2)
1148 {
1149 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 2; got " << count << TestLog::EndMessage;
1150 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1151 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1152 }
1153 // shaders are the attached shaders?
1154 if (!((shaders[0] == shaderVert && shaders[1] == shaderFrag) ||
1155 (shaders[0] == shaderFrag && shaders[1] == shaderVert)))
1156 {
1157 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << shaderVert << ", " << shaderFrag << "}; got {" << shaders[0] << ", " << shaders[1] << "}" << TestLog::EndMessage;
1158 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1159 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1160 }
1161 }
1162
1163 // check GetAttachedShaders with too small buffer
1164 {
1165 GLuint shaders[2] = {0, 0};
1166 GLint count = 0;
1167
1168 glGetAttachedShaders(program, 0, &count, shaders);
1169 if (count != 0)
1170 {
1171 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << count << TestLog::EndMessage;
1172 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1173 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1174 }
1175
1176 count = 0;
1177 glGetAttachedShaders(program, 1, &count, shaders);
1178 if (count != 1)
1179 {
1180 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 1; got " << count << TestLog::EndMessage;
1181 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1182 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1183 }
1184 }
1185
1186 glDeleteShader(shaderVert);
1187 glDeleteShader(shaderFrag);
1188 glDeleteProgram(program);
1189 expectError(GL_NO_ERROR);
1190 }
1191 };
1192
1193 class ProgramActiveUniformNameCase : public ApiCase
1194 {
1195 public:
ProgramActiveUniformNameCase(Context & context,const char * name,const char * description)1196 ProgramActiveUniformNameCase (Context& context, const char* name, const char* description)
1197 : ApiCase(context, name, description)
1198 {
1199 }
1200
test(void)1201 void test (void)
1202 {
1203 using tcu::TestLog;
1204
1205 static const char* testVertSource =
1206 "uniform highp float uniformNameWithLength23;\n"
1207 "uniform highp vec2 uniformVec2;\n"
1208 "uniform highp mat4 uniformMat4;\n"
1209 "void main (void)\n"
1210 "{\n"
1211 " gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n"
1212 "}\n\0";
1213 static const char* testFragSource =
1214
1215 "void main (void)\n"
1216 "{\n"
1217 " gl_FragColor = vec4(0.0);\n"
1218 "}\n\0";
1219
1220 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1221 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1222
1223 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
1224 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
1225
1226 glCompileShader(shaderVert);
1227 glCompileShader(shaderFrag);
1228 expectError(GL_NO_ERROR);
1229
1230 GLuint program = glCreateProgram();
1231 glAttachShader(program, shaderVert);
1232 glAttachShader(program, shaderFrag);
1233 glLinkProgram(program);
1234 expectError(GL_NO_ERROR);
1235
1236 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORMS, 3);
1237 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint)std::string("uniformNameWithLength23").length() + 1); // including a null terminator
1238 expectError(GL_NO_ERROR);
1239
1240 const char* uniformNames[] =
1241 {
1242 "uniformNameWithLength23",
1243 "uniformVec2",
1244 "uniformMat4"
1245 };
1246
1247 // check names
1248 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx)
1249 {
1250 char buffer[2048] = {'x'};
1251 char* bufferEnd = (buffer + 1);
1252
1253 GLint written = 0; // null terminator not included
1254 GLint size = 0;
1255 GLenum type = 0;
1256 glGetActiveUniform(program, ndx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
1257
1258 if (written < DE_LENGTH_OF_ARRAY(buffer))
1259 bufferEnd = &buffer[written];
1260
1261 // find matching uniform
1262 {
1263 const std::string uniformName(buffer, bufferEnd);
1264 bool found = false;
1265
1266 for (int uniformNdx = 0; uniformNdx < DE_LENGTH_OF_ARRAY(uniformNames); ++uniformNdx)
1267 {
1268 if (uniformName == uniformNames[uniformNdx])
1269 {
1270 found = true;
1271 break;
1272 }
1273 }
1274
1275 if (!found)
1276 {
1277 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unknown uniform name: " << uniformName << TestLog::EndMessage;
1278 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1279 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name");
1280 }
1281 }
1282
1283 // and with too small buffer
1284 written = 0;
1285 glGetActiveUniform(program, ndx, 1, &written, &size, &type, buffer);
1286
1287 if (written != 0)
1288 {
1289 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0 got " << written << TestLog::EndMessage;
1290 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1291 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
1292 }
1293 }
1294
1295
1296 glDeleteShader(shaderVert);
1297 glDeleteShader(shaderFrag);
1298 glDeleteProgram(program);
1299 expectError(GL_NO_ERROR);
1300 }
1301 };
1302
1303 class ProgramUniformCase : public ApiCase
1304 {
1305 public:
ProgramUniformCase(Context & context,const char * name,const char * description)1306 ProgramUniformCase (Context& context, const char* name, const char* description)
1307 : ApiCase(context, name, description)
1308 {
1309 }
1310
test(void)1311 void test (void)
1312 {
1313 const struct UniformType
1314 {
1315 const char* declaration;
1316 const char* postDeclaration;
1317 const char* precision;
1318 const char* layout;
1319 const char* getter;
1320 GLenum type;
1321 GLint size;
1322 GLint isRowMajor;
1323 } uniformTypes[] =
1324 {
1325 { "float", "", "highp", "", "uniformValue", GL_FLOAT, 1, GL_FALSE },
1326 { "float", "[2]", "highp", "", "uniformValue[1]", GL_FLOAT, 2, GL_FALSE },
1327 { "vec2", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC2, 1, GL_FALSE },
1328 { "vec3", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC3, 1, GL_FALSE },
1329 { "vec4", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC4, 1, GL_FALSE },
1330 { "int", "", "highp", "", "float(uniformValue)", GL_INT, 1, GL_FALSE },
1331 { "ivec2", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC2, 1, GL_FALSE },
1332 { "ivec3", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC3, 1, GL_FALSE },
1333 { "ivec4", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC4, 1, GL_FALSE },
1334 { "bool", "", "", "", "float(uniformValue)", GL_BOOL, 1, GL_FALSE },
1335 { "bvec2", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC2, 1, GL_FALSE },
1336 { "bvec3", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC3, 1, GL_FALSE },
1337 { "bvec4", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC4, 1, GL_FALSE },
1338 { "mat2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2, 1, GL_FALSE },
1339 { "mat3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3, 1, GL_FALSE },
1340 { "mat4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4, 1, GL_FALSE },
1341 { "sampler2D", "", "highp", "", "float(texture2D(uniformValue, vec2(0.0, 0.0)).r)", GL_SAMPLER_2D, 1, GL_FALSE },
1342 { "samplerCube", "", "highp", "", "float(textureCube(uniformValue, vec3(0.0, 0.0, 0.0)).r)", GL_SAMPLER_CUBE, 1, GL_FALSE },
1343 };
1344
1345 static const char* vertSource =
1346 "void main (void)\n"
1347 "{\n"
1348 " gl_Position = vec4(0.0);\n"
1349 "}\n\0";
1350
1351 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1352 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1353 GLuint program = glCreateProgram();
1354
1355 glAttachShader(program, shaderVert);
1356 glAttachShader(program, shaderFrag);
1357
1358 glShaderSource(shaderVert, 1, &vertSource, DE_NULL);
1359 glCompileShader(shaderVert);
1360 expectError(GL_NO_ERROR);
1361
1362 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformTypes); ++ndx)
1363 {
1364 tcu::ScopedLogSection(m_log, uniformTypes[ndx].declaration, std::string("Verify type of ") + uniformTypes[ndx].declaration + " variable" + uniformTypes[ndx].postDeclaration );
1365
1366 // gen fragment shader
1367
1368 std::ostringstream frag;
1369 frag << uniformTypes[ndx].layout << "uniform " << uniformTypes[ndx].precision << " " << uniformTypes[ndx].declaration << " uniformValue" << uniformTypes[ndx].postDeclaration << ";\n";
1370 frag << "void main (void)\n";
1371 frag << "{\n";
1372 frag << " gl_FragColor = vec4(" << uniformTypes[ndx].getter << ");\n";
1373 frag << "}\n";
1374
1375 {
1376 std::string fragmentSource = frag.str();
1377 const char* fragmentSourceCStr = fragmentSource.c_str();
1378 glShaderSource(shaderFrag, 1, &fragmentSourceCStr, DE_NULL);
1379 }
1380
1381 // compile & link
1382
1383 glCompileShader(shaderFrag);
1384 glLinkProgram(program);
1385
1386 // test
1387 if (verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE))
1388 {
1389 const GLint index = 0; // first and only active uniform
1390
1391 char buffer[] = "not written to"; // not written to
1392 GLint written = 0;
1393 GLint size = 0;
1394 GLenum type = 0;
1395 glGetActiveUniform(program, index, 0, &written, &size, &type, buffer);
1396
1397 checkIntEquals(m_testCtx, type, uniformTypes[ndx].type);
1398 checkIntEquals(m_testCtx, size, uniformTypes[ndx].size);
1399 }
1400 }
1401
1402 glDeleteShader(shaderVert);
1403 glDeleteShader(shaderFrag);
1404 glDeleteProgram(program);
1405 expectError(GL_NO_ERROR);
1406 }
1407 };
1408
1409 class ActiveAttributesCase : public ApiCase
1410 {
1411 public:
ActiveAttributesCase(Context & context,const char * name,const char * description)1412 ActiveAttributesCase (Context& context, const char* name, const char* description)
1413 : ApiCase(context, name, description)
1414 {
1415 }
1416
test(void)1417 void test (void)
1418 {
1419 using tcu::TestLog;
1420
1421 static const char* testVertSource =
1422 "attribute highp vec2 longInputAttributeName;\n"
1423 "attribute highp vec2 shortName;\n"
1424 "void main (void)\n"
1425 "{\n"
1426 " gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n"
1427 "}\n\0";
1428 static const char* testFragSource =
1429 "void main (void)\n"
1430 "{\n"
1431 " gl_FragColor = vec4(0.0);\n"
1432 "}\n\0";
1433
1434 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1435 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1436
1437 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
1438 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
1439
1440 glCompileShader(shaderVert);
1441 glCompileShader(shaderFrag);
1442 expectError(GL_NO_ERROR);
1443
1444 GLuint program = glCreateProgram();
1445 glAttachShader(program, shaderVert);
1446 glAttachShader(program, shaderFrag);
1447 glLinkProgram(program);
1448 expectError(GL_NO_ERROR);
1449
1450 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTES, 2);
1451 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint)std::string("longInputAttributeName").length() + 1); // does include null-terminator
1452
1453 // check names
1454 for (int attributeNdx = 0; attributeNdx < 2; ++attributeNdx)
1455 {
1456 char buffer[2048] = {'x'};
1457
1458 GLint written = 0;
1459 GLint size = 0;
1460 GLenum type = 0;
1461 glGetActiveAttrib(program, attributeNdx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
1462 expectError(GL_NO_ERROR);
1463
1464 if (deStringBeginsWith(buffer, "longInputAttributeName"))
1465 {
1466 checkIntEquals(m_testCtx, written, (GLint)std::string("longInputAttributeName").length()); // does NOT include null-terminator
1467 }
1468 else if (deStringBeginsWith(buffer, "shortName"))
1469 {
1470 checkIntEquals(m_testCtx, written, (GLint)std::string("shortName").length()); // does NOT include null-terminator
1471 }
1472 else
1473 {
1474 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unexpected attribute name." << TestLog::EndMessage;
1475 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1476 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected name");
1477 }
1478 }
1479
1480 // and with too short buffer
1481 {
1482 char buffer[2048] = {'x'};
1483
1484 GLint written = 0;
1485 GLint size = 0;
1486 GLenum type = 0;
1487
1488 glGetActiveAttrib(program, 0, 1, &written, &size, &type, buffer);
1489 expectError(GL_NO_ERROR);
1490 checkIntEquals(m_testCtx, written, 0);
1491 }
1492
1493 glDeleteShader(shaderVert);
1494 glDeleteShader(shaderFrag);
1495 glDeleteProgram(program);
1496 expectError(GL_NO_ERROR);
1497 }
1498 };
1499
1500 struct PointerData
1501 {
1502 GLint size;
1503 GLenum type;
1504 GLint stride;
1505 GLboolean normalized;
1506 void* pointer;
1507 };
1508
1509 class VertexAttributeSizeCase : public ApiCase
1510 {
1511 public:
VertexAttributeSizeCase(Context & context,const char * name,const char * description)1512 VertexAttributeSizeCase (Context& context, const char* name, const char* description)
1513 : ApiCase(context, name, description)
1514 {
1515 }
1516
test(void)1517 void test (void)
1518 {
1519 GLfloat vertexData[4] = {0.0f}; // never accessed
1520
1521 // test VertexAttribPointer
1522 const PointerData pointers[] =
1523 {
1524 // size test
1525 { 4, GL_FLOAT, 0, GL_FALSE, vertexData },
1526 { 3, GL_FLOAT, 0, GL_FALSE, vertexData },
1527 { 2, GL_FLOAT, 0, GL_FALSE, vertexData },
1528 { 1, GL_FLOAT, 0, GL_FALSE, vertexData },
1529 { 4, GL_SHORT, 0, GL_FALSE, vertexData },
1530 { 3, GL_SHORT, 0, GL_FALSE, vertexData },
1531 { 2, GL_SHORT, 0, GL_FALSE, vertexData },
1532 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
1533 };
1534
1535 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1536 {
1537 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1538 expectError(GL_NO_ERROR);
1539
1540 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size);
1541 }
1542 }
1543 };
1544
1545 class VertexAttributeTypeCase : public ApiCase
1546 {
1547 public:
VertexAttributeTypeCase(Context & context,const char * name,const char * description)1548 VertexAttributeTypeCase (Context& context, const char* name, const char* description)
1549 : ApiCase(context, name, description)
1550 {
1551 }
1552
test(void)1553 void test (void)
1554 {
1555 GLfloat vertexData[4] = {0.0f}; // never accessed
1556
1557 const PointerData pointers[] =
1558 {
1559 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
1560 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
1561 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
1562 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
1563 { 1, GL_FIXED, 0, GL_FALSE, vertexData },
1564 { 1, GL_FLOAT, 0, GL_FALSE, vertexData },
1565 };
1566
1567 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1568 {
1569 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1570 expectError(GL_NO_ERROR);
1571
1572 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
1573 }
1574 }
1575 };
1576
1577 class VertexAttributeStrideCase : public ApiCase
1578 {
1579 public:
VertexAttributeStrideCase(Context & context,const char * name,const char * description)1580 VertexAttributeStrideCase (Context& context, const char* name, const char* description)
1581 : ApiCase(context, name, description)
1582 {
1583 }
1584
test(void)1585 void test (void)
1586 {
1587 GLfloat vertexData[4] = {0.0f}; // never accessed
1588
1589 struct StridePointerData
1590 {
1591 GLint size;
1592 GLenum type;
1593 GLint stride;
1594 void* pointer;
1595 };
1596
1597 // test VertexAttribPointer
1598 {
1599 const StridePointerData pointers[] =
1600 {
1601 { 1, GL_FLOAT, 0, vertexData },
1602 { 1, GL_FLOAT, 1, vertexData },
1603 { 1, GL_FLOAT, 4, vertexData },
1604 { 1, GL_SHORT, 0, vertexData },
1605 { 1, GL_SHORT, 1, vertexData },
1606 { 1, GL_SHORT, 4, vertexData },
1607 { 1, GL_FIXED, 0, vertexData },
1608 { 1, GL_FIXED, 1, vertexData },
1609 { 1, GL_FIXED, 4, vertexData },
1610 { 1, GL_BYTE, 0, vertexData },
1611 { 1, GL_UNSIGNED_SHORT, 1, vertexData },
1612 { 1, GL_UNSIGNED_SHORT, 4, vertexData },
1613 { 4, GL_UNSIGNED_BYTE, 0, vertexData },
1614 { 4, GL_UNSIGNED_BYTE, 1, vertexData },
1615 { 4, GL_UNSIGNED_BYTE, 4, vertexData },
1616 };
1617
1618 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1619 {
1620 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride, pointers[ndx].pointer);
1621 expectError(GL_NO_ERROR);
1622
1623 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
1624 }
1625 }
1626 }
1627 };
1628
1629 class VertexAttributeNormalizedCase : public ApiCase
1630 {
1631 public:
VertexAttributeNormalizedCase(Context & context,const char * name,const char * description)1632 VertexAttributeNormalizedCase (Context& context, const char* name, const char* description)
1633 : ApiCase(context, name, description)
1634 {
1635 }
1636
test(void)1637 void test (void)
1638 {
1639 GLfloat vertexData[4] = {0.0f}; // never accessed
1640
1641 // test VertexAttribPointer
1642 {
1643 const PointerData pointers[] =
1644 {
1645 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
1646 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
1647 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
1648 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
1649 { 1, GL_BYTE, 0, GL_TRUE, vertexData },
1650 { 1, GL_SHORT, 0, GL_TRUE, vertexData },
1651 { 1, GL_UNSIGNED_BYTE, 0, GL_TRUE, vertexData },
1652 { 1, GL_UNSIGNED_SHORT, 0, GL_TRUE, vertexData },
1653 };
1654
1655 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1656 {
1657 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1658 expectError(GL_NO_ERROR);
1659
1660 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx].normalized);
1661 }
1662 }
1663 }
1664 };
1665
1666 class VertexAttributeEnabledCase : public ApiCase
1667 {
1668 public:
VertexAttributeEnabledCase(Context & context,const char * name,const char * description)1669 VertexAttributeEnabledCase (Context& context, const char* name, const char* description)
1670 : ApiCase(context, name, description)
1671 {
1672 }
1673
test(void)1674 void test (void)
1675 {
1676 // VERTEX_ATTRIB_ARRAY_ENABLED
1677
1678 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
1679 glEnableVertexAttribArray(0);
1680 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
1681 glDisableVertexAttribArray(0);
1682 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
1683 }
1684 };
1685
1686 class VertexAttributeBufferBindingCase : public ApiCase
1687 {
1688 public:
VertexAttributeBufferBindingCase(Context & context,const char * name,const char * description)1689 VertexAttributeBufferBindingCase (Context& context, const char* name, const char* description)
1690 : ApiCase(context, name, description)
1691 {
1692 }
1693
test(void)1694 void test (void)
1695 {
1696 // initial
1697 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0);
1698
1699 GLuint bufferID;
1700 glGenBuffers(1, &bufferID);
1701 glBindBuffer(GL_ARRAY_BUFFER, bufferID);
1702 expectError(GL_NO_ERROR);
1703
1704 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
1705 expectError(GL_NO_ERROR);
1706
1707 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID);
1708
1709 glDeleteBuffers(1, &bufferID);
1710 expectError(GL_NO_ERROR);
1711 }
1712 };
1713
1714 class VertexAttributePointerCase : public ApiCase
1715 {
1716 public:
VertexAttributePointerCase(Context & context,const char * name,const char * description)1717 VertexAttributePointerCase (Context& context, const char* name, const char* description)
1718 : ApiCase(context, name, description)
1719 {
1720 }
1721
test(void)1722 void test (void)
1723 {
1724 StateQueryMemoryWriteGuard<GLvoid*> initialState;
1725 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState);
1726 initialState.verifyValidity(m_testCtx);
1727 checkPointerEquals(m_testCtx, initialState, 0);
1728
1729 GLfloat vertexData[4] = {0.0f}; // never accessed
1730 const PointerData pointers[] =
1731 {
1732 { 1, GL_BYTE, 0, GL_FALSE, &vertexData[2] },
1733 { 1, GL_SHORT, 0, GL_FALSE, &vertexData[1] },
1734 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[2] },
1735 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[1] },
1736 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[0] },
1737 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[3] },
1738 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[2] },
1739 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[0] },
1740 { 4, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[1] },
1741 { 4, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[2] },
1742 };
1743
1744 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1745 {
1746 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1747 expectError(GL_NO_ERROR);
1748
1749 StateQueryMemoryWriteGuard<GLvoid*> state;
1750 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
1751 state.verifyValidity(m_testCtx);
1752 checkPointerEquals(m_testCtx, state, pointers[ndx].pointer);
1753 }
1754 }
1755 };
1756
1757 class UniformValueFloatCase : public ApiCase
1758 {
1759 public:
UniformValueFloatCase(Context & context,const char * name,const char * description)1760 UniformValueFloatCase (Context& context, const char* name, const char* description)
1761 : ApiCase(context, name, description)
1762 {
1763 }
1764
test(void)1765 void test (void)
1766 {
1767 static const char* testVertSource =
1768 "uniform highp float floatUniform;\n"
1769 "uniform highp vec2 float2Uniform;\n"
1770 "uniform highp vec3 float3Uniform;\n"
1771 "uniform highp vec4 float4Uniform;\n"
1772 "void main (void)\n"
1773 "{\n"
1774 " gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n"
1775 "}\n";
1776 static const char* testFragSource =
1777
1778 "void main (void)\n"
1779 "{\n"
1780 " gl_FragColor = vec4(0.0);\n"
1781 "}\n";
1782
1783 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1784 if (!program.isOk())
1785 {
1786 m_log << program;
1787 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1788 return;
1789 }
1790
1791 glUseProgram(program.getProgram());
1792 expectError(GL_NO_ERROR);
1793
1794 GLint location;
1795
1796 location = glGetUniformLocation(program.getProgram(), "floatUniform");
1797 glUniform1f(location, 1.0f);
1798 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), location, 1.0f);
1799
1800 location = glGetUniformLocation(program.getProgram(), "float2Uniform");
1801 glUniform2f(location, 1.0f, 2.0f);
1802 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f);
1803
1804 location = glGetUniformLocation(program.getProgram(), "float3Uniform");
1805 glUniform3f(location, 1.0f, 2.0f, 3.0f);
1806 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f);
1807
1808 location = glGetUniformLocation(program.getProgram(), "float4Uniform");
1809 glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f);
1810 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f, 4.0f);
1811
1812 glUseProgram(0);
1813 expectError(GL_NO_ERROR);
1814 }
1815 };
1816
1817 class UniformValueIntCase : public ApiCase
1818 {
1819 public:
UniformValueIntCase(Context & context,const char * name,const char * description)1820 UniformValueIntCase (Context& context, const char* name, const char* description)
1821 : ApiCase(context, name, description)
1822 {
1823 }
1824
test(void)1825 void test (void)
1826 {
1827 static const char* testVertSource =
1828 "uniform highp int intUniform;\n"
1829 "uniform highp ivec2 int2Uniform;\n"
1830 "uniform highp ivec3 int3Uniform;\n"
1831 "uniform highp ivec4 int4Uniform;\n"
1832 "void main (void)\n"
1833 "{\n"
1834 " gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n"
1835 "}\n";
1836 static const char* testFragSource =
1837 "void main (void)\n"
1838 "{\n"
1839 " gl_FragColor = vec4(0.0);\n"
1840 "}\n";
1841
1842 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1843 if (!program.isOk())
1844 {
1845 m_log << program;
1846 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1847 return;
1848 }
1849
1850 glUseProgram(program.getProgram());
1851 expectError(GL_NO_ERROR);
1852
1853 GLint location;
1854
1855 location = glGetUniformLocation(program.getProgram(), "intUniform");
1856 glUniform1i(location, 1);
1857 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1858
1859 location = glGetUniformLocation(program.getProgram(), "int2Uniform");
1860 glUniform2i(location, 1, 2);
1861 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 2);
1862
1863 location = glGetUniformLocation(program.getProgram(), "int3Uniform");
1864 glUniform3i(location, 1, 2, 3);
1865 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3);
1866
1867 location = glGetUniformLocation(program.getProgram(), "int4Uniform");
1868 glUniform4i(location, 1, 2, 3, 4);
1869 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3, 4);
1870
1871 glUseProgram(0);
1872 expectError(GL_NO_ERROR);
1873 }
1874 };
1875
1876 class UniformValueBooleanCase : public ApiCase
1877 {
1878 public:
UniformValueBooleanCase(Context & context,const char * name,const char * description)1879 UniformValueBooleanCase (Context& context, const char* name, const char* description)
1880 : ApiCase(context, name, description)
1881 {
1882 }
1883
test(void)1884 void test (void)
1885 {
1886 static const char* testVertSource =
1887 "uniform bool boolUniform;\n"
1888 "uniform bvec2 bool2Uniform;\n"
1889 "uniform bvec3 bool3Uniform;\n"
1890 "uniform bvec4 bool4Uniform;\n"
1891 "void main (void)\n"
1892 "{\n"
1893 " gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n"
1894 "}\n";
1895 static const char* testFragSource =
1896 "void main (void)\n"
1897 "{\n"
1898 " gl_FragColor = vec4(0.0);\n"
1899 "}\n";
1900
1901 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1902 if (!program.isOk())
1903 {
1904 m_log << program;
1905 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1906 return;
1907 }
1908
1909 glUseProgram(program.getProgram());
1910 expectError(GL_NO_ERROR);
1911
1912 GLint location;
1913
1914 // int conversion
1915
1916 location = glGetUniformLocation(program.getProgram(), "boolUniform");
1917 glUniform1i(location, 1);
1918 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1919
1920 location = glGetUniformLocation(program.getProgram(), "bool2Uniform");
1921 glUniform2i(location, 1, 2);
1922 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1);
1923
1924 location = glGetUniformLocation(program.getProgram(), "bool3Uniform");
1925 glUniform3i(location, 0, 1, 2);
1926 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1);
1927
1928 location = glGetUniformLocation(program.getProgram(), "bool4Uniform");
1929 glUniform4i(location, 1, 0, 1, -1);
1930 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1);
1931
1932 // float conversion
1933
1934 location = glGetUniformLocation(program.getProgram(), "boolUniform");
1935 glUniform1f(location, 1.0f);
1936 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1937
1938 location = glGetUniformLocation(program.getProgram(), "bool2Uniform");
1939 glUniform2f(location, 1.0f, 0.1f);
1940 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1);
1941
1942 location = glGetUniformLocation(program.getProgram(), "bool3Uniform");
1943 glUniform3f(location, 0.0f, 0.1f, -0.1f);
1944 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1);
1945
1946 location = glGetUniformLocation(program.getProgram(), "bool4Uniform");
1947 glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f);
1948 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1);
1949
1950 glUseProgram(0);
1951 expectError(GL_NO_ERROR);
1952 }
1953 };
1954
1955 class UniformValueSamplerCase : public ApiCase
1956 {
1957 public:
UniformValueSamplerCase(Context & context,const char * name,const char * description)1958 UniformValueSamplerCase (Context& context, const char* name, const char* description)
1959 : ApiCase(context, name, description)
1960 {
1961 }
1962
test(void)1963 void test (void)
1964 {
1965 static const char* testVertSource =
1966 "void main (void)\n"
1967 "{\n"
1968 " gl_Position = vec4(0.0);\n"
1969 "}\n";
1970 static const char* testFragSource =
1971 "uniform highp sampler2D uniformSampler;\n"
1972
1973 "void main (void)\n"
1974 "{\n"
1975 " gl_FragColor = vec4(texture2D(uniformSampler, vec2(0.0, 0.0)).x);\n"
1976 "}\n";
1977
1978 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1979 if (!program.isOk())
1980 {
1981 m_log << program;
1982 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1983 return;
1984 }
1985
1986 glUseProgram(program.getProgram());
1987 expectError(GL_NO_ERROR);
1988
1989 GLint location;
1990
1991 location = glGetUniformLocation(program.getProgram(), "uniformSampler");
1992 glUniform1i(location, 1);
1993 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1994
1995 glUseProgram(0);
1996 expectError(GL_NO_ERROR);
1997 }
1998 };
1999
2000 class UniformValueArrayCase : public ApiCase
2001 {
2002 public:
UniformValueArrayCase(Context & context,const char * name,const char * description)2003 UniformValueArrayCase (Context& context, const char* name, const char* description)
2004 : ApiCase(context, name, description)
2005 {
2006 }
2007
test(void)2008 void test (void)
2009 {
2010 static const char* testVertSource =
2011 "uniform highp float arrayUniform[5];"
2012 "uniform highp vec2 array2Uniform[5];"
2013 "uniform highp vec3 array3Uniform[5];"
2014 "uniform highp vec4 array4Uniform[5];"
2015 "void main (void)\n"
2016 "{\n"
2017 " gl_Position = \n"
2018 " + vec4(arrayUniform[0] + arrayUniform[1] + arrayUniform[2] + arrayUniform[3] + arrayUniform[4])\n"
2019 " + vec4(array2Uniform[0].x + array2Uniform[1].x + array2Uniform[2].x + array2Uniform[3].x + array2Uniform[4].x)\n"
2020 " + vec4(array3Uniform[0].x + array3Uniform[1].x + array3Uniform[2].x + array3Uniform[3].x + array3Uniform[4].x)\n"
2021 " + vec4(array4Uniform[0].x + array4Uniform[1].x + array4Uniform[2].x + array4Uniform[3].x + array4Uniform[4].x);\n"
2022 "}\n";
2023 static const char* testFragSource =
2024
2025 "void main (void)\n"
2026 "{\n"
2027 " gl_FragColor = vec4(0.0);\n"
2028 "}\n";
2029
2030 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
2031 if (!program.isOk())
2032 {
2033 m_log << program;
2034 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
2035 return;
2036 }
2037
2038 glUseProgram(program.getProgram());
2039 expectError(GL_NO_ERROR);
2040
2041 GLint location;
2042
2043 float uniformValue[5 * 4] =
2044 {
2045 -1.0f, 0.1f, 4.0f, 800.0f,
2046 13.0f, 55.0f, 12.0f, 91.0f,
2047 -55.1f, 1.1f, 98.0f, 19.0f,
2048 41.0f, 65.0f, 4.0f, 12.2f,
2049 95.0f, 77.0f, 32.0f, 48.0f
2050 };
2051
2052 location = glGetUniformLocation(program.getProgram(), "arrayUniform");
2053 glUniform1fv(location, 5, uniformValue);
2054 expectError(GL_NO_ERROR);
2055
2056 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[0]"), uniformValue[0]);
2057 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[1]"), uniformValue[1]);
2058 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[2]"), uniformValue[2]);
2059 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[3]"), uniformValue[3]);
2060 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[4]"), uniformValue[4]);
2061 expectError(GL_NO_ERROR);
2062
2063 location = glGetUniformLocation(program.getProgram(),"array2Uniform");
2064 glUniform2fv(location, 5, uniformValue);
2065 expectError(GL_NO_ERROR);
2066
2067 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[0]"), uniformValue[2 * 0], uniformValue[(2 * 0) + 1]);
2068 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[1]"), uniformValue[2 * 1], uniformValue[(2 * 1) + 1]);
2069 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[2]"), uniformValue[2 * 2], uniformValue[(2 * 2) + 1]);
2070 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[3]"), uniformValue[2 * 3], uniformValue[(2 * 3) + 1]);
2071 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[4]"), uniformValue[2 * 4], uniformValue[(2 * 4) + 1]);
2072 expectError(GL_NO_ERROR);
2073
2074 location = glGetUniformLocation(program.getProgram(),"array3Uniform");
2075 glUniform3fv(location, 5, uniformValue);
2076 expectError(GL_NO_ERROR);
2077
2078 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[0]"), uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]);
2079 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[1]"), uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]);
2080 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[2]"), uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]);
2081 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[3]"), uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]);
2082 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[4]"), uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]);
2083 expectError(GL_NO_ERROR);
2084
2085 location = glGetUniformLocation(program.getProgram(),"array4Uniform");
2086 glUniform4fv(location, 5, uniformValue);
2087 expectError(GL_NO_ERROR);
2088
2089 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[0]"), uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]);
2090 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[1]"), uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]);
2091 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[2]"), uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]);
2092 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[3]"), uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]);
2093 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[4]"), uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]);
2094 expectError(GL_NO_ERROR);
2095
2096 glUseProgram(0);
2097 expectError(GL_NO_ERROR);
2098 }
2099 };
2100
2101 class UniformValueMatrixCase : public ApiCase
2102 {
2103 public:
UniformValueMatrixCase(Context & context,const char * name,const char * description)2104 UniformValueMatrixCase (Context& context, const char* name, const char* description)
2105 : ApiCase(context, name, description)
2106 {
2107 }
2108
test(void)2109 void test (void)
2110 {
2111 static const char* testVertSource =
2112 "uniform highp mat2 mat2Uniform;"
2113 "uniform highp mat3 mat3Uniform;"
2114 "uniform highp mat4 mat4Uniform;"
2115 "void main (void)\n"
2116 "{\n"
2117 " gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n"
2118 "}\n";
2119 static const char* testFragSource =
2120
2121 "void main (void)\n"
2122 "{\n"
2123 " gl_FragColor = vec4(0.0);\n"
2124 "}\n";
2125
2126 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
2127 if (!program.isOk())
2128 {
2129 m_log << program;
2130 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
2131 return;
2132 }
2133
2134 glUseProgram(program.getProgram());
2135 expectError(GL_NO_ERROR);
2136
2137 GLint location;
2138
2139 float matrixValues[4 * 4] =
2140 {
2141 -1.0f, 0.1f, 4.0f, 800.0f,
2142 13.0f, 55.0f, 12.0f, 91.0f,
2143 -55.1f, 1.1f, 98.0f, 19.0f,
2144 41.0f, 65.0f, 4.0f, 12.2f,
2145 };
2146
2147 // the values of the matrix are returned in column major order but they can be given in either order
2148
2149 location = glGetUniformLocation(program.getProgram(), "mat2Uniform");
2150 glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues);
2151 verifyUniformMatrixValues<2>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);
2152
2153 location = glGetUniformLocation(program.getProgram(), "mat3Uniform");
2154 glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues);
2155 verifyUniformMatrixValues<3>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);
2156
2157 location = glGetUniformLocation(program.getProgram(), "mat4Uniform");
2158 glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues);
2159 verifyUniformMatrixValues<4>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);
2160
2161 glUseProgram(0);
2162 expectError(GL_NO_ERROR);
2163 }
2164 };
2165
2166 class PrecisionFormatCase : public ApiCase
2167 {
2168 public:
2169 struct RequiredFormat
2170 {
2171 int negativeRange;
2172 int positiveRange;
2173 int precision;
2174 };
2175
PrecisionFormatCase(Context & context,const char * name,const char * description,glw::GLenum shaderType,glw::GLenum precisionType)2176 PrecisionFormatCase (Context& context, const char* name, const char* description, glw::GLenum shaderType, glw::GLenum precisionType)
2177 : ApiCase (context, name, description)
2178 , m_shaderType (shaderType)
2179 , m_precisionType (precisionType)
2180 {
2181 }
2182
2183 private:
test(void)2184 void test (void)
2185 {
2186 const RequiredFormat expected = getRequiredFormat();
2187 bool error = false;
2188 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> shaderCompiler;
2189 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]> range;
2190 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> precision;
2191
2192 // requires SHADER_COMPILER = true
2193 glGetBooleanv(GL_SHADER_COMPILER, &shaderCompiler);
2194 expectError(GL_NO_ERROR);
2195
2196 if (!shaderCompiler.verifyValidity(m_testCtx))
2197 return;
2198 if (shaderCompiler != GL_TRUE)
2199 throw tcu::NotSupportedError("SHADER_COMPILER = TRUE required");
2200
2201 // query values
2202 glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision);
2203 expectError(GL_NO_ERROR);
2204
2205 if (!range.verifyValidity(m_testCtx))
2206 return;
2207 if (!precision.verifyValidity(m_testCtx))
2208 return;
2209
2210 m_log
2211 << tcu::TestLog::Message
2212 << "range[0] = " << range[0] << "\n"
2213 << "range[1] = " << range[1] << "\n"
2214 << "precision = " << precision
2215 << tcu::TestLog::EndMessage;
2216
2217 // special case for highp and fragment shader
2218
2219 if (m_shaderType == GL_FRAGMENT_SHADER && (m_precisionType == GL_HIGH_FLOAT || m_precisionType == GL_HIGH_INT))
2220 {
2221 // not supported is a valid return value
2222 if (range[0] == 0 && range[1] == 0 && precision == 0)
2223 return;
2224 }
2225
2226 // verify the returned values
2227
2228 if (range[0] < expected.negativeRange)
2229 {
2230 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to " << expected.negativeRange << tcu::TestLog::EndMessage;
2231 error = true;
2232 }
2233
2234 if (range[1] < expected.positiveRange)
2235 {
2236 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to " << expected.positiveRange << tcu::TestLog::EndMessage;
2237 error = true;
2238 }
2239
2240 if (precision < expected.precision)
2241 {
2242 m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to " << expected.precision << tcu::TestLog::EndMessage;
2243 error = true;
2244 }
2245
2246 if (error)
2247 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range");
2248 }
2249
getRequiredFormat(void) const2250 RequiredFormat getRequiredFormat (void) const
2251 {
2252 // Precisions for different types.
2253 // For example highp float: range: (-2^62, 2^62) => min = -2^62 + e, max = 2^62 - e
2254 const RequiredFormat requirements[] =
2255 {
2256 { 0, 0, 8 }, //!< lowp float
2257 { 13, 13, 10 }, //!< mediump float
2258 { 61, 61, 16 }, //!< highp float
2259 { 7, 7, 0 }, //!< lowp int
2260 { 9, 9, 0 }, //!< mediump int
2261 { 15, 15, 0 }, //!< highp int
2262 };
2263 const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT;
2264
2265 DE_ASSERT(ndx >= 0);
2266 DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements));
2267 return requirements[ndx];
2268 }
2269
2270 const glw::GLenum m_shaderType;
2271 const glw::GLenum m_precisionType;
2272 };
2273
2274 } // anonymous
2275
2276
ShaderStateQueryTests(Context & context)2277 ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
2278 : TestCaseGroup(context, "shader", "Shader State Query tests")
2279 {
2280 }
2281
init(void)2282 void ShaderStateQueryTests::init (void)
2283 {
2284 // shader
2285 addChild(new ShaderTypeCase (m_context, "shader_type", "SHADER_TYPE"));
2286 addChild(new ShaderCompileStatusCase (m_context, "shader_compile_status", "COMPILE_STATUS"));
2287 addChild(new ShaderInfoLogCase (m_context, "shader_info_log_length", "INFO_LOG_LENGTH"));
2288 addChild(new ShaderSourceCase (m_context, "shader_source_length", "SHADER_SOURCE_LENGTH"));
2289
2290 // shader and program
2291 addChild(new DeleteStatusCase (m_context, "delete_status", "DELETE_STATUS"));
2292
2293 // vertex-attrib
2294 addChild(new CurrentVertexAttribInitialCase (m_context, "current_vertex_attrib_initial", "CURRENT_VERTEX_ATTRIB"));
2295 addChild(new CurrentVertexAttribFloatCase (m_context, "current_vertex_attrib_float", "CURRENT_VERTEX_ATTRIB"));
2296 addChild(new CurrentVertexAttribConversionCase (m_context, "current_vertex_attrib_float_to_int", "CURRENT_VERTEX_ATTRIB"));
2297
2298 // program
2299 addChild(new ProgramInfoLogCase (m_context, "program_info_log_length", "INFO_LOG_LENGTH"));
2300 addChild(new ProgramValidateStatusCase (m_context, "program_validate_status", "VALIDATE_STATUS"));
2301 addChild(new ProgramAttachedShadersCase (m_context, "program_attached_shaders", "ATTACHED_SHADERS"));
2302
2303 addChild(new ProgramActiveUniformNameCase (m_context, "program_active_uniform_name", "ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH"));
2304 addChild(new ProgramUniformCase (m_context, "program_active_uniform_types", "UNIFORM_TYPE and UNIFORM_SIZE"));
2305
2306 // attribute related
2307 addChild(new ActiveAttributesCase (m_context, "active_attributes", "ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH"));
2308 addChild(new VertexAttributeSizeCase (m_context, "vertex_attrib_size", "VERTEX_ATTRIB_ARRAY_SIZE"));
2309 addChild(new VertexAttributeTypeCase (m_context, "vertex_attrib_type", "VERTEX_ATTRIB_ARRAY_TYPE"));
2310 addChild(new VertexAttributeStrideCase (m_context, "vertex_attrib_stride", "VERTEX_ATTRIB_ARRAY_STRIDE"));
2311 addChild(new VertexAttributeNormalizedCase (m_context, "vertex_attrib_normalized", "VERTEX_ATTRIB_ARRAY_NORMALIZED"));
2312 addChild(new VertexAttributeEnabledCase (m_context, "vertex_attrib_array_enabled", "VERTEX_ATTRIB_ARRAY_ENABLED"));
2313 addChild(new VertexAttributeBufferBindingCase (m_context, "vertex_attrib_array_buffer_binding", "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"));
2314 addChild(new VertexAttributePointerCase (m_context, "vertex_attrib_pointerv", "GetVertexAttribPointerv"));
2315
2316 // uniform values
2317 addChild(new UniformValueFloatCase (m_context, "uniform_value_float", "GetUniform*"));
2318 addChild(new UniformValueIntCase (m_context, "uniform_value_int", "GetUniform*"));
2319 addChild(new UniformValueBooleanCase (m_context, "uniform_value_boolean", "GetUniform*"));
2320 addChild(new UniformValueSamplerCase (m_context, "uniform_value_sampler", "GetUniform*"));
2321 addChild(new UniformValueArrayCase (m_context, "uniform_value_array", "GetUniform*"));
2322 addChild(new UniformValueMatrixCase (m_context, "uniform_value_matrix", "GetUniform*"));
2323
2324 // precision format query
2325 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_FLOAT));
2326 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_FLOAT));
2327 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_FLOAT));
2328 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_INT));
2329 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_INT));
2330 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_INT));
2331 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_FLOAT));
2332 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT));
2333 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_FLOAT));
2334 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_INT));
2335 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_INT));
2336 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_INT));
2337 }
2338
2339 } // Functional
2340 } // gles2
2341 } // deqp
2342