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