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