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
34using namespace glw; // GL types
35
36namespace deqp
37{
38namespace gles2
39{
40namespace Functional
41{
42
43static const char* vertexShaderSource	= "void main (void) { gl_Position = vec4(0.0); }\n\0";
44static const char* fragmentShaderSource	= "void main (void) { gl_FragColor = vec4(0.0); }\n\0";
45
46static 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";
52static 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
60using tcu::TestLog;
61
62NegativeShaderApiTests::NegativeShaderApiTests (Context& context)
63	: TestCaseGroup(context, "shader", "Negative Shader API Cases")
64{
65}
66
67NegativeShaderApiTests::~NegativeShaderApiTests (void)
68{
69}
70
71void 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