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 Vertex Array API tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fNegativeVertexArrayApiTests.hpp"
25 #include "es3fApiCase.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "gluContextInfo.hpp"
28 #include "deString.h"
29 
30 #include "glwDefs.hpp"
31 #include "glwEnums.hpp"
32 
33 using namespace glw; // GL types
34 
35 namespace deqp
36 {
37 namespace gles3
38 {
39 namespace Functional
40 {
41 
42 static const char* vertexShaderSource		=	"#version 300 es\n"
43 												"void main (void)\n"
44 												"{\n"
45 												"	gl_Position = vec4(0.0);\n"
46 												"}\n\0";
47 
48 static const char* fragmentShaderSource		=	"#version 300 es\n"
49 												"layout(location = 0) out mediump vec4 fragColor;"
50 												"void main (void)\n"
51 												"{\n"
52 												"	fragColor = vec4(0.0);\n"
53 												"}\n\0";
54 
55 using tcu::TestLog;
56 
57 // Helper class that enables tests to be executed on GL4.5 context
58 // and removes code redundancy in each test that requires it.
59 class VAOHelper: protected glu::CallLogWrapper
60 {
61 public:
VAOHelper(Context& ctx)62 	VAOHelper(Context& ctx)
63 		: CallLogWrapper(ctx.getRenderContext().getFunctions(), ctx.getTestContext().getLog())
64 		, m_vao(0)
65 	{
66 		// tests need vao only for GL4.5 context
67 		if (glu::isContextTypeES(ctx.getRenderContext().getType()))
68 			return;
69 
70 		glGenVertexArrays(1, &m_vao);
71 		glBindVertexArray(m_vao);
72 		glVertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, NULL);
73 		glEnableVertexAttribArray(0);
74 	}
75 
~VAOHelper()76 	~VAOHelper()
77 	{
78 		if (m_vao)
79 			glDeleteVertexArrays(1, &m_vao);
80 	}
81 
82 private:
83 	GLuint		m_vao;
84 };
85 
NegativeVertexArrayApiTests(Context& context)86 NegativeVertexArrayApiTests::NegativeVertexArrayApiTests (Context& context)
87 	: TestCaseGroup(context, "vertex_array", "Negative Vertex Array API Cases")
88 {
89 }
90 
~NegativeVertexArrayApiTests(void)91 NegativeVertexArrayApiTests::~NegativeVertexArrayApiTests (void)
92 {
93 }
94 
init(void)95 void NegativeVertexArrayApiTests::init (void)
96 {
97 	ES3F_ADD_API_CASE(vertex_attribf, "Invalid glVertexAttrib{1234}f() usage",
98 		{
99 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
100 			int maxVertexAttribs = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
101 			glVertexAttrib1f(maxVertexAttribs, 0.0f);
102 			expectError(GL_INVALID_VALUE);
103 			glVertexAttrib2f(maxVertexAttribs, 0.0f, 0.0f);
104 			expectError(GL_INVALID_VALUE);
105 			glVertexAttrib3f(maxVertexAttribs, 0.0f, 0.0f, 0.0f);
106 			expectError(GL_INVALID_VALUE);
107 			glVertexAttrib4f(maxVertexAttribs, 0.0f, 0.0f, 0.0f, 0.0f);
108 			expectError(GL_INVALID_VALUE);
109 			m_log << tcu::TestLog::EndSection;
110 		});
111 	ES3F_ADD_API_CASE(vertex_attribfv, "Invalid glVertexAttrib{1234}fv() usage",
112 		{
113 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
114 			int maxVertexAttribs = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
115 			float v[4] = {0.0f};
116 			glVertexAttrib1fv(maxVertexAttribs, &v[0]);
117 			expectError(GL_INVALID_VALUE);
118 			glVertexAttrib2fv(maxVertexAttribs, &v[0]);
119 			expectError(GL_INVALID_VALUE);
120 			glVertexAttrib3fv(maxVertexAttribs, &v[0]);
121 			expectError(GL_INVALID_VALUE);
122 			glVertexAttrib4fv(maxVertexAttribs, &v[0]);
123 			expectError(GL_INVALID_VALUE);
124 			m_log << tcu::TestLog::EndSection;
125 		});
126 	ES3F_ADD_API_CASE(vertex_attribi4, "Invalid glVertexAttribI4{i|ui}f() usage",
127 		{
128 			int maxVertexAttribs	= m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
129 			GLint valInt			= 0;
130 			GLuint valUint			= 0;
131 
132 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
133 			glVertexAttribI4i(maxVertexAttribs, valInt, valInt, valInt, valInt);
134 			expectError(GL_INVALID_VALUE);
135 			glVertexAttribI4ui(maxVertexAttribs, valUint, valUint, valUint, valUint);
136 			expectError(GL_INVALID_VALUE);
137 			m_log << tcu::TestLog::EndSection;
138 		});
139 	ES3F_ADD_API_CASE(vertex_attribi4v, "Invalid glVertexAttribI4{i|ui}fv() usage",
140 		{
141 			int maxVertexAttribs	= m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
142 			GLint valInt[4]			= { 0 };
143 			GLuint valUint[4]		= { 0 };
144 
145 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
146 			glVertexAttribI4iv(maxVertexAttribs, &valInt[0]);
147 			expectError(GL_INVALID_VALUE);
148 			glVertexAttribI4uiv(maxVertexAttribs, &valUint[0]);
149 			expectError(GL_INVALID_VALUE);
150 			m_log << tcu::TestLog::EndSection;
151 		});
152 	ES3F_ADD_API_CASE(vertex_attrib_pointer, "Invalid glVertexAttribPointer() usage",
153 		{
154 			GLuint vao = 0;
155 			glGenVertexArrays(1, &vao);
156 			if (glu::isContextTypeES(m_context.getRenderContext().getType()))
157 				glBindVertexArray(0);
158 			else
159 				glBindVertexArray(vao);
160 
161 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not an accepted value.");
162 			glVertexAttribPointer(0, 1, 0, GL_TRUE, 0, 0);
163 			expectError(GL_INVALID_ENUM);
164 			m_log << tcu::TestLog::EndSection;
165 
166 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
167 			int maxVertexAttribs = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
168 			glVertexAttribPointer(maxVertexAttribs, 1, GL_BYTE, GL_TRUE, 0, 0);
169 			expectError(GL_INVALID_VALUE);
170 			m_log << tcu::TestLog::EndSection;
171 
172 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if size is not 1, 2, 3, or 4.");
173 			glVertexAttribPointer(0, 0, GL_BYTE, GL_TRUE, 0, 0);
174 			expectError(GL_INVALID_VALUE);
175 			m_log << tcu::TestLog::EndSection;
176 
177 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if stride is negative.");
178 			glVertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, -1, 0);
179 			expectError(GL_INVALID_VALUE);
180 			m_log << tcu::TestLog::EndSection;
181 
182 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if type is GL_INT_2_10_10_10_REV or GL_UNSIGNED_INT_2_10_10_10_REV and size is not 4.");
183 			glVertexAttribPointer(0, 2, GL_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
184 			expectError(GL_INVALID_OPERATION);
185 			glVertexAttribPointer(0, 2, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
186 			expectError(GL_INVALID_OPERATION);
187 			glVertexAttribPointer(0, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
188 			expectError(GL_NO_ERROR);
189 			glVertexAttribPointer(0, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
190 			expectError(GL_NO_ERROR);
191 			m_log << tcu::TestLog::EndSection;
192 
193 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated a non-zero vertex array object is bound, zero is bound to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.");
194 			GLbyte offset = 1;
195 			glBindVertexArray(vao);
196 			glBindBuffer(GL_ARRAY_BUFFER, 0);
197 			expectError(GL_NO_ERROR);
198 
199 			glVertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, &offset);
200 			expectError(GL_INVALID_OPERATION);
201 
202 			glBindVertexArray(0);
203 			glDeleteVertexArrays(1, &vao);
204 			expectError(GL_NO_ERROR);
205 			m_log << tcu::TestLog::EndSection;
206 		});
207 	ES3F_ADD_API_CASE(vertex_attrib_i_pointer, "Invalid glVertexAttribPointer() usage",
208 		{
209 			GLuint vao = 0;
210 			glGenVertexArrays(1, &vao);
211 			if (glu::isContextTypeES(m_context.getRenderContext().getType()))
212 				glBindVertexArray(0);
213 			else
214 				glBindVertexArray(vao);
215 
216 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not an accepted value.");
217 			glVertexAttribIPointer(0, 1, 0, 0, 0);
218 			expectError(GL_INVALID_ENUM);
219 			glVertexAttribIPointer(0, 4, GL_INT_2_10_10_10_REV, 0, 0);
220 			expectError(GL_INVALID_ENUM);
221 			glVertexAttribIPointer(0, 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 0);
222 			expectError(GL_INVALID_ENUM);
223 			m_log << tcu::TestLog::EndSection;
224 
225 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
226 			int maxVertexAttribs = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
227 			glVertexAttribIPointer(maxVertexAttribs, 1, GL_BYTE, 0, 0);
228 			expectError(GL_INVALID_VALUE);
229 			m_log << tcu::TestLog::EndSection;
230 
231 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if size is not 1, 2, 3, or 4.");
232 			glVertexAttribIPointer(0, 0, GL_BYTE, 0, 0);
233 			expectError(GL_INVALID_VALUE);
234 			m_log << tcu::TestLog::EndSection;
235 
236 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if stride is negative.");
237 			glVertexAttribIPointer(0, 1, GL_BYTE, -1, 0);
238 			expectError(GL_INVALID_VALUE);
239 			m_log << tcu::TestLog::EndSection;
240 
241 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated a non-zero vertex array object is bound, zero is bound to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.");
242 			GLbyte offset = 1;
243 			glBindVertexArray(vao);
244 			glBindBuffer(GL_ARRAY_BUFFER, 0);
245 			expectError(GL_NO_ERROR);
246 
247 			glVertexAttribIPointer(0, 1, GL_BYTE, 0, &offset);
248 			expectError(GL_INVALID_OPERATION);
249 
250 			glBindVertexArray(0);
251 			glDeleteVertexArrays(1, &vao);
252 			expectError(GL_NO_ERROR);
253 			m_log << tcu::TestLog::EndSection;
254 		});
255 	ES3F_ADD_API_CASE(enable_vertex_attrib_array, "Invalid glEnableVertexAttribArray() usage",
256 		{
257 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
258 			int maxVertexAttribs = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
259 			glEnableVertexAttribArray(maxVertexAttribs);
260 			expectError(GL_INVALID_VALUE);
261 			m_log << tcu::TestLog::EndSection;
262 		});
263 	ES3F_ADD_API_CASE(disable_vertex_attrib_array, "Invalid glDisableVertexAttribArray() usage",
264 		{
265 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
266 			int maxVertexAttribs = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
267 			glDisableVertexAttribArray(maxVertexAttribs);
268 			expectError(GL_INVALID_VALUE);
269 			m_log << tcu::TestLog::EndSection;
270 		});
271 	ES3F_ADD_API_CASE(gen_vertex_arrays, "Invalid glGenVertexArrays() usage",
272 		{
273 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
274 			GLuint arrays;
275 			glGenVertexArrays(-1, &arrays);
276 			expectError(GL_INVALID_VALUE);
277 			m_log << tcu::TestLog::EndSection;
278 		});
279 	ES3F_ADD_API_CASE(bind_vertex_array, "Invalid glBindVertexArray() usage",
280 		{
281 			m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if array is not zero or the name of an existing vertex array object.");
282 			glBindVertexArray(-1);
283 			expectError(GL_INVALID_OPERATION);
284 			m_log << tcu::TestLog::EndSection;
285 		});
286 	ES3F_ADD_API_CASE(delete_vertex_arrays, "Invalid glDeleteVertexArrays() usage",
287 		{
288 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
289 			glDeleteVertexArrays(-1, 0);
290 			expectError(GL_INVALID_VALUE);
291 			m_log << tcu::TestLog::EndSection;
292 		});
293 	ES3F_ADD_API_CASE(vertex_attrib_divisor, "Invalid glVertexAttribDivisor() usage",
294 		{
295 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
296 			int maxVertexAttribs = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
297 			glVertexAttribDivisor(maxVertexAttribs, 0);
298 			expectError(GL_INVALID_VALUE);
299 			m_log << tcu::TestLog::EndSection;
300 		});
301 	ES3F_ADD_API_CASE(draw_arrays, "Invalid glDrawArrays() usage",
302 		{
303 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
304 			glUseProgram(program.getProgram());
305 			GLuint fbo;
306 			VAOHelper vao(m_context);
307 
308 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
309 			glDrawArrays(-1, 0, 1);
310 			expectError(GL_INVALID_ENUM);
311 			m_log << tcu::TestLog::EndSection;
312 
313 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
314 			glDrawArrays(GL_POINTS, 0, -1);
315 			expectError(GL_INVALID_VALUE);
316 			m_log << tcu::TestLog::EndSection;
317 
318 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
319 			glGenFramebuffers(1, &fbo);
320 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
321 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
322 			glDrawArrays(GL_POINTS, 0, 1);
323 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
324 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
325 			glDeleteFramebuffers(1, &fbo);
326 			m_log << tcu::TestLog::EndSection;
327 
328 			glUseProgram(0);
329 		});
330 	ES3F_ADD_API_CASE(draw_arrays_invalid_program, "Invalid glDrawArrays() usage",
331 		{
332 			glUseProgram(0);
333 			GLuint fbo;
334 			VAOHelper vao(m_context);
335 
336 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
337 			glDrawArrays(-1, 0, 1);
338 			expectError(GL_INVALID_ENUM);
339 			m_log << tcu::TestLog::EndSection;
340 
341 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
342 			glDrawArrays(GL_POINTS, 0, -1);
343 			expectError(GL_INVALID_VALUE);
344 			m_log << tcu::TestLog::EndSection;
345 
346 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
347 			glGenFramebuffers(1, &fbo);
348 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
349 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
350 			glDrawArrays(GL_POINTS, 0, 1);
351 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
352 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
353 			glDeleteFramebuffers(1, &fbo);
354 			m_log << tcu::TestLog::EndSection;
355 		});
356 	ES3F_ADD_API_CASE(draw_arrays_incomplete_primitive, "Invalid glDrawArrays() usage",
357 		{
358 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
359 			glUseProgram(program.getProgram());
360 			GLuint fbo;
361 			VAOHelper vao(m_context);
362 
363 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
364 			glDrawArrays(-1, 0, 1);
365 			expectError(GL_INVALID_ENUM);
366 			m_log << tcu::TestLog::EndSection;
367 
368 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
369 			glDrawArrays(GL_TRIANGLES, 0, -1);
370 			expectError(GL_INVALID_VALUE);
371 			m_log << tcu::TestLog::EndSection;
372 
373 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
374 			glGenFramebuffers(1, &fbo);
375 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
376 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
377 			glDrawArrays(GL_TRIANGLES, 0, 1);
378 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
379 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
380 			glDeleteFramebuffers(1, &fbo);
381 			m_log << tcu::TestLog::EndSection;
382 
383 			glUseProgram(0);
384 		});
385 	ES3F_ADD_API_CASE(draw_elements, "Invalid glDrawElements() usage",
386 		{
387 			const bool isES	= glu::isContextTypeES(m_context.getRenderContext().getType());
388 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
389 			glUseProgram(program.getProgram());
390 			GLuint fbo;
391 			GLuint buf;
392 			GLuint tfID;
393 			GLfloat vertices[1] = { 0 };
394 			VAOHelper vao(m_context);
395 
396 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
397 			glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
398 			expectError(GL_INVALID_ENUM);
399 			m_log << tcu::TestLog::EndSection;
400 
401 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
402 			glDrawElements(GL_POINTS, 1, -1, vertices);
403 			expectError(GL_INVALID_ENUM);
404 			glDrawElements(GL_POINTS, 1, GL_FLOAT, vertices);
405 			expectError(GL_INVALID_ENUM);
406 			m_log << tcu::TestLog::EndSection;
407 
408 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
409 			glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices);
410 			expectError(GL_INVALID_VALUE);
411 			m_log << tcu::TestLog::EndSection;
412 
413 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
414 			glGenFramebuffers(1, &fbo);
415 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
416 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
417 			glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
418 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
419 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
420 			glDeleteFramebuffers(1, &fbo);
421 			m_log << tcu::TestLog::EndSection;
422 
423 			if (isES && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
424 			{
425 				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
426 				const char* tfVarying		= "gl_Position";
427 
428 				glGenBuffers				(1, &buf);
429 				glGenTransformFeedbacks		(1, &tfID);
430 
431 				glUseProgram				(program.getProgram());
432 				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
433 				glLinkProgram				(program.getProgram());
434 				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
435 				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
436 				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
437 				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
438 				glBeginTransformFeedback	(GL_POINTS);
439 				expectError					(GL_NO_ERROR);
440 
441 				glDrawElements				(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
442 				expectError					(GL_INVALID_OPERATION);
443 
444 				glPauseTransformFeedback();
445 				glDrawElements				(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
446 				expectError					(GL_NO_ERROR);
447 
448 				glEndTransformFeedback		();
449 				glDeleteBuffers				(1, &buf);
450 				glDeleteTransformFeedbacks	(1, &tfID);
451 				expectError					(GL_NO_ERROR);
452 				m_log << tcu::TestLog::EndSection;
453 			}
454 
455 			glUseProgram(0);
456 		});
457 	ES3F_ADD_API_CASE(draw_elements_invalid_program, "Invalid glDrawElements() usage",
458 		{
459 			glUseProgram(0);
460 			GLuint fbo;
461 			GLfloat vertices[1] = { 0 };
462 			VAOHelper vao(m_context);
463 
464 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
465 			glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
466 			expectError(GL_INVALID_ENUM);
467 			m_log << tcu::TestLog::EndSection;
468 
469 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
470 			glDrawElements(GL_POINTS, 1, -1, vertices);
471 			expectError(GL_INVALID_ENUM);
472 			glDrawElements(GL_POINTS, 1, GL_FLOAT, vertices);
473 			expectError(GL_INVALID_ENUM);
474 			m_log << tcu::TestLog::EndSection;
475 
476 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
477 			glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices);
478 			expectError(GL_INVALID_VALUE);
479 			m_log << tcu::TestLog::EndSection;
480 
481 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
482 			glGenFramebuffers(1, &fbo);
483 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
484 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
485 			glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
486 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
487 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
488 			glDeleteFramebuffers(1, &fbo);
489 			m_log << tcu::TestLog::EndSection;
490 		});
491 	ES3F_ADD_API_CASE(draw_elements_incomplete_primitive, "Invalid glDrawElements() usage",
492 		{
493 			const bool isES	= glu::isContextTypeES(m_context.getRenderContext().getType());
494 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
495 			glUseProgram(program.getProgram());
496 			GLuint fbo;
497 			GLuint buf;
498 			GLuint tfID;
499 			GLfloat vertices[1] = { 0 };
500 			VAOHelper vao(m_context);
501 
502 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
503 			glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
504 			expectError(GL_INVALID_ENUM);
505 			m_log << tcu::TestLog::EndSection;
506 
507 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
508 			glDrawElements(GL_TRIANGLES, 1, -1, vertices);
509 			expectError(GL_INVALID_ENUM);
510 			glDrawElements(GL_TRIANGLES, 1, GL_FLOAT, vertices);
511 			expectError(GL_INVALID_ENUM);
512 			m_log << tcu::TestLog::EndSection;
513 
514 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
515 			glDrawElements(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, vertices);
516 			expectError(GL_INVALID_VALUE);
517 			m_log << tcu::TestLog::EndSection;
518 
519 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
520 			glGenFramebuffers(1, &fbo);
521 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
522 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
523 			glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
524 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
525 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
526 			glDeleteFramebuffers(1, &fbo);
527 			m_log << tcu::TestLog::EndSection;
528 
529 			if (isES && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
530 			{
531 				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
532 				const char* tfVarying		= "gl_Position";
533 
534 				glGenBuffers				(1, &buf);
535 				glGenTransformFeedbacks		(1, &tfID);
536 
537 				glUseProgram				(program.getProgram());
538 				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
539 				glLinkProgram				(program.getProgram());
540 				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
541 				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
542 				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
543 				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
544 				glBeginTransformFeedback	(GL_TRIANGLES);
545 				expectError					(GL_NO_ERROR);
546 
547 				glDrawElements				(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
548 				expectError					(GL_INVALID_OPERATION);
549 
550 				glPauseTransformFeedback();
551 				glDrawElements				(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
552 				expectError					(GL_NO_ERROR);
553 
554 				glEndTransformFeedback		();
555 				glDeleteBuffers				(1, &buf);
556 				glDeleteTransformFeedbacks	(1, &tfID);
557 				expectError					(GL_NO_ERROR);
558 				m_log << tcu::TestLog::EndSection;
559 			}
560 
561 			glUseProgram(0);
562 		});
563 	ES3F_ADD_API_CASE(draw_arrays_instanced, "Invalid glDrawArraysInstanced() usage",
564 		{
565 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
566 			glUseProgram(program.getProgram());
567 			GLuint fbo;
568 			VAOHelper vao(m_context);
569 			glVertexAttribDivisor(0, 1);
570 			expectError(GL_NO_ERROR);
571 
572 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
573 			glDrawArraysInstanced(-1, 0, 1, 1);
574 			expectError(GL_INVALID_ENUM);
575 			m_log << tcu::TestLog::EndSection;
576 
577 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count or primcount are negative.");
578 			glDrawArraysInstanced(GL_POINTS, 0, -1, 1);
579 			expectError(GL_INVALID_VALUE);
580 			glDrawArraysInstanced(GL_POINTS, 0, 1, -1);
581 			expectError(GL_INVALID_VALUE);
582 			m_log << tcu::TestLog::EndSection;
583 
584 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
585 			glGenFramebuffers(1, &fbo);
586 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
587 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
588 			glDrawArraysInstanced(GL_POINTS, 0, 1, 1);
589 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
590 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
591 			glDeleteFramebuffers(1, &fbo);
592 			m_log << tcu::TestLog::EndSection;
593 
594 			glUseProgram(0);
595 		});
596 	ES3F_ADD_API_CASE(draw_arrays_instanced_invalid_program, "Invalid glDrawArraysInstanced() usage",
597 		{
598 			glUseProgram(0);
599 			GLuint fbo;
600 			VAOHelper vao(m_context);
601 			glVertexAttribDivisor(0, 1);
602 			expectError(GL_NO_ERROR);
603 
604 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
605 			glDrawArraysInstanced(-1, 0, 1, 1);
606 			expectError(GL_INVALID_ENUM);
607 			m_log << tcu::TestLog::EndSection;
608 
609 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count or primcount are negative.");
610 			glDrawArraysInstanced(GL_POINTS, 0, -1, 1);
611 			expectError(GL_INVALID_VALUE);
612 			glDrawArraysInstanced(GL_POINTS, 0, 1, -1);
613 			expectError(GL_INVALID_VALUE);
614 			m_log << tcu::TestLog::EndSection;
615 
616 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
617 			glGenFramebuffers(1, &fbo);
618 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
619 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
620 			glDrawArraysInstanced(GL_POINTS, 0, 1, 1);
621 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
622 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
623 			glDeleteFramebuffers(1, &fbo);
624 			m_log << tcu::TestLog::EndSection;
625 		});
626 	ES3F_ADD_API_CASE(draw_arrays_instanced_incomplete_primitive, "Invalid glDrawArraysInstanced() usage",
627 		{
628 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
629 			glUseProgram(program.getProgram());
630 			GLuint fbo;
631 			VAOHelper vao(m_context);
632 			glVertexAttribDivisor(0, 1);
633 			expectError(GL_NO_ERROR);
634 
635 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
636 			glDrawArraysInstanced(-1, 0, 1, 1);
637 			expectError(GL_INVALID_ENUM);
638 			m_log << tcu::TestLog::EndSection;
639 
640 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count or primcount are negative.");
641 			glDrawArraysInstanced(GL_TRIANGLES, 0, -1, 1);
642 			expectError(GL_INVALID_VALUE);
643 			glDrawArraysInstanced(GL_TRIANGLES, 0, 1, -1);
644 			expectError(GL_INVALID_VALUE);
645 			m_log << tcu::TestLog::EndSection;
646 
647 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
648 			glGenFramebuffers(1, &fbo);
649 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
650 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
651 			glDrawArraysInstanced(GL_TRIANGLES, 0, 1, 1);
652 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
653 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
654 			glDeleteFramebuffers(1, &fbo);
655 			m_log << tcu::TestLog::EndSection;
656 
657 			glUseProgram(0);
658 		});
659 	ES3F_ADD_API_CASE(draw_elements_instanced, "Invalid glDrawElementsInstanced() usage",
660 		{
661 			const bool isES	= glu::isContextTypeES(m_context.getRenderContext().getType());
662 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
663 			glUseProgram(program.getProgram());
664 			GLuint fbo;
665 			GLuint buf;
666 			GLuint tfID;
667 			GLfloat vertices[1] = { 0 };
668 			VAOHelper vao(m_context);
669 
670 			glVertexAttribDivisor(0, 1);
671 			expectError(GL_NO_ERROR);
672 
673 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
674 			glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
675 			expectError(GL_INVALID_ENUM);
676 			m_log << tcu::TestLog::EndSection;
677 
678 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
679 			glDrawElementsInstanced(GL_POINTS, 1, -1, vertices, 1);
680 			expectError(GL_INVALID_ENUM);
681 			glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, vertices, 1);
682 			expectError(GL_INVALID_ENUM);
683 			m_log << tcu::TestLog::EndSection;
684 
685 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count or primcount are negative.");
686 			glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1);
687 			expectError(GL_INVALID_VALUE);
688 			glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1);
689 			expectError(GL_INVALID_VALUE);
690 			m_log << tcu::TestLog::EndSection;
691 
692 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
693 			glGenFramebuffers(1, &fbo);
694 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
695 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
696 			glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
697 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
698 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
699 			glDeleteFramebuffers(1, &fbo);
700 			m_log << tcu::TestLog::EndSection;
701 
702 			if (isES && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
703 			{
704 				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
705 				const char* tfVarying		= "gl_Position";
706 
707 				glGenBuffers				(1, &buf);
708 				glGenTransformFeedbacks		(1, &tfID);
709 
710 				glUseProgram				(program.getProgram());
711 				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
712 				glLinkProgram				(program.getProgram());
713 				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
714 				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
715 				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
716 				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
717 				glBeginTransformFeedback	(GL_POINTS);
718 				expectError					(GL_NO_ERROR);
719 
720 				glDrawElementsInstanced		(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
721 				expectError					(GL_INVALID_OPERATION);
722 
723 				glPauseTransformFeedback();
724 				glDrawElementsInstanced		(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
725 				expectError					(GL_NO_ERROR);
726 
727 				glEndTransformFeedback		();
728 				glDeleteBuffers				(1, &buf);
729 				glDeleteTransformFeedbacks	(1, &tfID);
730 				expectError					(GL_NO_ERROR);
731 				m_log << tcu::TestLog::EndSection;
732 			}
733 
734 			glUseProgram(0);
735 		});
736 	ES3F_ADD_API_CASE(draw_elements_instanced_invalid_program, "Invalid glDrawElementsInstanced() usage",
737 		{
738 			glUseProgram(0);
739 			GLuint fbo;
740 			GLfloat vertices[1] = { 0 };
741 			VAOHelper vao(m_context);
742 			glVertexAttribDivisor(0, 1);
743 			expectError(GL_NO_ERROR);
744 
745 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
746 			glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
747 			expectError(GL_INVALID_ENUM);
748 			m_log << tcu::TestLog::EndSection;
749 
750 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
751 			glDrawElementsInstanced(GL_POINTS, 1, -1, vertices, 1);
752 			expectError(GL_INVALID_ENUM);
753 			glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, vertices, 1);
754 			expectError(GL_INVALID_ENUM);
755 			m_log << tcu::TestLog::EndSection;
756 
757 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count or primcount are negative.");
758 			glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1);
759 			expectError(GL_INVALID_VALUE);
760 			glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1);
761 			expectError(GL_INVALID_VALUE);
762 			m_log << tcu::TestLog::EndSection;
763 
764 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
765 			glGenFramebuffers(1, &fbo);
766 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
767 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
768 			glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
769 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
770 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
771 			glDeleteFramebuffers(1, &fbo);
772 			m_log << tcu::TestLog::EndSection;
773 		});
774 	ES3F_ADD_API_CASE(draw_elements_instanced_incomplete_primitive, "Invalid glDrawElementsInstanced() usage",
775 		{
776 			const bool isES	= glu::isContextTypeES(m_context.getRenderContext().getType());
777 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
778 			glUseProgram(program.getProgram());
779 			GLuint fbo;
780 			GLuint buf;
781 			GLuint tfID;
782 			GLfloat vertices[1] = { 0 };
783 			VAOHelper vao(m_context);
784 			glVertexAttribDivisor(0, 1);
785 			expectError(GL_NO_ERROR);
786 
787 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
788 			glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
789 			expectError(GL_INVALID_ENUM);
790 			m_log << tcu::TestLog::EndSection;
791 
792 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
793 			glDrawElementsInstanced(GL_TRIANGLES, 1, -1, vertices, 1);
794 			expectError(GL_INVALID_ENUM);
795 			glDrawElementsInstanced(GL_TRIANGLES, 1, GL_FLOAT, vertices, 1);
796 			expectError(GL_INVALID_ENUM);
797 			m_log << tcu::TestLog::EndSection;
798 
799 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count or primcount are negative.");
800 			glDrawElementsInstanced(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, vertices, 1);
801 			expectError(GL_INVALID_VALUE);
802 			glDrawElementsInstanced(GL_TRIANGLES, 11, GL_UNSIGNED_BYTE, vertices, -1);
803 			expectError(GL_INVALID_VALUE);
804 			m_log << tcu::TestLog::EndSection;
805 
806 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
807 			glGenFramebuffers(1, &fbo);
808 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
809 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
810 			glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
811 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
812 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
813 			glDeleteFramebuffers(1, &fbo);
814 			m_log << tcu::TestLog::EndSection;
815 
816 			if (isES && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
817 			{
818 				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
819 				const char* tfVarying		= "gl_Position";
820 
821 				glGenBuffers				(1, &buf);
822 				glGenTransformFeedbacks		(1, &tfID);
823 
824 				glUseProgram				(program.getProgram());
825 				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
826 				glLinkProgram				(program.getProgram());
827 				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
828 				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
829 				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
830 				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
831 				glBeginTransformFeedback	(GL_TRIANGLES);
832 				expectError					(GL_NO_ERROR);
833 
834 				glDrawElementsInstanced		(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
835 				expectError					(GL_INVALID_OPERATION);
836 
837 				glPauseTransformFeedback();
838 				glDrawElementsInstanced		(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
839 				expectError					(GL_NO_ERROR);
840 
841 				glEndTransformFeedback		();
842 				glDeleteBuffers				(1, &buf);
843 				glDeleteTransformFeedbacks	(1, &tfID);
844 				expectError					(GL_NO_ERROR);
845 				m_log << tcu::TestLog::EndSection;
846 			}
847 
848 			glUseProgram(0);
849 		});
850 	ES3F_ADD_API_CASE(draw_range_elements, "Invalid glDrawRangeElements() usage",
851 		{
852 			const bool isES	= glu::isContextTypeES(m_context.getRenderContext().getType());
853 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
854 			glUseProgram(program.getProgram());
855 			GLuint fbo;
856 			GLuint buf;
857 			GLuint tfID;
858 			deUint32 vertices[1];
859 			vertices[0] = 0xffffffffu;
860 			VAOHelper vao(m_context);
861 
862 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
863 			glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
864 			expectError(GL_INVALID_ENUM);
865 			m_log << tcu::TestLog::EndSection;
866 
867 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
868 			glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
869 			expectError(GL_INVALID_ENUM);
870 			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
871 			expectError(GL_INVALID_ENUM);
872 			m_log << tcu::TestLog::EndSection;
873 
874 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
875 			glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
876 			expectError(GL_INVALID_VALUE);
877 			m_log << tcu::TestLog::EndSection;
878 
879 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if end < start.");
880 			glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
881 			expectError(GL_INVALID_VALUE);
882 			m_log << tcu::TestLog::EndSection;
883 
884 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
885 			glGenFramebuffers(1, &fbo);
886 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
887 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
888 			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
889 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
890 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
891 			glDeleteFramebuffers(1, &fbo);
892 			m_log << tcu::TestLog::EndSection;
893 
894 			if (isES && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
895 			{
896 				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
897 				const char* tfVarying		= "gl_Position";
898 				deUint32 verticesInRange[1];
899 				verticesInRange[0]			= 0;
900 
901 				glGenBuffers				(1, &buf);
902 				glGenTransformFeedbacks		(1, &tfID);
903 
904 				glUseProgram				(program.getProgram());
905 				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
906 				glLinkProgram				(program.getProgram());
907 				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
908 				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
909 				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
910 				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
911 				glBeginTransformFeedback	(GL_POINTS);
912 				expectError					(GL_NO_ERROR);
913 
914 				glDrawRangeElements			(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
915 				expectError					(GL_INVALID_OPERATION);
916 
917 				glPauseTransformFeedback();
918 				glDrawRangeElements			(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, verticesInRange);
919 				expectError					(GL_NO_ERROR);
920 
921 				glEndTransformFeedback		();
922 				glDeleteBuffers				(1, &buf);
923 				glDeleteTransformFeedbacks	(1, &tfID);
924 				expectError					(GL_NO_ERROR);
925 				m_log << tcu::TestLog::EndSection;
926 			}
927 
928 			glUseProgram(0);
929 		});
930 	ES3F_ADD_API_CASE(draw_range_elements_invalid_program, "Invalid glDrawRangeElements() usage",
931 		{
932 			glUseProgram(0);
933 			GLuint fbo;
934 			deUint32 vertices[1];
935 			VAOHelper vao(m_context);
936 			vertices[0] = 0xffffffffu;
937 
938 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
939 			glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
940 			expectError(GL_INVALID_ENUM);
941 			m_log << tcu::TestLog::EndSection;
942 
943 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
944 			glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
945 			expectError(GL_INVALID_ENUM);
946 			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
947 			expectError(GL_INVALID_ENUM);
948 			m_log << tcu::TestLog::EndSection;
949 
950 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
951 			glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
952 			expectError(GL_INVALID_VALUE);
953 			m_log << tcu::TestLog::EndSection;
954 
955 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if end < start.");
956 			glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
957 			expectError(GL_INVALID_VALUE);
958 			m_log << tcu::TestLog::EndSection;
959 
960 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
961 			glGenFramebuffers(1, &fbo);
962 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
963 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
964 			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
965 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
966 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
967 			glDeleteFramebuffers(1, &fbo);
968 			m_log << tcu::TestLog::EndSection;
969 		});
970 	ES3F_ADD_API_CASE(draw_range_elements_incomplete_primitive, "Invalid glDrawRangeElements() usage",
971 		{
972 			const bool isES	= glu::isContextTypeES(m_context.getRenderContext().getType());
973 			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
974 			glUseProgram(program.getProgram());
975 			GLuint fbo;
976 			GLuint buf;
977 			GLuint tfID;
978 			deUint32 vertices[1];
979 			VAOHelper vao(m_context);
980 			vertices[0] = 0xffffffffu;
981 
982 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
983 			glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
984 			expectError(GL_INVALID_ENUM);
985 			m_log << tcu::TestLog::EndSection;
986 
987 			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
988 			glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, -1, vertices);
989 			expectError(GL_INVALID_ENUM);
990 			glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_FLOAT, vertices);
991 			expectError(GL_INVALID_ENUM);
992 			m_log << tcu::TestLog::EndSection;
993 
994 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
995 			glDrawRangeElements(GL_TRIANGLES, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
996 			expectError(GL_INVALID_VALUE);
997 			m_log << tcu::TestLog::EndSection;
998 
999 			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if end < start.");
1000 			glDrawRangeElements(GL_TRIANGLES, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
1001 			expectError(GL_INVALID_VALUE);
1002 			m_log << tcu::TestLog::EndSection;
1003 
1004 			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
1005 			glGenFramebuffers(1, &fbo);
1006 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1007 			glCheckFramebufferStatus(GL_FRAMEBUFFER);
1008 			glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1009 			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
1010 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
1011 			glDeleteFramebuffers(1, &fbo);
1012 			m_log << tcu::TestLog::EndSection;
1013 
1014 			if (isES && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
1015 			{
1016 				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
1017 				const char* tfVarying		= "gl_Position";
1018 				deUint32 verticesInRange[1];
1019 				verticesInRange[0]			= 0;
1020 
1021 				glGenBuffers				(1, &buf);
1022 				glGenTransformFeedbacks		(1, &tfID);
1023 
1024 				glUseProgram				(program.getProgram());
1025 				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1026 				glLinkProgram				(program.getProgram());
1027 				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
1028 				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1029 				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1030 				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1031 				glBeginTransformFeedback	(GL_TRIANGLES);
1032 				expectError					(GL_NO_ERROR);
1033 
1034 				glDrawRangeElements			(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1035 				expectError					(GL_INVALID_OPERATION);
1036 
1037 				glPauseTransformFeedback();
1038 				glDrawRangeElements			(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, verticesInRange);
1039 				expectError					(GL_NO_ERROR);
1040 
1041 				glEndTransformFeedback		();
1042 				glDeleteBuffers				(1, &buf);
1043 				glDeleteTransformFeedbacks	(1, &tfID);
1044 				expectError					(GL_NO_ERROR);
1045 				m_log << tcu::TestLog::EndSection;
1046 			}
1047 
1048 			glUseProgram(0);
1049 		});
1050 }
1051 
1052 } // Functional
1053 } // gles3
1054 } // deqp
1055