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