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