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