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