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
33using namespace glw; // GL types
34
35namespace deqp
36{
37namespace gles3
38{
39namespace Functional
40{
41
42static 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
48static 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
55using tcu::TestLog;
56
57NegativeVertexArrayApiTests::NegativeVertexArrayApiTests (Context& context)
58	: TestCaseGroup(context, "vertex_array", "Negative Vertex Array API Cases")
59{
60}
61
62NegativeVertexArrayApiTests::~NegativeVertexArrayApiTests (void)
63{
64}
65
66void 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			GLfloat vertices[1];
802
803			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
804			glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
805			expectError(GL_INVALID_ENUM);
806			m_log << tcu::TestLog::EndSection;
807
808			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
809			glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
810			expectError(GL_INVALID_ENUM);
811			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
812			expectError(GL_INVALID_ENUM);
813			m_log << tcu::TestLog::EndSection;
814
815			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
816			glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
817			expectError(GL_INVALID_VALUE);
818			m_log << tcu::TestLog::EndSection;
819
820			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if end < start.");
821			glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
822			expectError(GL_INVALID_VALUE);
823			m_log << tcu::TestLog::EndSection;
824
825			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
826			glGenFramebuffers(1, &fbo);
827			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
828			glCheckFramebufferStatus(GL_FRAMEBUFFER);
829			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
830			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
831			glBindFramebuffer(GL_FRAMEBUFFER, 0);
832			glDeleteFramebuffers(1, &fbo);
833			m_log << tcu::TestLog::EndSection;
834
835			if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
836			{
837				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
838				const char* tfVarying		= "gl_Position";
839
840				glGenBuffers				(1, &buf);
841				glGenTransformFeedbacks		(1, &tfID);
842
843				glUseProgram				(program.getProgram());
844				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
845				glLinkProgram				(program.getProgram());
846				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
847				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
848				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
849				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
850				glBeginTransformFeedback	(GL_POINTS);
851				expectError					(GL_NO_ERROR);
852
853				glDrawRangeElements			(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
854				expectError					(GL_INVALID_OPERATION);
855
856				glPauseTransformFeedback();
857				glDrawRangeElements			(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
858				expectError					(GL_NO_ERROR);
859
860				glEndTransformFeedback		();
861				glDeleteBuffers				(1, &buf);
862				glDeleteTransformFeedbacks	(1, &tfID);
863				expectError					(GL_NO_ERROR);
864				m_log << tcu::TestLog::EndSection;
865			}
866
867			glUseProgram(0);
868		});
869	ES3F_ADD_API_CASE(draw_range_elements_invalid_program, "Invalid glDrawRangeElements() usage",
870		{
871			glUseProgram(0);
872			GLuint fbo;
873			GLfloat vertices[1];
874
875			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
876			glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
877			expectError(GL_INVALID_ENUM);
878			m_log << tcu::TestLog::EndSection;
879
880			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
881			glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
882			expectError(GL_INVALID_ENUM);
883			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
884			expectError(GL_INVALID_ENUM);
885			m_log << tcu::TestLog::EndSection;
886
887			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
888			glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
889			expectError(GL_INVALID_VALUE);
890			m_log << tcu::TestLog::EndSection;
891
892			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if end < start.");
893			glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
894			expectError(GL_INVALID_VALUE);
895			m_log << tcu::TestLog::EndSection;
896
897			m_log << tcu::TestLog::Section("", "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
898			glGenFramebuffers(1, &fbo);
899			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
900			glCheckFramebufferStatus(GL_FRAMEBUFFER);
901			glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
902			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
903			glBindFramebuffer(GL_FRAMEBUFFER, 0);
904			glDeleteFramebuffers(1, &fbo);
905			m_log << tcu::TestLog::EndSection;
906		});
907	ES3F_ADD_API_CASE(draw_range_elements_incomplete_primitive, "Invalid glDrawRangeElements() usage",
908		{
909			glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
910			glUseProgram(program.getProgram());
911			GLuint fbo;
912			GLuint buf;
913			GLuint tfID;
914			GLfloat vertices[1];
915
916			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if mode is not an accepted value.");
917			glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
918			expectError(GL_INVALID_ENUM);
919			m_log << tcu::TestLog::EndSection;
920
921			m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if type is not one of the accepted values.");
922			glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, -1, vertices);
923			expectError(GL_INVALID_ENUM);
924			glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_FLOAT, vertices);
925			expectError(GL_INVALID_ENUM);
926			m_log << tcu::TestLog::EndSection;
927
928			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if count is negative.");
929			glDrawRangeElements(GL_TRIANGLES, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
930			expectError(GL_INVALID_VALUE);
931			m_log << tcu::TestLog::EndSection;
932
933			m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if end < start.");
934			glDrawRangeElements(GL_TRIANGLES, 1, 0, 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_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
939			glGenFramebuffers(1, &fbo);
940			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
941			glCheckFramebufferStatus(GL_FRAMEBUFFER);
942			glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
943			expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
944			glBindFramebuffer(GL_FRAMEBUFFER, 0);
945			glDeleteFramebuffers(1, &fbo);
946			m_log << tcu::TestLog::EndSection;
947
948			if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
949			{
950				m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
951				const char* tfVarying		= "gl_Position";
952
953				glGenBuffers				(1, &buf);
954				glGenTransformFeedbacks		(1, &tfID);
955
956				glUseProgram				(program.getProgram());
957				glTransformFeedbackVaryings	(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
958				glLinkProgram				(program.getProgram());
959				glBindTransformFeedback		(GL_TRANSFORM_FEEDBACK, tfID);
960				glBindBuffer				(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
961				glBufferData				(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
962				glBindBufferBase			(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
963				glBeginTransformFeedback	(GL_TRIANGLES);
964				expectError					(GL_NO_ERROR);
965
966				glDrawRangeElements			(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
967				expectError					(GL_INVALID_OPERATION);
968
969				glPauseTransformFeedback();
970				glDrawRangeElements			(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
971				expectError					(GL_NO_ERROR);
972
973				glEndTransformFeedback		();
974				glDeleteBuffers				(1, &buf);
975				glDeleteTransformFeedbacks	(1, &tfID);
976				expectError					(GL_NO_ERROR);
977				m_log << tcu::TestLog::EndSection;
978			}
979
980			glUseProgram(0);
981		});
982}
983
984} // Functional
985} // gles3
986} // deqp
987