1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Negative Shader API tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es3fNegativeShaderApiTests.hpp"
25#include "es3fApiCase.hpp"
26#include "gluShaderProgram.hpp"
27#include "gluContextInfo.hpp"
28#include "deUniquePtr.hpp"
29
30#include "glwDefs.hpp"
31#include "glwEnums.hpp"
32
33using namespace glw; // GL types
34
35namespace deqp
36{
37namespace gles3
38{
39namespace Functional
40{
41
42using tcu::TestLog;
43
44static const char* vertexShaderSource		=	"#version 300 es\n"
45												"void main (void)\n"
46												"{\n"
47												"	gl_Position = vec4(0.0);\n"
48												"}\n\0";
49
50static const char* fragmentShaderSource		=	"#version 300 es\n"
51												"layout(location = 0) out mediump vec4 fragColor;"
52												"void main (void)\n"
53												"{\n"
54												"	fragColor = vec4(0.0);\n"
55												"}\n\0";
56
57static const char* uniformTestVertSource	=	"#version 300 es\n"
58												"uniform mediump vec4 vec4_v;\n"
59												"uniform mediump mat4 mat4_v;\n"
60												"void main (void)\n"
61												"{\n"
62												"	gl_Position = mat4_v * vec4_v;\n"
63												"}\n\0";
64
65static const char* uniformTestFragSource	=	"#version 300 es\n"
66												"uniform mediump ivec4 ivec4_f;\n"
67												"uniform mediump uvec4 uvec4_f;\n"
68												"uniform sampler2D sampler_f;\n"
69												"layout(location = 0) out mediump vec4 fragColor;"
70												"void main (void)\n"
71												"{\n"
72												"	fragColor.xy = (vec4(uvec4_f) + vec4(ivec4_f)).xy;\n"
73												"	fragColor.zw = texture(sampler_f, vec2(0.0, 0.0)).zw;\n"
74												"}\n\0";
75
76static const char* uniformBlockVertSource	=	"#version 300 es\n"
77												"layout(shared) uniform Block { lowp float var; };\n"
78												"void main (void)\n"
79												"{\n"
80												"	gl_Position = vec4(var);\n"
81												"}\n\0";
82
83NegativeShaderApiTests::NegativeShaderApiTests (Context& context)
84	: TestCaseGroup(context, "shader", "Negative Shader API Cases")
85{
86}
87
88NegativeShaderApiTests::~NegativeShaderApiTests (void)
89{
90}
91
92void NegativeShaderApiTests::init (void)
93{
94	// Shader control commands
95
96	ES3F_ADD_API_CASE(create_shader, "Invalid glCreateShader() usage",
97		{
98			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if shaderType is not an accepted value.");
99			glCreateShader(-1);
100			expectError(GL_INVALID_ENUM);
101			m_log << TestLog::EndSection;
102		});
103	ES3F_ADD_API_CASE(shader_source, "Invalid glShaderSource() usage",
104		{
105			// \note Shader compilation must be supported.
106
107			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
108			glShaderSource(1, 0, 0, 0);
109			expectError(GL_INVALID_VALUE);
110			m_log << TestLog::EndSection;
111
112			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if count is less than 0.");
113			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
114			glShaderSource(shader, -1, 0, 0);
115			expectError(GL_INVALID_VALUE);
116			m_log << TestLog::EndSection;
117
118			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
119			GLuint program = glCreateProgram();
120			glShaderSource(program, 0, 0, 0);
121			expectError(GL_INVALID_OPERATION);
122			m_log << TestLog::EndSection;
123
124			glDeleteProgram(program);
125			glDeleteShader(shader);
126		});
127	ES3F_ADD_API_CASE(compile_shader, "Invalid glCompileShader() usage",
128		{
129			// \note Shader compilation must be supported.
130
131			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
132			glCompileShader(9);
133			expectError(GL_INVALID_VALUE);
134			m_log << TestLog::EndSection;
135
136			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
137			GLuint program = glCreateProgram();
138			glCompileShader(program);
139			expectError(GL_INVALID_OPERATION);
140			m_log << TestLog::EndSection;
141
142			glDeleteProgram(program);
143		});
144	ES3F_ADD_API_CASE(delete_shader, "Invalid glDeleteShader() usage",
145		{
146			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
147			glDeleteShader(9);
148			expectError(GL_INVALID_VALUE);
149			m_log << TestLog::EndSection;
150		});
151	ES3F_ADD_API_CASE(shader_binary, "Invalid glShaderBinary() usage",
152		{
153			std::vector<deInt32> binaryFormats;
154			getSupportedExtensions(GL_NUM_SHADER_BINARY_FORMATS, GL_SHADER_BINARY_FORMATS, binaryFormats);
155			deBool shaderBinarySupported = !binaryFormats.empty();
156			if (!shaderBinarySupported)
157				m_log << TestLog::Message << "// Shader binaries not supported." << TestLog::EndMessage;
158			else
159				m_log << TestLog::Message << "// Shader binaries supported" << TestLog::EndMessage;
160
161			GLuint shaders[2];
162			shaders[0]		= glCreateShader(GL_VERTEX_SHADER);
163			shaders[1]		= glCreateShader(GL_VERTEX_SHADER);
164
165			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if binaryFormat is not an accepted value.");
166			glShaderBinary(1, &shaders[0], -1, 0, 0);
167			expectError(GL_INVALID_ENUM);
168			m_log << TestLog::EndSection;
169
170			if (shaderBinarySupported)
171			{
172				m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if the data pointed to by binary does not match the format specified by binaryFormat.");
173				const GLbyte data = 0x005F;
174				glShaderBinary(1, &shaders[0], binaryFormats[0], &data, 1);
175				expectError(GL_INVALID_VALUE);
176				m_log << TestLog::EndSection;
177
178				// Error handling is different in case of SPIRV.
179				const bool spirvBinary = binaryFormats[0] == GL_SHADER_BINARY_FORMAT_SPIR_V;
180				if (spirvBinary)
181					m_log << TestLog::Section("", "GL_INVALID_VALUE due to invalid data pointer.");
182				else
183					m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if more than one of the handles in shaders refers to the same type of shader, or GL_INVALID_VALUE due to invalid data pointer.");
184
185				glShaderBinary(2, &shaders[0], binaryFormats[0], 0, 0);
186
187				if (spirvBinary)
188					expectError(GL_INVALID_VALUE);
189				else
190					expectError(GL_INVALID_OPERATION, GL_INVALID_VALUE);
191
192				m_log << TestLog::EndSection;
193			}
194
195			glDeleteShader(shaders[0]);
196			glDeleteShader(shaders[1]);
197		});
198	ES3F_ADD_API_CASE(attach_shader, "Invalid glAttachShader() usage",
199		{
200			GLuint shader1 = glCreateShader(GL_VERTEX_SHADER);
201			GLuint shader2 = glCreateShader(GL_VERTEX_SHADER);
202			GLuint program = glCreateProgram();
203
204			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
205			glAttachShader(shader1, shader1);
206			expectError(GL_INVALID_OPERATION);
207			m_log << TestLog::EndSection;
208
209			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
210			glAttachShader(program, program);
211			expectError(GL_INVALID_OPERATION);
212			glAttachShader(shader1, program);
213			expectError(GL_INVALID_OPERATION);
214			m_log << TestLog::EndSection;
215
216			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
217			glAttachShader(program, -1);
218			expectError(GL_INVALID_VALUE);
219			glAttachShader(-1, shader1);
220			expectError(GL_INVALID_VALUE);
221			glAttachShader(-1, -1);
222			expectError(GL_INVALID_VALUE);
223			m_log << TestLog::EndSection;
224
225			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is already attached to program.");
226			glAttachShader(program, shader1);
227			expectError(GL_NO_ERROR);
228			glAttachShader(program, shader1);
229			expectError(GL_INVALID_OPERATION);
230			m_log << TestLog::EndSection;
231
232			if (glu::isContextTypeES(m_context.getRenderContext().getType())){
233				m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if a shader of the same type as shader is already attached to program.");
234				glAttachShader(program, shader2);
235				expectError(GL_INVALID_OPERATION);
236				m_log << TestLog::EndSection;
237			}
238
239			glDeleteProgram(program);
240			glDeleteShader(shader1);
241			glDeleteShader(shader2);
242		});
243	ES3F_ADD_API_CASE(detach_shader, "Invalid glDetachShader() usage",
244		{
245			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
246			GLuint program = glCreateProgram();
247
248			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
249			glDetachShader(-1, shader);
250			expectError(GL_INVALID_VALUE);
251			glDetachShader(program, -1);
252			expectError(GL_INVALID_VALUE);
253			glDetachShader(-1, -1);
254			expectError(GL_INVALID_VALUE);
255			m_log << TestLog::EndSection;
256
257			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
258			glDetachShader(shader, shader);
259			expectError(GL_INVALID_OPERATION);
260			m_log << TestLog::EndSection;
261
262			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
263			glDetachShader(program, program);
264			expectError(GL_INVALID_OPERATION);
265			glDetachShader(shader, program);
266			expectError(GL_INVALID_OPERATION);
267			m_log << TestLog::EndSection;
268
269			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not attached to program.");
270			glDetachShader(program, shader);
271			expectError(GL_INVALID_OPERATION);
272			m_log << TestLog::EndSection;
273
274			glDeleteProgram(program);
275			glDeleteShader(shader);
276		});
277	ES3F_ADD_API_CASE(link_program, "Invalid glLinkProgram() usage",
278		{
279			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
280
281			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
282			glLinkProgram(-1);
283			expectError(GL_INVALID_VALUE);
284			m_log << TestLog::EndSection;
285
286			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
287			glLinkProgram(shader);
288			expectError(GL_INVALID_OPERATION);
289			m_log << TestLog::EndSection;
290
291			glDeleteShader(shader);
292
293			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is the currently active program object and transform feedback mode is active.");
294			glu::ShaderProgram			program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
295			deUint32					buf;
296			deUint32					tfID;
297			const char* tfVarying		= "gl_Position";
298
299			glGenTransformFeedbacks		(1, &tfID);
300			glGenBuffers				(1, &buf);
301
302			glUseProgram				(program.getProgram());
303			glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
304			glLinkProgram				(program.getProgram());
305			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
306			glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
307			glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
308			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
309			glBeginTransformFeedback	(GL_TRIANGLES);
310			expectError					(GL_NO_ERROR);
311
312			glLinkProgram				(program.getProgram());
313			expectError					(GL_INVALID_OPERATION);
314
315			glEndTransformFeedback		();
316			glDeleteTransformFeedbacks	(1, &tfID);
317			glDeleteBuffers				(1, &buf);
318			expectError					(GL_NO_ERROR);
319			m_log << TestLog::EndSection;
320		});
321	ES3F_ADD_API_CASE(use_program, "Invalid glUseProgram() usage",
322		{
323			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
324
325			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is neither 0 nor a value generated by OpenGL.");
326			glUseProgram(-1);
327			expectError(GL_INVALID_VALUE);
328			m_log << TestLog::EndSection;
329
330			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
331			glUseProgram(shader);
332			expectError(GL_INVALID_OPERATION);
333			m_log << TestLog::EndSection;
334
335			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback mode is active and not paused.");
336			glu::ShaderProgram			program1(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
337			glu::ShaderProgram			program2(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
338			deUint32					buf;
339			deUint32					tfID;
340			const char* tfVarying		= "gl_Position";
341
342			glGenTransformFeedbacks		(1, &tfID);
343			glGenBuffers				(1, &buf);
344
345			glUseProgram				(program1.getProgram());
346			glTransformFeedbackVaryings	(program1.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
347			glLinkProgram				(program1.getProgram());
348			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
349			glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
350			glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
351			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
352			glBeginTransformFeedback	(GL_TRIANGLES);
353			expectError					(GL_NO_ERROR);
354
355			glUseProgram				(program2.getProgram());
356			expectError					(GL_INVALID_OPERATION);
357
358			glPauseTransformFeedback	();
359			glUseProgram				(program2.getProgram());
360			expectError					(GL_NO_ERROR);
361
362			glEndTransformFeedback		();
363			glDeleteTransformFeedbacks	(1, &tfID);
364			glDeleteBuffers				(1, &buf);
365			expectError					(GL_NO_ERROR);
366			m_log << TestLog::EndSection;
367
368			glUseProgram(0);
369			glDeleteShader(shader);
370		});
371	ES3F_ADD_API_CASE(delete_program, "Invalid glDeleteProgram() usage",
372		{
373			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
374			glDeleteProgram(-1);
375			expectError(GL_INVALID_VALUE);
376			m_log << TestLog::EndSection;
377		});
378	ES3F_ADD_API_CASE(validate_program, "Invalid glValidateProgram() usage",
379		{
380			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
381
382			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
383			glValidateProgram(-1);
384			expectError(GL_INVALID_VALUE);
385			m_log << TestLog::EndSection;
386
387			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
388			glValidateProgram(shader);
389			expectError(GL_INVALID_OPERATION);
390			m_log << TestLog::EndSection;
391
392			glDeleteShader(shader);
393		});
394	if (glu::isContextTypeES(m_context.getRenderContext().getType()))
395	{
396		ES3F_ADD_API_CASE(get_program_binary, "Invalid glGetProgramBinary() usage",
397			{
398				glu::ShaderProgram				program			(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
399				glu::ShaderProgram				programInvalid	(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, ""));
400				GLenum							binaryFormat	= -1;
401				GLsizei							binaryLength	= -1;
402				GLint							binaryPtr		= -1;
403				GLint							bufSize			= -1;
404				GLint							linkStatus		= -1;
405
406				m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if bufSize is less than the size of GL_PROGRAM_BINARY_LENGTH for program.");
407				glGetProgramiv		(program.getProgram(), GL_PROGRAM_BINARY_LENGTH,	&bufSize);
408				expectError			(GL_NO_ERROR);
409				glGetProgramiv		(program.getProgram(), GL_LINK_STATUS,				&linkStatus);
410				m_log << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
411				m_log << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
412				expectError			(GL_NO_ERROR);
413
414				glGetProgramBinary	(program.getProgram(), 0, &binaryLength, &binaryFormat, &binaryPtr);
415				expectError			(GL_INVALID_OPERATION);
416				if (bufSize > 0)
417				{
418					glGetProgramBinary	(program.getProgram(), bufSize-1, &binaryLength, &binaryFormat, &binaryPtr);
419					expectError			(GL_INVALID_OPERATION);
420				}
421				m_log << TestLog::EndSection;
422
423				m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if GL_LINK_STATUS for the program object is false.");
424				glGetProgramiv		(programInvalid.getProgram(), GL_PROGRAM_BINARY_LENGTH,	&bufSize);
425				expectError			(GL_NO_ERROR);
426				glGetProgramiv		(programInvalid.getProgram(), GL_LINK_STATUS,			&linkStatus);
427				m_log << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
428				m_log << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
429				expectError			(GL_NO_ERROR);
430
431				glGetProgramBinary	(programInvalid.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryPtr);
432				expectError			(GL_INVALID_OPERATION);
433				m_log << TestLog::EndSection;
434			});
435	}
436	ES3F_ADD_API_CASE(program_binary, "Invalid glProgramBinary() usage",
437		{
438			glu::ShaderProgram		srcProgram		(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
439			GLuint					dstProgram		= glCreateProgram();
440			GLuint					unusedShader	= glCreateShader(GL_VERTEX_SHADER);
441			GLenum					binaryFormat	= -1;
442			GLsizei					binaryLength	= -1;
443			std::vector<deUint8>	binaryBuf;
444			GLint					bufSize			= -1;
445			GLint					linkStatus		= -1;
446
447			glGetProgramiv		(srcProgram.getProgram(), GL_PROGRAM_BINARY_LENGTH,	&bufSize);
448			glGetProgramiv		(srcProgram.getProgram(), GL_LINK_STATUS,			&linkStatus);
449			m_log << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
450			m_log << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
451
452			TCU_CHECK(bufSize >= 0);
453
454			if (bufSize > 0)
455			{
456				binaryBuf.resize(bufSize);
457				glGetProgramBinary	(srcProgram.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryBuf[0]);
458				expectError			(GL_NO_ERROR);
459
460				m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not the name of an existing program object.");
461				glProgramBinary		(unusedShader, binaryFormat, &binaryBuf[0], binaryLength);
462				expectError			(GL_INVALID_OPERATION);
463				m_log << TestLog::EndSection;
464
465				m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation.");
466				glProgramBinary		(dstProgram, -1, &binaryBuf[0], binaryLength);
467				expectError			(GL_INVALID_ENUM);
468				m_log << TestLog::EndSection;
469			}
470
471			glDeleteShader(unusedShader);
472			glDeleteProgram(dstProgram);
473		});
474	ES3F_ADD_API_CASE(program_parameteri, "Invalid glProgramParameteri() usage",
475		{
476			GLuint	program	= glCreateProgram();
477
478			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not the name of an existing program object.");
479			glProgramParameteri		(0, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
480			expectError				(GL_INVALID_VALUE);
481			m_log << TestLog::EndSection;
482
483			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not GL_PROGRAM_BINARY_RETRIEVABLE_HINT.");
484			glProgramParameteri		(program, -1, GL_TRUE);
485			expectError				(GL_INVALID_ENUM);
486			m_log << TestLog::EndSection;
487
488			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if value is not GL_FALSE or GL_TRUE.");
489			glProgramParameteri		(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, 2);
490			expectError				(GL_INVALID_VALUE);
491			m_log << TestLog::EndSection;
492
493			glDeleteProgram(program);
494		});
495	ES3F_ADD_API_CASE(gen_samplers, "Invalid glGenSamplers() usage",
496		{
497			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
498			GLuint sampler;
499			glGenSamplers	(-1, &sampler);
500			expectError		(GL_INVALID_VALUE);
501			m_log << TestLog::EndSection;
502		});
503	ES3F_ADD_API_CASE(bind_sampler, "Invalid glBindSampler() usage",
504		{
505			int				maxTexImageUnits;
506			GLuint			sampler;
507			glGetIntegerv	(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTexImageUnits);
508			glGenSamplers	(1, &sampler);
509
510			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if unit is greater than or equal to the value of GL_MAX_COMBIED_TEXTURE_IMAGE_UNITS.");
511			glBindSampler	(maxTexImageUnits, sampler);
512			expectError		(GL_INVALID_VALUE);
513			m_log << TestLog::EndSection;
514
515			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not zero or a name previously returned from a call to glGenSamplers.");
516			glBindSampler	(1, -1);
517			expectError		(GL_INVALID_OPERATION);
518			m_log << TestLog::EndSection;
519
520			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler has been deleted by a call to glDeleteSamplers.");
521			glDeleteSamplers(1, &sampler);
522			glBindSampler	(1, sampler);
523			expectError		(GL_INVALID_OPERATION);
524			m_log << TestLog::EndSection;
525		});
526	ES3F_ADD_API_CASE(delete_samplers, "Invalid glDeleteSamplers() usage",
527		{
528			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
529			glDeleteSamplers(-1, 0);
530			expectError		(GL_INVALID_VALUE);
531			m_log << TestLog::EndSection;
532		});
533	ES3F_ADD_API_CASE(get_sampler_parameteriv, "Invalid glGetSamplerParameteriv() usage",
534		{
535			int				params	= -1;
536			GLuint			sampler;
537			glGenSamplers	(1, &sampler);
538
539			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object returned from a previous call to glGenSamplers.");
540			glGetSamplerParameteriv	(-1, GL_TEXTURE_MAG_FILTER, &params);
541			expectError				(GL_INVALID_OPERATION);
542			m_log << TestLog::EndSection;
543
544			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value.");
545			glGetSamplerParameteriv	(sampler, -1, &params);
546			expectError				(GL_INVALID_ENUM);
547			m_log << TestLog::EndSection;
548
549			glDeleteSamplers(1, &sampler);
550		});
551	ES3F_ADD_API_CASE(get_sampler_parameterfv, "Invalid glGetSamplerParameterfv() usage",
552		{
553			float			params	= 0.0f;
554			GLuint			sampler;
555			glGenSamplers	(1, &sampler);
556
557			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object returned from a previous call to glGenSamplers.");
558			glGetSamplerParameterfv	(-1, GL_TEXTURE_MAG_FILTER, &params);
559			expectError				(GL_INVALID_OPERATION);
560			m_log << TestLog::EndSection;
561
562			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value.");
563			glGetSamplerParameterfv	(sampler, -1, &params);
564			expectError				(GL_INVALID_ENUM);
565			m_log << TestLog::EndSection;
566
567			glDeleteSamplers(1, &sampler);
568		});
569	ES3F_ADD_API_CASE(sampler_parameteri, "Invalid glSamplerParameteri() usage",
570		{
571			GLuint			sampler;
572			glGenSamplers	(1, &sampler);
573
574			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to glGenSamplers.");
575			glSamplerParameteri		(-1, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
576			expectError				(GL_INVALID_OPERATION);
577			m_log << TestLog::EndSection;
578
579			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
580			glSamplerParameteri		(sampler, GL_TEXTURE_WRAP_S, -1);
581			expectError				(GL_INVALID_ENUM);
582			m_log << TestLog::EndSection;
583
584			glDeleteSamplers(1, &sampler);
585		});
586	ES3F_ADD_API_CASE(sampler_parameteriv, "Invalid glSamplerParameteriv() usage",
587		{
588			int				params	= -1;
589			GLuint			sampler;
590			glGenSamplers	(1, &sampler);
591
592			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to glGenSamplers.");
593			params = GL_CLAMP_TO_EDGE;
594			glSamplerParameteriv	(-1, GL_TEXTURE_WRAP_S, &params);
595			expectError				(GL_INVALID_OPERATION);
596			m_log << TestLog::EndSection;
597
598			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
599			params = -1;
600			glSamplerParameteriv	(sampler, GL_TEXTURE_WRAP_S, &params);
601			expectError				(GL_INVALID_ENUM);
602			m_log << TestLog::EndSection;
603
604			glDeleteSamplers(1, &sampler);
605		});
606	ES3F_ADD_API_CASE(sampler_parameterf, "Invalid glSamplerParameterf() usage",
607		{
608			GLuint			sampler;
609			glGenSamplers	(1, &sampler);
610
611			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to glGenSamplers.");
612			glSamplerParameterf		(-1, GL_TEXTURE_MIN_LOD, -1000.0f);
613			expectError				(GL_INVALID_OPERATION);
614			m_log << TestLog::EndSection;
615
616			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
617			glSamplerParameterf		(sampler, GL_TEXTURE_WRAP_S, -1.0f);
618			expectError				(GL_INVALID_ENUM);
619			m_log << TestLog::EndSection;
620
621			glDeleteSamplers(1, &sampler);
622		});
623	ES3F_ADD_API_CASE(sampler_parameterfv, "Invalid glSamplerParameterfv() usage",
624		{
625			float			params	= 0.0f;
626			GLuint			sampler;
627			glGenSamplers	(1, &sampler);
628
629			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to glGenSamplers.");
630			params = -1000.0f;
631			glSamplerParameterfv	(-1, GL_TEXTURE_WRAP_S, &params);
632			expectError				(GL_INVALID_OPERATION);
633			m_log << TestLog::EndSection;
634
635			m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
636			params = -1.0f;
637			glSamplerParameterfv	(sampler, GL_TEXTURE_WRAP_S, &params);
638			expectError				(GL_INVALID_ENUM);
639			m_log << TestLog::EndSection;
640
641			glDeleteSamplers(1, &sampler);
642		});
643
644	// Shader data commands
645
646	ES3F_ADD_API_CASE(get_attrib_location, "Invalid glGetAttribLocation() usage",
647		{
648			GLuint programEmpty		= glCreateProgram();
649			GLuint shader			= glCreateShader(GL_VERTEX_SHADER);
650
651			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
652
653			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked.");
654			glBindAttribLocation	(programEmpty, 0, "test");
655			glGetAttribLocation		(programEmpty, "test");
656			expectError				(GL_INVALID_OPERATION);
657			m_log << TestLog::EndSection;
658
659			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a program or shader object.");
660			glUseProgram			(program.getProgram());
661			glBindAttribLocation	(program.getProgram(), 0, "test");
662			expectError				(GL_NO_ERROR);
663			glGetAttribLocation		(program.getProgram(), "test");
664			expectError				(GL_NO_ERROR);
665			glGetAttribLocation		(-2, "test");
666			expectError				(GL_INVALID_VALUE);
667			m_log << TestLog::EndSection;
668
669			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
670			glGetAttribLocation		(shader, "test");
671			expectError				(GL_INVALID_OPERATION);
672			m_log << TestLog::EndSection;
673
674			glUseProgram			(0);
675			glDeleteShader			(shader);
676			glDeleteProgram			(programEmpty);
677		});
678	ES3F_ADD_API_CASE(get_uniform_location, "Invalid glGetUniformLocation() usage",
679		{
680			GLuint programEmpty = glCreateProgram();
681			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
682
683			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
684
685			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked.");
686			glGetUniformLocation(programEmpty, "test");
687			expectError(GL_INVALID_OPERATION);
688			m_log << TestLog::EndSection;
689
690			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
691			glUseProgram(program.getProgram());
692			glGetUniformLocation(-2, "test");
693			expectError(GL_INVALID_VALUE);
694			m_log << TestLog::EndSection;
695
696			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
697			glGetAttribLocation(shader, "test");
698			expectError(GL_INVALID_OPERATION);
699			m_log << TestLog::EndSection;
700
701			glUseProgram(0);
702			glDeleteProgram(programEmpty);
703			glDeleteShader(shader);
704		});
705	ES3F_ADD_API_CASE(bind_attrib_location, "Invalid glBindAttribLocation() usage",
706		{
707			GLuint program = glCreateProgram();
708			GLuint maxIndex = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
709			GLuint shader = glCreateShader(GL_VERTEX_SHADER);
710
711			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
712			glBindAttribLocation(program, maxIndex, "test");
713			expectError(GL_INVALID_VALUE);
714			m_log << TestLog::EndSection;
715
716			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if name starts with the reserved prefix \"gl_\".");
717			glBindAttribLocation(program, maxIndex-1, "gl_test");
718			expectError(GL_INVALID_OPERATION);
719			m_log << TestLog::EndSection;
720
721			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
722			glBindAttribLocation(-1, maxIndex-1, "test");
723			expectError(GL_INVALID_VALUE);
724			m_log << TestLog::EndSection;
725
726			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
727			glBindAttribLocation(shader, maxIndex-1, "test");
728			expectError(GL_INVALID_OPERATION);
729			m_log << TestLog::EndSection;
730
731			glDeleteProgram(program);
732			glDeleteShader(shader);
733		});
734	ES3F_ADD_API_CASE(uniform_block_binding, "Invalid glUniformBlockBinding() usage",
735		{
736			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformBlockVertSource, uniformTestFragSource));
737
738			glUseProgram	(program.getProgram());
739
740			GLint			maxUniformBufferBindings;
741			GLint			numActiveUniforms			= -1;
742			GLint			numActiveBlocks				= -1;
743			glGetIntegerv	(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
744			glGetProgramiv	(program.getProgram(), GL_ACTIVE_UNIFORMS,			&numActiveUniforms);
745			glGetProgramiv	(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCKS,	&numActiveBlocks);
746			m_log << TestLog::Message << "// GL_MAX_UNIFORM_BUFFER_BINDINGS = " << maxUniformBufferBindings << TestLog::EndMessage;
747			m_log << TestLog::Message << "// GL_ACTIVE_UNIFORMS = "				<< numActiveUniforms		<< TestLog::EndMessage;
748			m_log << TestLog::Message << "// GL_ACTIVE_UNIFORM_BLOCKS = "		<< numActiveBlocks			<< TestLog::EndMessage;
749			expectError		(GL_NO_ERROR);
750
751			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if uniformBlockIndex is not an active uniform block index of program.");
752			glUniformBlockBinding(program.getProgram(), -1, 0);
753			expectError(GL_INVALID_VALUE);
754			glUniformBlockBinding(program.getProgram(), 5, 0);
755			expectError(GL_INVALID_VALUE);
756			m_log << tcu::TestLog::EndSection;
757
758			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if uniformBlockBinding is greater than or equal to the value of GL_MAX_UNIFORM_BUFFER_BINDINGS.");
759			glUniformBlockBinding(program.getProgram(), maxUniformBufferBindings, 0);
760			expectError(GL_INVALID_VALUE);
761			m_log << tcu::TestLog::EndSection;
762
763			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if program is not the name of a program object generated by the GL.");
764			glUniformBlockBinding(-1, 0, 0);
765			expectError(GL_INVALID_VALUE);
766			m_log << tcu::TestLog::EndSection;
767		});
768
769	// glUniform*f
770
771	ES3F_ADD_API_CASE(uniformf_invalid_program, "Invalid glUniform{1234}f() usage",
772		{
773			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
774			glUseProgram(0);
775			glUniform1f(-1, 0.0f);
776			expectError(GL_INVALID_OPERATION);
777			glUniform2f(-1, 0.0f, 0.0f);
778			expectError(GL_INVALID_OPERATION);
779			glUniform3f(-1, 0.0f, 0.0f, 0.0f);
780			expectError(GL_INVALID_OPERATION);
781			glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
782			expectError(GL_INVALID_OPERATION);
783			m_log << tcu::TestLog::EndSection;
784		});
785	ES3F_ADD_API_CASE(uniformf_incompatible_type, "Invalid glUniform{1234}f() usage",
786		{
787			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
788
789			glUseProgram(program.getProgram());
790			GLint vec4_v	= glGetUniformLocation(program.getProgram(), "vec4_v");	// vec4
791			GLint ivec4_f	= glGetUniformLocation(program.getProgram(), "ivec4_f");	// ivec4
792			GLint uvec4_f	= glGetUniformLocation(program.getProgram(), "uvec4_f");	// uvec4
793			GLint sampler_f	= glGetUniformLocation(program.getProgram(), "sampler_f");	// sampler2D
794			expectError(GL_NO_ERROR);
795
796			if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
797			{
798				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
799				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
800			}
801
802			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.");
803			glUseProgram(program.getProgram());
804			glUniform1f(vec4_v, 0.0f);
805			expectError(GL_INVALID_OPERATION);
806			glUniform2f(vec4_v, 0.0f, 0.0f);
807			expectError(GL_INVALID_OPERATION);
808			glUniform3f(vec4_v, 0.0f, 0.0f, 0.0f);
809			expectError(GL_INVALID_OPERATION);
810			glUniform4f(vec4_v, 0.0f, 0.0f, 0.0f, 0.0f);
811			expectError(GL_NO_ERROR);
812			m_log << tcu::TestLog::EndSection;
813
814			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}f is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.");
815			glUseProgram(program.getProgram());
816			glUniform4f(ivec4_f, 0.0f, 0.0f, 0.0f, 0.0f);
817			expectError(GL_INVALID_OPERATION);
818			glUniform4f(uvec4_f, 0.0f, 0.0f, 0.0f, 0.0f);
819			expectError(GL_INVALID_OPERATION);
820			m_log << tcu::TestLog::EndSection;
821
822			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
823			glUseProgram(program.getProgram());
824			glUniform1f(sampler_f, 0.0f);
825			expectError(GL_INVALID_OPERATION);
826			m_log << tcu::TestLog::EndSection;
827
828			glUseProgram(0);
829		});
830	ES3F_ADD_API_CASE(uniformf_invalid_location, "Invalid glUniform{1234}f() usage",
831		{
832			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
833
834			glUseProgram(program.getProgram());
835			expectError(GL_NO_ERROR);
836
837			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.");
838			glUseProgram(program.getProgram());
839			glUniform1f(-2, 0.0f);
840			expectError(GL_INVALID_OPERATION);
841			glUniform2f(-2, 0.0f, 0.0f);
842			expectError(GL_INVALID_OPERATION);
843			glUniform3f(-2, 0.0f, 0.0f, 0.0f);
844			expectError(GL_INVALID_OPERATION);
845			glUniform4f(-2, 0.0f, 0.0f, 0.0f, 0.0f);
846			expectError(GL_INVALID_OPERATION);
847
848			glUseProgram(program.getProgram());
849			glUniform1f(-1, 0.0f);
850			expectError(GL_NO_ERROR);
851			glUniform2f(-1, 0.0f, 0.0f);
852			expectError(GL_NO_ERROR);
853			glUniform3f(-1, 0.0f, 0.0f, 0.0f);
854			expectError(GL_NO_ERROR);
855			glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
856			expectError(GL_NO_ERROR);
857			m_log << tcu::TestLog::EndSection;
858
859			glUseProgram(0);
860		});
861
862	// glUniform*fv
863
864	ES3F_ADD_API_CASE(uniformfv_invalid_program, "Invalid glUniform{1234}fv() usage",
865		{
866			std::vector<GLfloat> data(4);
867
868			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
869			glUseProgram(0);
870			glUniform1fv(-1, 1, &data[0]);
871			expectError(GL_INVALID_OPERATION);
872			glUniform2fv(-1, 1, &data[0]);
873			expectError(GL_INVALID_OPERATION);
874			glUniform3fv(-1, 1, &data[0]);
875			expectError(GL_INVALID_OPERATION);
876			glUniform4fv(-1, 1, &data[0]);
877			expectError(GL_INVALID_OPERATION);
878			m_log << tcu::TestLog::EndSection;
879		});
880	ES3F_ADD_API_CASE(uniformfv_incompatible_type, "Invalid glUniform{1234}fv() usage",
881		{
882			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
883
884			glUseProgram(program.getProgram());
885			GLint vec4_v	= glGetUniformLocation(program.getProgram(), "vec4_v");	// vec4
886			GLint ivec4_f	= glGetUniformLocation(program.getProgram(), "ivec4_f");	// ivec4
887			GLint uvec4_f	= glGetUniformLocation(program.getProgram(), "uvec4_f");	// uvec4
888			GLint sampler_f	= glGetUniformLocation(program.getProgram(), "sampler_f");	// sampler2D
889			expectError(GL_NO_ERROR);
890
891			if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
892			{
893				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
894				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
895			}
896
897			std::vector<GLfloat> data(4);
898
899			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.");
900			glUseProgram(program.getProgram());
901			glUniform1fv(vec4_v, 1, &data[0]);
902			expectError(GL_INVALID_OPERATION);
903			glUniform2fv(vec4_v, 1, &data[0]);
904			expectError(GL_INVALID_OPERATION);
905			glUniform3fv(vec4_v, 1, &data[0]);
906			expectError(GL_INVALID_OPERATION);
907			glUniform4fv(vec4_v, 1, &data[0]);
908			expectError(GL_NO_ERROR);
909			m_log << tcu::TestLog::EndSection;
910
911			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}fv is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.");
912			glUseProgram(program.getProgram());
913			glUniform4fv(ivec4_f, 1, &data[0]);
914			expectError(GL_INVALID_OPERATION);
915			glUniform4fv(uvec4_f, 1, &data[0]);
916			expectError(GL_INVALID_OPERATION);
917			m_log << tcu::TestLog::EndSection;
918
919			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
920			glUseProgram(program.getProgram());
921			glUniform1fv(sampler_f, 1, &data[0]);
922			expectError(GL_INVALID_OPERATION);
923			m_log << tcu::TestLog::EndSection;
924
925			glUseProgram(0);
926		});
927	ES3F_ADD_API_CASE(uniformfv_invalid_location, "Invalid glUniform{1234}fv() usage",
928		{
929			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
930
931			glUseProgram(program.getProgram());
932			expectError(GL_NO_ERROR);
933
934			std::vector<GLfloat> data(4);
935
936			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.");
937			glUseProgram(program.getProgram());
938			glUniform1fv(-2, 1, &data[0]);
939			expectError(GL_INVALID_OPERATION);
940			glUniform2fv(-2, 1, &data[0]);
941			expectError(GL_INVALID_OPERATION);
942			glUniform3fv(-2, 1, &data[0]);
943			expectError(GL_INVALID_OPERATION);
944			glUniform4fv(-2, 1, &data[0]);
945			expectError(GL_INVALID_OPERATION);
946
947			glUseProgram(program.getProgram());
948			glUniform1fv(-1, 1, &data[0]);
949			expectError(GL_NO_ERROR);
950			glUniform2fv(-1, 1, &data[0]);
951			expectError(GL_NO_ERROR);
952			glUniform3fv(-1, 1, &data[0]);
953			expectError(GL_NO_ERROR);
954			glUniform4fv(-1, 1, &data[0]);
955			expectError(GL_NO_ERROR);
956			m_log << tcu::TestLog::EndSection;
957
958			glUseProgram(0);
959		});
960	ES3F_ADD_API_CASE(uniformfv_invalid_count, "Invalid glUniform{1234}fv() usage",
961		{
962			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
963
964			glUseProgram			(program.getProgram());
965			GLint vec4_v			= glGetUniformLocation(program.getProgram(), "vec4_v");	// vec4
966			expectError(GL_NO_ERROR);
967
968			if (vec4_v == -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			std::vector<GLfloat> data(8);
975
976			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.");
977			glUseProgram(program.getProgram());
978			glUniform1fv(vec4_v, 2, &data[0]);
979			expectError(GL_INVALID_OPERATION);
980			glUniform2fv(vec4_v, 2, &data[0]);
981			expectError(GL_INVALID_OPERATION);
982			glUniform3fv(vec4_v, 2, &data[0]);
983			expectError(GL_INVALID_OPERATION);
984			glUniform4fv(vec4_v, 2, &data[0]);
985			expectError(GL_INVALID_OPERATION);
986			m_log << tcu::TestLog::EndSection;
987
988			glUseProgram(0);
989		});
990
991	// glUniform*i
992
993	ES3F_ADD_API_CASE(uniformi_invalid_program, "Invalid glUniform{1234}i() usage",
994		{
995			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
996			glUseProgram(0);
997			glUniform1i(-1, 0);
998			expectError(GL_INVALID_OPERATION);
999			glUniform2i(-1, 0, 0);
1000			expectError(GL_INVALID_OPERATION);
1001			glUniform3i(-1, 0, 0, 0);
1002			expectError(GL_INVALID_OPERATION);
1003			glUniform4i(-1, 0, 0, 0, 0);
1004			expectError(GL_INVALID_OPERATION);
1005			m_log << tcu::TestLog::EndSection;
1006		});
1007	ES3F_ADD_API_CASE(uniformi_incompatible_type, "Invalid glUniform{1234}i() usage",
1008		{
1009			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1010
1011			glUseProgram(program.getProgram());
1012			GLint vec4_v	= glGetUniformLocation(program.getProgram(), "vec4_v");	// vec4
1013			GLint ivec4_f	= glGetUniformLocation(program.getProgram(), "ivec4_f");	// ivec4
1014			GLint uvec4_f	= glGetUniformLocation(program.getProgram(), "uvec4_f");	// uvec4
1015			GLint sampler_f	= glGetUniformLocation(program.getProgram(), "sampler_f");	// sampler2D
1016			expectError(GL_NO_ERROR);
1017
1018			if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1019			{
1020				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1021				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1022			}
1023
1024			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.");
1025			glUseProgram(program.getProgram());
1026			glUniform1i(ivec4_f, 0);
1027			expectError(GL_INVALID_OPERATION);
1028			glUniform2i(ivec4_f, 0, 0);
1029			expectError(GL_INVALID_OPERATION);
1030			glUniform3i(ivec4_f, 0, 0, 0);
1031			expectError(GL_INVALID_OPERATION);
1032			glUniform4i(ivec4_f, 0, 0, 0, 0);
1033			expectError(GL_NO_ERROR);
1034			m_log << tcu::TestLog::EndSection;
1035
1036			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type unsigned int, uvec2, uvec3, uvec4, or an array of these.");
1037			glUseProgram(program.getProgram());
1038			glUniform1i(uvec4_f, 0);
1039			expectError(GL_INVALID_OPERATION);
1040			glUniform2i(uvec4_f, 0, 0);
1041			expectError(GL_INVALID_OPERATION);
1042			glUniform3i(uvec4_f, 0, 0, 0);
1043			expectError(GL_INVALID_OPERATION);
1044			glUniform4i(uvec4_f, 0, 0, 0, 0);
1045			expectError(GL_INVALID_OPERATION);
1046			m_log << tcu::TestLog::EndSection;
1047
1048			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type float, vec2, vec3, or vec4.");
1049			glUseProgram(program.getProgram());
1050			glUniform1i(vec4_v, 0);
1051			expectError(GL_INVALID_OPERATION);
1052			glUniform2i(vec4_v, 0, 0);
1053			expectError(GL_INVALID_OPERATION);
1054			glUniform3i(vec4_v, 0, 0, 0);
1055			expectError(GL_INVALID_OPERATION);
1056			glUniform4i(vec4_v, 0, 0, 0, 0);
1057			expectError(GL_INVALID_OPERATION);
1058			m_log << tcu::TestLog::EndSection;
1059
1060			glUseProgram(0);
1061		});
1062	ES3F_ADD_API_CASE(uniformi_invalid_location, "Invalid glUniform{1234}i() usage",
1063		{
1064			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1065
1066			glUseProgram(program.getProgram());
1067			expectError(GL_NO_ERROR);
1068
1069			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.");
1070			glUseProgram(program.getProgram());
1071			glUniform1i(-2, 0);
1072			expectError(GL_INVALID_OPERATION);
1073			glUniform2i(-2, 0, 0);
1074			expectError(GL_INVALID_OPERATION);
1075			glUniform3i(-2, 0, 0, 0);
1076			expectError(GL_INVALID_OPERATION);
1077			glUniform4i(-2, 0, 0, 0, 0);
1078			expectError(GL_INVALID_OPERATION);
1079
1080			glUseProgram(program.getProgram());
1081			glUniform1i(-1, 0);
1082			expectError(GL_NO_ERROR);
1083			glUniform2i(-1, 0, 0);
1084			expectError(GL_NO_ERROR);
1085			glUniform3i(-1, 0, 0, 0);
1086			expectError(GL_NO_ERROR);
1087			glUniform4i(-1, 0, 0, 0, 0);
1088			expectError(GL_NO_ERROR);
1089			m_log << tcu::TestLog::EndSection;
1090
1091			glUseProgram(0);
1092		});
1093
1094	// glUniform*iv
1095
1096	ES3F_ADD_API_CASE(uniformiv_invalid_program, "Invalid glUniform{1234}iv() usage",
1097		{
1098			std::vector<GLint> data(4);
1099
1100			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1101			glUseProgram(0);
1102			glUniform1iv(-1, 1, &data[0]);
1103			expectError(GL_INVALID_OPERATION);
1104			glUniform2iv(-1, 1, &data[0]);
1105			expectError(GL_INVALID_OPERATION);
1106			glUniform3iv(-1, 1, &data[0]);
1107			expectError(GL_INVALID_OPERATION);
1108			glUniform4iv(-1, 1, &data[0]);
1109			expectError(GL_INVALID_OPERATION);
1110			m_log << tcu::TestLog::EndSection;
1111		});
1112	ES3F_ADD_API_CASE(uniformiv_incompatible_type, "Invalid glUniform{1234}iv() usage",
1113		{
1114			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1115
1116			glUseProgram(program.getProgram());
1117			GLint vec4_v	= glGetUniformLocation(program.getProgram(), "vec4_v");	// vec4
1118			GLint ivec4_f	= glGetUniformLocation(program.getProgram(), "ivec4_f");	// ivec4
1119			GLint uvec4_f	= glGetUniformLocation(program.getProgram(), "uvec4_f");	// uvec4
1120			GLint sampler_f	= glGetUniformLocation(program.getProgram(), "sampler_f");	// sampler2D
1121			expectError(GL_NO_ERROR);
1122
1123			if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1124			{
1125				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1126				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1127			}
1128
1129			std::vector<GLint> data(4);
1130
1131			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.");
1132			glUseProgram(program.getProgram());
1133			glUniform1iv(ivec4_f, 1, &data[0]);
1134			expectError(GL_INVALID_OPERATION);
1135			glUniform2iv(ivec4_f, 1, &data[0]);
1136			expectError(GL_INVALID_OPERATION);
1137			glUniform3iv(ivec4_f, 1, &data[0]);
1138			expectError(GL_INVALID_OPERATION);
1139			glUniform4iv(ivec4_f, 1, &data[0]);
1140			expectError(GL_NO_ERROR);
1141			m_log << tcu::TestLog::EndSection;
1142
1143			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}iv is used to load a uniform variable of type float, vec2, vec3, or vec4.");
1144			glUseProgram(program.getProgram());
1145			glUniform1iv(vec4_v, 1, &data[0]);
1146			expectError(GL_INVALID_OPERATION);
1147			glUniform2iv(vec4_v, 1, &data[0]);
1148			expectError(GL_INVALID_OPERATION);
1149			glUniform3iv(vec4_v, 1, &data[0]);
1150			expectError(GL_INVALID_OPERATION);
1151			glUniform4iv(vec4_v, 1, &data[0]);
1152			expectError(GL_INVALID_OPERATION);
1153			m_log << tcu::TestLog::EndSection;
1154
1155			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}iv is used to load a uniform variable of type unsigned int, uvec2, uvec3 or uvec4.");
1156			glUseProgram(program.getProgram());
1157			glUniform1iv(uvec4_f, 1, &data[0]);
1158			expectError(GL_INVALID_OPERATION);
1159			glUniform2iv(uvec4_f, 1, &data[0]);
1160			expectError(GL_INVALID_OPERATION);
1161			glUniform3iv(uvec4_f, 1, &data[0]);
1162			expectError(GL_INVALID_OPERATION);
1163			glUniform4iv(uvec4_f, 1, &data[0]);
1164			expectError(GL_INVALID_OPERATION);
1165			m_log << tcu::TestLog::EndSection;
1166
1167			glUseProgram(0);
1168		});
1169	ES3F_ADD_API_CASE(uniformiv_invalid_location, "Invalid glUniform{1234}iv() usage",
1170		{
1171			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1172
1173			glUseProgram(program.getProgram());
1174			expectError(GL_NO_ERROR);
1175
1176			std::vector<GLint> data(4);
1177
1178			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.");
1179			glUseProgram(program.getProgram());
1180			glUniform1iv(-2, 1, &data[0]);
1181			expectError(GL_INVALID_OPERATION);
1182			glUniform2iv(-2, 1, &data[0]);
1183			expectError(GL_INVALID_OPERATION);
1184			glUniform3iv(-2, 1, &data[0]);
1185			expectError(GL_INVALID_OPERATION);
1186			glUniform4iv(-2, 1, &data[0]);
1187			expectError(GL_INVALID_OPERATION);
1188
1189			glUseProgram(program.getProgram());
1190			glUniform1iv(-1, 1, &data[0]);
1191			expectError(GL_NO_ERROR);
1192			glUniform2iv(-1, 1, &data[0]);
1193			expectError(GL_NO_ERROR);
1194			glUniform3iv(-1, 1, &data[0]);
1195			expectError(GL_NO_ERROR);
1196			glUniform4iv(-1, 1, &data[0]);
1197			expectError(GL_NO_ERROR);
1198			m_log << tcu::TestLog::EndSection;
1199
1200			glUseProgram(0);
1201		});
1202	ES3F_ADD_API_CASE(uniformiv_invalid_count, "Invalid glUniform{1234}iv() usage",
1203		{
1204			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1205
1206			glUseProgram			(program.getProgram());
1207			GLint ivec4_f			= glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
1208			expectError(GL_NO_ERROR);
1209
1210			if (ivec4_f == -1)
1211			{
1212				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1213				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1214			}
1215
1216			std::vector<GLint> data(8);
1217
1218			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.");
1219			glUseProgram(program.getProgram());
1220			glUniform1iv(ivec4_f, 2, &data[0]);
1221			expectError(GL_INVALID_OPERATION);
1222			glUniform2iv(ivec4_f, 2, &data[0]);
1223			expectError(GL_INVALID_OPERATION);
1224			glUniform3iv(ivec4_f, 2, &data[0]);
1225			expectError(GL_INVALID_OPERATION);
1226			glUniform4iv(ivec4_f, 2, &data[0]);
1227			expectError(GL_INVALID_OPERATION);
1228			m_log << tcu::TestLog::EndSection;
1229
1230			glUseProgram(0);
1231		});
1232
1233	// glUniform{1234}ui
1234
1235	ES3F_ADD_API_CASE(uniformui_invalid_program, "Invalid glUniform{234}ui() usage",
1236		{
1237			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1238			glUseProgram(0);
1239			glUniform1ui(-1, 0);
1240			expectError(GL_INVALID_OPERATION);
1241			glUniform2ui(-1, 0, 0);
1242			expectError(GL_INVALID_OPERATION);
1243			glUniform3ui(-1, 0, 0, 0);
1244			expectError(GL_INVALID_OPERATION);
1245			glUniform4ui(-1, 0, 0, 0, 0);
1246			expectError(GL_INVALID_OPERATION);
1247			m_log << tcu::TestLog::EndSection;
1248		});
1249	ES3F_ADD_API_CASE(uniformui_incompatible_type, "Invalid glUniform{1234}ui() usage",
1250		{
1251			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1252
1253			glUseProgram(program.getProgram());
1254			GLint vec4_v	= glGetUniformLocation(program.getProgram(), "vec4_v");	// vec4
1255			GLint ivec4_f	= glGetUniformLocation(program.getProgram(), "ivec4_f");	// ivec4
1256			GLint uvec4_f	= glGetUniformLocation(program.getProgram(), "uvec4_f");	// uvec4
1257			GLint sampler_f	= glGetUniformLocation(program.getProgram(), "sampler_f");	// sampler2D
1258			expectError(GL_NO_ERROR);
1259
1260			if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1261			{
1262				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1263				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1264			}
1265
1266			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.");
1267			glUseProgram(program.getProgram());
1268			glUniform1ui(uvec4_f, 0);
1269			expectError(GL_INVALID_OPERATION);
1270			glUniform2ui(uvec4_f, 0, 0);
1271			expectError(GL_INVALID_OPERATION);
1272			glUniform3ui(uvec4_f, 0, 0, 0);
1273			expectError(GL_INVALID_OPERATION);
1274			glUniform4ui(uvec4_f, 0, 0, 0, 0);
1275			expectError(GL_NO_ERROR);
1276			m_log << tcu::TestLog::EndSection;
1277
1278			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type int, ivec2, ivec3, ivec4, or an array of these.");
1279			glUseProgram(program.getProgram());
1280			glUniform1ui(ivec4_f, 0);
1281			expectError(GL_INVALID_OPERATION);
1282			glUniform2ui(ivec4_f, 0, 0);
1283			expectError(GL_INVALID_OPERATION);
1284			glUniform3ui(ivec4_f, 0, 0, 0);
1285			expectError(GL_INVALID_OPERATION);
1286			glUniform4ui(ivec4_f, 0, 0, 0, 0);
1287			expectError(GL_INVALID_OPERATION);
1288			m_log << tcu::TestLog::EndSection;
1289
1290			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type float, vec2, vec3, or vec4.");
1291			glUseProgram(program.getProgram());
1292			glUniform1ui(vec4_v, 0);
1293			expectError(GL_INVALID_OPERATION);
1294			glUniform2ui(vec4_v, 0, 0);
1295			expectError(GL_INVALID_OPERATION);
1296			glUniform3ui(vec4_v, 0, 0, 0);
1297			expectError(GL_INVALID_OPERATION);
1298			glUniform4ui(vec4_v, 0, 0, 0, 0);
1299			expectError(GL_INVALID_OPERATION);
1300			m_log << tcu::TestLog::EndSection;
1301
1302			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
1303			glUseProgram(program.getProgram());
1304			glUniform1ui(sampler_f, 0);
1305			expectError(GL_INVALID_OPERATION);
1306			m_log << tcu::TestLog::EndSection;
1307
1308			glUseProgram(0);
1309		});
1310	ES3F_ADD_API_CASE(uniformui_invalid_location, "Invalid glUniform{1234}ui() usage",
1311		{
1312			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1313
1314			glUseProgram(program.getProgram());
1315			expectError(GL_NO_ERROR);
1316
1317			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.");
1318			glUseProgram(program.getProgram());
1319			glUniform1i(-2, 0);
1320			expectError(GL_INVALID_OPERATION);
1321			glUniform2i(-2, 0, 0);
1322			expectError(GL_INVALID_OPERATION);
1323			glUniform3i(-2, 0, 0, 0);
1324			expectError(GL_INVALID_OPERATION);
1325			glUniform4i(-2, 0, 0, 0, 0);
1326			expectError(GL_INVALID_OPERATION);
1327
1328			glUseProgram(program.getProgram());
1329			glUniform1i(-1, 0);
1330			expectError(GL_NO_ERROR);
1331			glUniform2i(-1, 0, 0);
1332			expectError(GL_NO_ERROR);
1333			glUniform3i(-1, 0, 0, 0);
1334			expectError(GL_NO_ERROR);
1335			glUniform4i(-1, 0, 0, 0, 0);
1336			expectError(GL_NO_ERROR);
1337			m_log << tcu::TestLog::EndSection;
1338
1339			glUseProgram(0);
1340		});
1341
1342	// glUniform{1234}uiv
1343
1344	ES3F_ADD_API_CASE(uniformuiv_invalid_program, "Invalid glUniform{234}uiv() usage",
1345		{
1346			std::vector<GLuint> data(4);
1347
1348			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1349			glUseProgram(0);
1350			glUniform1uiv(-1, 1, &data[0]);
1351			expectError(GL_INVALID_OPERATION);
1352			glUniform2uiv(-1, 1, &data[0]);
1353			expectError(GL_INVALID_OPERATION);
1354			glUniform3uiv(-1, 1, &data[0]);
1355			expectError(GL_INVALID_OPERATION);
1356			glUniform4uiv(-1, 1, &data[0]);
1357			expectError(GL_INVALID_OPERATION);
1358			m_log << tcu::TestLog::EndSection;
1359		});
1360	ES3F_ADD_API_CASE(uniformuiv_incompatible_type, "Invalid glUniform{1234}uiv() usage",
1361		{
1362			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1363
1364			glUseProgram(program.getProgram());
1365			GLint vec4_v	= glGetUniformLocation(program.getProgram(), "vec4_v");	// vec4
1366			GLint ivec4_f	= glGetUniformLocation(program.getProgram(), "ivec4_f");	// ivec4
1367			GLint uvec4_f	= glGetUniformLocation(program.getProgram(), "uvec4_f");	// uvec4
1368			GLint sampler_f	= glGetUniformLocation(program.getProgram(), "sampler_f");	// sampler2D
1369			expectError(GL_NO_ERROR);
1370
1371			if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1372			{
1373				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1374				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1375			}
1376
1377			std::vector<GLuint> data(4);
1378
1379			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.");
1380			glUseProgram(program.getProgram());
1381			glUniform1uiv(uvec4_f, 1, &data[0]);
1382			expectError(GL_INVALID_OPERATION);
1383			glUniform2uiv(uvec4_f, 1, &data[0]);
1384			expectError(GL_INVALID_OPERATION);
1385			glUniform3uiv(uvec4_f, 1, &data[0]);
1386			expectError(GL_INVALID_OPERATION);
1387			glUniform4uiv(uvec4_f, 1, &data[0]);
1388			expectError(GL_NO_ERROR);
1389			m_log << tcu::TestLog::EndSection;
1390
1391			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a uniform variable of type float, vec2, vec3, or vec4.");
1392			glUseProgram(program.getProgram());
1393			glUniform1uiv(vec4_v, 1, &data[0]);
1394			expectError(GL_INVALID_OPERATION);
1395			glUniform2uiv(vec4_v, 1, &data[0]);
1396			expectError(GL_INVALID_OPERATION);
1397			glUniform3uiv(vec4_v, 1, &data[0]);
1398			expectError(GL_INVALID_OPERATION);
1399			glUniform4uiv(vec4_v, 1, &data[0]);
1400			expectError(GL_INVALID_OPERATION);
1401			m_log << tcu::TestLog::EndSection;
1402
1403			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a uniform variable of type int, ivec2, ivec3 or ivec4.");
1404			glUseProgram(program.getProgram());
1405			glUniform1uiv(ivec4_f, 1, &data[0]);
1406			expectError(GL_INVALID_OPERATION);
1407			glUniform2uiv(ivec4_f, 1, &data[0]);
1408			expectError(GL_INVALID_OPERATION);
1409			glUniform3uiv(ivec4_f, 1, &data[0]);
1410			expectError(GL_INVALID_OPERATION);
1411			glUniform4uiv(ivec4_f, 1, &data[0]);
1412			expectError(GL_INVALID_OPERATION);
1413			m_log << tcu::TestLog::EndSection;
1414
1415			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
1416			glUseProgram(program.getProgram());
1417			glUniform1uiv(sampler_f, 1, &data[0]);
1418			expectError(GL_INVALID_OPERATION);
1419			m_log << tcu::TestLog::EndSection;
1420
1421			glUseProgram(0);
1422		});
1423	ES3F_ADD_API_CASE(uniformuiv_invalid_location, "Invalid glUniform{1234}uiv() usage",
1424		{
1425			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1426
1427			glUseProgram(program.getProgram());
1428			expectError(GL_NO_ERROR);
1429
1430			std::vector<GLuint> data(4);
1431
1432			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.");
1433			glUseProgram(program.getProgram());
1434			glUniform1uiv(-2, 1, &data[0]);
1435			expectError(GL_INVALID_OPERATION);
1436			glUniform2uiv(-2, 1, &data[0]);
1437			expectError(GL_INVALID_OPERATION);
1438			glUniform3uiv(-2, 1, &data[0]);
1439			expectError(GL_INVALID_OPERATION);
1440			glUniform4uiv(-2, 1, &data[0]);
1441			expectError(GL_INVALID_OPERATION);
1442
1443			glUseProgram(program.getProgram());
1444			glUniform1uiv(-1, 1, &data[0]);
1445			expectError(GL_NO_ERROR);
1446			glUniform2uiv(-1, 1, &data[0]);
1447			expectError(GL_NO_ERROR);
1448			glUniform3uiv(-1, 1, &data[0]);
1449			expectError(GL_NO_ERROR);
1450			glUniform4uiv(-1, 1, &data[0]);
1451			expectError(GL_NO_ERROR);
1452			m_log << tcu::TestLog::EndSection;
1453
1454			glUseProgram(0);
1455		});
1456	ES3F_ADD_API_CASE(uniformuiv_invalid_count, "Invalid glUniform{1234}uiv() usage",
1457		{
1458			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1459
1460			glUseProgram			(program.getProgram());
1461			int uvec4_f				= glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
1462			expectError(GL_NO_ERROR);
1463
1464			if (uvec4_f == -1)
1465			{
1466				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1467				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1468			}
1469
1470			std::vector<GLuint> data(8);
1471
1472			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.");
1473			glUseProgram(program.getProgram());
1474			glUniform1uiv(uvec4_f, 2, &data[0]);
1475			expectError(GL_INVALID_OPERATION);
1476			glUniform2uiv(uvec4_f, 2, &data[0]);
1477			expectError(GL_INVALID_OPERATION);
1478			glUniform3uiv(uvec4_f, 2, &data[0]);
1479			expectError(GL_INVALID_OPERATION);
1480			glUniform4uiv(uvec4_f, 2, &data[0]);
1481			expectError(GL_INVALID_OPERATION);
1482			m_log << tcu::TestLog::EndSection;
1483
1484			glUseProgram(0);
1485		});
1486
1487
1488	// glUniformMatrix*fv
1489
1490	ES3F_ADD_API_CASE(uniform_matrixfv_invalid_program, "Invalid glUniformMatrix{234}fv() usage",
1491		{
1492			std::vector<GLfloat> data(16);
1493
1494			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1495			glUseProgram(0);
1496			glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
1497			expectError(GL_INVALID_OPERATION);
1498			glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
1499			expectError(GL_INVALID_OPERATION);
1500			glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
1501			expectError(GL_INVALID_OPERATION);
1502
1503			glUniformMatrix2x3fv(-1, 1, GL_FALSE, &data[0]);
1504			expectError(GL_INVALID_OPERATION);
1505			glUniformMatrix3x2fv(-1, 1, GL_FALSE, &data[0]);
1506			expectError(GL_INVALID_OPERATION);
1507			glUniformMatrix2x4fv(-1, 1, GL_FALSE, &data[0]);
1508			expectError(GL_INVALID_OPERATION);
1509			glUniformMatrix4x2fv(-1, 1, GL_FALSE, &data[0]);
1510			expectError(GL_INVALID_OPERATION);
1511			glUniformMatrix3x4fv(-1, 1, GL_FALSE, &data[0]);
1512			expectError(GL_INVALID_OPERATION);
1513			glUniformMatrix4x3fv(-1, 1, GL_FALSE, &data[0]);
1514			expectError(GL_INVALID_OPERATION);
1515			m_log << tcu::TestLog::EndSection;
1516		});
1517	ES3F_ADD_API_CASE(uniform_matrixfv_incompatible_type, "Invalid glUniformMatrix{234}fv() usage",
1518		{
1519			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1520
1521			glUseProgram			(program.getProgram());
1522			GLint mat4_v			= glGetUniformLocation(program.getProgram(), "mat4_v");	// mat4
1523			GLint sampler_f			= glGetUniformLocation(program.getProgram(), "sampler_f");	// sampler2D
1524			expectError(GL_NO_ERROR);
1525
1526			if (mat4_v == -1 || sampler_f == -1)
1527			{
1528				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1529				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1530			}
1531
1532			std::vector<GLfloat> data(16);
1533
1534			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.");
1535			glUseProgram(program.getProgram());
1536			glUniformMatrix2fv(mat4_v, 1, GL_FALSE, &data[0]);
1537			expectError(GL_INVALID_OPERATION);
1538			glUniformMatrix3fv(mat4_v, 1, GL_FALSE, &data[0]);
1539			expectError(GL_INVALID_OPERATION);
1540			glUniformMatrix4fv(mat4_v, 1, GL_FALSE, &data[0]);
1541			expectError(GL_NO_ERROR);
1542
1543			glUniformMatrix2x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1544			expectError(GL_INVALID_OPERATION);
1545			glUniformMatrix3x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1546			expectError(GL_INVALID_OPERATION);
1547			glUniformMatrix2x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1548			expectError(GL_INVALID_OPERATION);
1549			glUniformMatrix4x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1550			expectError(GL_INVALID_OPERATION);
1551			glUniformMatrix3x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1552			expectError(GL_INVALID_OPERATION);
1553			glUniformMatrix4x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1554			expectError(GL_INVALID_OPERATION);
1555			m_log << tcu::TestLog::EndSection;
1556
1557			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.");
1558			glUseProgram(program.getProgram());
1559			glUniformMatrix2fv(sampler_f, 1, GL_FALSE, &data[0]);
1560			expectError(GL_INVALID_OPERATION);
1561			glUniformMatrix3fv(sampler_f, 1, GL_FALSE, &data[0]);
1562			expectError(GL_INVALID_OPERATION);
1563			glUniformMatrix4fv(sampler_f, 1, GL_FALSE, &data[0]);
1564			expectError(GL_INVALID_OPERATION);
1565
1566			glUniformMatrix2x3fv(sampler_f, 1, GL_FALSE, &data[0]);
1567			expectError(GL_INVALID_OPERATION);
1568			glUniformMatrix3x2fv(sampler_f, 1, GL_FALSE, &data[0]);
1569			expectError(GL_INVALID_OPERATION);
1570			glUniformMatrix2x4fv(sampler_f, 1, GL_FALSE, &data[0]);
1571			expectError(GL_INVALID_OPERATION);
1572			glUniformMatrix4x2fv(sampler_f, 1, GL_FALSE, &data[0]);
1573			expectError(GL_INVALID_OPERATION);
1574			glUniformMatrix3x4fv(sampler_f, 1, GL_FALSE, &data[0]);
1575			expectError(GL_INVALID_OPERATION);
1576			glUniformMatrix4x3fv(sampler_f, 1, GL_FALSE, &data[0]);
1577			expectError(GL_INVALID_OPERATION);
1578			m_log << tcu::TestLog::EndSection;
1579
1580			glUseProgram(0);
1581		});
1582	ES3F_ADD_API_CASE(uniform_matrixfv_invalid_location, "Invalid glUniformMatrix{234}fv() usage",
1583		{
1584			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1585
1586			glUseProgram(program.getProgram());
1587			expectError(GL_NO_ERROR);
1588
1589			std::vector<GLfloat> data(16);
1590
1591			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.");
1592			glUseProgram(program.getProgram());
1593			glUniformMatrix2fv(-2, 1, GL_FALSE, &data[0]);
1594			expectError(GL_INVALID_OPERATION);
1595			glUniformMatrix3fv(-2, 1, GL_FALSE, &data[0]);
1596			expectError(GL_INVALID_OPERATION);
1597			glUniformMatrix4fv(-2, 1, GL_FALSE, &data[0]);
1598			expectError(GL_INVALID_OPERATION);
1599
1600			glUniformMatrix2x3fv(-2, 1, GL_FALSE, &data[0]);
1601			expectError(GL_INVALID_OPERATION);
1602			glUniformMatrix3x2fv(-2, 1, GL_FALSE, &data[0]);
1603			expectError(GL_INVALID_OPERATION);
1604			glUniformMatrix2x4fv(-2, 1, GL_FALSE, &data[0]);
1605			expectError(GL_INVALID_OPERATION);
1606			glUniformMatrix4x2fv(-2, 1, GL_FALSE, &data[0]);
1607			expectError(GL_INVALID_OPERATION);
1608			glUniformMatrix3x4fv(-2, 1, GL_FALSE, &data[0]);
1609			expectError(GL_INVALID_OPERATION);
1610			glUniformMatrix4x3fv(-2, 1, GL_FALSE, &data[0]);
1611			expectError(GL_INVALID_OPERATION);
1612
1613			glUseProgram(program.getProgram());
1614			glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
1615			expectError(GL_NO_ERROR);
1616			glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
1617			expectError(GL_NO_ERROR);
1618			glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
1619			expectError(GL_NO_ERROR);
1620
1621			glUniformMatrix2x3fv(-1, 1, GL_FALSE, &data[0]);
1622			expectError(GL_NO_ERROR);
1623			glUniformMatrix3x2fv(-1, 1, GL_FALSE, &data[0]);
1624			expectError(GL_NO_ERROR);
1625			glUniformMatrix2x4fv(-1, 1, GL_FALSE, &data[0]);
1626			expectError(GL_NO_ERROR);
1627			glUniformMatrix4x2fv(-1, 1, GL_FALSE, &data[0]);
1628			expectError(GL_NO_ERROR);
1629			glUniformMatrix3x4fv(-1, 1, GL_FALSE, &data[0]);
1630			expectError(GL_NO_ERROR);
1631			glUniformMatrix4x3fv(-1, 1, GL_FALSE, &data[0]);
1632			expectError(GL_NO_ERROR);
1633			m_log << tcu::TestLog::EndSection;
1634
1635			glUseProgram(0);
1636		});
1637	ES3F_ADD_API_CASE(uniform_matrixfv_invalid_count, "Invalid glUniformMatrix{234}fv() usage",
1638		{
1639			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1640
1641			glUseProgram			(program.getProgram());
1642			GLint mat4_v			= glGetUniformLocation(program.getProgram(), "mat4_v"); // mat4
1643			expectError(GL_NO_ERROR);
1644
1645			if (mat4_v == -1)
1646			{
1647				m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1648				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1649			}
1650
1651			std::vector<GLfloat> data(32);
1652
1653			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.");
1654			glUseProgram(program.getProgram());
1655			glUniformMatrix2fv(mat4_v, 2, GL_FALSE, &data[0]);
1656			expectError(GL_INVALID_OPERATION);
1657			glUniformMatrix3fv(mat4_v, 2, GL_FALSE, &data[0]);
1658			expectError(GL_INVALID_OPERATION);
1659			glUniformMatrix4fv(mat4_v, 2, GL_FALSE, &data[0]);
1660			expectError(GL_INVALID_OPERATION);
1661
1662			glUniformMatrix2x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1663			expectError(GL_INVALID_OPERATION);
1664			glUniformMatrix3x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1665			expectError(GL_INVALID_OPERATION);
1666			glUniformMatrix2x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1667			expectError(GL_INVALID_OPERATION);
1668			glUniformMatrix4x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1669			expectError(GL_INVALID_OPERATION);
1670			glUniformMatrix3x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1671			expectError(GL_INVALID_OPERATION);
1672			glUniformMatrix4x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1673			expectError(GL_INVALID_OPERATION);
1674			m_log << tcu::TestLog::EndSection;
1675
1676			glUseProgram(0);
1677		});
1678
1679	// Transform feedback
1680
1681	ES3F_ADD_API_CASE(gen_transform_feedbacks, "Invalid glGenTransformFeedbacks() usage",
1682		{
1683			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
1684			GLuint id;
1685			glGenTransformFeedbacks(-1, &id);
1686			expectError(GL_INVALID_VALUE);
1687			m_log << tcu::TestLog::EndSection;
1688		});
1689	ES3F_ADD_API_CASE(bind_transform_feedback, "Invalid glBindTransformFeedback() usage",
1690		{
1691			GLuint						tfID[2];
1692			glu::ShaderProgram			program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1693			deUint32					buf;
1694			const char* tfVarying		= "gl_Position";
1695
1696			glGenBuffers				(1, &buf);
1697			glGenTransformFeedbacks		(2, tfID);
1698
1699			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if target is not GL_TRANSFORM_FEEDBACK.");
1700			glBindTransformFeedback(-1, tfID[0]);
1701			expectError(GL_INVALID_ENUM);
1702			m_log << tcu::TestLog::EndSection;
1703
1704			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the transform feedback operation is active on the currently bound transform feedback object, and is not paused.");
1705			glUseProgram				(program.getProgram());
1706			glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1707			glLinkProgram				(program.getProgram());
1708			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID[0]);
1709			glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1710			glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1711			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1712			glBeginTransformFeedback	(GL_TRIANGLES);
1713			expectError					(GL_NO_ERROR);
1714
1715			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID[1]);
1716			expectError					(GL_INVALID_OPERATION);
1717
1718			glEndTransformFeedback		();
1719			expectError					(GL_NO_ERROR);
1720			m_log << tcu::TestLog::EndSection;
1721
1722			glUseProgram				(0);
1723			glDeleteBuffers				(1, &buf);
1724			glDeleteTransformFeedbacks	(2, tfID);
1725			expectError					(GL_NO_ERROR);
1726		});
1727	ES3F_ADD_API_CASE(delete_transform_feedbacks, "Invalid glDeleteTransformFeedbacks() usage",
1728		{
1729			GLuint id;
1730			glGenTransformFeedbacks(1, &id);
1731
1732			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
1733			glDeleteTransformFeedbacks(-1, &id);
1734			expectError(GL_INVALID_VALUE);
1735			m_log << tcu::TestLog::EndSection;
1736
1737			glDeleteTransformFeedbacks(1, &id);
1738		});
1739	ES3F_ADD_API_CASE(begin_transform_feedback, "Invalid glBeginTransformFeedback() usage",
1740		{
1741			GLuint						tfID[2];
1742			glu::ShaderProgram			program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1743			deUint32					buf;
1744			const char* tfVarying		= "gl_Position";
1745
1746			glGenBuffers				(1, &buf);
1747			glGenTransformFeedbacks		(2, tfID);
1748
1749			glUseProgram				(program.getProgram());
1750			glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1751			glLinkProgram				(program.getProgram());
1752			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID[0]);
1753			glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1754			glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1755			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1756			expectError					(GL_NO_ERROR);
1757
1758			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if primitiveMode is not one of GL_POINTS, GL_LINES, or GL_TRIANGLES.");
1759			glBeginTransformFeedback	(-1);
1760			expectError					(GL_INVALID_ENUM);
1761			m_log << tcu::TestLog::EndSection;
1762
1763			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is already active.");
1764			glBeginTransformFeedback	(GL_TRIANGLES);
1765			expectError					(GL_NO_ERROR);
1766			glBeginTransformFeedback	(GL_POINTS);
1767			expectError					(GL_INVALID_OPERATION);
1768			m_log << tcu::TestLog::EndSection;
1769
1770			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if any binding point used in transform feedback mode does not have a buffer object bound.");
1771			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
1772			glBeginTransformFeedback	(GL_TRIANGLES);
1773			expectError					(GL_INVALID_OPERATION);
1774			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1775			m_log << tcu::TestLog::EndSection;
1776
1777			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if no binding points would be used because no program object is active.");
1778			glUseProgram				(0);
1779			glBeginTransformFeedback	(GL_TRIANGLES);
1780			expectError					(GL_INVALID_OPERATION);
1781			glUseProgram				(program.getProgram());
1782			m_log << tcu::TestLog::EndSection;
1783
1784			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if no binding points would be used because the active program object has specified no varying variables to record.");
1785			glTransformFeedbackVaryings	(program.getProgram(), 0, 0, GL_INTERLEAVED_ATTRIBS);
1786			glBeginTransformFeedback	(GL_TRIANGLES);
1787			expectError					(GL_INVALID_OPERATION);
1788			m_log << tcu::TestLog::EndSection;
1789
1790			glEndTransformFeedback		();
1791			glDeleteBuffers				(1, &buf);
1792			glDeleteTransformFeedbacks	(2, tfID);
1793			expectError					(GL_NO_ERROR);
1794		});
1795	ES3F_ADD_API_CASE(pause_transform_feedback, "Invalid glPauseTransformFeedback() usage",
1796		{
1797			GLuint						tfID[2];
1798			glu::ShaderProgram			program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1799			deUint32					buf;
1800			const char* tfVarying		= "gl_Position";
1801
1802			glGenBuffers				(1, &buf);
1803			glGenTransformFeedbacks		(2, tfID);
1804
1805			glUseProgram				(program.getProgram());
1806			glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1807			glLinkProgram				(program.getProgram());
1808			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID[0]);
1809			glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1810			glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1811			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1812			expectError					(GL_NO_ERROR);
1813
1814			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is paused.");
1815			glPauseTransformFeedback	();
1816			expectError					(GL_INVALID_OPERATION);
1817			glBeginTransformFeedback	(GL_TRIANGLES);
1818			glPauseTransformFeedback	();
1819			expectError					(GL_NO_ERROR);
1820			glPauseTransformFeedback	();
1821			expectError					(GL_INVALID_OPERATION);
1822			m_log << tcu::TestLog::EndSection;
1823
1824			glEndTransformFeedback		();
1825			glDeleteBuffers				(1, &buf);
1826			glDeleteTransformFeedbacks	(2, tfID);
1827			expectError					(GL_NO_ERROR);
1828		});
1829	ES3F_ADD_API_CASE(resume_transform_feedback, "Invalid glResumeTransformFeedback() usage",
1830		{
1831			GLuint						tfID[2];
1832			glu::ShaderProgram			program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1833			deUint32					buf;
1834			const char* tfVarying		= "gl_Position";
1835
1836			glGenBuffers				(1, &buf);
1837			glGenTransformFeedbacks		(2, tfID);
1838
1839			glUseProgram				(program.getProgram());
1840			glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1841			glLinkProgram				(program.getProgram());
1842			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID[0]);
1843			glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1844			glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1845			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1846			expectError					(GL_NO_ERROR);
1847
1848			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is not paused.");
1849			glResumeTransformFeedback	();
1850			expectError					(GL_INVALID_OPERATION);
1851			glBeginTransformFeedback	(GL_TRIANGLES);
1852			glResumeTransformFeedback	();
1853			expectError					(GL_INVALID_OPERATION);
1854			glPauseTransformFeedback	();
1855			glResumeTransformFeedback	();
1856			expectError					(GL_NO_ERROR);
1857			m_log << tcu::TestLog::EndSection;
1858
1859			glEndTransformFeedback		();
1860			glDeleteBuffers				(1, &buf);
1861			glDeleteTransformFeedbacks	(2, tfID);
1862			expectError					(GL_NO_ERROR);
1863		});
1864	ES3F_ADD_API_CASE(end_transform_feedback, "Invalid glEndTransformFeedback() usage",
1865		{
1866			GLuint						tfID;
1867			glu::ShaderProgram			program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1868			deUint32					buf;
1869			const char* tfVarying		= "gl_Position";
1870
1871			glGenBuffers				(1, &buf);
1872			glGenTransformFeedbacks		(1, &tfID);
1873
1874			glUseProgram				(program.getProgram());
1875			glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1876			glLinkProgram				(program.getProgram());
1877			glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
1878			glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1879			glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1880			glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1881			expectError					(GL_NO_ERROR);
1882
1883			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is not active.");
1884			glEndTransformFeedback		();
1885			expectError					(GL_INVALID_OPERATION);
1886			glBeginTransformFeedback	(GL_TRIANGLES);
1887			glEndTransformFeedback		();
1888			expectError					(GL_NO_ERROR);
1889			m_log << tcu::TestLog::EndSection;
1890
1891			glDeleteBuffers				(1, &buf);
1892			glDeleteTransformFeedbacks	(1, &tfID);
1893			expectError					(GL_NO_ERROR);
1894		});
1895	ES3F_ADD_API_CASE(get_transform_feedback_varying, "Invalid glGetTransformFeedbackVarying() usage",
1896		{
1897			GLuint					tfID;
1898			glu::ShaderProgram		program			(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1899			glu::ShaderProgram		programInvalid	(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, ""));
1900			const char* tfVarying	= "gl_Position";
1901			int						maxTransformFeedbackVaryings = 0;
1902
1903			GLsizei					length;
1904			GLsizei					size;
1905			GLenum					type;
1906			char					name[32];
1907
1908			glGenTransformFeedbacks			(1, &tfID);
1909
1910			glTransformFeedbackVaryings		(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1911			expectError						(GL_NO_ERROR);
1912			glLinkProgram					(program.getProgram());
1913			expectError						(GL_NO_ERROR);
1914
1915			glBindTransformFeedback			(GL_TRANSFORM_FEEDBACK, tfID);
1916			expectError						(GL_NO_ERROR);
1917
1918			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if program is not the name of a program object.");
1919			glGetTransformFeedbackVarying	(-1, 0, 32, &length, &size, &type, &name[0]);
1920			expectError						(GL_INVALID_VALUE);
1921			m_log << tcu::TestLog::EndSection;
1922
1923			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater or equal to the value of GL_TRANSFORM_FEEDBACK_VARYINGS.");
1924			glGetProgramiv					(program.getProgram(), GL_TRANSFORM_FEEDBACK_VARYINGS, &maxTransformFeedbackVaryings);
1925			glGetTransformFeedbackVarying	(program.getProgram(), maxTransformFeedbackVaryings, 32, &length, &size, &type, &name[0]);
1926			expectError						(GL_INVALID_VALUE);
1927			m_log << tcu::TestLog::EndSection;
1928
1929			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION or GL_INVALID_VALUE is generated program has not been linked.");
1930			glGetTransformFeedbackVarying	(programInvalid.getProgram(), 0, 32, &length, &size, &type, &name[0]);
1931			expectError						(GL_INVALID_OPERATION, GL_INVALID_VALUE);
1932			m_log << tcu::TestLog::EndSection;
1933
1934			glDeleteTransformFeedbacks		(1, &tfID);
1935			expectError						(GL_NO_ERROR);
1936		});
1937	ES3F_ADD_API_CASE(transform_feedback_varyings, "Invalid glTransformFeedbackVaryings() usage",
1938		{
1939			GLuint					tfID;
1940			glu::ShaderProgram		program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1941			const char* tfVarying	= "gl_Position";
1942			GLint					maxTransformFeedbackSeparateAttribs = 0;
1943
1944			glGenTransformFeedbacks			(1, &tfID);
1945			expectError						(GL_NO_ERROR);
1946
1947			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if program is not the name of a program object.");
1948			glTransformFeedbackVaryings		(0, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1949			expectError						(GL_INVALID_VALUE);
1950			m_log << tcu::TestLog::EndSection;
1951
1952			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if bufferMode is GL_SEPARATE_ATTRIBS and count is greater than GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.");
1953			glGetIntegerv					(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxTransformFeedbackSeparateAttribs);
1954			glTransformFeedbackVaryings		(program.getProgram(), maxTransformFeedbackSeparateAttribs+1, &tfVarying, GL_SEPARATE_ATTRIBS);
1955			expectError						(GL_INVALID_VALUE);
1956			m_log << tcu::TestLog::EndSection;
1957
1958			glDeleteTransformFeedbacks		(1, &tfID);
1959			expectError						(GL_NO_ERROR);
1960		});
1961}
1962
1963} // Functional
1964} // gles3
1965} // deqp
1966