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