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