• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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