1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 2.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Negative Shader API tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es2fNegativeShaderApiTests.hpp"
25 #include "es2fApiCase.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "gluContextInfo.hpp"
28 
29 #include "glwDefs.hpp"
30 #include "glwEnums.hpp"
31 
32 #include "deStringUtil.hpp"
33 
34 using namespace glw; // GL types
35 
36 namespace deqp
37 {
38 namespace gles2
39 {
40 namespace Functional
41 {
42 
43 static const char* vertexShaderSource	= "void main (void) { gl_Position = vec4(0.0); }\n\0";
44 static const char* fragmentShaderSource	= "void main (void) { gl_FragColor = vec4(0.0); }\n\0";
45 
46 static const char* uniformTestVertSource	=	"uniform mediump vec4 vTest;\n"
47 												"uniform mediump mat4 vMatrix;\n"
48 												"void main (void)\n"
49 												"{\n"
50 												"	gl_Position = vMatrix * vTest;\n"
51 												"}\n\0";
52 static const char* uniformTestFragSource	=	"uniform mediump ivec4 fTest;\n"
53 												"uniform sampler2D fSampler;\n"
54 												"void main (void)\n"
55 												"{\n"
56 												"	gl_FragColor.xy = vec4(fTest).xy;\n"
57 												"	gl_FragColor.zw = texture2D(fSampler, vec2(0.0, 0.0)).zw;\n"
58 												"}\n\0";
59 
60 using tcu::TestLog;
61 
NegativeShaderApiTests(Context & context)62 NegativeShaderApiTests::NegativeShaderApiTests (Context& context)
63 	: TestCaseGroup(context, "shader", "Negative Shader API Cases")
64 {
65 }
66 
~NegativeShaderApiTests(void)67 NegativeShaderApiTests::~NegativeShaderApiTests (void)
68 {
69 }
70 
init(void)71 void NegativeShaderApiTests::init (void)
72 {
73 	ES2F_ADD_API_CASE(create_shader, "Invalid glCreateShader() usage",
74 		{
75 			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if shaderType is not an accepted value.");
76 			glCreateShader(-1);
77 			expectError(GL_INVALID_ENUM);
78 			m_log << TestLog::EndSection;
79 		});
80 	ES2F_ADD_API_CASE(shader_source, "Invalid glShaderSource() usage",
81 		{
82 			GLboolean shaderCompilerSupported;
83 			glGetBooleanv(GL_SHADER_COMPILER, &shaderCompilerSupported);
84 			if (!shaderCompilerSupported)
85 				m_log << TestLog::Message << "// Shader compiler not supported, always expect GL_INVALID_OPERATION" << TestLog::EndMessage;
86 			else
87 				m_log << TestLog::Message << "// Shader compiler supported" << TestLog::EndMessage;
88 
89 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
90 			glShaderSource(1, 0, 0, 0);
91 			expectError(shaderCompilerSupported ? GL_INVALID_VALUE : GL_INVALID_OPERATION);
92 			m_log << TestLog::EndSection;
93 
94 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if count is less than 0.");
95 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
96 			glShaderSource(shader, -1, 0, 0);
97 			expectError(shaderCompilerSupported ? GL_INVALID_VALUE : GL_INVALID_OPERATION);
98 			m_log << TestLog::EndSection;
99 
100 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
101 			GLuint program = glCreateProgram();
102 			glShaderSource(program, 0, 0, 0);
103 			expectError(GL_INVALID_OPERATION);
104 			m_log << TestLog::EndSection;
105 
106 			glDeleteProgram(program);
107 			glDeleteShader(shader);
108 		});
109 	ES2F_ADD_API_CASE(compile_shader, "Invalid glCompileShader() usage",
110 		{
111 			GLboolean shaderCompilerSupported;
112 			glGetBooleanv(GL_SHADER_COMPILER, &shaderCompilerSupported);
113 			if (!shaderCompilerSupported)
114 				m_log << TestLog::Message << "// Shader compiler not supported, always expect GL_INVALID_OPERATION" << TestLog::EndMessage;
115 			else
116 				m_log << TestLog::Message << "// Shader compiler supported" << TestLog::EndMessage;
117 
118 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
119 			glCompileShader(9);
120 			expectError(shaderCompilerSupported ? GL_INVALID_VALUE : GL_INVALID_OPERATION);
121 			m_log << TestLog::EndSection;
122 
123 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
124 			GLuint program = glCreateProgram();
125 			glCompileShader(program);
126 			expectError(GL_INVALID_OPERATION);
127 			m_log << TestLog::EndSection;
128 
129 			glDeleteProgram(program);
130 		});
131 	ES2F_ADD_API_CASE(delete_shader, "Invalid glDeleteShader() usage",
132 		{
133 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
134 			glDeleteShader(9);
135 			expectError(GL_INVALID_VALUE);
136 			m_log << TestLog::EndSection;
137 		});
138 	ES2F_ADD_API_CASE(shader_binary, "Invalid glShaderBinary() usage",
139 		{
140 			std::vector<deInt32> binaryFormats;
141 			getSupportedExtensions(GL_NUM_SHADER_BINARY_FORMATS, GL_SHADER_BINARY_FORMATS, binaryFormats);
142 			deBool shaderBinarySupported = !binaryFormats.empty();
143 			if (!shaderBinarySupported)
144 				m_log << TestLog::Message << "// Shader binaries not supported." << TestLog::EndMessage;
145 			else
146 				m_log << TestLog::Message << "// Shader binaries supported" << TestLog::EndMessage;
147 
148 			GLuint shaders[2];
149 
150 			shaders[0] = glCreateShader(GL_VERTEX_SHADER);
151 			shaders[1] = glCreateShader(GL_VERTEX_SHADER);
152 			GLuint program = glCreateProgram();
153 
154 			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if binaryformat is not a supported format returned in GL_SHADER_BINARY_FORMATS.");
155 			glShaderBinary(1, &shaders[0], -1, 0, 0);
156 			expectError(GL_INVALID_ENUM);
157 			m_log << TestLog::EndSection;
158 
159 			if (shaderBinarySupported)
160 			{
161 				m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if any value in shaders is not a value generated by OpenGL.");
162 				shaders[0] = 137;
163 				glShaderBinary(1, &shaders[0], binaryFormats[0], 0, 0);
164 				expectError(shaderBinarySupported ? GL_INVALID_VALUE : GL_INVALID_OPERATION);
165 				m_log << TestLog::EndSection;
166 
167 				m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if n or length is negative.");
168 				shaders[0] = glCreateShader(GL_VERTEX_SHADER);
169 				glShaderBinary(-1, &shaders[0], binaryFormats[0], 0, 0);
170 				expectError(GL_INVALID_VALUE);
171 				glShaderBinary(1, &shaders[0], binaryFormats[0], 0, -1);
172 				expectError(GL_INVALID_VALUE);
173 				m_log << TestLog::EndSection;
174 
175 				m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if any value in shaders is not a shader object.");
176 				glShaderBinary(1, &program, binaryFormats[0], 0, 0);
177 				expectError(GL_INVALID_OPERATION);
178 				m_log << TestLog::EndSection;
179 
180 				m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if there is more than one vertex shader object handle or more than one fragment shader object handle in shaders.");
181 				shaders[0] = glCreateShader(GL_VERTEX_SHADER);
182 				shaders[1] = glCreateShader(GL_VERTEX_SHADER);
183 				glShaderBinary(2, &shaders[0], binaryFormats[0], 0, 1);
184 				expectError(GL_INVALID_OPERATION);
185 				m_log << TestLog::EndSection;
186 			}
187 
188 			glDeleteShader(shaders[0]);
189 			glDeleteShader(shaders[1]);
190 			glDeleteProgram(program);
191 
192 			// \note: The format of the data pointed to by binary does not match binaryformat.
193 		});
194 	ES2F_ADD_API_CASE(attach_shader, "Invalid glAttachShader() usage",
195 		{
196 			GLuint shader1 = glCreateShader(GL_VERTEX_SHADER);
197 			GLuint shader2 = glCreateShader(GL_VERTEX_SHADER);
198 			GLuint program = glCreateProgram();
199 
200 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
201 			glAttachShader(shader1, shader1);
202 			expectError(GL_INVALID_OPERATION);
203 			m_log << TestLog::EndSection;
204 
205 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
206 			glAttachShader(program, program);
207 			expectError(GL_INVALID_OPERATION);
208 			glAttachShader(shader1, program);
209 			expectError(GL_INVALID_OPERATION);
210 			m_log << TestLog::EndSection;
211 
212 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
213 			glAttachShader(program, -1);
214 			expectError(GL_INVALID_VALUE);
215 			glAttachShader(-1, shader1);
216 			expectError(GL_INVALID_VALUE);
217 			glAttachShader(-1, -1);
218 			expectError(GL_INVALID_VALUE);
219 			m_log << TestLog::EndSection;
220 
221 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is already attached to program, or if another shader object of the same type as shader is already attached to program.");
222 			glAttachShader(program, shader1);
223 			expectError(GL_NO_ERROR);
224 			glAttachShader(program, shader1);
225 			expectError(GL_INVALID_OPERATION);
226 			glAttachShader(program, shader2);
227 			expectError(GL_INVALID_OPERATION);
228 			m_log << TestLog::EndSection;
229 
230 			glDeleteProgram(program);
231 			glDeleteShader(shader1);
232 			glDeleteShader(shader2);
233 		});
234 	ES2F_ADD_API_CASE(detach_shader, "Invalid glDetachShader() usage",
235 		{
236 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
237 			GLuint program = glCreateProgram();
238 
239 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
240 			glDetachShader(-1, shader);
241 			expectError(GL_INVALID_VALUE);
242 			glDetachShader(program, -1);
243 			expectError(GL_INVALID_VALUE);
244 			glDetachShader(-1, -1);
245 			expectError(GL_INVALID_VALUE);
246 			m_log << TestLog::EndSection;
247 
248 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
249 			glDetachShader(shader, shader);
250 			expectError(GL_INVALID_OPERATION);
251 			m_log << TestLog::EndSection;
252 
253 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
254 			glDetachShader(program, program);
255 			expectError(GL_INVALID_OPERATION);
256 			glDetachShader(shader, program);
257 			expectError(GL_INVALID_OPERATION);
258 			m_log << TestLog::EndSection;
259 
260 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not attached to program.");
261 			glDetachShader(program, shader);
262 			expectError(GL_INVALID_OPERATION);
263 			m_log << TestLog::EndSection;
264 
265 			glDeleteProgram(program);
266 			glDeleteShader(shader);
267 		});
268 	ES2F_ADD_API_CASE(link_program, "Invalid glLinkProgram() usage",
269 		{
270 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
271 
272 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
273 			glLinkProgram(-1);
274 			expectError(GL_INVALID_VALUE);
275 			m_log << TestLog::EndSection;
276 
277 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
278 			glLinkProgram(shader);
279 			expectError(GL_INVALID_OPERATION);
280 			m_log << TestLog::EndSection;
281 
282 			glDeleteShader(shader);
283 		});
284 	ES2F_ADD_API_CASE(use_program, "Invalid glUseProgram() usage",
285 		{
286 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
287 
288 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is neither 0 nor a value generated by OpenGL.");
289 			glUseProgram(-1);
290 			expectError(GL_INVALID_VALUE);
291 			m_log << TestLog::EndSection;
292 
293 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
294 			glUseProgram(shader);
295 			expectError(GL_INVALID_OPERATION);
296 			m_log << TestLog::EndSection;
297 
298 			glUseProgram(0);
299 			glDeleteShader(shader);
300 		});
301 	ES2F_ADD_API_CASE(delete_program, "Invalid glDeleteProgram() usage",
302 		{
303 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
304 			glDeleteProgram(-1);
305 			expectError(GL_INVALID_VALUE);
306 			m_log << TestLog::EndSection;
307 		});
308 	ES2F_ADD_API_CASE(get_active_attrib, "Invalid glGetActiveAttrib() usage",
309 		{
310 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
311 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
312 			glUseProgram(program.getProgram());
313 
314 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
315 			glGetActiveAttrib(-1, 0, 0, 0, 0, 0, 0);
316 			expectError(GL_INVALID_VALUE);
317 			m_log << TestLog::EndSection;
318 
319 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
320 			glGetActiveAttrib(shader, 0, 0, 0, 0, 0, 0);
321 			expectError(GL_INVALID_OPERATION);
322 			m_log << TestLog::EndSection;
323 
324 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to the number of active attribute variables in program.");
325 			glGetActiveAttrib(program.getProgram(), 0, 0, 0, 0, 0, 0);
326 			expectError(GL_INVALID_VALUE);
327 			m_log << TestLog::EndSection;
328 
329 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if bufSize is less than 0.");
330 			glGetActiveAttrib(program.getProgram(), 0, -1, 0, 0, 0, 0);
331 			expectError(GL_INVALID_VALUE);
332 			m_log << TestLog::EndSection;
333 
334 			glUseProgram(0);
335 			glDeleteShader(shader);
336 		});
337 	ES2F_ADD_API_CASE(get_attrib_location, "Invalid glGetAttribLocation() usage",
338 		{
339 			GLuint programEmpty = glCreateProgram();
340 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
341 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
342 
343 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked.");
344 			glBindAttribLocation(programEmpty, 0, "test");
345 			glGetAttribLocation(programEmpty, "test");
346 			expectError(GL_INVALID_OPERATION);
347 			m_log << TestLog::EndSection;
348 
349 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a program or shader object.");
350 			glUseProgram(program.getProgram());
351 			glBindAttribLocation(program.getProgram(), 0, "test");
352 			expectError(GL_NO_ERROR);
353 			glGetAttribLocation(program.getProgram(), "test");
354 			expectError(GL_NO_ERROR);
355 			glGetAttribLocation(-2, "test");
356 			expectError(GL_INVALID_VALUE);
357 			m_log << TestLog::EndSection;
358 
359 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
360 			glGetAttribLocation(shader, "test");
361 			expectError(GL_INVALID_OPERATION);
362 			m_log << TestLog::EndSection;
363 
364 			glUseProgram(0);
365 			glDeleteShader(shader);
366 			glDeleteProgram(programEmpty);
367 		});
368 	ES2F_ADD_API_CASE(get_uniform_location, "Invalid glGetUniformLocation() usage",
369 		{
370 			GLuint programEmpty = glCreateProgram();
371 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
372 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
373 
374 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked.");
375 			glGetUniformLocation(programEmpty, "test");
376 			expectError(GL_INVALID_OPERATION);
377 			m_log << TestLog::EndSection;
378 
379 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
380 			glUseProgram(program.getProgram());
381 			glGetUniformLocation(-2, "test");
382 			expectError(GL_INVALID_VALUE);
383 			m_log << TestLog::EndSection;
384 
385 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
386 			glGetAttribLocation(shader, "test");
387 			expectError(GL_INVALID_OPERATION);
388 			m_log << TestLog::EndSection;
389 
390 			glUseProgram(0);
391 			glDeleteProgram(programEmpty);
392 			glDeleteShader(shader);
393 		});
394 	ES2F_ADD_API_CASE(bind_attrib_location, "Invalid glBindAttribLocation() usage",
395 		{
396 			GLuint program = glCreateProgram();
397 			GLuint maxIndex = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
398 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
399 
400 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
401 			glBindAttribLocation(program, maxIndex, "test");
402 			expectError(GL_INVALID_VALUE);
403 			m_log << TestLog::EndSection;
404 
405 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if name starts with the reserved prefix \"gl_\".");
406 			glBindAttribLocation(program, maxIndex-1, "gl_test");
407 			expectError(GL_INVALID_OPERATION);
408 			m_log << TestLog::EndSection;
409 
410 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
411 			glBindAttribLocation(-1, maxIndex-1, "test");
412 			expectError(GL_INVALID_VALUE);
413 			m_log << TestLog::EndSection;
414 
415 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
416 			glBindAttribLocation(shader, maxIndex-1, "test");
417 			expectError(GL_INVALID_OPERATION);
418 			m_log << TestLog::EndSection;
419 
420 			glDeleteProgram(program);
421 			glDeleteShader(shader);
422 		});
423 	ES2F_ADD_API_CASE(get_active_uniform, "Invalid glGetActiveUniform() usage",
424 		{
425 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
426 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
427 
428 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
429 			glGetActiveUniform(-1, 0, 0, 0, 0, 0, 0);
430 			expectError(GL_INVALID_VALUE);
431 			m_log << TestLog::EndSection;
432 
433 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
434 			glGetActiveUniform(shader, 0, 0, 0, 0, 0, 0);
435 			expectError(GL_INVALID_OPERATION);
436 			m_log << TestLog::EndSection;
437 
438 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to the number of active attribute variables in program.");
439 			glUseProgram(program.getProgram());
440 			glGetActiveUniform(program.getProgram(), 5, 0, 0, 0, 0, 0);
441 			expectError(GL_INVALID_VALUE);
442 			m_log << TestLog::EndSection;
443 
444 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if bufSize is less than 0.");
445 			glGetActiveUniform(program.getProgram(), 0, -1, 0, 0, 0, 0);
446 			expectError(GL_INVALID_VALUE);
447 			m_log << TestLog::EndSection;
448 
449 			glUseProgram(0);
450 			glDeleteShader(shader);
451 		});
452 	ES2F_ADD_API_CASE(validate_program, "Invalid glValidateProgram() usage",
453 		{
454 			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
455 
456 			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
457 			glValidateProgram(-1);
458 			expectError(GL_INVALID_VALUE);
459 			m_log << TestLog::EndSection;
460 
461 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
462 			glValidateProgram(shader);
463 			expectError(GL_INVALID_OPERATION);
464 			m_log << TestLog::EndSection;
465 
466 			glDeleteShader(shader);
467 		});
468 
469 	ES2F_ADD_API_CASE(release_shader_compiler, "Invalid glReleaseShaderCompiler() usage",
470 		{
471 			GLboolean shaderCompilerSupported;
472 			glGetBooleanv(GL_SHADER_COMPILER, &shaderCompilerSupported);
473 
474 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if a shader compiler is not supported.");
475 			glReleaseShaderCompiler();
476 			expectError(shaderCompilerSupported ? GL_NONE : GL_INVALID_OPERATION);
477 			m_log << TestLog::EndSection;
478 		});
479 
480 	// glUniform*f
481 
482 	ES2F_ADD_API_CASE(uniformf_invalid_program, "Invalid glUniform{1234}f() usage",
483 		{
484 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
485 			glUseProgram(0);
486 			glUniform1f(-1, 0.0f);
487 			expectError(GL_INVALID_OPERATION);
488 			glUniform2f(-1, 0.0f, 0.0f);
489 			expectError(GL_INVALID_OPERATION);
490 			glUniform3f(-1, 0.0f, 0.0f, 0.0f);
491 			expectError(GL_INVALID_OPERATION);
492 			glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
493 			expectError(GL_INVALID_OPERATION);
494 			m_log << tcu::TestLog::EndSection;
495 		});
496 	ES2F_ADD_API_CASE(uniformf_incompatible_type, "Invalid glUniform{1234}f() usage",
497 		{
498 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
499 			glUseProgram(program.getProgram());
500 			GLint vUnif		= glGetUniformLocation(program.getProgram(), "vTest");		// vec4
501 			GLint fUnif		= glGetUniformLocation(program.getProgram(), "fTest");		// ivec4
502 			GLint fSampler	= glGetUniformLocation(program.getProgram(), "fSampler");	// sampler2D
503 
504 			if (vUnif == -1 || fUnif == -1 || fSampler == -1)
505 				{
506 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
507 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
508 			}
509 
510 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.");
511 			glUseProgram(program.getProgram());
512 			glUniform1f(vUnif, 0.0f);
513 			expectError(GL_INVALID_OPERATION);
514 			glUniform2f(vUnif, 0.0f, 0.0f);
515 			expectError(GL_INVALID_OPERATION);
516 			glUniform3f(vUnif, 0.0f, 0.0f, 0.0f);
517 			expectError(GL_INVALID_OPERATION);
518 			glUniform4f(vUnif, 0.0f, 0.0f, 0.0f, 0.0f);
519 			expectError(GL_NO_ERROR);
520 			m_log << tcu::TestLog::EndSection;
521 
522 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if one of the floating-point variants of this function is used to load a uniform variable of type int, ivec2, ivec3, or ivec4.");
523 			glUseProgram(program.getProgram());
524 			glUniform4f(fUnif, 0.0f, 0.0f, 0.0f, 0.0f);
525 			expectError(GL_INVALID_OPERATION);
526 			m_log << tcu::TestLog::EndSection;
527 
528 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
529 			glUseProgram(program.getProgram());
530 			glUniform1f(fSampler, 0.0f);
531 			expectError(GL_INVALID_OPERATION);
532 			m_log << tcu::TestLog::EndSection;
533 
534 			glUseProgram(0);
535 		});
536 	ES2F_ADD_API_CASE(uniformf_invalid_location, "Invalid glUniform{1234}f() usage",
537 		{
538 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
539 			glUseProgram(program.getProgram());
540 
541 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
542 			glUseProgram(program.getProgram());
543 			glUniform1f(-2, 0.0f);
544 			expectError(GL_INVALID_OPERATION);
545 			glUniform2f(-2, 0.0f, 0.0f);
546 			expectError(GL_INVALID_OPERATION);
547 			glUniform3f(-2, 0.0f, 0.0f, 0.0f);
548 			expectError(GL_INVALID_OPERATION);
549 			glUniform4f(-2, 0.0f, 0.0f, 0.0f, 0.0f);
550 			expectError(GL_INVALID_OPERATION);
551 
552 			glUseProgram(program.getProgram());
553 			glUniform1f(-1, 0.0f);
554 			expectError(GL_NO_ERROR);
555 			glUniform2f(-1, 0.0f, 0.0f);
556 			expectError(GL_NO_ERROR);
557 			glUniform3f(-1, 0.0f, 0.0f, 0.0f);
558 			expectError(GL_NO_ERROR);
559 			glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
560 			expectError(GL_NO_ERROR);
561 			m_log << tcu::TestLog::EndSection;
562 
563 			glUseProgram(0);
564 		});
565 
566 	// glUniform*fv
567 
568 	ES2F_ADD_API_CASE(uniformfv_invalid_program, "Invalid glUniform{1234}fv() usage",
569 		{
570 			std::vector<GLfloat> data(4);
571 
572 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
573 			glUseProgram(0);
574 			glUniform1fv(-1, 1, &data[0]);
575 			expectError(GL_INVALID_OPERATION);
576 			glUniform2fv(-1, 1, &data[0]);
577 			expectError(GL_INVALID_OPERATION);
578 			glUniform3fv(-1, 1, &data[0]);
579 			expectError(GL_INVALID_OPERATION);
580 			glUniform4fv(-1, 1, &data[0]);
581 			expectError(GL_INVALID_OPERATION);
582 			m_log << tcu::TestLog::EndSection;
583 		});
584 	ES2F_ADD_API_CASE(uniformfv_incompatible_type, "Invalid glUniform{1234}fv() usage",
585 		{
586 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
587 			glUseProgram(program.getProgram());
588 			GLint vUnif		= glGetUniformLocation(program.getProgram(), "vTest");		// vec4
589 			GLint fUnif		= glGetUniformLocation(program.getProgram(), "fTest");		// ivec4
590 			GLint fSampler	= glGetUniformLocation(program.getProgram(), "fSampler");	// sampler2D
591 
592 			if (vUnif == -1 || fUnif == -1 || fSampler == -1)
593 			{
594 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
595 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
596 			}
597 
598 			std::vector<GLfloat> data(4);
599 
600 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.");
601 			glUseProgram(program.getProgram());
602 			glUniform1fv(vUnif, 1, &data[0]);
603 			expectError(GL_INVALID_OPERATION);
604 			glUniform2fv(vUnif, 1, &data[0]);
605 			expectError(GL_INVALID_OPERATION);
606 			glUniform3fv(vUnif, 1, &data[0]);
607 			expectError(GL_INVALID_OPERATION);
608 			glUniform4fv(vUnif, 1, &data[0]);
609 			expectError(GL_NO_ERROR);
610 			m_log << tcu::TestLog::EndSection;
611 
612 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if one of the floating-point variants of this function is used to load a uniform variable of type int, ivec2, ivec3, or ivec4.");
613 			glUseProgram(program.getProgram());
614 			glUniform4fv(fUnif, 1, &data[0]);
615 			expectError(GL_INVALID_OPERATION);
616 			m_log << tcu::TestLog::EndSection;
617 
618 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
619 			glUseProgram(program.getProgram());
620 			glUniform1fv(fSampler, 1, &data[0]);
621 			expectError(GL_INVALID_OPERATION);
622 			m_log << tcu::TestLog::EndSection;
623 
624 			glUseProgram(0);
625 		});
626 	ES2F_ADD_API_CASE(uniformfv_invalid_location, "Invalid glUniform{1234}fv() usage",
627 		{
628 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
629 			glUseProgram(program.getProgram());
630 
631 			std::vector<GLfloat> data(4);
632 
633 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
634 			glUseProgram(program.getProgram());
635 			glUniform1fv(-2, 1, &data[0]);
636 			expectError(GL_INVALID_OPERATION);
637 			glUniform2fv(-2, 1, &data[0]);
638 			expectError(GL_INVALID_OPERATION);
639 			glUniform3fv(-2, 1, &data[0]);
640 			expectError(GL_INVALID_OPERATION);
641 			glUniform4fv(-2, 1, &data[0]);
642 			expectError(GL_INVALID_OPERATION);
643 
644 			glUseProgram(program.getProgram());
645 			glUniform1fv(-1, 1, &data[0]);
646 			expectError(GL_NO_ERROR);
647 			glUniform2fv(-1, 1, &data[0]);
648 			expectError(GL_NO_ERROR);
649 			glUniform3fv(-1, 1, &data[0]);
650 			expectError(GL_NO_ERROR);
651 			glUniform4fv(-1, 1, &data[0]);
652 			expectError(GL_NO_ERROR);
653 			m_log << tcu::TestLog::EndSection;
654 
655 			glUseProgram(0);
656 		});
657 	ES2F_ADD_API_CASE(uniformfv_invalid_count, "Invalid glUniform{1234}fv() usage",
658 		{
659 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
660 			glUseProgram(program.getProgram());
661 			GLint vUnif		= glGetUniformLocation(program.getProgram(), "vTest");		// vec4
662 
663 			if (vUnif == -1)
664 			{
665 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
666 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
667 			}
668 
669 			std::vector<GLfloat> data(8);
670 
671 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.");
672 			glUseProgram(program.getProgram());
673 			glUniform1fv(vUnif, 2, &data[0]);
674 			expectError(GL_INVALID_OPERATION);
675 			glUniform2fv(vUnif, 2, &data[0]);
676 			expectError(GL_INVALID_OPERATION);
677 			glUniform3fv(vUnif, 2, &data[0]);
678 			expectError(GL_INVALID_OPERATION);
679 			glUniform4fv(vUnif, 2, &data[0]);
680 			expectError(GL_INVALID_OPERATION);
681 			m_log << tcu::TestLog::EndSection;
682 
683 			glUseProgram(0);
684 		});
685 
686 	// glUniform*i
687 
688 	ES2F_ADD_API_CASE(uniformi_invalid_program, "Invalid glUniform{1234}i() usage",
689 		{
690 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
691 			glUseProgram(0);
692 			glUniform1i(-1, 0);
693 			expectError(GL_INVALID_OPERATION);
694 			glUniform2i(-1, 0, 0);
695 			expectError(GL_INVALID_OPERATION);
696 			glUniform3i(-1, 0, 0, 0);
697 			expectError(GL_INVALID_OPERATION);
698 			glUniform4i(-1, 0, 0, 0, 0);
699 			expectError(GL_INVALID_OPERATION);
700 			m_log << tcu::TestLog::EndSection;
701 		});
702 	ES2F_ADD_API_CASE(uniformi_incompatible_type, "Invalid glUniform{1234}i() usage",
703 		{
704 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
705 			glUseProgram(program.getProgram());
706 			GLint vUnif		= glGetUniformLocation(program.getProgram(), "vTest");		// vec4
707 			GLint fUnif		= glGetUniformLocation(program.getProgram(), "fTest");		// ivec4
708 			GLint fSampler	= glGetUniformLocation(program.getProgram(), "fSampler");	// sampler2D
709 
710 			if (vUnif == -1 || fUnif == -1 || fSampler == -1)
711 			{
712 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
713 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
714 			}
715 
716 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.");
717 			glUseProgram(program.getProgram());
718 			glUniform1i(fUnif, 0);
719 			expectError(GL_INVALID_OPERATION);
720 			glUniform2i(fUnif, 0, 0);
721 			expectError(GL_INVALID_OPERATION);
722 			glUniform3i(fUnif, 0, 0, 0);
723 			expectError(GL_INVALID_OPERATION);
724 			glUniform4i(fUnif, 0, 0, 0, 0);
725 			expectError(GL_NO_ERROR);
726 			m_log << tcu::TestLog::EndSection;
727 
728 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if one of the integer variants of this function is used to load a uniform variable of type float, vec2, vec3, or vec4.");
729 			glUseProgram(program.getProgram());
730 			glUniform4i(vUnif, 0, 0, 0, 0);
731 			expectError(GL_INVALID_OPERATION);
732 			m_log << tcu::TestLog::EndSection;
733 
734 			glUseProgram(0);
735 		});
736 	ES2F_ADD_API_CASE(uniformi_invalid_location, "Invalid glUniform{1234}i() usage",
737 		{
738 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
739 			glUseProgram(program.getProgram());
740 
741 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
742 			glUseProgram(program.getProgram());
743 			glUniform1i(-2, 0);
744 			expectError(GL_INVALID_OPERATION);
745 			glUniform2i(-2, 0, 0);
746 			expectError(GL_INVALID_OPERATION);
747 			glUniform3i(-2, 0, 0, 0);
748 			expectError(GL_INVALID_OPERATION);
749 			glUniform4i(-2, 0, 0, 0, 0);
750 			expectError(GL_INVALID_OPERATION);
751 
752 			glUseProgram(program.getProgram());
753 			glUniform1i(-1, 0);
754 			expectError(GL_NO_ERROR);
755 			glUniform2i(-1, 0, 0);
756 			expectError(GL_NO_ERROR);
757 			glUniform3i(-1, 0, 0, 0);
758 			expectError(GL_NO_ERROR);
759 			glUniform4i(-1, 0, 0, 0, 0);
760 			expectError(GL_NO_ERROR);
761 			m_log << tcu::TestLog::EndSection;
762 
763 			glUseProgram(0);
764 		});
765 
766 	// glUniform*iv
767 
768 	ES2F_ADD_API_CASE(uniformiv_invalid_program, "Invalid glUniform{1234}iv() usage",
769 		{
770 			std::vector<GLint> data(4);
771 
772 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
773 			glUseProgram(0);
774 			glUniform1iv(-1, 1, &data[0]);
775 			expectError(GL_INVALID_OPERATION);
776 			glUniform2iv(-1, 1, &data[0]);
777 			expectError(GL_INVALID_OPERATION);
778 			glUniform3iv(-1, 1, &data[0]);
779 			expectError(GL_INVALID_OPERATION);
780 			glUniform4iv(-1, 1, &data[0]);
781 			expectError(GL_INVALID_OPERATION);
782 			m_log << tcu::TestLog::EndSection;
783 		});
784 	ES2F_ADD_API_CASE(uniformiv_incompatible_type, "Invalid glUniform{1234}iv() usage",
785 		{
786 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
787 			glUseProgram(program.getProgram());
788 			GLint vUnif		= glGetUniformLocation(program.getProgram(), "vTest");		// vec4
789 			GLint fUnif		= glGetUniformLocation(program.getProgram(), "fTest");		// ivec4
790 			GLint fSampler	= glGetUniformLocation(program.getProgram(), "fSampler");	// sampler2D
791 
792 			if (vUnif == -1 || fUnif == -1 || fSampler == -1)
793 			{
794 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
795 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
796 			}
797 
798 			std::vector<GLint> data(4);
799 
800 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.");
801 			glUseProgram(program.getProgram());
802 			glUniform1iv(fUnif, 1, &data[0]);
803 			expectError(GL_INVALID_OPERATION);
804 			glUniform2iv(fUnif, 1, &data[0]);
805 			expectError(GL_INVALID_OPERATION);
806 			glUniform3iv(fUnif, 1, &data[0]);
807 			expectError(GL_INVALID_OPERATION);
808 			glUniform4iv(fUnif, 1, &data[0]);
809 			expectError(GL_NO_ERROR);
810 			m_log << tcu::TestLog::EndSection;
811 
812 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if one of the integer variants of this function is used to load a uniform variable of type float, vec2, vec3, or vec4.");
813 			glUseProgram(program.getProgram());
814 			glUniform4iv(vUnif, 1, &data[0]);
815 			expectError(GL_INVALID_OPERATION);
816 			m_log << tcu::TestLog::EndSection;
817 
818 			glUseProgram(0);
819 		});
820 	ES2F_ADD_API_CASE(uniformiv_invalid_location, "Invalid glUniform{1234}iv() usage",
821 		{
822 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
823 			glUseProgram(program.getProgram());
824 
825 			std::vector<GLint> data(4);
826 
827 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
828 			glUseProgram(program.getProgram());
829 			glUniform1iv(-2, 1, &data[0]);
830 			expectError(GL_INVALID_OPERATION);
831 			glUniform2iv(-2, 1, &data[0]);
832 			expectError(GL_INVALID_OPERATION);
833 			glUniform3iv(-2, 1, &data[0]);
834 			expectError(GL_INVALID_OPERATION);
835 			glUniform4iv(-2, 1, &data[0]);
836 			expectError(GL_INVALID_OPERATION);
837 
838 			glUseProgram(program.getProgram());
839 			glUniform1iv(-1, 1, &data[0]);
840 			expectError(GL_NO_ERROR);
841 			glUniform2iv(-1, 1, &data[0]);
842 			expectError(GL_NO_ERROR);
843 			glUniform3iv(-1, 1, &data[0]);
844 			expectError(GL_NO_ERROR);
845 			glUniform4iv(-1, 1, &data[0]);
846 			expectError(GL_NO_ERROR);
847 			m_log << tcu::TestLog::EndSection;
848 
849 			glUseProgram(0);
850 		});
851 	ES2F_ADD_API_CASE(uniformiv_invalid_count, "Invalid glUniform{1234}iv() usage",
852 		{
853 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
854 			glUseProgram(program.getProgram());
855 			GLint fUnif		= glGetUniformLocation(program.getProgram(), "fTest");		// ivec4
856 
857 			if (fUnif == -1)
858 			{
859 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
860 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
861 			}
862 
863 			std::vector<GLint> data(8);
864 
865 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.");
866 			glUseProgram(program.getProgram());
867 			glUniform1iv(fUnif, 2, &data[0]);
868 			expectError(GL_INVALID_OPERATION);
869 			glUniform2iv(fUnif, 2, &data[0]);
870 			expectError(GL_INVALID_OPERATION);
871 			glUniform3iv(fUnif, 2, &data[0]);
872 			expectError(GL_INVALID_OPERATION);
873 			glUniform4iv(fUnif, 2, &data[0]);
874 			expectError(GL_INVALID_OPERATION);
875 			m_log << tcu::TestLog::EndSection;
876 
877 			glUseProgram(0);
878 		});
879 
880 	// glUniformMatrix*fv
881 
882 	ES2F_ADD_API_CASE(uniform_matrixfv_invalid_program, "Invalid glUniformMatrix{234}fv() usage",
883 		{
884 			std::vector<GLfloat> data(16);
885 
886 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
887 			glUseProgram(0);
888 			glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
889 			expectError(GL_INVALID_OPERATION);
890 			glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
891 			expectError(GL_INVALID_OPERATION);
892 			glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
893 			expectError(GL_INVALID_OPERATION);
894 			m_log << tcu::TestLog::EndSection;
895 		});
896 	ES2F_ADD_API_CASE(uniform_matrixfv_incompatible_type, "Invalid glUniformMatrix{234}fv() usage",
897 		{
898 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
899 			glUseProgram(program.getProgram());
900 			GLint vMatUnif		= glGetUniformLocation(program.getProgram(), "vMatrix");	// mat4
901 			GLint fSamplerUnif	= glGetUniformLocation(program.getProgram(), "fSampler");	// sampler2D
902 
903 			m_log << program;
904 
905 			if (vMatUnif == -1 || fSamplerUnif == -1)
906 			{
907 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
908 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
909 			}
910 
911 			std::vector<GLfloat> data(16);
912 
913 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.");
914 			glUseProgram(program.getProgram());
915 			glUniformMatrix2fv(vMatUnif, 1, GL_FALSE, &data[0]);
916 			expectError(GL_INVALID_OPERATION);
917 			glUniformMatrix3fv(vMatUnif, 1, GL_FALSE, &data[0]);
918 			expectError(GL_INVALID_OPERATION);
919 			glUniformMatrix4fv(vMatUnif, 1, GL_FALSE, &data[0]);
920 			expectError(GL_NO_ERROR);
921 			m_log << tcu::TestLog::EndSection;
922 
923 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
924 			glUseProgram(program.getProgram());
925 			glUniformMatrix4fv(fSamplerUnif, 1, GL_FALSE, &data[0]);
926 			expectError(GL_INVALID_OPERATION);
927 			m_log << tcu::TestLog::EndSection;
928 
929 			glUseProgram(0);
930 		});
931 	ES2F_ADD_API_CASE(uniform_matrixfv_invalid_location, "Invalid glUniformMatrix{234}fv() usage",
932 		{
933 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
934 			glUseProgram(program.getProgram());
935 
936 			m_log << program;
937 
938 			std::vector<GLfloat> data(16);
939 
940 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
941 			glUseProgram(program.getProgram());
942 			glUniformMatrix2fv(-2, 1, GL_FALSE, &data[0]);
943 			expectError(GL_INVALID_OPERATION);
944 			glUniformMatrix3fv(-2, 1, GL_FALSE, &data[0]);
945 			expectError(GL_INVALID_OPERATION);
946 			glUniformMatrix4fv(-2, 1, GL_FALSE, &data[0]);
947 			expectError(GL_INVALID_OPERATION);
948 
949 			glUseProgram(program.getProgram());
950 			glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
951 			expectError(GL_NO_ERROR);
952 			glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
953 			expectError(GL_NO_ERROR);
954 			glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
955 			expectError(GL_NO_ERROR);
956 			m_log << tcu::TestLog::EndSection;
957 
958 			glUseProgram(0);
959 		});
960 	ES2F_ADD_API_CASE(uniform_matrixfv_invalid_count, "Invalid glUniformMatrix{234}fv() usage",
961 		{
962 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
963 			glUseProgram(program.getProgram());
964 			GLint vMatUnif		= glGetUniformLocation(program.getProgram(), "vMatrix");		// mat4
965 
966 			m_log << program;
967 
968 			if (vMatUnif == -1)
969 			{
970 				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
971 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
972 			}
973 
974 
975 			std::vector<GLfloat> data(32);
976 
977 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.");
978 			glUseProgram(program.getProgram());
979 			glUniformMatrix2fv(vMatUnif, 2, GL_FALSE, &data[0]);
980 			expectError(GL_INVALID_OPERATION);
981 			glUniformMatrix3fv(vMatUnif, 2, GL_FALSE, &data[0]);
982 			expectError(GL_INVALID_OPERATION);
983 			glUniformMatrix4fv(vMatUnif, 2, GL_FALSE, &data[0]);
984 			expectError(GL_INVALID_OPERATION);
985 			m_log << tcu::TestLog::EndSection;
986 
987 			glUseProgram(0);
988 		});
989 	ES2F_ADD_API_CASE(uniform_matrixfv_invalid_transpose, "Invalid glUniformMatrix{234}fv() usage",
990 		{
991 			if (de::beginsWith((const char*)glGetString(GL_VERSION), "OpenGL ES 2.0 "))
992 			{
993 				DE_ASSERT(m_context.getRenderContext().getType().getMajorVersion() < 3);
994 				DE_ASSERT(m_context.getRenderContext().getType().getMinorVersion() == 0);
995 				DE_ASSERT(m_context.getRenderContext().getType().getProfile() == glu::PROFILE_ES);
996 
997 				glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
998 				glUseProgram(program.getProgram());
999 
1000 				m_log << program;
1001 
1002 				std::vector<GLfloat> data(16);
1003 
1004 				m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if transpose is not GL_FALSE.");
1005 				glUseProgram(program.getProgram());
1006 				glUniformMatrix2fv(0, 1, GL_TRUE, &data[0]);
1007 				expectError(GL_INVALID_VALUE);
1008 				glUniformMatrix3fv(0, 1, GL_TRUE, &data[0]);
1009 				expectError(GL_INVALID_VALUE);
1010 				glUniformMatrix4fv(0, 1, GL_TRUE, &data[0]);
1011 				expectError(GL_INVALID_VALUE);
1012 				m_log << tcu::TestLog::EndSection;
1013 
1014 				glUseProgram(0);
1015 			}
1016 		});
1017 }
1018 
1019 } // Functional
1020 } // gles2
1021 } // deqp
1022