Home | History | Annotate | Download | only in functional
      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 
     62 NegativeShaderApiTests::NegativeShaderApiTests (Context& context)
     63 	: TestCaseGroup(context, "shader", "Negative Shader API Cases")
     64 {
     65 }
     66 
     67 NegativeShaderApiTests::~NegativeShaderApiTests (void)
     68 {
     69 }
     70 
     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