1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 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 "es31fNegativeVertexArrayApiTests.hpp"
25#include "gluCallLogWrapper.hpp"
26#include "gluContextInfo.hpp"
27#include "gluShaderProgram.hpp"
28#include "glwDefs.hpp"
29#include "glwEnums.hpp"
30#include "tcuStringTemplate.hpp"
31
32namespace deqp
33{
34
35using std::string;
36using std::map;
37
38namespace gles31
39{
40namespace Functional
41{
42namespace NegativeTestShared
43{
44
45using tcu::TestLog;
46using glu::CallLogWrapper;
47using namespace glw;
48
49static const char* vertexShaderSource		=	"${GLSL_VERSION_STRING}\n"
50												"void main (void)\n"
51												"{\n"
52												"	gl_Position = vec4(0.0);\n"
53												"}\n\0";
54
55static const char* fragmentShaderSource		=	"${GLSL_VERSION_STRING}\n"
56												"layout(location = 0) out mediump vec4 fragColor;"
57												"void main (void)\n"
58												"{\n"
59												"	fragColor = vec4(0.0);\n"
60												"}\n\0";
61
62static const char* geometryShaderSource		=	"#version 320 es\n"
63												"layout(points) in;\n"
64												"layout(points, max_vertices = 3) out;\n"
65												"void main (void)\n"
66												"{\n"
67												"}\n";
68
69void vertex_attribf (NegativeTestContext& ctx)
70{
71	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
72	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
73	ctx.glVertexAttrib1f(maxVertexAttribs, 0.0f);
74	ctx.expectError(GL_INVALID_VALUE);
75	ctx.glVertexAttrib2f(maxVertexAttribs, 0.0f, 0.0f);
76	ctx.expectError(GL_INVALID_VALUE);
77	ctx.glVertexAttrib3f(maxVertexAttribs, 0.0f, 0.0f, 0.0f);
78	ctx.expectError(GL_INVALID_VALUE);
79	ctx.glVertexAttrib4f(maxVertexAttribs, 0.0f, 0.0f, 0.0f, 0.0f);
80	ctx.expectError(GL_INVALID_VALUE);
81	ctx.endSection();
82}
83
84void vertex_attribfv (NegativeTestContext& ctx)
85{
86	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
87	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
88	float v[4] = {0.0f};
89	ctx.glVertexAttrib1fv(maxVertexAttribs, &v[0]);
90	ctx.expectError(GL_INVALID_VALUE);
91	ctx.glVertexAttrib2fv(maxVertexAttribs, &v[0]);
92	ctx.expectError(GL_INVALID_VALUE);
93	ctx.glVertexAttrib3fv(maxVertexAttribs, &v[0]);
94	ctx.expectError(GL_INVALID_VALUE);
95	ctx.glVertexAttrib4fv(maxVertexAttribs, &v[0]);
96	ctx.expectError(GL_INVALID_VALUE);
97	ctx.endSection();
98}
99
100void vertex_attribi4 (NegativeTestContext& ctx)
101{
102	int maxVertexAttribs	= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
103	GLint valInt			= 0;
104	GLuint valUint			= 0;
105
106	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
107	ctx.glVertexAttribI4i(maxVertexAttribs, valInt, valInt, valInt, valInt);
108	ctx.expectError(GL_INVALID_VALUE);
109	ctx.glVertexAttribI4ui(maxVertexAttribs, valUint, valUint, valUint, valUint);
110	ctx.expectError(GL_INVALID_VALUE);
111	ctx.endSection();
112}
113
114void vertex_attribi4v (NegativeTestContext& ctx)
115{
116	int maxVertexAttribs	= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
117	GLint valInt[4]			= { 0 };
118	GLuint valUint[4]		= { 0 };
119
120	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
121	ctx.glVertexAttribI4iv(maxVertexAttribs, &valInt[0]);
122	ctx.expectError(GL_INVALID_VALUE);
123	ctx.glVertexAttribI4uiv(maxVertexAttribs, &valUint[0]);
124	ctx.expectError(GL_INVALID_VALUE);
125	ctx.endSection();
126}
127
128void vertex_attrib_pointer (NegativeTestContext& ctx)
129{
130	ctx.beginSection("GL_INVALID_ENUM is generated if type is not an accepted value.");
131	ctx.glVertexAttribPointer(0, 1, 0, GL_TRUE, 0, 0);
132	ctx.expectError(GL_INVALID_ENUM);
133	ctx.endSection();
134
135	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
136	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
137	ctx.glVertexAttribPointer(maxVertexAttribs, 1, GL_BYTE, GL_TRUE, 0, 0);
138	ctx.expectError(GL_INVALID_VALUE);
139	ctx.endSection();
140
141	ctx.beginSection("GL_INVALID_VALUE is generated if size is not 1, 2, 3, or 4.");
142	ctx.glVertexAttribPointer(0, 0, GL_BYTE, GL_TRUE, 0, 0);
143	ctx.expectError(GL_INVALID_VALUE);
144	ctx.endSection();
145
146	ctx.beginSection("GL_INVALID_VALUE is generated if stride is negative.");
147	ctx.glVertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, -1, 0);
148	ctx.expectError(GL_INVALID_VALUE);
149	ctx.endSection();
150
151	ctx.beginSection("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.");
152	ctx.glVertexAttribPointer(0, 2, GL_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
153	ctx.expectError(GL_INVALID_OPERATION);
154	ctx.glVertexAttribPointer(0, 2, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
155	ctx.expectError(GL_INVALID_OPERATION);
156	ctx.glVertexAttribPointer(0, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
157	ctx.expectError(GL_NO_ERROR);
158	ctx.glVertexAttribPointer(0, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
159	ctx.expectError(GL_NO_ERROR);
160	ctx.endSection();
161
162	ctx.beginSection("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.");
163	GLuint vao = 0;
164	GLbyte offset = 1;
165	ctx.glGenVertexArrays(1, &vao);
166	ctx.glBindVertexArray(vao);
167	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
168	ctx.expectError(GL_NO_ERROR);
169
170	ctx.glVertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, &offset);
171	ctx.expectError(GL_INVALID_OPERATION);
172
173	ctx.glBindVertexArray(0);
174	ctx.glDeleteVertexArrays(1, &vao);
175	ctx.expectError(GL_NO_ERROR);
176	ctx.endSection();
177}
178
179void vertex_attrib_i_pointer (NegativeTestContext& ctx)
180{
181	ctx.beginSection("GL_INVALID_ENUM is generated if type is not an accepted value.");
182	ctx.glVertexAttribIPointer(0, 1, 0, 0, 0);
183	ctx.expectError(GL_INVALID_ENUM);
184	ctx.glVertexAttribIPointer(0, 4, GL_INT_2_10_10_10_REV, 0, 0);
185	ctx.expectError(GL_INVALID_ENUM);
186	ctx.glVertexAttribIPointer(0, 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 0);
187	ctx.expectError(GL_INVALID_ENUM);
188	ctx.endSection();
189
190	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
191	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
192	ctx.glVertexAttribIPointer(maxVertexAttribs, 1, GL_BYTE, 0, 0);
193	ctx.expectError(GL_INVALID_VALUE);
194	ctx.endSection();
195
196	ctx.beginSection("GL_INVALID_VALUE is generated if size is not 1, 2, 3, or 4.");
197	ctx.glVertexAttribIPointer(0, 0, GL_BYTE, 0, 0);
198	ctx.expectError(GL_INVALID_VALUE);
199	ctx.endSection();
200
201	ctx.beginSection("GL_INVALID_VALUE is generated if stride is negative.");
202	ctx.glVertexAttribIPointer(0, 1, GL_BYTE, -1, 0);
203	ctx.expectError(GL_INVALID_VALUE);
204	ctx.endSection();
205
206	ctx.beginSection("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.");
207	GLuint vao = 0;
208	GLbyte offset = 1;
209	ctx.glGenVertexArrays(1, &vao);
210	ctx.glBindVertexArray(vao);
211	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
212	ctx.expectError(GL_NO_ERROR);
213
214	ctx.glVertexAttribIPointer(0, 1, GL_BYTE, 0, &offset);
215	ctx.expectError(GL_INVALID_OPERATION);
216
217	ctx.glBindVertexArray(0);
218	ctx.glDeleteVertexArrays(1, &vao);
219	ctx.expectError(GL_NO_ERROR);
220	ctx.endSection();
221}
222
223void vertex_attrib_format (NegativeTestContext& ctx)
224{
225	int		maxVertexAttribs				= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
226	int		maxVertexAttribRelativeOffset	= ctx.getInteger(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
227	GLuint	vao								= 0;
228
229	ctx.beginSection("GL_INVALID_VALUE is generated if attribindex is greater than or equal to the value of MAX_VERTEX_ATTRIBS.");
230	ctx.glGenVertexArrays(1, &vao);
231	ctx.glBindVertexArray(vao);
232	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
233	ctx.glVertexAttribFormat(maxVertexAttribs, 4, GL_FLOAT, GL_FALSE, maxVertexAttribRelativeOffset);
234	ctx.expectError(GL_INVALID_VALUE);
235	ctx.endSection();
236
237	ctx.beginSection("GL_INVALID_VALUE is generated if size is not one of 1, 2, 3, 4.");
238	ctx.glGenVertexArrays(1, &vao);
239	ctx.glBindVertexArray(vao);
240	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
241	ctx.glVertexAttribFormat(1, 0, GL_FLOAT, GL_FALSE, maxVertexAttribRelativeOffset);
242	ctx.expectError(GL_INVALID_VALUE);
243	ctx.endSection();
244
245	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the parameter token names allowed.");
246	ctx.glGenVertexArrays(1, &vao);
247	ctx.glBindVertexArray(vao);
248	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
249	ctx.glVertexAttribFormat(1, 4, 1, GL_FALSE, 0);
250	ctx.expectError(GL_INVALID_ENUM);
251	ctx.endSection();
252
253	ctx.beginSection("GL_INVALID_OPERATION is generated if type is not a token name allowed.");
254	ctx.glGenVertexArrays(1, &vao);
255	ctx.glBindVertexArray(0);
256	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
257	ctx.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 0);
258	ctx.expectError(GL_INVALID_OPERATION);
259	ctx.endSection();
260
261	ctx.beginSection("GL_INVALID_OPERATION is generated if type is GL_INT_2_10_10_10_REV and size is not 4.");
262	ctx.glGenVertexArrays(1, &vao);
263	ctx.glBindVertexArray(vao);
264	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
265	ctx.glVertexAttribFormat(1, 3, GL_INT_2_10_10_10_REV, GL_FALSE, 0);
266	ctx.expectError(GL_INVALID_OPERATION);
267	ctx.endSection();
268
269	ctx.beginSection("GL_INVALID_OPERATION is generated if type is GL_UNSIGNED_INT_2_10_10_10_REV and size is not 4.");
270	ctx.glGenVertexArrays(1, &vao);
271	ctx.glBindVertexArray(vao);
272	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
273	ctx.glVertexAttribFormat(1, 3, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 0);
274	ctx.expectError(GL_INVALID_OPERATION);
275	ctx.endSection();
276
277	ctx.beginSection("GL_INVALID_VALUE is generated if relativeoffset is larger than the value of GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
278	ctx.glGenVertexArrays(1, &vao);
279	ctx.glBindVertexArray(vao);
280	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
281	ctx.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, maxVertexAttribRelativeOffset + 1);
282	ctx.expectError(GL_INVALID_VALUE);
283	ctx.endSection();
284}
285
286void vertex_attrib_i_format (NegativeTestContext& ctx)
287{
288	int		maxVertexAttribs				= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
289	int		maxVertexAttribRelativeOffset	= ctx.getInteger(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
290	GLuint	vao								= 0;
291
292	ctx.beginSection("GL_INVALID_VALUE is generated if attribindex is greater than or equal to the value of GL_MAX_VERTEX_ATTRIBS.");
293	ctx.glGenVertexArrays(1, &vao);
294	ctx.glBindVertexArray(vao);
295	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
296	ctx.glVertexAttribIFormat(maxVertexAttribs, 4, GL_INT, 0);
297	ctx.expectError(GL_INVALID_VALUE);
298	ctx.endSection();
299
300	ctx.beginSection("GL_INVALID_VALUE is generated if size is not one the values 1, 2, 3, 4.");
301	ctx.glGenVertexArrays(1, &vao);
302	ctx.glBindVertexArray(vao);
303	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
304	ctx.glVertexAttribIFormat(1, 0, GL_INT, 0);
305	ctx.expectError(GL_INVALID_VALUE);
306	ctx.endSection();
307
308	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the parameter token names allowed.");
309	ctx.glGenVertexArrays(1, &vao);
310	ctx.glBindVertexArray(vao);
311	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
312	ctx.glVertexAttribIFormat(1, 4, GL_FLOAT, 0);
313	ctx.expectError(GL_INVALID_ENUM);
314	ctx.endSection();
315
316	ctx.beginSection("GL_INVALID_OPERATION is generated if type is not a token name allowed.");
317	ctx.glGenVertexArrays(1, &vao);
318	ctx.glBindVertexArray(0);
319	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
320	ctx.glVertexAttribIFormat(1, 4, GL_INT, 0);
321	ctx.expectError(GL_INVALID_OPERATION);
322	ctx.endSection();
323
324	ctx.beginSection("GL_INVALID_VALUE is generated if relativeoffset is larger than the value of GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
325	ctx.glGenVertexArrays(1, &vao);
326	ctx.glBindVertexArray(vao);
327	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
328	ctx.glVertexAttribIFormat(1, 4, GL_INT, maxVertexAttribRelativeOffset + 1);
329	ctx.expectError(GL_INVALID_VALUE);
330	ctx.endSection();
331}
332
333void enable_vertex_attrib_array (NegativeTestContext& ctx)
334{
335	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
336
337	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
338	ctx.glEnableVertexAttribArray(maxVertexAttribs);
339	ctx.expectError(GL_INVALID_VALUE);
340	ctx.endSection();
341}
342
343void disable_vertex_attrib_array (NegativeTestContext& ctx)
344{
345	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
346
347	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
348	ctx.glDisableVertexAttribArray(maxVertexAttribs);
349	ctx.expectError(GL_INVALID_VALUE);
350	ctx.endSection();
351}
352
353void gen_vertex_arrays (NegativeTestContext& ctx)
354{
355	GLuint arrays = 0;
356
357	ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
358	ctx.glGenVertexArrays(-1, &arrays);
359	ctx.expectError(GL_INVALID_VALUE);
360	ctx.endSection();
361}
362
363void bind_vertex_array (NegativeTestContext& ctx)
364{
365	ctx.beginSection("GL_INVALID_OPERATION is generated if array is not zero or the name of an existing vertex array object.");
366	ctx.glBindVertexArray(-1);
367	ctx.expectError(GL_INVALID_OPERATION);
368	ctx.endSection();
369}
370
371void delete_vertex_arrays (NegativeTestContext& ctx)
372{
373	ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
374	ctx.glDeleteVertexArrays(-1, 0);
375	ctx.expectError(GL_INVALID_VALUE);
376	ctx.endSection();
377}
378
379void vertex_attrib_divisor (NegativeTestContext& ctx)
380{
381	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
382
383	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
384	ctx.glVertexAttribDivisor(maxVertexAttribs, 0);
385	ctx.expectError(GL_INVALID_VALUE);
386	ctx.endSection();
387}
388
389void draw_arrays (NegativeTestContext& ctx)
390{
391	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
392	GLuint						fbo		= 0;
393	map<string, string>			args;
394	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
395	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
396
397	ctx.glUseProgram(program.getProgram());
398	ctx.expectError(GL_NO_ERROR);
399
400	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
401	ctx.glDrawArrays(-1, 0, 1);
402	ctx.expectError(GL_INVALID_ENUM);
403	ctx.endSection();
404
405	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
406	ctx.glDrawArrays(GL_POINTS, 0, -1);
407	ctx.expectError(GL_INVALID_VALUE);
408	ctx.endSection();
409
410	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
411	ctx.glGenFramebuffers(1, &fbo);
412	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
413	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
414	ctx.glDrawArrays(GL_POINTS, 0, 1);
415	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
416	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
417	ctx.glDeleteFramebuffers(1, &fbo);
418	ctx.endSection();
419
420	ctx.glUseProgram(0);
421}
422
423void draw_arrays_invalid_program (NegativeTestContext& ctx)
424{
425	GLuint fbo = 0;
426	ctx.glUseProgram(0);
427
428	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
429	ctx.glDrawArrays(-1, 0, 1);
430	ctx.expectError(GL_INVALID_ENUM);
431	ctx.endSection();
432
433	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
434	ctx.glDrawArrays(GL_POINTS, 0, -1);
435	ctx.expectError(GL_INVALID_VALUE);
436	ctx.endSection();
437
438	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
439	ctx.glGenFramebuffers(1, &fbo);
440	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
441	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
442	ctx.glDrawArrays(GL_POINTS, 0, 1);
443	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
444	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
445	ctx.glDeleteFramebuffers(1, &fbo);
446	ctx.endSection();
447}
448
449void draw_arrays_incomplete_primitive (NegativeTestContext& ctx)
450{
451	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
452	GLuint						fbo		= 0;
453	map<string, string>			args;
454	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
455	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
456
457	ctx.glUseProgram(program.getProgram());
458	ctx.expectError(GL_NO_ERROR);
459
460	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
461	ctx.glDrawArrays(-1, 0, 1);
462	ctx.expectError(GL_INVALID_ENUM);
463	ctx.endSection();
464
465	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
466	ctx.glDrawArrays(GL_TRIANGLES, 0, -1);
467	ctx.expectError(GL_INVALID_VALUE);
468	ctx.endSection();
469
470	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
471	ctx.glGenFramebuffers(1, &fbo);
472	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
473	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
474	ctx.glDrawArrays(GL_TRIANGLES, 0, 1);
475	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
476	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
477	ctx.glDeleteFramebuffers(1, &fbo);
478	ctx.endSection();
479
480	ctx.glUseProgram(0);
481}
482
483void draw_elements (NegativeTestContext& ctx)
484{
485	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
486	GLuint						fbo		= 0;
487	GLuint						buf		= 0;
488	GLuint						tfID	= 0;
489	GLfloat						vertices[1];
490	map<string, string>			args;
491	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
492	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
493
494	ctx.glUseProgram(program.getProgram());
495	ctx.expectError(GL_NO_ERROR);
496
497	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
498	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
499	ctx.expectError(GL_INVALID_ENUM);
500	ctx.endSection();
501
502	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
503	ctx.glDrawElements(GL_POINTS, 1, -1, vertices);
504	ctx.expectError(GL_INVALID_ENUM);
505	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, vertices);
506	ctx.expectError(GL_INVALID_ENUM);
507	ctx.endSection();
508
509	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
510	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices);
511	ctx.expectError(GL_INVALID_VALUE);
512	ctx.endSection();
513
514	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
515	ctx.glGenFramebuffers(1, &fbo);
516	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
517	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
518	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
519	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
520	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
521	ctx.glDeleteFramebuffers(1, &fbo);
522	ctx.endSection();
523
524	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
525	{
526		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
527		const char* tfVarying = "gl_Position";
528
529		ctx.glGenBuffers(1, &buf);
530		ctx.glGenTransformFeedbacks(1, &tfID);
531
532		ctx.glUseProgram(program.getProgram());
533		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
534		ctx.glLinkProgram(program.getProgram());
535		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
536		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
537		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
538		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
539		ctx.glBeginTransformFeedback(GL_POINTS);
540		ctx.expectError(GL_NO_ERROR);
541
542		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
543		ctx.expectError(GL_INVALID_OPERATION);
544
545		ctx.glPauseTransformFeedback();
546		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
547		ctx.expectError(GL_NO_ERROR);
548
549		ctx.glEndTransformFeedback();
550		ctx.glDeleteBuffers(1, &buf);
551		ctx.glDeleteTransformFeedbacks(1, &tfID);
552		ctx.expectError(GL_NO_ERROR);
553		ctx.endSection();
554	}
555
556	ctx.glUseProgram(0);
557}
558
559void draw_elements_invalid_program (NegativeTestContext& ctx)
560{
561	ctx.glUseProgram(0);
562	GLuint	fbo = 0;
563	GLfloat	vertices[1];
564
565	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
566	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
567	ctx.expectError(GL_INVALID_ENUM);
568	ctx.endSection();
569
570	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
571	ctx.glDrawElements(GL_POINTS, 1, -1, vertices);
572	ctx.expectError(GL_INVALID_ENUM);
573	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, vertices);
574	ctx.expectError(GL_INVALID_ENUM);
575	ctx.endSection();
576
577	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
578	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices);
579	ctx.expectError(GL_INVALID_VALUE);
580	ctx.endSection();
581
582	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
583	ctx.glGenFramebuffers(1, &fbo);
584	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
585	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
586	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices);
587	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
588	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
589	ctx.glDeleteFramebuffers(1, &fbo);
590	ctx.endSection();
591}
592
593void draw_elements_incomplete_primitive (NegativeTestContext& ctx)
594{
595	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
596	GLuint						fbo		= 0;
597	GLuint						buf		= 0;
598	GLuint						tfID	= 0;
599	GLfloat						vertices[1];
600	map<string, string>			args;
601	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
602	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
603
604	ctx.glUseProgram(program.getProgram());
605	ctx.expectError(GL_NO_ERROR);
606
607	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
608	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, vertices);
609	ctx.expectError(GL_INVALID_ENUM);
610	ctx.endSection();
611
612	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
613	ctx.glDrawElements(GL_TRIANGLES, 1, -1, vertices);
614	ctx.expectError(GL_INVALID_ENUM);
615	ctx.glDrawElements(GL_TRIANGLES, 1, GL_FLOAT, vertices);
616	ctx.expectError(GL_INVALID_ENUM);
617	ctx.endSection();
618
619	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
620	ctx.glDrawElements(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, vertices);
621	ctx.expectError(GL_INVALID_VALUE);
622	ctx.endSection();
623
624	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
625	ctx.glGenFramebuffers(1, &fbo);
626	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
627	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
628	ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
629	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
630	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
631	ctx.glDeleteFramebuffers(1, &fbo);
632	ctx.endSection();
633
634	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
635	{
636		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
637		const char* tfVarying= "gl_Position";
638
639		ctx.glGenBuffers(1, &buf);
640		ctx.glGenTransformFeedbacks(1, &tfID);
641
642		ctx.glUseProgram(program.getProgram());
643		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
644		ctx.glLinkProgram(program.getProgram());
645		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
646		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
647		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
648		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
649		ctx.glBeginTransformFeedback(GL_TRIANGLES);
650		ctx.expectError(GL_NO_ERROR);
651
652		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
653		ctx.expectError(GL_INVALID_OPERATION);
654
655		ctx.glPauseTransformFeedback();
656		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices);
657		ctx.expectError(GL_NO_ERROR);
658
659		ctx.glEndTransformFeedback();
660		ctx.glDeleteBuffers(1, &buf);
661		ctx.glDeleteTransformFeedbacks(1, &tfID);
662		ctx.expectError(GL_NO_ERROR);
663		ctx.endSection();
664	}
665
666	ctx.glUseProgram(0);
667}
668
669void draw_elements_base_vertex (NegativeTestContext& ctx)
670{
671	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
672
673	GLuint				fbo = 0;
674	GLfloat				vertices[1];
675
676	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
677	ctx.glDrawElementsBaseVertex(-1, 1, GL_UNSIGNED_INT, vertices, 1);
678	ctx.expectError(GL_INVALID_ENUM);
679	ctx.endSection();
680
681	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
682	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, -1, vertices, 1);
683	ctx.expectError(GL_INVALID_ENUM);
684	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_FLOAT, vertices, 1);
685	ctx.expectError(GL_INVALID_ENUM);
686	ctx.endSection();
687
688	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
689	ctx.glDrawElementsBaseVertex(GL_POINTS, -1, GL_UNSIGNED_INT, vertices, 1);
690	ctx.expectError(GL_INVALID_VALUE);
691	ctx.endSection();
692
693	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
694	ctx.glGenFramebuffers(1, &fbo);
695	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
696	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
697	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_UNSIGNED_INT, vertices, 1);
698	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
699	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
700	ctx.glDeleteFramebuffers(1, &fbo);
701	ctx.endSection();
702}
703
704void draw_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
705{
706	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
707
708	GLfloat						vertices[1];
709	map<string, string>			args;
710	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
711
712	glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
713
714	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
715	ctx.glUseProgram(program.getProgram());
716	ctx.glDrawElementsBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1);
717	ctx.expectError(GL_INVALID_OPERATION);
718	ctx.endSection();
719
720	ctx.glUseProgram(0);
721}
722
723void draw_arrays_instanced (NegativeTestContext& ctx)
724{
725	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
726	GLuint						fbo		= 0;
727	map<string, string>			args;
728	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
729	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
730
731	ctx.glUseProgram(program.getProgram());
732	ctx.expectError(GL_NO_ERROR);
733	ctx.glVertexAttribDivisor(0, 1);
734	ctx.expectError(GL_NO_ERROR);
735
736	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
737	ctx.glDrawArraysInstanced(-1, 0, 1, 1);
738	ctx.expectError(GL_INVALID_ENUM);
739	ctx.endSection();
740
741	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
742	ctx.glDrawArraysInstanced(GL_POINTS, 0, -1, 1);
743	ctx.expectError(GL_INVALID_VALUE);
744	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, -1);
745	ctx.expectError(GL_INVALID_VALUE);
746	ctx.endSection();
747
748	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
749	ctx.glGenFramebuffers(1, &fbo);
750	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
751	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
752	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, 1);
753	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
754	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
755	ctx.glDeleteFramebuffers(1, &fbo);
756	ctx.endSection();
757
758	ctx.glUseProgram(0);
759}
760
761void draw_arrays_instanced_invalid_program (NegativeTestContext& ctx)
762{
763	ctx.glUseProgram(0);
764	GLuint fbo = 0;
765	ctx.glVertexAttribDivisor(0, 1);
766	ctx.expectError(GL_NO_ERROR);
767
768	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
769	ctx.glDrawArraysInstanced(-1, 0, 1, 1);
770	ctx.expectError(GL_INVALID_ENUM);
771	ctx.endSection();
772
773	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
774	ctx.glDrawArraysInstanced(GL_POINTS, 0, -1, 1);
775	ctx.expectError(GL_INVALID_VALUE);
776	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, -1);
777	ctx.expectError(GL_INVALID_VALUE);
778	ctx.endSection();
779
780	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
781	ctx.glGenFramebuffers(1, &fbo);
782	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
783	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
784	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, 1);
785	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
786	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
787	ctx.glDeleteFramebuffers(1, &fbo);
788	ctx.endSection();
789}
790
791void draw_arrays_instanced_incomplete_primitive (NegativeTestContext& ctx)
792{
793	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
794	GLuint						fbo		= 0;
795	map<string, string>			args;
796	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
797	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
798
799	ctx.glVertexAttribDivisor(0, 1);
800	ctx.expectError(GL_NO_ERROR);
801
802	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
803	ctx.glDrawArraysInstanced(-1, 0, 1, 1);
804	ctx.expectError(GL_INVALID_ENUM);
805	ctx.endSection();
806
807	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
808	ctx.glDrawArraysInstanced(GL_TRIANGLES, 0, -1, 1);
809	ctx.expectError(GL_INVALID_VALUE);
810	ctx.glDrawArraysInstanced(GL_TRIANGLES, 0, 1, -1);
811	ctx.expectError(GL_INVALID_VALUE);
812	ctx.endSection();
813
814	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
815	ctx.glGenFramebuffers(1, &fbo);
816	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
817	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
818	ctx.glDrawArraysInstanced(GL_TRIANGLES, 0, 1, 1);
819	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
820	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
821	ctx.glDeleteFramebuffers(1, &fbo);
822	ctx.endSection();
823
824	ctx.glUseProgram(0);
825}
826
827void draw_elements_instanced (NegativeTestContext& ctx)
828{
829	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
830	GLuint						fbo		= 0;
831	GLuint						buf		= 0;
832	GLuint						tfID	= 0;
833	GLfloat						vertices[1];
834	map<string, string>			args;
835	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
836	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
837
838	ctx.glUseProgram(program.getProgram());
839	ctx.glVertexAttribDivisor(0, 1);
840	ctx.expectError(GL_NO_ERROR);
841
842	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
843	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
844	ctx.expectError(GL_INVALID_ENUM);
845	ctx.endSection();
846
847	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
848	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, vertices, 1);
849	ctx.expectError(GL_INVALID_ENUM);
850	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, vertices, 1);
851	ctx.expectError(GL_INVALID_ENUM);
852	ctx.endSection();
853
854	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
855	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1);
856	ctx.expectError(GL_INVALID_VALUE);
857	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1);
858	ctx.expectError(GL_INVALID_VALUE);
859	ctx.endSection();
860
861	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
862	ctx.glGenFramebuffers(1, &fbo);
863	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
864	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
865	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
866	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
867	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
868	ctx.glDeleteFramebuffers(1, &fbo);
869	ctx.endSection();
870
871	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
872	{
873		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
874		const char* tfVarying = "gl_Position";
875
876		ctx.glGenBuffers(1, &buf);
877		ctx.glGenTransformFeedbacks(1, &tfID);
878
879		ctx.glUseProgram(program.getProgram());
880		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
881		ctx.glLinkProgram(program.getProgram());
882		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
883		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
884		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
885		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
886		ctx.glBeginTransformFeedback(GL_POINTS);
887		ctx.expectError(GL_NO_ERROR);
888
889		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
890		ctx.expectError(GL_INVALID_OPERATION);
891
892		ctx.glPauseTransformFeedback();
893		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
894		ctx.expectError(GL_NO_ERROR);
895
896		ctx.glEndTransformFeedback();
897		ctx.glDeleteBuffers(1, &buf);
898		ctx.glDeleteTransformFeedbacks(1, &tfID);
899		ctx.expectError(GL_NO_ERROR);
900		ctx.endSection();
901	}
902
903	ctx.glUseProgram(0);
904}
905
906void draw_elements_instanced_invalid_program (NegativeTestContext& ctx)
907{
908	ctx.glUseProgram(0);
909	GLuint fbo = 0;
910	GLfloat vertices[1];
911	ctx.glVertexAttribDivisor(0, 1);
912	ctx.expectError(GL_NO_ERROR);
913
914	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
915	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
916	ctx.expectError(GL_INVALID_ENUM);
917	ctx.endSection();
918
919	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
920	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, vertices, 1);
921	ctx.expectError(GL_INVALID_ENUM);
922	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, vertices, 1);
923	ctx.expectError(GL_INVALID_ENUM);
924	ctx.endSection();
925
926	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
927	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1);
928	ctx.expectError(GL_INVALID_VALUE);
929	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1);
930	ctx.expectError(GL_INVALID_VALUE);
931	ctx.endSection();
932
933	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
934	ctx.glGenFramebuffers(1, &fbo);
935	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
936	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
937	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1);
938	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
939	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
940	ctx.glDeleteFramebuffers(1, &fbo);
941	ctx.endSection();
942}
943
944void draw_elements_instanced_incomplete_primitive (NegativeTestContext& ctx)
945{
946	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
947	GLuint						fbo		= 0;
948	GLuint						buf		= 0;
949	GLuint						tfID	= 0;
950	GLfloat						vertices[1];
951	map<string, string>			args;
952	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
953	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
954
955	ctx.glUseProgram(program.getProgram());
956	ctx.glVertexAttribDivisor(0, 1);
957	ctx.expectError(GL_NO_ERROR);
958
959	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
960	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, vertices, 1);
961	ctx.expectError(GL_INVALID_ENUM);
962	ctx.endSection();
963
964	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
965	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, -1, vertices, 1);
966	ctx.expectError(GL_INVALID_ENUM);
967	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_FLOAT, vertices, 1);
968	ctx.expectError(GL_INVALID_ENUM);
969	ctx.endSection();
970
971	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
972	ctx.glDrawElementsInstanced(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, vertices, 1);
973	ctx.expectError(GL_INVALID_VALUE);
974	ctx.glDrawElementsInstanced(GL_TRIANGLES, 11, GL_UNSIGNED_BYTE, vertices, -1);
975	ctx.expectError(GL_INVALID_VALUE);
976	ctx.endSection();
977
978	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
979	ctx.glGenFramebuffers(1, &fbo);
980	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
981	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
982	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
983	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
984	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
985	ctx.glDeleteFramebuffers(1, &fbo);
986	ctx.endSection();
987
988	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
989	{
990		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
991		const char* tfVarying= "gl_Position";
992
993		ctx.glGenBuffers(1, &buf);
994		ctx.glGenTransformFeedbacks(1, &tfID);
995
996		ctx.glUseProgram(program.getProgram());
997		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
998		ctx.glLinkProgram(program.getProgram());
999		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
1000		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1001		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1002		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1003		ctx.glBeginTransformFeedback(GL_TRIANGLES);
1004		ctx.expectError(GL_NO_ERROR);
1005
1006		ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
1007		ctx.expectError(GL_INVALID_OPERATION);
1008
1009		ctx.glPauseTransformFeedback();
1010		ctx.glDrawElementsInstanced	(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, vertices, 1);
1011		ctx.expectError(GL_NO_ERROR);
1012
1013		ctx.glEndTransformFeedback();
1014		ctx.glDeleteBuffers(1, &buf);
1015		ctx.glDeleteTransformFeedbacks(1, &tfID);
1016		ctx.expectError(GL_NO_ERROR);
1017		ctx.endSection();
1018	}
1019
1020	ctx.glUseProgram(0);
1021}
1022
1023void draw_elements_instanced_base_vertex (NegativeTestContext& ctx)
1024{
1025	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
1026
1027	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
1028	GLuint						fbo		= 0;
1029	GLfloat						vertices[1];
1030	map<string, string>			args;
1031	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1032	glu::ShaderProgram			program			(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
1033
1034	ctx.glUseProgram(program.getProgram());
1035	ctx.glVertexAttribDivisor(0, 1);
1036	ctx.expectError(GL_NO_ERROR);
1037
1038	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
1039	ctx.glDrawElementsInstancedBaseVertex(-1, 1, GL_UNSIGNED_BYTE, vertices, 1, 1);
1040	ctx.expectError(GL_INVALID_ENUM);
1041	ctx.endSection();
1042
1043	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
1044	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, -1, vertices, 1, 1);
1045	ctx.expectError(GL_INVALID_ENUM);
1046	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_FLOAT, vertices, 1, 1);
1047	ctx.expectError(GL_INVALID_ENUM);
1048	ctx.endSection();
1049
1050	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
1051	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, -1, GL_UNSIGNED_BYTE, vertices, 1, 1);
1052	ctx.expectError(GL_INVALID_VALUE);
1053	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 11, GL_UNSIGNED_BYTE, vertices, -1, 1);
1054	ctx.expectError(GL_INVALID_VALUE);
1055	ctx.endSection();
1056
1057	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
1058	ctx.glGenFramebuffers(1, &fbo);
1059	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1060	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1061	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_UNSIGNED_BYTE, vertices, 1, 1);
1062	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
1063	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1064	ctx.glDeleteFramebuffers(1, &fbo);
1065	ctx.endSection();
1066
1067	ctx.glUseProgram(0);
1068}
1069
1070void draw_elements_instanced_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
1071{
1072	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
1073
1074	GLfloat						vertices[1];
1075	map<string, string>			args;
1076	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
1077	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
1078
1079	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
1080	ctx.glUseProgram(geometryProgram.getProgram());
1081	ctx.glDrawElementsInstancedBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1, 1);
1082	ctx.expectError(GL_INVALID_OPERATION);
1083	ctx.endSection();
1084
1085	ctx.glUseProgram(0);
1086}
1087
1088void draw_range_elements (NegativeTestContext& ctx)
1089{
1090	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
1091	GLuint						fbo		= 0;
1092	GLuint						buf		= 0;
1093	GLuint						tfID	= 0;
1094	GLfloat						vertices[1];
1095	map<string, string>			args;
1096	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1097	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
1098
1099	ctx.glUseProgram(program.getProgram());
1100	ctx.expectError(GL_NO_ERROR);
1101
1102	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
1103	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1104	ctx.expectError(GL_INVALID_ENUM);
1105	ctx.endSection();
1106
1107	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
1108	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
1109	ctx.expectError(GL_INVALID_ENUM);
1110	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
1111	ctx.expectError(GL_INVALID_ENUM);
1112	ctx.endSection();
1113
1114	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
1115	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
1116	ctx.expectError(GL_INVALID_VALUE);
1117	ctx.endSection();
1118
1119	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
1120	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
1121	ctx.expectError(GL_INVALID_VALUE);
1122	ctx.endSection();
1123
1124	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
1125	ctx.glGenFramebuffers(1, &fbo);
1126	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1127	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1128	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1129	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
1130	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1131	ctx.glDeleteFramebuffers(1, &fbo);
1132	ctx.endSection();
1133
1134	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
1135	{
1136		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
1137		const char* tfVarying= "gl_Position";
1138
1139		ctx.glGenBuffers(1, &buf);
1140		ctx.glGenTransformFeedbacks(1, &tfID);
1141
1142		ctx.glUseProgram(program.getProgram());
1143		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1144		ctx.glLinkProgram(program.getProgram());
1145		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
1146		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1147		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1148		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1149		ctx.glBeginTransformFeedback(GL_POINTS);
1150		ctx.expectError(GL_NO_ERROR);
1151
1152		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1153		ctx.expectError(GL_INVALID_OPERATION);
1154
1155		ctx.glPauseTransformFeedback();
1156		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1157		ctx.expectError(GL_NO_ERROR);
1158
1159		ctx.glEndTransformFeedback();
1160		ctx.glDeleteBuffers(1, &buf);
1161		ctx.glDeleteTransformFeedbacks(1, &tfID);
1162		ctx.expectError(GL_NO_ERROR);
1163		ctx.endSection();
1164	}
1165
1166	ctx.glUseProgram(0);
1167}
1168
1169void draw_range_elements_invalid_program (NegativeTestContext& ctx)
1170{
1171	ctx.glUseProgram(0);
1172	GLuint fbo = 0;
1173	GLfloat vertices[1];
1174
1175	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
1176	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1177	ctx.expectError(GL_INVALID_ENUM);
1178	ctx.endSection();
1179
1180	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
1181	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, vertices);
1182	ctx.expectError(GL_INVALID_ENUM);
1183	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices);
1184	ctx.expectError(GL_INVALID_ENUM);
1185	ctx.endSection();
1186
1187	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
1188	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
1189	ctx.expectError(GL_INVALID_VALUE);
1190	ctx.endSection();
1191
1192	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
1193	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
1194	ctx.expectError(GL_INVALID_VALUE);
1195	ctx.endSection();
1196
1197	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
1198	ctx.glGenFramebuffers(1, &fbo);
1199	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1200	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1201	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1202	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
1203	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1204	ctx.glDeleteFramebuffers(1, &fbo);
1205	ctx.endSection();
1206}
1207
1208void draw_range_elements_incomplete_primitive (NegativeTestContext& ctx)
1209{
1210	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
1211	GLuint						fbo		= 0;
1212	GLuint						buf		= 0;
1213	GLuint						tfID	= 0;
1214	GLfloat						vertices[1];
1215	map<string, string>			args;
1216	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1217	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
1218
1219	ctx.glUseProgram(program.getProgram());
1220	ctx.expectError(GL_NO_ERROR);
1221
1222	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
1223	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1224	ctx.expectError(GL_INVALID_ENUM);
1225	ctx.endSection();
1226
1227	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
1228	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, -1, vertices);
1229	ctx.expectError(GL_INVALID_ENUM);
1230	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_FLOAT, vertices);
1231	ctx.expectError(GL_INVALID_ENUM);
1232	ctx.endSection();
1233
1234	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
1235	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, -1, GL_UNSIGNED_BYTE, vertices);
1236	ctx.expectError(GL_INVALID_VALUE);
1237	ctx.endSection();
1238
1239	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
1240	ctx.glDrawRangeElements(GL_TRIANGLES, 1, 0, 1, GL_UNSIGNED_BYTE, vertices);
1241	ctx.expectError(GL_INVALID_VALUE);
1242	ctx.endSection();
1243
1244	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
1245	ctx.glGenFramebuffers(1, &fbo);
1246	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1247	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1248	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1249	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
1250	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1251	ctx.glDeleteFramebuffers(1, &fbo);
1252	ctx.endSection();
1253
1254	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
1255	{
1256		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
1257		const char* tfVarying = "gl_Position";
1258
1259		ctx.glGenBuffers(1, &buf);
1260		ctx.glGenTransformFeedbacks(1, &tfID);
1261
1262		ctx.glUseProgram(program.getProgram());
1263		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1264		ctx.glLinkProgram(program.getProgram());
1265		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
1266		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1267		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1268		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1269		ctx.glBeginTransformFeedback(GL_TRIANGLES);
1270		ctx.expectError(GL_NO_ERROR);
1271
1272		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1273		ctx.expectError(GL_INVALID_OPERATION);
1274
1275		ctx.glPauseTransformFeedback();
1276		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, vertices);
1277		ctx.expectError(GL_NO_ERROR);
1278
1279		ctx.glEndTransformFeedback();
1280		ctx.glDeleteBuffers(1, &buf);
1281		ctx.glDeleteTransformFeedbacks(1, &tfID);
1282		ctx.expectError(GL_NO_ERROR);
1283		ctx.endSection();
1284	}
1285
1286	ctx.glUseProgram(0);
1287}
1288
1289void draw_range_elements_base_vertex (NegativeTestContext& ctx)
1290{
1291	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
1292
1293	GLuint						fbo		= 0;
1294	GLfloat						vertices[1];
1295	map<string, string>			args;
1296	args["GLSL_VERSION_STRING"]			= getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
1297	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
1298
1299	ctx.glUseProgram(program.getProgram());
1300	ctx.expectError(GL_NO_ERROR);
1301
1302	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
1303	ctx.glDrawRangeElementsBaseVertex(-1, 0, 1, 1, GL_UNSIGNED_BYTE, vertices, 1);
1304	ctx.expectError(GL_INVALID_ENUM);
1305	ctx.endSection();
1306
1307	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
1308	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, -1, vertices, 1);
1309	ctx.expectError(GL_INVALID_ENUM);
1310	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_FLOAT, vertices, 1);
1311	ctx.expectError(GL_INVALID_ENUM);
1312	ctx.endSection();
1313
1314	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
1315	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, vertices, 1);
1316	ctx.expectError(GL_INVALID_VALUE);
1317	ctx.endSection();
1318
1319	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
1320	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, vertices, 1);
1321	ctx.expectError(GL_INVALID_VALUE);
1322	ctx.endSection();
1323
1324	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
1325	ctx.glGenFramebuffers(1, &fbo);
1326	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1327	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
1328	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, vertices, 1);
1329	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
1330	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
1331	ctx.glDeleteFramebuffers(1, &fbo);
1332	ctx.endSection();
1333
1334	ctx.glUseProgram(0);
1335}
1336
1337void draw_range_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
1338{
1339	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
1340
1341	GLfloat						vertices[1];
1342	map<string, string>			args;
1343	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
1344	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
1345
1346	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
1347	ctx.glUseProgram(geometryProgram.getProgram());
1348	ctx.glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_INT, vertices, 1);
1349	ctx.expectError(GL_INVALID_OPERATION);
1350	ctx.endSection();
1351
1352	ctx.glUseProgram(0);
1353}
1354
1355std::vector<FunctionContainer> getNegativeVertexArrayApiTestFunctions ()
1356{
1357	FunctionContainer funcs[] =
1358	{
1359		{vertex_attribf,												"vertex_attribf",												"Invalid glVertexAttrib{1234}f() usage"				},
1360		{vertex_attribfv,												"vertex_attribfv",												"Invalid glVertexAttrib{1234}fv() usage"			},
1361		{vertex_attribi4,												"vertex_attribi4",												"Invalid glVertexAttribI4{i|ui}f() usage"			},
1362		{vertex_attribi4v,												"vertex_attribi4v",												"Invalid glVertexAttribI4{i|ui}fv() usage"			},
1363		{vertex_attrib_pointer,											"vertex_attrib_pointer",										"Invalid glVertexAttribPointer() usage"				},
1364		{vertex_attrib_i_pointer,										"vertex_attrib_i_pointer",										"Invalid glVertexAttribPointer() usage"				},
1365		{vertex_attrib_format,											"vertex_attrib_format",											"Invalid glVertexAttribFormat() usage"				},
1366		{vertex_attrib_i_format,										"vertex_attrib_i_format",										"Invalid glVertexAttribIFormat() usage"				},
1367		{enable_vertex_attrib_array,									"enable_vertex_attrib_array",									"Invalid glEnableVertexAttribArray() usage"			},
1368		{disable_vertex_attrib_array,									"disable_vertex_attrib_array",									"Invalid glDisableVertexAttribArray() usage"		},
1369		{gen_vertex_arrays,												"gen_vertex_arrays",											"Invalid glGenVertexArrays() usage"					},
1370		{bind_vertex_array,												"bind_vertex_array",											"Invalid glBindVertexArray() usage"					},
1371		{delete_vertex_arrays,											"delete_vertex_arrays",											"Invalid glDeleteVertexArrays() usage"				},
1372		{vertex_attrib_divisor,											"vertex_attrib_divisor",										"Invalid glVertexAttribDivisor() usage"				},
1373		{draw_arrays,													"draw_arrays",													"Invalid glDrawArrays() usage"						},
1374		{draw_arrays_invalid_program,									"draw_arrays_invalid_program",									"Invalid glDrawArrays() usage"						},
1375		{draw_arrays_incomplete_primitive,								"draw_arrays_incomplete_primitive",								"Invalid glDrawArrays() usage"						},
1376		{draw_elements,													"draw_elements",												"Invalid glDrawElements() usage"					},
1377		{draw_elements_base_vertex,										"draw_elements_base_vertex",									"Invalid glDrawElementsBaseVertex() usage"			},
1378		{draw_elements_base_vertex_primitive_mode_mismatch,				"draw_elements_base_vertex_primitive_mode_mismatch",			"Invalid glDrawElementsBaseVertex() usage"			},
1379		{draw_elements_invalid_program,									"draw_elements_invalid_program",								"Invalid glDrawElements() usage"					},
1380		{draw_elements_incomplete_primitive,							"draw_elements_incomplete_primitive",							"Invalid glDrawElements() usage"					},
1381		{draw_arrays_instanced,											"draw_arrays_instanced",										"Invalid glDrawArraysInstanced() usage"				},
1382		{draw_arrays_instanced_invalid_program,							"draw_arrays_instanced_invalid_program",						"Invalid glDrawArraysInstanced() usage"				},
1383		{draw_arrays_instanced_incomplete_primitive,					"draw_arrays_instanced_incomplete_primitive",					"Invalid glDrawArraysInstanced() usage"				},
1384		{draw_elements_instanced,										"draw_elements_instanced",										"Invalid glDrawElementsInstanced() usage"			},
1385		{draw_elements_instanced_invalid_program,						"draw_elements_instanced_invalid_program",						"Invalid glDrawElementsInstanced() usage"			},
1386		{draw_elements_instanced_incomplete_primitive,					"draw_elements_instanced_incomplete_primitive",					"Invalid glDrawElementsInstanced() usage"			},
1387		{draw_elements_instanced_base_vertex,							"draw_elements_instanced_base_vertex",							"Invalid glDrawElementsInstancedBaseVertex() usage"	},
1388		{draw_elements_instanced_base_vertex_primitive_mode_mismatch,	"draw_elements_instanced_base_vertex_primitive_mode_mismatch",	"Invalid glDrawElementsInstancedBaseVertex() usage"	},
1389		{draw_range_elements,											"draw_range_elements",											"Invalid glDrawRangeElements() usage"				},
1390		{draw_range_elements_invalid_program,							"draw_range_elements_invalid_program",							"Invalid glDrawRangeElements() usage"				},
1391		{draw_range_elements_incomplete_primitive,						"draw_range_elements_incomplete_primitive",						"Invalid glDrawRangeElements() usage"				},
1392		{draw_range_elements_base_vertex,								"draw_range_elements_base_vertex",								"Invalid glDrawRangeElementsBaseVertex() usage"		},
1393		{draw_range_elements_base_vertex_primitive_mode_mismatch,		"draw_range_elements_base_vertex_primitive_mode_mismatch",		"Invalid glDrawRangeElementsBaseVertex() usage"		},
1394	};
1395
1396	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
1397}
1398
1399} // NegativeTestShared
1400} // Functional
1401} // gles31
1402} // deqp
1403