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