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