tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

es3fNegativeVertexArrayApiTests.js (45685B)


      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 'use strict';
     24 goog.provide('functional.gles3.es3fNegativeVertexArrayApiTests');
     25 
     26 goog.require('framework.common.tcuTestCase');
     27 goog.require('framework.common.tcuTexture');
     28 goog.require('functional.gles3.es3fApiCase');
     29 goog.require('framework.opengl.gluShaderProgram');
     30 goog.require('framework.opengl.simplereference.sglrGLContext');
     31 
     32 goog.scope(function() {
     33 
     34    var es3fNegativeVertexArrayApiTests = functional.gles3.es3fNegativeVertexArrayApiTests;
     35    var tcuTexture = framework.common.tcuTexture;
     36    var es3fApiCase = functional.gles3.es3fApiCase;
     37    var tcuTestCase = framework.common.tcuTestCase;
     38    var gluShaderProgram = framework.opengl.gluShaderProgram;
     39    var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
     40 
     41    /**
     42     * @type {string}
     43     * @const
     44     */
     45    var vertexShaderSource = '#version 300 es\n' +
     46    'void main (void)\n' +
     47    '{\n' +
     48    ' gl_Position = vec4(0.0);\n' +
     49    '}\n';
     50 
     51    /**
     52     * @type {string}
     53     * @const
     54     */
     55    var fragmentShaderSource = '#version 300 es\n' +
     56    'layout(location = 0) out mediump vec4 fragColor;\n' +
     57    'void main (void)\n' +
     58    '{\n' +
     59    ' fragColor = vec4(0.0);\n' +
     60    '}\n';
     61 
     62    /**
     63    * @param {WebGL2RenderingContext} gl
     64    */
     65    es3fNegativeVertexArrayApiTests.init = function(gl) {
     66 
     67        var testGroup = tcuTestCase.runner.testCases;
     68 
     69        testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribf', 'Invalid glVertexAttrib{1234}f() usage', gl, function() {
     70            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
     71            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
     72            gl.vertexAttrib1f(maxVertexAttribs, 0.0);
     73            this.expectError(gl.INVALID_VALUE);
     74            gl.vertexAttrib2f(maxVertexAttribs, 0.0, 0.0);
     75            this.expectError(gl.INVALID_VALUE);
     76            gl.vertexAttrib3f(maxVertexAttribs, 0.0, 0.0, 0.0);
     77            this.expectError(gl.INVALID_VALUE);
     78            gl.vertexAttrib4f(maxVertexAttribs, 0.0, 0.0, 0.0, 0.0);
     79            this.expectError(gl.INVALID_VALUE);
     80 
     81        }));
     82 
     83        testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribfv', 'Invalid glVertexAttrib{1234}fv() usage', gl, function() {
     84            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
     85            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
     86            /** @type{Array<number>} */ var v = [0.0];
     87            gl.vertexAttrib1fv(maxVertexAttribs, v);
     88            this.expectError(gl.INVALID_VALUE);
     89            gl.vertexAttrib2fv(maxVertexAttribs, v);
     90            this.expectError(gl.INVALID_VALUE);
     91            gl.vertexAttrib3fv(maxVertexAttribs, v);
     92            this.expectError(gl.INVALID_VALUE);
     93            gl.vertexAttrib4fv(maxVertexAttribs, v);
     94            this.expectError(gl.INVALID_VALUE);
     95 
     96        }));
     97 
     98        testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribi4', 'Invalid glVertexAttribI4{i|ui}f() usage', gl, function() {
     99            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    100            /** @type{number} */ var valInt = 0;
    101            /** @type{number} */ var valUint = 0;
    102 
    103            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    104            gl.vertexAttribI4i(maxVertexAttribs, valInt, valInt, valInt, valInt);
    105            this.expectError(gl.INVALID_VALUE);
    106            gl.vertexAttribI4ui(maxVertexAttribs, valUint, valUint, valUint, valUint);
    107            this.expectError(gl.INVALID_VALUE);
    108 
    109        }));
    110 
    111        testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribi4v', 'Invalid glVertexAttribI4{i|ui}fv() usage', gl, function() {
    112            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    113            /** @type{Array<number>} */ var valInt = [0];
    114            /** @type{Array<number>} */ var valUint = [0];
    115 
    116            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    117            gl.vertexAttribI4iv(maxVertexAttribs, valInt);
    118            this.expectError(gl.INVALID_VALUE);
    119            gl.vertexAttribI4uiv(maxVertexAttribs, valUint);
    120            this.expectError(gl.INVALID_VALUE);
    121 
    122        }));
    123 
    124        testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attrib_pointer', 'Invalid gl.vertexAttribPointer() usage', gl, function() {
    125            /** @type{WebGLBuffer} */ var buffer = gl.createBuffer();
    126            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    127 
    128            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not an accepted value.');
    129            gl.vertexAttribPointer(0, 1, 0, true, 0, 0);
    130            this.expectError(gl.INVALID_ENUM);
    131 
    132            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    133            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    134            gl.vertexAttribPointer(maxVertexAttribs, 1, gl.BYTE, true, 0, 0);
    135            this.expectError(gl.INVALID_VALUE);
    136 
    137            bufferedLogToConsole('gl.INVALID_VALUE is generated if size is not 1, 2, 3, or 4.');
    138            gl.vertexAttribPointer(0, 0, gl.BYTE, true, 0, 0);
    139            this.expectError(gl.INVALID_VALUE);
    140 
    141            bufferedLogToConsole('gl.INVALID_VALUE is generated if stride is negative.');
    142            gl.vertexAttribPointer(0, 1, gl.BYTE, true, -1, 0);
    143            this.expectError(gl.INVALID_VALUE);
    144 
    145            bufferedLogToConsole('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.');
    146            gl.vertexAttribPointer(0, 2, gl.INT_2_10_10_10_REV, true, 0, 0);
    147            this.expectError(gl.INVALID_OPERATION);
    148            gl.vertexAttribPointer(0, 2, gl.UNSIGNED_INT_2_10_10_10_REV, true, 0, 0);
    149            this.expectError(gl.INVALID_OPERATION);
    150            gl.vertexAttribPointer(0, 4, gl.INT_2_10_10_10_REV, true, 0, 0);
    151            this.expectError(gl.NO_ERROR);
    152            gl.vertexAttribPointer(0, 4, gl.UNSIGNED_INT_2_10_10_10_REV, true, 0, 0);
    153            this.expectError(gl.NO_ERROR);
    154 
    155            bufferedLogToConsole('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.');
    156            /** @type{WebGLVertexArrayObject} */ var vao;
    157            /** @type{number} */ var offset = 1;
    158            vao = gl.createVertexArray();
    159            gl.bindVertexArray(vao);
    160            gl.bindBuffer(gl.ARRAY_BUFFER, null);
    161            this.expectError(gl.NO_ERROR);
    162 
    163            gl.vertexAttribPointer(0, 1, gl.BYTE, true, 0, offset);
    164            this.expectError(gl.INVALID_OPERATION);
    165 
    166            gl.bindVertexArray(null);
    167            gl.deleteVertexArray(vao);
    168            this.expectError(gl.NO_ERROR);
    169 
    170        }));
    171 
    172        testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attrib_i_pointer', 'Invalid gl.vertexAttribIPointer() usage', gl, function() {
    173            /** @type{WebGLBuffer} */ var buffer = gl.createBuffer();
    174            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    175 
    176            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not an accepted value.');
    177            gl.vertexAttribIPointer(0, 1, 0, 0, 0);
    178            this.expectError(gl.INVALID_ENUM);
    179            gl.vertexAttribIPointer(0, 4, gl.INT_2_10_10_10_REV, 0, 0);
    180            this.expectError(gl.INVALID_ENUM);
    181            gl.vertexAttribIPointer(0, 4, gl.UNSIGNED_INT_2_10_10_10_REV, 0, 0);
    182            this.expectError(gl.INVALID_ENUM);
    183 
    184            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    185            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    186            gl.vertexAttribIPointer(maxVertexAttribs, 1, gl.BYTE, 0, 0);
    187            this.expectError(gl.INVALID_VALUE);
    188 
    189            bufferedLogToConsole('gl.INVALID_VALUE is generated if size is not 1, 2, 3, or 4.');
    190            gl.vertexAttribIPointer(0, 0, gl.BYTE, 0, 0);
    191            this.expectError(gl.INVALID_VALUE);
    192 
    193            bufferedLogToConsole('gl.INVALID_VALUE is generated if stride is negative.');
    194            gl.vertexAttribIPointer(0, 1, gl.BYTE, -1, 0);
    195            this.expectError(gl.INVALID_VALUE);
    196 
    197            bufferedLogToConsole('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.');
    198            /** @type{WebGLVertexArrayObject} */ var vao;
    199            /** @type{number} */ var offset = 1;
    200            vao = gl.createVertexArray();
    201            gl.bindVertexArray(vao);
    202            gl.bindBuffer(gl.ARRAY_BUFFER, null);
    203            this.expectError(gl.NO_ERROR);
    204 
    205            gl.vertexAttribIPointer(0, 1, gl.BYTE, 0, offset);
    206            this.expectError(gl.INVALID_OPERATION);
    207 
    208            gl.bindVertexArray(null);
    209            gl.deleteVertexArray(vao);
    210            this.expectError(gl.NO_ERROR);
    211 
    212        }));
    213 
    214        testGroup.addChild(new es3fApiCase.ApiCaseCallback('enable_vertex_attrib_array', 'Invalid gl.enableVertexAttribArray() usage', gl, function() {
    215            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    216            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    217            gl.enableVertexAttribArray(maxVertexAttribs);
    218            this.expectError(gl.INVALID_VALUE);
    219 
    220        }));
    221 
    222        testGroup.addChild(new es3fApiCase.ApiCaseCallback('disable_vertex_attrib_array', 'Invalid gl.disableVertexAttribArray() usage', gl, function() {
    223            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    224            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    225            gl.disableVertexAttribArray(maxVertexAttribs);
    226            this.expectError(gl.INVALID_VALUE);
    227 
    228        }));
    229 
    230        testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attrib_divisor', 'Invalid gl.vertexAttribDivisor() usage', gl, function() {
    231            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    232            var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    233            gl.vertexAttribDivisor(maxVertexAttribs, 0);
    234            this.expectError(gl.INVALID_VALUE);
    235 
    236        }));
    237 
    238        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays', 'Invalid gl.drawArrays() usage', gl, function() {
    239            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    240            gl.useProgram(program.getProgram());
    241            /** @type{WebGLFramebuffer} */ var fbo;
    242 
    243            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    244            gl.drawArrays(-1, 0, 1);
    245            this.expectError(gl.INVALID_ENUM);
    246 
    247            bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
    248            gl.drawArrays(gl.POINTS, 0, -1);
    249            this.expectError(gl.INVALID_VALUE);
    250 
    251            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    252            fbo = gl.createFramebuffer();
    253            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    254            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    255            gl.drawArrays(gl.POINTS, 0, 1);
    256            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    257            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    258            gl.deleteFramebuffer(fbo);
    259 
    260            gl.useProgram(null);
    261        }));
    262 
    263        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_invalid_program', 'Invalid gl.drawArrays() usage', gl, function() {
    264            gl.useProgram(null);
    265 
    266            bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is used.');
    267            gl.drawArrays(gl.POINTS, 0, 1);
    268            this.expectError(gl.INVALID_OPERATION);
    269 
    270        }));
    271 
    272        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_incomplete_primitive', 'Invalid gl.drawArrays() usage', gl, function() {
    273            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    274            gl.useProgram(program.getProgram());
    275            /** @type{WebGLFramebuffer} */ var fbo;
    276 
    277            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    278            gl.drawArrays(-1, 0, 1);
    279            this.expectError(gl.INVALID_ENUM);
    280 
    281            bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
    282            gl.drawArrays(gl.TRIANGLES, 0, -1);
    283            this.expectError(gl.INVALID_VALUE);
    284 
    285            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    286            fbo = gl.createFramebuffer();
    287            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    288            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    289            gl.drawArrays(gl.TRIANGLES, 0, 1);
    290            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    291            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    292            gl.deleteFramebuffer(fbo);
    293 
    294            gl.useProgram(null);
    295        }));
    296 
    297        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements', 'Invalid gl.drawElements() usage', gl, function() {
    298            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    299            gl.useProgram(program.getProgram());
    300            /** @type{WebGLFramebuffer} */ var fbo;
    301            /** @type{WebGLBuffer} */ var buf;
    302            /** @type{WebGLTransformFeedback} */ var tfID;
    303            /** @type{number} */ var vertices = 0;
    304 
    305            /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
    306            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    307 
    308            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    309            gl.drawElements(-1, 0, gl.UNSIGNED_BYTE, vertices);
    310            this.expectError(gl.INVALID_ENUM);
    311 
    312            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
    313            gl.drawElements(gl.POINTS, 0, -1, vertices);
    314            this.expectError(gl.INVALID_ENUM);
    315            gl.drawElements(gl.POINTS, 0, gl.FLOAT, vertices);
    316            this.expectError(gl.INVALID_ENUM);
    317 
    318            bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
    319            gl.drawElements(gl.POINTS, -1, gl.UNSIGNED_BYTE, vertices);
    320            this.expectError(gl.INVALID_VALUE);
    321 
    322            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    323            fbo = gl.createFramebuffer();
    324            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    325            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    326            gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
    327            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    328            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    329            gl.deleteFramebuffer(fbo);
    330 
    331            if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) { // gl.EXT_geometry_shader removes error
    332                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
    333                /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
    334 
    335                buf = gl.createBuffer();
    336                tfID = gl.createTransformFeedback();
    337 
    338                gl.useProgram (program.getProgram());
    339                gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    340                gl.linkProgram (program.getProgram());
    341                gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
    342                gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    343                gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    344                gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    345                gl.beginTransformFeedback (gl.POINTS);
    346                this.expectError (gl.NO_ERROR);
    347 
    348                gl.drawElements (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
    349                this.expectError (gl.INVALID_OPERATION);
    350 
    351                gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
    352 
    353                gl.pauseTransformFeedback();
    354                gl.drawElements (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
    355                this.expectError (gl.NO_ERROR);
    356 
    357                gl.endTransformFeedback ();
    358                gl.deleteBuffer(buf);
    359                gl.deleteTransformFeedback(tfID);
    360                gl.deleteBuffer(bufElements);
    361                this.expectError (gl.NO_ERROR);
    362 
    363            }
    364 
    365            gl.useProgram(null);
    366        }));
    367 
    368        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_invalid_program', 'Invalid gl.drawElements() usage', gl, function() {
    369            gl.useProgram(null);
    370            /** @type{number} */ var vertices = 0;
    371 
    372            /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
    373            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    374 
    375            bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) was set.');
    376            gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
    377            this.expectError(gl.INVALID_OPERATION);
    378 
    379            gl.deleteBuffer(bufElements);
    380 
    381        }));
    382 
    383        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_incomplete_primitive', 'Invalid gl.drawElements() usage', gl, function() {
    384            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    385            gl.useProgram(program.getProgram());
    386            /** @type{WebGLFramebuffer} */ var fbo;
    387            /** @type{WebGLBuffer} */ var buf;
    388            /** @type{WebGLTransformFeedback} */ var tfID;
    389            /** @type{number} */ var vertices = 0;
    390 
    391            /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
    392            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    393 
    394            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    395            gl.drawElements(-1, 0, gl.UNSIGNED_BYTE, vertices);
    396            this.expectError(gl.INVALID_ENUM);
    397 
    398            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
    399            gl.drawElements(gl.TRIANGLES, 0, -1, vertices);
    400            this.expectError(gl.INVALID_ENUM);
    401            gl.drawElements(gl.TRIANGLES, 0, gl.FLOAT, vertices);
    402            this.expectError(gl.INVALID_ENUM);
    403 
    404            bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
    405            gl.drawElements(gl.TRIANGLES, -1, gl.UNSIGNED_BYTE, vertices);
    406            this.expectError(gl.INVALID_VALUE);
    407 
    408            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    409            fbo = gl.createFramebuffer();
    410            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    411            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    412            gl.drawElements(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
    413            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    414            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    415            gl.deleteFramebuffer(fbo);
    416 
    417            if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
    418                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
    419                /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
    420 
    421                buf = gl.createBuffer();
    422                tfID = gl.createTransformFeedback();
    423 
    424                gl.useProgram (program.getProgram());
    425                gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    426                gl.linkProgram (program.getProgram());
    427                gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
    428                gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    429                gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    430                gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    431                gl.beginTransformFeedback (gl.TRIANGLES);
    432                this.expectError (gl.NO_ERROR);
    433 
    434                gl.drawElements (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
    435                this.expectError (gl.INVALID_OPERATION);
    436 
    437                gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
    438 
    439                gl.pauseTransformFeedback();
    440                gl.drawElements (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
    441                this.expectError (gl.NO_ERROR);
    442 
    443                gl.endTransformFeedback ();
    444                gl.deleteBuffer(buf);
    445                gl.deleteTransformFeedback(tfID);
    446                gl.deleteBuffer(bufElements);
    447                this.expectError (gl.NO_ERROR);
    448 
    449            }
    450 
    451            gl.useProgram(null);
    452        }));
    453 
    454        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_instanced', 'Invalid gl.drawArraysInstanced() usage', gl, function() {
    455            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    456            gl.useProgram(program.getProgram());
    457            /** @type{WebGLFramebuffer} */ var fbo;
    458 
    459            /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
    460            gl.bindBuffer(gl.ARRAY_BUFFER, bufElements);
    461 
    462            gl.vertexAttribDivisor(0, 1);
    463            this.expectError(gl.NO_ERROR);
    464 
    465            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    466            gl.drawArraysInstanced(-1, 0, 1, 1);
    467            this.expectError(gl.INVALID_ENUM);
    468 
    469            bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
    470            gl.drawArraysInstanced(gl.POINTS, 0, -1, 1);
    471            this.expectError(gl.INVALID_VALUE);
    472            gl.drawArraysInstanced(gl.POINTS, 0, 1, -1);
    473            this.expectError(gl.INVALID_VALUE);
    474 
    475            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    476            fbo = gl.createFramebuffer();
    477            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    478            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    479            gl.drawArraysInstanced(gl.POINTS, 0, 1, 1);
    480            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    481            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    482            gl.deleteFramebuffer(fbo);
    483 
    484            gl.deleteBuffer(bufElements);
    485 
    486            gl.useProgram(null);
    487        }));
    488 
    489        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_instanced_invalid_program', 'Invalid gl.drawArraysInstanced() usage', gl, function() {
    490            gl.useProgram(null);
    491 
    492            /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
    493            gl.bindBuffer(gl.ARRAY_BUFFER, bufElements);
    494 
    495            gl.vertexAttribDivisor(0, 1);
    496            this.expectError(gl.NO_ERROR);
    497 
    498            bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
    499            gl.drawArraysInstanced(gl.POINTS, 0, 1, 1);
    500            this.expectError(gl.INVALID_OPERATION);
    501 
    502            gl.deleteBuffer(bufElements);
    503 
    504        }));
    505 
    506        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_instanced_incomplete_primitive', 'Invalid gl.drawArraysInstanced() usage', gl, function() {
    507            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    508            gl.useProgram(program.getProgram());
    509            /** @type{WebGLFramebuffer} */ var fbo;
    510 
    511            /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
    512            gl.bindBuffer(gl.ARRAY_BUFFER, bufElements);
    513 
    514            gl.vertexAttribDivisor(0, 1);
    515            this.expectError(gl.NO_ERROR);
    516 
    517            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    518            gl.drawArraysInstanced(-1, 0, 1, 1);
    519            this.expectError(gl.INVALID_ENUM);
    520 
    521            bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
    522            gl.drawArraysInstanced(gl.TRIANGLES, 0, -1, 1);
    523            this.expectError(gl.INVALID_VALUE);
    524            gl.drawArraysInstanced(gl.TRIANGLES, 0, 1, -1);
    525            this.expectError(gl.INVALID_VALUE);
    526 
    527            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    528            fbo = gl.createFramebuffer();
    529            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    530            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    531            gl.drawArraysInstanced(gl.TRIANGLES, 0, 1, 1);
    532            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    533            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    534            gl.deleteFramebuffer(fbo);
    535 
    536            gl.deleteBuffer(bufElements);
    537 
    538            gl.useProgram(null);
    539        }));
    540 
    541        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_instanced', 'Invalid gl.drawElementsInstanced() usage', gl, function() {
    542            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    543            gl.useProgram(program.getProgram());
    544            /** @type{WebGLFramebuffer} */ var fbo;
    545            /** @type{WebGLBuffer} */ var buf;
    546            /** @type{WebGLTransformFeedback} */ var tfID;
    547            /** @type{number} */ var vertices = 0;
    548 
    549            /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
    550            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    551 
    552            gl.vertexAttribDivisor(0, 1);
    553            this.expectError(gl.NO_ERROR);
    554 
    555            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    556            gl.drawElementsInstanced(-1, 0, gl.UNSIGNED_BYTE, vertices, 1);
    557            this.expectError(gl.INVALID_ENUM);
    558 
    559            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
    560            gl.drawElementsInstanced(gl.POINTS, 0, -1, vertices, 1);
    561            this.expectError(gl.INVALID_ENUM);
    562            gl.drawElementsInstanced(gl.POINTS, 0, gl.FLOAT, vertices, 1);
    563            this.expectError(gl.INVALID_ENUM);
    564 
    565            bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
    566            gl.drawElementsInstanced(gl.POINTS, -1, gl.UNSIGNED_BYTE, vertices, 0);
    567            this.expectError(gl.INVALID_VALUE);
    568            gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, -1);
    569            this.expectError(gl.INVALID_VALUE);
    570 
    571            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    572            fbo = gl.createFramebuffer();
    573            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    574            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    575            gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
    576            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    577            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    578            gl.deleteFramebuffer(fbo);
    579 
    580            if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
    581                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
    582                /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
    583 
    584                buf = gl.createBuffer();
    585                tfID = gl.createTransformFeedback();
    586 
    587                gl.useProgram (program.getProgram());
    588                gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    589                gl.linkProgram (program.getProgram());
    590                gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
    591                gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    592                gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    593                gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    594                gl.beginTransformFeedback (gl.POINTS);
    595                this.expectError (gl.NO_ERROR);
    596 
    597                gl.drawElementsInstanced (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
    598                this.expectError (gl.INVALID_OPERATION);
    599 
    600                gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
    601 
    602                gl.pauseTransformFeedback();
    603                gl.drawElementsInstanced (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
    604                this.expectError (gl.NO_ERROR);
    605 
    606                gl.endTransformFeedback ();
    607                gl.deleteBuffer(buf);
    608                gl.deleteTransformFeedback(tfID);
    609                gl.deleteBuffer(bufElements);
    610                this.expectError (gl.NO_ERROR);
    611 
    612            }
    613 
    614            gl.useProgram(null);
    615        }));
    616 
    617        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_instanced_invalid_program', 'Invalid gl.drawElementsInstanced() usage', gl, function() {
    618            gl.useProgram(null);
    619            /** @type{number} */ var vertices = 0;
    620 
    621            /** @type{WebGLBuffer} */ var bufElements;
    622            bufElements = gl.createBuffer();
    623            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    624 
    625            gl.vertexAttribDivisor(0, 1);
    626            this.expectError(gl.NO_ERROR);
    627 
    628            bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
    629            gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
    630            this.expectError(gl.INVALID_OPERATION);
    631 
    632            gl.deleteBuffer(bufElements);
    633 
    634        }));
    635 
    636        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_instanced_incomplete_primitive', 'Invalid gl.drawElementsInstanced() usage', gl, function() {
    637            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    638            gl.useProgram(program.getProgram());
    639            /** @type{WebGLFramebuffer} */ var fbo;
    640            /** @type{WebGLBuffer} */ var buf;
    641            /** @type{WebGLTransformFeedback} */ var tfID;
    642            /** @type{number} */ var vertices = 0;
    643 
    644            /** @type{WebGLBuffer} */ var bufElements;
    645            bufElements = gl.createBuffer();
    646            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    647 
    648            gl.vertexAttribDivisor(0, 1);
    649            this.expectError(gl.NO_ERROR);
    650 
    651            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    652            gl.drawElementsInstanced(-1, 0, gl.UNSIGNED_BYTE, vertices, 1);
    653            this.expectError(gl.INVALID_ENUM);
    654 
    655            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
    656            gl.drawElementsInstanced(gl.TRIANGLES, 0, -1, vertices, 1);
    657            this.expectError(gl.INVALID_ENUM);
    658            gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.FLOAT, vertices, 1);
    659            this.expectError(gl.INVALID_ENUM);
    660 
    661            bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
    662            gl.drawElementsInstanced(gl.TRIANGLES, -1, gl.UNSIGNED_BYTE, vertices, 0);
    663            this.expectError(gl.INVALID_VALUE);
    664            gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, -1);
    665            this.expectError(gl.INVALID_VALUE);
    666 
    667            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    668            fbo = gl.createFramebuffer();
    669            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    670            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    671            gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
    672            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    673            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    674            gl.deleteFramebuffer(fbo);
    675 
    676            if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
    677                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
    678                /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
    679 
    680                buf = gl.createBuffer();
    681                tfID = gl.createTransformFeedback();
    682 
    683                gl.useProgram (program.getProgram());
    684                gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    685                gl.linkProgram (program.getProgram());
    686                gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
    687                gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    688                gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    689                gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    690                gl.beginTransformFeedback (gl.TRIANGLES);
    691                this.expectError (gl.NO_ERROR);
    692 
    693                gl.drawElementsInstanced (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
    694                this.expectError (gl.INVALID_OPERATION);
    695 
    696                gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
    697 
    698                gl.pauseTransformFeedback();
    699                gl.drawElementsInstanced (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
    700                this.expectError (gl.NO_ERROR);
    701 
    702                gl.endTransformFeedback ();
    703                gl.deleteBuffer(buf);
    704                gl.deleteTransformFeedback(tfID);
    705                gl.deleteBuffer(bufElements);
    706                this.expectError (gl.NO_ERROR);
    707 
    708            }
    709 
    710            gl.useProgram(null);
    711        }));
    712 
    713        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_range_elements', 'Invalid gl.drawRangeElements() usage', gl, function() {
    714            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    715            gl.useProgram(program.getProgram());
    716            /** @type{WebGLFramebuffer} */ var fbo;
    717            /** @type{WebGLBuffer} */ var buf;
    718            /** @type{WebGLTransformFeedback} */ var tfID;
    719            /** @type{number} */ var vertices = 0;
    720 
    721            /** @type{WebGLBuffer} */ var bufElements;
    722            bufElements = gl.createBuffer();
    723            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    724 
    725            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    726            gl.drawRangeElements(-1, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    727            this.expectError(gl.INVALID_ENUM);
    728 
    729            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
    730            gl.drawRangeElements(gl.POINTS, 0, 1, 0, -1, vertices);
    731            this.expectError(gl.INVALID_ENUM);
    732            gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.FLOAT, vertices);
    733            this.expectError(gl.INVALID_ENUM);
    734 
    735            bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
    736            gl.drawRangeElements(gl.POINTS, 0, 1, -1, gl.UNSIGNED_BYTE, vertices);
    737            this.expectError(gl.INVALID_VALUE);
    738 
    739            bufferedLogToConsole('gl.INVALID_VALUE is generated if end < start.');
    740            gl.drawRangeElements(gl.POINTS, 1, 0, 0, gl.UNSIGNED_BYTE, vertices);
    741            this.expectError(gl.INVALID_VALUE);
    742 
    743            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    744            fbo = gl.createFramebuffer();
    745            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    746            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    747            gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    748            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    749            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    750            gl.deleteFramebuffer(fbo);
    751 
    752            if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
    753                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
    754                /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
    755 
    756                buf = gl.createBuffer();
    757                tfID = gl.createTransformFeedback();
    758 
    759                gl.useProgram (program.getProgram());
    760                gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    761                gl.linkProgram (program.getProgram());
    762                gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
    763                gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    764                gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    765                gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    766                gl.beginTransformFeedback (gl.POINTS);
    767                this.expectError (gl.NO_ERROR);
    768 
    769                gl.drawRangeElements (gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    770                this.expectError (gl.INVALID_OPERATION);
    771 
    772                gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
    773 
    774                gl.pauseTransformFeedback();
    775                gl.drawRangeElements (gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    776                this.expectError (gl.NO_ERROR);
    777 
    778                gl.endTransformFeedback ();
    779                gl.deleteBuffer(buf);
    780                gl.deleteTransformFeedback(tfID);
    781                gl.deleteBuffer(bufElements);
    782                this.expectError (gl.NO_ERROR);
    783 
    784            }
    785 
    786            gl.useProgram(null);
    787        }));
    788 
    789        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_range_elements_invalid_program', 'Invalid gl.drawRangeElements() usage', gl, function() {
    790            gl.useProgram(null);
    791            /** @type{number} */ var vertices = 0;
    792 
    793            /** @type{WebGLBuffer} */ var bufElements;
    794            bufElements = gl.createBuffer();
    795            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    796            gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
    797 
    798            bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
    799            gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    800            this.expectError(gl.INVALID_OPERATION);
    801 
    802            gl.deleteBuffer(bufElements);
    803 
    804        }));
    805 
    806        testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_range_elements_incomplete_primitive', 'Invalid gl.drawRangeElements() usage', gl, function() {
    807            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    808            gl.useProgram(program.getProgram());
    809            /** @type{WebGLFramebuffer} */ var fbo;
    810            /** @type{WebGLBuffer} */ var buf;
    811            /** @type{WebGLTransformFeedback} */ var tfID;
    812            /** @type{number} */ var vertices = 0;
    813 
    814            /** @type{WebGLBuffer} */ var bufElements;
    815            bufElements = gl.createBuffer();
    816            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
    817 
    818            bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
    819            gl.drawRangeElements(-1, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    820            this.expectError(gl.INVALID_ENUM);
    821 
    822            bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
    823            gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, -1, vertices);
    824            this.expectError(gl.INVALID_ENUM);
    825            gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, gl.FLOAT, vertices);
    826            this.expectError(gl.INVALID_ENUM);
    827 
    828            bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
    829            gl.drawRangeElements(gl.TRIANGLES, 0, 1, -1, gl.UNSIGNED_BYTE, vertices);
    830            this.expectError(gl.INVALID_VALUE);
    831 
    832            bufferedLogToConsole('gl.INVALID_VALUE is generated if end < start.');
    833            gl.drawRangeElements(gl.TRIANGLES, 1, 0, 0, gl.UNSIGNED_BYTE, vertices);
    834            this.expectError(gl.INVALID_VALUE);
    835 
    836            bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
    837            fbo = gl.createFramebuffer();
    838            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    839            gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    840            gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    841            this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
    842            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    843            gl.deleteFramebuffer(fbo);
    844 
    845            if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
    846                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
    847                /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
    848 
    849                buf = gl.createBuffer();
    850                tfID = gl.createTransformFeedback();
    851 
    852                gl.useProgram (program.getProgram());
    853                gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    854                gl.linkProgram (program.getProgram());
    855                gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
    856                gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    857                gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    858                gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    859                gl.beginTransformFeedback (gl.TRIANGLES);
    860                this.expectError (gl.NO_ERROR);
    861 
    862                gl.drawRangeElements (gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    863                this.expectError (gl.INVALID_OPERATION);
    864 
    865                gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
    866 
    867                gl.pauseTransformFeedback();
    868                gl.drawRangeElements (gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
    869                this.expectError (gl.NO_ERROR);
    870 
    871                gl.endTransformFeedback ();
    872                gl.deleteBuffer(buf);
    873                gl.deleteTransformFeedback(tfID);
    874                gl.deleteBuffer(bufElements);
    875                this.expectError (gl.NO_ERROR);
    876 
    877            }
    878 
    879            gl.useProgram(null);
    880        }));
    881    };
    882 
    883    /**
    884    * @param {WebGL2RenderingContext} gl
    885    */
    886    es3fNegativeVertexArrayApiTests.run = function(gl) {
    887        var testName = 'vertex_array';
    888        var testDescription = 'Negative Vertex Array API Cases';
    889        var state = tcuTestCase.runner;
    890 
    891        state.testName = testName;
    892        state.testCases = tcuTestCase.newTest(testName, testDescription, null);
    893 
    894        //Set up name and description of this test series.
    895        setCurrentTestName(testName);
    896        description(testDescription);
    897        try {
    898            es3fNegativeVertexArrayApiTests.init(gl);
    899            tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
    900        } catch (err) {
    901            bufferedLogToConsole(err);
    902            tcuTestCase.runner.terminate();
    903        }
    904    };
    905 
    906 });