tor-browser

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

es3fNegativeShaderApiTests.js (64632B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES Utilities
      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 
     21 'use strict';
     22 goog.provide('functional.gles3.es3fNegativeShaderApiTests');
     23 goog.require('framework.common.tcuTestCase');
     24 goog.require('framework.opengl.gluShaderProgram');
     25 goog.require('functional.gles3.es3fApiCase');
     26 
     27 goog.scope(function() {
     28 
     29    var es3fNegativeShaderApiTests = functional.gles3.es3fNegativeShaderApiTests;
     30    var es3fApiCase = functional.gles3.es3fApiCase;
     31    var tcuTestCase = framework.common.tcuTestCase;
     32    var gluShaderProgram = framework.opengl.gluShaderProgram;
     33 
     34    /**
     35    * @type {string}
     36    * @const
     37    */
     38    var vertexShaderSource = '#version 300 es\n' +
     39    'void main (void)\n' +
     40    '{\n' +
     41    ' gl_Position = vec4(0.0);\n' +
     42    '}\n';
     43 
     44    /**
     45    * @type {string}
     46    * @const
     47    */
     48    var fragmentShaderSource = '#version 300 es\n' +
     49    'layout(location = 0) out mediump vec4 fragColor;\n' +
     50    'void main (void)\n' +
     51    '{\n' +
     52    ' fragColor = vec4(0.0);\n' +
     53    '}\n';
     54 
     55    /**
     56    * @type {string}
     57    * @const
     58    */
     59    var uniformTestVertSource = '#version 300 es\n' +
     60    'uniform mediump vec4 vec4_v;\n' +
     61    'uniform mediump mat4 mat4_v;\n' +
     62    'void main (void)\n' +
     63    '{\n' +
     64    ' gl_Position = mat4_v * vec4_v;\n' +
     65    '}\n';
     66 
     67    /**
     68    * @type {string}
     69    * @const
     70    */
     71    var uniformTestFragSource = '#version 300 es\n' +
     72    'uniform mediump ivec4 ivec4_f;\n' +
     73    'uniform mediump uvec4 uvec4_f;\n' +
     74    'uniform sampler2D sampler_f;\n' +
     75    'layout(location = 0) out mediump vec4 fragColor;\n' +
     76    'void main (void)\n' +
     77    '{\n' +
     78    ' fragColor.xy = (vec4(uvec4_f) + vec4(ivec4_f)).xy;\n' +
     79    ' fragColor.zw = texture(sampler_f, vec2(0.0, 0.0)).zw;\n' +
     80    '}\n';
     81 
     82    /**
     83    * @type {string}
     84    * @const
     85    */
     86    var uniformBlockVertSource = '#version 300 es\n' +
     87    'layout(std140) uniform Block { lowp float var; };\n' +
     88    'void main (void)\n' +
     89    '{\n' +
     90    ' gl_Position = vec4(var);\n' +
     91    '}\n';
     92 
     93    /**
     94    * @param {WebGL2RenderingContext} gl
     95    */
     96    es3fNegativeShaderApiTests.init = function(gl) {
     97        var testGroup = tcuTestCase.runner.testCases;
     98 
     99        testGroup.addChild(new es3fApiCase.ApiCaseCallback(
    100            'create_shader', 'Invalid gl.createShader() usage', gl,
    101            function() {
    102                bufferedLogToConsole('INVALID_ENUM is generated if shaderType is not an accepted value.');
    103                gl.createShader(-1);
    104                this.expectError(gl.INVALID_ENUM);
    105            }
    106        ));
    107 
    108        testGroup.addChild(new es3fApiCase.ApiCaseCallback('attach_shader', 'Invalid gl.attachShader() usage', gl,
    109            function() {
    110                /** @type {WebGLShader} */ var shader1 = gl.createShader(gl.VERTEX_SHADER);
    111                /** @type {WebGLShader} */ var shader2 = gl.createShader(gl.VERTEX_SHADER);
    112                /** @type {WebGLProgram} */ var program = gl.createProgram();
    113 
    114                bufferedLogToConsole('gl.INVALID_OPERATION is generated if shader is already attached to program.');
    115                gl.attachShader(program, shader1);
    116                    this.expectError(gl.NO_ERROR);
    117                gl.attachShader(program, shader1);
    118                    this.expectError(gl.INVALID_OPERATION);
    119 
    120                bufferedLogToConsole('gl.INVALID_OPERATION is generated if a shader of the same type as shader is already attached to program.');
    121                gl.attachShader(program, shader2);
    122                    this.expectError(gl.INVALID_OPERATION);
    123 
    124                gl.deleteProgram(program);
    125                gl.deleteShader(shader1);
    126                gl.deleteShader(shader2);
    127            }
    128        ));
    129 
    130        testGroup.addChild(new es3fApiCase.ApiCaseCallback('detach_shader', 'Invalid gl.detachShader() usage', gl,
    131            function() {
    132                /** @type {WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    133                /** @type {WebGLProgram} */ var program = gl.createProgram();
    134 
    135                bufferedLogToConsole('gl.INVALID_OPERATION is generated if shader is not attached to program.');
    136                gl.detachShader(program, shader);
    137                this.expectError(gl.INVALID_OPERATION);
    138 
    139                gl.deleteProgram(program);
    140                gl.deleteShader(shader);
    141            }
    142        ));
    143 
    144        testGroup.addChild(new es3fApiCase.ApiCaseCallback('link_program', 'Invalid gl.linkProgram() usage', gl,
    145            function() {
    146 
    147                bufferedLogToConsole('gl.INVALID_OPERATION is generated if program is the currently active program object and transform feedback mode is active.');
    148 
    149                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    150                /** @type {WebGLBuffer} */ var buf;
    151                /** @type {WebGLTransformFeedback} */ var tfID;
    152                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
    153 
    154                tfID = gl.createTransformFeedback();
    155                buf = gl.createBuffer();
    156 
    157                gl.useProgram(program.getProgram());
    158                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    159                gl.linkProgram(program.getProgram());
    160                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
    161                gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    162                gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    163                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    164                gl.beginTransformFeedback(gl.TRIANGLES);
    165 
    166                this.expectError(gl.NO_ERROR);
    167 
    168                gl.linkProgram(program.getProgram());
    169                this.expectError(gl.INVALID_OPERATION);
    170 
    171                gl.endTransformFeedback();
    172                gl.deleteTransformFeedback(tfID);
    173                gl.deleteBuffer(buf);
    174                this.expectError(gl.NO_ERROR);
    175 
    176            }
    177        ));
    178 
    179        testGroup.addChild(new es3fApiCase.ApiCaseCallback('use_program', 'Invalid gl.useProgram() usage', gl,
    180            function() {
    181 
    182                /** @type {WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    183 
    184                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback mode is active and not paused.');
    185                /** @type {gluShaderProgram.ShaderProgram} */ var program1 = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    186                /** @type {gluShaderProgram.ShaderProgram} */ var program2 = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    187                /** @type {WebGLBuffer} */ var buf;
    188                /** @type {WebGLTransformFeedback} */ var tfID;
    189                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
    190 
    191                tfID = gl.createTransformFeedback();
    192                buf = gl.createBuffer();
    193 
    194                gl.useProgram(program1.getProgram());
    195                gl.transformFeedbackVaryings(program1.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    196                gl.linkProgram(program1.getProgram());
    197                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
    198                gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    199                gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    200                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    201                gl.beginTransformFeedback(gl.TRIANGLES);
    202                this.expectError(gl.NO_ERROR);
    203 
    204                gl.useProgram(program2.getProgram());
    205                this.expectError(gl.INVALID_OPERATION);
    206 
    207                gl.pauseTransformFeedback();
    208                gl.useProgram(program2.getProgram());
    209                this.expectError(gl.NO_ERROR);
    210 
    211                gl.endTransformFeedback();
    212                gl.deleteTransformFeedback(tfID);
    213                gl.deleteBuffer(buf);
    214                this.expectError(gl.NO_ERROR);
    215 
    216                gl.useProgram(null);
    217                gl.deleteShader(shader);
    218            }
    219        ));
    220 
    221        testGroup.addChild(new es3fApiCase.ApiCaseCallback('bind_sampler', 'Invalid gl.bindSampler() usage', gl,
    222            function() {
    223                /** @type {number} */ var maxTexImageUnits;
    224                /** @type {WebGLSampler} */ var sampler;
    225                /** @type {WebGLSampler} */ var buf;
    226                maxTexImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS));
    227                sampler = gl.createSampler();
    228 
    229                bufferedLogToConsole('gl.INVALID_VALUE is generated if unit is greater than or equal to the value of gl.MAX_COMBIED_TEXTURE_IMAGE_UNITS.');
    230                gl.bindSampler(maxTexImageUnits, sampler);
    231                this.expectError(gl.INVALID_VALUE);
    232 
    233                bufferedLogToConsole('gl.INVALID_OPERATION is generated if sampler has been deleted by a call to glDeleteSamplers.');
    234                gl.deleteSampler(sampler);
    235                gl.bindSampler(1, sampler);
    236                this.expectError(gl.INVALID_OPERATION);
    237            }
    238        ));
    239 
    240        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_sampler_parameteriv', 'Invalid gl.getSamplerParameter() usage', gl,
    241            function() {
    242                /** @type {number} */ var params;
    243                /** @type {WebGLSampler} */ var sampler;
    244                sampler = gl.createSampler();
    245 
    246                bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
    247                params = /** @type {number} */ (gl.getSamplerParameter(sampler, -1));
    248                this.expectError(gl.INVALID_ENUM);
    249 
    250                gl.deleteSampler(sampler);
    251            }
    252        ));
    253 
    254        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_sampler_parameterfv', 'Invalid gl.getSamplerParameter() usage', gl,
    255            function() {
    256                /** @type {number} */ var params;
    257                /** @type {WebGLSampler} */ var sampler;
    258                sampler = gl.createSampler();
    259 
    260                bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
    261                params = /** @type {number} */ (gl.getSamplerParameter(sampler, -1));
    262                this.expectError(gl.INVALID_ENUM);
    263 
    264                gl.deleteSampler(sampler);
    265            }
    266        ));
    267 
    268        testGroup.addChild(new es3fApiCase.ApiCaseCallback('sampler_parameteri', 'Invalid gl.samplerParameteri() usage', gl,
    269            function() {
    270                /** @type {WebGLSampler} */ var sampler;
    271                sampler = gl.createSampler();
    272 
    273                bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.');
    274                gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, -1);
    275                this.expectError(gl.INVALID_ENUM);
    276 
    277                gl.deleteSampler(sampler);
    278            }
    279        ));
    280 
    281        testGroup.addChild(new es3fApiCase.ApiCaseCallback(
    282            'sampler_parameteriv', 'Invalid gl.samplerParameteri() usage', gl,
    283            function() {
    284                /** @type {number} */ var params;
    285                /** @type {WebGLSampler} */ var sampler;
    286                sampler = gl.createSampler();
    287 
    288                bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.');
    289                params = -1;
    290                gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, params);
    291                this.expectError(gl.INVALID_ENUM);
    292 
    293                gl.deleteSampler(sampler);
    294            }
    295        ));
    296 
    297        testGroup.addChild(new es3fApiCase.ApiCaseCallback(
    298            'sampler_parameterf', 'Invalid glSamplerParameterf() usage', gl,
    299            function() {
    300                /** @type {WebGLSampler} */ var sampler;
    301                sampler = gl.createSampler();
    302 
    303                bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.');
    304                gl.samplerParameterf(sampler, gl.TEXTURE_WRAP_S, -1.0);
    305                this.expectError(gl.INVALID_ENUM);
    306 
    307                gl.deleteSampler(sampler);
    308            }
    309        ));
    310 
    311        // Shader data commands
    312 
    313        testGroup.addChild(new es3fApiCase.ApiCaseCallback(
    314            'get_attrib_location', 'Invalid gl.getAttribLocation() usage', gl,
    315            function() {
    316                /** @type {WebGLProgram} */ var programEmpty = gl.createProgram();
    317                /** @type {WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    318                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    319 
    320                bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been successfully linked.');
    321                gl.bindAttribLocation(programEmpty, 0, 'test');
    322                gl.getAttribLocation(programEmpty, 'test');
    323                this.expectError(gl.INVALID_OPERATION);
    324 
    325                gl.useProgram(null);
    326                gl.deleteShader(shader);
    327                gl.deleteProgram(programEmpty);
    328            }
    329        ));
    330 
    331        testGroup.addChild(new es3fApiCase.ApiCaseCallback(
    332            'get_uniform_location', 'Invalid gl.getUniformLocation() usage', gl,
    333            function() {
    334                /** @type {WebGLProgram} */ var programEmpty = gl.createProgram();
    335 
    336                bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been successfully linked.');
    337                gl.getUniformLocation(programEmpty, 'test');
    338                this.expectError(gl.INVALID_OPERATION);
    339                gl.deleteProgram(programEmpty);
    340            }
    341        ));
    342 
    343        testGroup.addChild(new es3fApiCase.ApiCaseCallback(
    344            'bind_attrib_location', 'Invalid gl.bindAttribLocation() usage', gl,
    345            function() {
    346                /** @type {WebGLProgram} */ var program = gl.createProgram();
    347                var maxIndex = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    348 
    349                bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    350                gl.bindAttribLocation(program, maxIndex, 'test');
    351                this.expectError(gl.INVALID_VALUE);
    352 
    353                bufferedLogToConsole('gl.INVALID_OPERATION is generated if name starts with the reserved prefix \'gl.\'.');
    354                gl.bindAttribLocation(program, maxIndex-1, 'gl_test');
    355                this.expectError(gl.INVALID_OPERATION);
    356 
    357                gl.deleteProgram(program);
    358            }
    359        ));
    360 
    361        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniform_block_binding', 'Invalid gl.uniformBlockBinding() usage', gl,
    362            function() {
    363                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformBlockVertSource, uniformTestFragSource));
    364 
    365                gl.useProgram(program.getProgram());
    366 
    367                /** @type {number} */ var maxUniformBufferBindings;
    368                /** @type {number} */ var numActiveUniforms = -1;
    369                /** @type {number} */ var numActiveBlocks = -1;
    370                maxUniformBufferBindings = /** @type {number} */ (gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS));
    371                numActiveUniforms = /** @type {number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORMS));
    372                numActiveBlocks = /** @type {number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
    373                bufferedLogToConsole('// gl.MAX_UNIFORM_BUFFER_BINDINGS = ' + maxUniformBufferBindings);
    374                bufferedLogToConsole('// gl.ACTIVE_UNIFORMS = ' + numActiveUniforms);
    375                bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks);
    376                this.expectError(gl.NO_ERROR);
    377 
    378                bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockIndex is not an active uniform block index of program.');
    379                gl.uniformBlockBinding(program.getProgram(), -1, 0);
    380                this.expectError(gl.INVALID_VALUE);
    381                gl.uniformBlockBinding(program.getProgram(), 5, 0);
    382                this.expectError(gl.INVALID_VALUE);
    383 
    384                bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockBinding is greater than or equal to the value of gl.MAX_UNIFORM_BUFFER_BINDINGS.');
    385                gl.uniformBlockBinding(program.getProgram(), maxUniformBufferBindings, 0);
    386                this.expectError(gl.INVALID_VALUE);
    387 
    388                bufferedLogToConsole('An exception is thrown if program is null.');
    389                this.expectThrowNoError(function() {
    390                    gl.uniformBlockBinding(null, 0, 0);
    391                });
    392            }
    393        ));
    394 
    395        // glUniform*f
    396 
    397        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformf_incompatible_type', 'Invalid glUniform{1234}f() usage', gl,
    398            function() {
    399                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    400 
    401                gl.useProgram(program.getProgram());
    402                /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
    403                /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
    404                /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
    405                /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
    406                this.expectError(gl.NO_ERROR);
    407 
    408                if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null) {
    409                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    410                }
    411 
    412                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
    413                gl.useProgram(program.getProgram());
    414                gl.uniform1f(vec4_v, 0.0);
    415                this.expectError(gl.INVALID_OPERATION);
    416                gl.uniform2f(vec4_v, 0.0, 0.0);
    417                this.expectError(gl.INVALID_OPERATION);
    418                gl.uniform3f(vec4_v, 0.0, 0.0, 0.0);
    419                this.expectError(gl.INVALID_OPERATION);
    420                gl.uniform4f(vec4_v, 0.0, 0.0, 0.0, 0.0);
    421                this.expectError(gl.NO_ERROR);
    422 
    423                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}f is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.');
    424                gl.useProgram(program.getProgram());
    425                gl.uniform4f(ivec4_f, 0.0, 0.0, 0.0, 0.0);
    426                this.expectError(gl.INVALID_OPERATION);
    427                gl.uniform4f(uvec4_f, 0.0, 0.0, 0.0, 0.0);
    428                this.expectError(gl.INVALID_OPERATION);
    429 
    430                bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
    431                gl.useProgram(program.getProgram());
    432                gl.uniform1f(sampler_f, 0.0);
    433                this.expectError(gl.INVALID_OPERATION);
    434 
    435                gl.useProgram(null);
    436            }
    437        ));
    438 
    439        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformfv_incompatible_type', 'Invalid glUniform{1234}fv() usage', gl,
    440            function() {
    441                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    442 
    443                gl.useProgram(program.getProgram());
    444                /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
    445                /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
    446                /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
    447                /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
    448                this.expectError(gl.NO_ERROR);
    449 
    450                if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
    451                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    452 
    453                /** @type {Float32Array} */ var data = new Float32Array(4);
    454 
    455                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
    456                gl.useProgram(program.getProgram());
    457                gl.uniform1fv(vec4_v, new Float32Array(1));
    458                this.expectError(gl.INVALID_OPERATION);
    459                gl.uniform2fv(vec4_v, new Float32Array(2));
    460                this.expectError(gl.INVALID_OPERATION);
    461                gl.uniform3fv(vec4_v, new Float32Array(3));
    462                this.expectError(gl.INVALID_OPERATION);
    463                gl.uniform4fv(vec4_v, new Float32Array(4));
    464                this.expectError(gl.NO_ERROR);
    465 
    466                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}fv is used to load a uniform variable of type /** @type {number} */ var , ivec2, ivec3, ivec4, unsigned /** @type {number} */ var , uvec2, uvec3, uvec4.');
    467                gl.useProgram(program.getProgram());
    468                gl.uniform4fv(ivec4_f, data);
    469                this.expectError(gl.INVALID_OPERATION);
    470                gl.uniform4fv(uvec4_f, data);
    471                this.expectError(gl.INVALID_OPERATION);
    472 
    473                bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
    474                gl.useProgram(program.getProgram());
    475                gl.uniform1fv(sampler_f, new Float32Array(1));
    476                this.expectError(gl.INVALID_OPERATION);
    477 
    478                gl.useProgram(null);
    479            }
    480        ));
    481 
    482        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformfv_invalid_count', 'Invalid glUniform{1234}fv() usage', gl,
    483            function() {
    484                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    485 
    486                gl.useProgram(program.getProgram());
    487                /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
    488                this.expectError(gl.NO_ERROR);
    489 
    490                if (vec4_v == null)
    491                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    492 
    493                /** @type {Float32Array} */ var data = new Float32Array(12);
    494 
    495                bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
    496                gl.useProgram(program.getProgram());
    497                gl.uniform1fv(vec4_v, data);
    498                this.expectError(gl.INVALID_OPERATION);
    499                gl.uniform2fv(vec4_v, data);
    500                this.expectError(gl.INVALID_OPERATION);
    501                gl.uniform3fv(vec4_v, data);
    502                this.expectError(gl.INVALID_OPERATION);
    503                gl.uniform4fv(vec4_v, data);
    504                this.expectError(gl.INVALID_OPERATION);
    505 
    506                gl.useProgram(null);
    507            }
    508        ));
    509 
    510        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformi_incompatible_type', 'Invalid glUniform{1234}i() usage', gl,
    511            function() {
    512                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    513 
    514                gl.useProgram(program.getProgram());
    515                /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
    516                /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
    517                /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
    518                /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
    519                this.expectError(gl.NO_ERROR);
    520 
    521                if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
    522                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    523 
    524                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
    525                gl.useProgram(program.getProgram());
    526                gl.uniform1i(ivec4_f, 0);
    527                this.expectError(gl.INVALID_OPERATION);
    528                gl.uniform2i(ivec4_f, 0, 0);
    529                this.expectError(gl.INVALID_OPERATION);
    530                gl.uniform3i(ivec4_f, 0, 0, 0);
    531                this.expectError(gl.INVALID_OPERATION);
    532                gl.uniform4i(ivec4_f, 0, 0, 0, 0);
    533                this.expectError(gl.NO_ERROR);
    534 
    535                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type unsigned /** @type {number} */ var , uvec2, uvec3, uvec4, or an array of these.');
    536                gl.useProgram(program.getProgram());
    537                gl.uniform1i(uvec4_f, 0);
    538                this.expectError(gl.INVALID_OPERATION);
    539                gl.uniform2i(uvec4_f, 0, 0);
    540                this.expectError(gl.INVALID_OPERATION);
    541                gl.uniform3i(uvec4_f, 0, 0, 0);
    542                this.expectError(gl.INVALID_OPERATION);
    543                gl.uniform4i(uvec4_f, 0, 0, 0, 0);
    544                this.expectError(gl.INVALID_OPERATION);
    545 
    546                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
    547                gl.useProgram(program.getProgram());
    548                gl.uniform1i(vec4_v, 0);
    549                this.expectError(gl.INVALID_OPERATION);
    550                gl.uniform2i(vec4_v, 0, 0);
    551                this.expectError(gl.INVALID_OPERATION);
    552                gl.uniform3i(vec4_v, 0, 0, 0);
    553                this.expectError(gl.INVALID_OPERATION);
    554                gl.uniform4i(vec4_v, 0, 0, 0, 0);
    555                this.expectError(gl.INVALID_OPERATION);
    556 
    557                gl.useProgram(null);
    558            }
    559        ));
    560 
    561        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformiv_incompatible_type', 'Invalid glUniform{1234}iv() usage', gl,
    562            function() {
    563                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    564 
    565                gl.useProgram(program.getProgram());
    566                /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
    567                /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
    568                /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
    569                /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
    570                this.expectError(gl.NO_ERROR);
    571 
    572                if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
    573                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    574 
    575                /** @type {Int32Array} */ var data1 = new Int32Array(1);
    576                /** @type {Int32Array} */ var data2 = new Int32Array(2);
    577                /** @type {Int32Array} */ var data3 = new Int32Array(3);
    578                /** @type {Int32Array} */ var data4 = new Int32Array(4);
    579 
    580                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
    581                gl.useProgram(program.getProgram());
    582                gl.uniform1iv(ivec4_f, data1);
    583                this.expectError(gl.INVALID_OPERATION);
    584                gl.uniform2iv(ivec4_f, data2);
    585                this.expectError(gl.INVALID_OPERATION);
    586                gl.uniform3iv(ivec4_f, data3);
    587                this.expectError(gl.INVALID_OPERATION);
    588                gl.uniform4iv(ivec4_f, data4);
    589                this.expectError(gl.NO_ERROR);
    590 
    591                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}iv is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
    592                gl.useProgram(program.getProgram());
    593                gl.uniform1iv(vec4_v, data1);
    594                this.expectError(gl.INVALID_OPERATION);
    595                gl.uniform2iv(vec4_v, data2);
    596                this.expectError(gl.INVALID_OPERATION);
    597                gl.uniform3iv(vec4_v, data3);
    598                this.expectError(gl.INVALID_OPERATION);
    599                gl.uniform4iv(vec4_v, data4);
    600                this.expectError(gl.INVALID_OPERATION);
    601 
    602                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}iv is used to load a uniform variable of type unsigned /** @type {number} */ var , uvec2, uvec3 or uvec4.');
    603                gl.useProgram(program.getProgram());
    604                gl.uniform1iv(uvec4_f, data1);
    605                this.expectError(gl.INVALID_OPERATION);
    606                gl.uniform2iv(uvec4_f, data2);
    607                this.expectError(gl.INVALID_OPERATION);
    608                gl.uniform3iv(uvec4_f, data3);
    609                this.expectError(gl.INVALID_OPERATION);
    610                gl.uniform4iv(uvec4_f, data4);
    611                this.expectError(gl.INVALID_OPERATION);
    612 
    613                gl.useProgram(null);
    614            }
    615        ));
    616 
    617        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformiv_invalid_count', 'Invalid glUniform{1234}iv() usage', gl,
    618            function() {
    619                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    620 
    621                gl.useProgram(program.getProgram());
    622                /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
    623                this.expectError(gl.NO_ERROR);
    624 
    625                if (ivec4_f == null)
    626                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    627 
    628                /** @type {Int32Array} */ var data = new Int32Array(12);
    629 
    630                bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
    631                gl.useProgram(program.getProgram());
    632                gl.uniform1iv(ivec4_f, data);
    633                this.expectError(gl.INVALID_OPERATION);
    634                gl.uniform2iv(ivec4_f, data);
    635                this.expectError(gl.INVALID_OPERATION);
    636                gl.uniform3iv(ivec4_f, data);
    637                this.expectError(gl.INVALID_OPERATION);
    638                gl.uniform4iv(ivec4_f, data);
    639                this.expectError(gl.INVALID_OPERATION);
    640 
    641                gl.useProgram(null);
    642            }
    643        ));
    644 
    645        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformui_incompatible_type', 'Invalid glUniform{1234}ui() usage', gl,
    646            function() {
    647                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    648 
    649                gl.useProgram(program.getProgram());
    650                /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
    651                /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
    652                /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
    653                /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
    654                this.expectError(gl.NO_ERROR);
    655 
    656                if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
    657                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    658 
    659                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
    660                gl.useProgram(program.getProgram());
    661                gl.uniform1ui(uvec4_f, 0);
    662                this.expectError(gl.INVALID_OPERATION);
    663                gl.uniform2ui(uvec4_f, 0, 0);
    664                this.expectError(gl.INVALID_OPERATION);
    665                gl.uniform3ui(uvec4_f, 0, 0, 0);
    666                this.expectError(gl.INVALID_OPERATION);
    667                gl.uniform4ui(uvec4_f, 0, 0, 0, 0);
    668                this.expectError(gl.NO_ERROR);
    669 
    670                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type /** @type {number} */ var , ivec2, ivec3, ivec4, or an array of these.');
    671                gl.useProgram(program.getProgram());
    672                gl.uniform1ui(ivec4_f, 0);
    673                this.expectError(gl.INVALID_OPERATION);
    674                gl.uniform2ui(ivec4_f, 0, 0);
    675                this.expectError(gl.INVALID_OPERATION);
    676                gl.uniform3ui(ivec4_f, 0, 0, 0);
    677                this.expectError(gl.INVALID_OPERATION);
    678                gl.uniform4ui(ivec4_f, 0, 0, 0, 0);
    679                this.expectError(gl.INVALID_OPERATION);
    680 
    681                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
    682                gl.useProgram(program.getProgram());
    683                gl.uniform1ui(vec4_v, 0);
    684                this.expectError(gl.INVALID_OPERATION);
    685                gl.uniform2ui(vec4_v, 0, 0);
    686                this.expectError(gl.INVALID_OPERATION);
    687                gl.uniform3ui(vec4_v, 0, 0, 0);
    688                this.expectError(gl.INVALID_OPERATION);
    689                gl.uniform4ui(vec4_v, 0, 0, 0, 0);
    690                this.expectError(gl.INVALID_OPERATION);
    691 
    692                bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
    693                gl.useProgram(program.getProgram());
    694                gl.uniform1ui(sampler_f, 0);
    695                this.expectError(gl.INVALID_OPERATION);
    696 
    697                gl.useProgram(null);
    698            }
    699        ));
    700 
    701        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformuiv_incompatible_type', 'Invalid glUniform{1234}uiv() usage', gl,
    702            function() {
    703                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    704 
    705                gl.useProgram(program.getProgram());
    706                /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
    707                /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
    708                /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
    709                /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
    710                this.expectError(gl.NO_ERROR);
    711 
    712                if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
    713                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    714 
    715                /** @type {Uint32Array} */ var data1 = new Uint32Array(1);
    716                /** @type {Uint32Array} */ var data2 = new Uint32Array(2);
    717                /** @type {Uint32Array} */ var data3 = new Uint32Array(3);
    718                /** @type {Uint32Array} */ var data4 = new Uint32Array(4);
    719 
    720                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
    721                gl.useProgram(program.getProgram());
    722                gl.uniform1uiv(uvec4_f, data1);
    723                this.expectError(gl.INVALID_OPERATION);
    724                gl.uniform2uiv(uvec4_f, data2);
    725                this.expectError(gl.INVALID_OPERATION);
    726                gl.uniform3uiv(uvec4_f, data3);
    727                this.expectError(gl.INVALID_OPERATION);
    728                gl.uniform4uiv(uvec4_f, data4);
    729                this.expectError(gl.NO_ERROR);
    730 
    731                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
    732                gl.useProgram(program.getProgram());
    733                gl.uniform1uiv(vec4_v, data1);
    734                this.expectError(gl.INVALID_OPERATION);
    735                gl.uniform2uiv(vec4_v, data2);
    736                this.expectError(gl.INVALID_OPERATION);
    737                gl.uniform3uiv(vec4_v, data3);
    738                this.expectError(gl.INVALID_OPERATION);
    739                gl.uniform4uiv(vec4_v, data4);
    740                this.expectError(gl.INVALID_OPERATION);
    741 
    742                bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a uniform variable of type /** @type {number} */ var , ivec2, ivec3 or ivec4.');
    743                gl.useProgram(program.getProgram());
    744                gl.uniform1uiv(ivec4_f, data1);
    745                this.expectError(gl.INVALID_OPERATION);
    746                gl.uniform2uiv(ivec4_f, data2);
    747                this.expectError(gl.INVALID_OPERATION);
    748                gl.uniform3uiv(ivec4_f, data3);
    749                this.expectError(gl.INVALID_OPERATION);
    750                gl.uniform4uiv(ivec4_f, data4);
    751                this.expectError(gl.INVALID_OPERATION);
    752 
    753                bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
    754                gl.useProgram(program.getProgram());
    755                gl.uniform1uiv(sampler_f, data1);
    756                this.expectError(gl.INVALID_OPERATION);
    757 
    758                gl.useProgram(null);
    759            }
    760        ));
    761 
    762        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformuiv_invalid_count', 'Invalid glUniform{1234}uiv() usage', gl,
    763            function() {
    764                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    765 
    766                gl.useProgram(program.getProgram());
    767                /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
    768                this.expectError(gl.NO_ERROR);
    769 
    770                if (uvec4_f == null)
    771                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    772 
    773                /** @type {Uint32Array} */ var data = new Uint32Array(12);
    774 
    775                bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
    776                gl.useProgram(program.getProgram());
    777                gl.uniform1uiv(uvec4_f, data);
    778                this.expectError(gl.INVALID_OPERATION);
    779                gl.uniform2uiv(uvec4_f, data);
    780                this.expectError(gl.INVALID_OPERATION);
    781                gl.uniform3uiv(uvec4_f, data);
    782                this.expectError(gl.INVALID_OPERATION);
    783                gl.uniform4uiv(uvec4_f, data);
    784                this.expectError(gl.INVALID_OPERATION);
    785 
    786                gl.useProgram(null);
    787            }
    788        ));
    789 
    790        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniform_matrixfv_incompatible_type', 'Invalid glUniformMatrix{234}fv() usage', gl,
    791            function() {
    792                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    793 
    794                gl.useProgram(program.getProgram());
    795                /** @type {WebGLUniformLocation} */ var mat4_v = gl.getUniformLocation(program.getProgram(), 'mat4_v'); // mat4
    796                /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
    797                this.expectError(gl.NO_ERROR);
    798 
    799                if (mat4_v == null || sampler_f == null)
    800                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    801 
    802                /** @type {Float32Array} */ var data4 = new Float32Array(4);
    803                /** @type {Float32Array} */ var data9 = new Float32Array(9);
    804                /** @type {Float32Array} */ var data16 = new Float32Array(16);
    805                /** @type {Float32Array} */ var data6 = new Float32Array(6);
    806                /** @type {Float32Array} */ var data8 = new Float32Array(8);
    807                /** @type {Float32Array} */ var data12 = new Float32Array(12);
    808 
    809                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
    810                gl.useProgram(program.getProgram());
    811                gl.uniformMatrix2fv(mat4_v, false, data4);
    812                this.expectError(gl.INVALID_OPERATION);
    813                gl.uniformMatrix3fv(mat4_v, false, data9);
    814                this.expectError(gl.INVALID_OPERATION);
    815                gl.uniformMatrix4fv(mat4_v, false, data16);
    816                this.expectError(gl.NO_ERROR);
    817 
    818                gl.uniformMatrix2x3fv(mat4_v, false, data6);
    819                this.expectError(gl.INVALID_OPERATION);
    820                gl.uniformMatrix3x2fv(mat4_v, false, data6);
    821                this.expectError(gl.INVALID_OPERATION);
    822                gl.uniformMatrix2x4fv(mat4_v, false, data8);
    823                this.expectError(gl.INVALID_OPERATION);
    824                gl.uniformMatrix4x2fv(mat4_v, false, data8);
    825                this.expectError(gl.INVALID_OPERATION);
    826                gl.uniformMatrix3x4fv(mat4_v, false, data12);
    827                this.expectError(gl.INVALID_OPERATION);
    828                gl.uniformMatrix4x3fv(mat4_v, false, data12);
    829                this.expectError(gl.INVALID_OPERATION);
    830 
    831                bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
    832                gl.useProgram(program.getProgram());
    833                gl.uniformMatrix2fv(sampler_f, false, data4);
    834                this.expectError(gl.INVALID_OPERATION);
    835                gl.uniformMatrix3fv(sampler_f, false, data9);
    836                this.expectError(gl.INVALID_OPERATION);
    837                gl.uniformMatrix4fv(sampler_f, false, data16);
    838                this.expectError(gl.INVALID_OPERATION);
    839 
    840                gl.uniformMatrix2x3fv(sampler_f, false, data6);
    841                this.expectError(gl.INVALID_OPERATION);
    842                gl.uniformMatrix3x2fv(sampler_f, false, data6);
    843                this.expectError(gl.INVALID_OPERATION);
    844                gl.uniformMatrix2x4fv(sampler_f, false, data8);
    845                this.expectError(gl.INVALID_OPERATION);
    846                gl.uniformMatrix4x2fv(sampler_f, false, data8);
    847                this.expectError(gl.INVALID_OPERATION);
    848                gl.uniformMatrix3x4fv(sampler_f, false, data12);
    849                this.expectError(gl.INVALID_OPERATION);
    850                gl.uniformMatrix4x3fv(sampler_f, false, data12);
    851                this.expectError(gl.INVALID_OPERATION);
    852 
    853                gl.useProgram(null);
    854            }
    855        ));
    856 
    857        testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniform_matrixfv_invalid_count', 'Invalid glUniformMatrix{234}fv() usage', gl,
    858            function() {
    859                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    860 
    861                gl.useProgram(program.getProgram());
    862                /** @type {WebGLUniformLocation} */ var mat4_v = gl.getUniformLocation(program.getProgram(), 'mat4_v'); // mat4
    863                this.expectError(gl.NO_ERROR);
    864 
    865                if (mat4_v == null)
    866                    assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
    867 
    868                /** @type {Float32Array} */ var data = new Float32Array(144);
    869 
    870                bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
    871                gl.useProgram(program.getProgram());
    872                gl.uniformMatrix2fv(mat4_v, false, data);
    873                this.expectError(gl.INVALID_OPERATION);
    874                gl.uniformMatrix3fv(mat4_v, false, data);
    875                this.expectError(gl.INVALID_OPERATION);
    876                gl.uniformMatrix4fv(mat4_v, false, data);
    877                this.expectError(gl.INVALID_OPERATION);
    878 
    879                gl.uniformMatrix2x3fv(mat4_v, false, data);
    880                this.expectError(gl.INVALID_OPERATION);
    881                gl.uniformMatrix3x2fv(mat4_v, false, data);
    882                this.expectError(gl.INVALID_OPERATION);
    883                gl.uniformMatrix2x4fv(mat4_v, false, data);
    884                this.expectError(gl.INVALID_OPERATION);
    885                gl.uniformMatrix4x2fv(mat4_v, false, data);
    886                this.expectError(gl.INVALID_OPERATION);
    887                gl.uniformMatrix3x4fv(mat4_v, false, data);
    888                this.expectError(gl.INVALID_OPERATION);
    889                gl.uniformMatrix4x3fv(mat4_v, false, data);
    890                this.expectError(gl.INVALID_OPERATION);
    891 
    892                gl.useProgram(null);
    893            }
    894        ));
    895 
    896        testGroup.addChild(new es3fApiCase.ApiCaseCallback('bind_transform_feedback', 'Invalid gl.bindTransformFeedback() usage', gl,
    897            function() {
    898                /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
    899                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    900                /** @type {WebGLBuffer} */ var buf;
    901                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
    902 
    903                buf = gl.createBuffer();
    904                tfID[0] = gl.createTransformFeedback();
    905                tfID[1] = gl.createTransformFeedback();
    906 
    907                bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.TRANSFORM_FEEDBACK.');
    908                gl.bindTransformFeedback(-1, tfID[0]);
    909                this.expectError(gl.INVALID_ENUM);
    910 
    911                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the transform feedback operation is active on the currently bound transform feedback object, and is not paused.');
    912                gl.useProgram(program.getProgram());
    913                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    914                gl.linkProgram(program.getProgram());
    915                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
    916                gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    917                gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    918                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    919                gl.beginTransformFeedback(gl.TRIANGLES);
    920                this.expectError(gl.NO_ERROR);
    921 
    922                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[1]);
    923                this.expectError(gl.INVALID_OPERATION);
    924 
    925                gl.endTransformFeedback();
    926                this.expectError(gl.NO_ERROR);
    927 
    928                gl.useProgram(null);
    929                gl.deleteBuffer(buf);
    930                gl.deleteTransformFeedback(tfID[0]);
    931                gl.deleteTransformFeedback(tfID[1]);
    932                this.expectError(gl.NO_ERROR);
    933            }
    934        ));
    935 
    936        testGroup.addChild(new es3fApiCase.ApiCaseCallback('begin_transform_feedback', 'Invalid gl.beginTransformFeedback() usage', gl,
    937            function() {
    938                /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
    939                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    940                /** @type {WebGLBuffer} */ var buf;
    941                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
    942 
    943                buf = gl.createBuffer();
    944                tfID[0] = gl.createTransformFeedback();
    945                tfID[1] = gl.createTransformFeedback();
    946 
    947                gl.useProgram(program.getProgram());
    948                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
    949                gl.linkProgram(program.getProgram());
    950                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
    951                gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
    952                gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
    953                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    954                this.expectError(gl.NO_ERROR);
    955 
    956                bufferedLogToConsole('gl.INVALID_ENUM is generated if primitiveMode is not one of gl.POINTS, gl.LINES, or gl.TRIANGLES.');
    957                gl.beginTransformFeedback(-1);
    958                this.expectError(gl.INVALID_ENUM);
    959 
    960                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is already active.');
    961                gl.beginTransformFeedback(gl.TRIANGLES);
    962                this.expectError(gl.NO_ERROR);
    963                gl.beginTransformFeedback(gl.POINTS);
    964                this.expectError(gl.INVALID_OPERATION);
    965 
    966                bufferedLogToConsole('gl.INVALID_OPERATION is generated if any binding point used in transform feedback mode does not have a buffer object bound.');
    967                /** @type{WebGLBuffer} */ var dummyBuf = gl.createBuffer()
    968                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, dummyBuf);
    969                gl.beginTransformFeedback(gl.TRIANGLES);
    970                this.expectError(gl.INVALID_OPERATION);
    971                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
    972 
    973                bufferedLogToConsole('gl.INVALID_OPERATION is generated if no binding points would be used because no program object is active.');
    974                gl.useProgram(null);
    975                gl.beginTransformFeedback(gl.TRIANGLES);
    976                this.expectError(gl.INVALID_OPERATION);
    977                gl.useProgram(program.getProgram());
    978 
    979                bufferedLogToConsole('gl.INVALID_OPERATION is generated if no binding points would be used because the active program object has specified no varying variables to record.');
    980                gl.transformFeedbackVaryings(program.getProgram(), [], gl.INTERLEAVED_ATTRIBS);
    981                gl.beginTransformFeedback(gl.TRIANGLES);
    982                this.expectError(gl.INVALID_OPERATION);
    983 
    984                gl.endTransformFeedback();
    985                gl.deleteBuffer(buf);
    986                gl.deleteBuffer(dummyBuf);
    987                gl.deleteTransformFeedback(tfID[0]);
    988                gl.deleteTransformFeedback(tfID[1]);
    989                this.expectError(gl.NO_ERROR);
    990            }
    991        ));
    992 
    993        testGroup.addChild(new es3fApiCase.ApiCaseCallback('pause_transform_feedback', 'Invalid gl.pauseTransformFeedback() usage', gl,
    994            function() {
    995                /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
    996                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
    997                /** @type {WebGLBuffer} */ var buf;
    998                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
    999 
   1000                buf = gl.createBuffer();
   1001                tfID[0] = gl.createTransformFeedback();
   1002                tfID[1] = gl.createTransformFeedback();
   1003 
   1004                gl.useProgram(program.getProgram());
   1005                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
   1006                gl.linkProgram(program.getProgram());
   1007                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
   1008                gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
   1009                gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
   1010                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
   1011                this.expectError(gl.NO_ERROR);
   1012 
   1013                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is paused.');
   1014                gl.pauseTransformFeedback();
   1015                this.expectError(gl.INVALID_OPERATION);
   1016                gl.beginTransformFeedback(gl.TRIANGLES);
   1017                gl.pauseTransformFeedback();
   1018                this.expectError(gl.NO_ERROR);
   1019                gl.pauseTransformFeedback();
   1020                this.expectError(gl.INVALID_OPERATION);
   1021 
   1022                gl.endTransformFeedback();
   1023                gl.deleteBuffer(buf);
   1024                gl.deleteTransformFeedback(tfID[0]);
   1025                gl.deleteTransformFeedback(tfID[1]);
   1026                this.expectError(gl.NO_ERROR);
   1027            }
   1028        ));
   1029 
   1030        testGroup.addChild(new es3fApiCase.ApiCaseCallback('resume_transform_feedback', 'Invalid gl.resumeTransformFeedback() usage', gl,
   1031            function() {
   1032                /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
   1033                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
   1034                /** @type {WebGLBuffer} */ var buf;
   1035                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
   1036 
   1037                buf = gl.createBuffer();
   1038                tfID[0] = gl.createTransformFeedback();
   1039                tfID[1] = gl.createTransformFeedback();
   1040 
   1041                gl.useProgram(program.getProgram());
   1042                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
   1043                gl.linkProgram(program.getProgram());
   1044                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
   1045                gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
   1046                gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
   1047                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
   1048                this.expectError(gl.NO_ERROR);
   1049 
   1050                bufferedLogToConsole('gl.INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is not paused.');
   1051                gl.resumeTransformFeedback();
   1052                this.expectError(gl.INVALID_OPERATION);
   1053                gl.beginTransformFeedback(gl.TRIANGLES);
   1054                gl.resumeTransformFeedback();
   1055                this.expectError(gl.INVALID_OPERATION);
   1056                gl.pauseTransformFeedback();
   1057                gl.resumeTransformFeedback();
   1058                this.expectError(gl.NO_ERROR);
   1059 
   1060                gl.endTransformFeedback();
   1061                gl.deleteBuffer(buf);
   1062                gl.deleteTransformFeedback(tfID[0]);
   1063                gl.deleteTransformFeedback(tfID[1]);
   1064                this.expectError(gl.NO_ERROR);
   1065            }
   1066        ));
   1067 
   1068        testGroup.addChild(new es3fApiCase.ApiCaseCallback('end_transform_feedback', 'Invalid gl.endTransformFeedback() usage', gl,
   1069            function() {
   1070                /** @type {WebGLTransformFeedback} */ var tfID;
   1071                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
   1072                /** @type {WebGLBuffer} */ var buf;
   1073                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
   1074 
   1075                buf = gl.createBuffer();
   1076                tfID = gl.createTransformFeedback();
   1077 
   1078                gl.useProgram(program.getProgram());
   1079                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
   1080                gl.linkProgram(program.getProgram());
   1081                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
   1082                gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
   1083                gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
   1084                gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
   1085                this.expectError(gl.NO_ERROR);
   1086 
   1087                bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is not active.');
   1088                gl.endTransformFeedback();
   1089                this.expectError(gl.INVALID_OPERATION);
   1090                gl.beginTransformFeedback(gl.TRIANGLES);
   1091                gl.endTransformFeedback();
   1092                this.expectError(gl.NO_ERROR);
   1093 
   1094                gl.deleteBuffer(buf);
   1095                gl.deleteTransformFeedback(tfID);
   1096                this.expectError(gl.NO_ERROR);
   1097            }
   1098        ));
   1099 
   1100        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_transform_feedback_varying', 'Invalid glGetTransformFeedbackVarying() usage', gl,
   1101            function() {
   1102                /** @type {WebGLTransformFeedback} */ var tfID;
   1103                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
   1104                /** @type {gluShaderProgram.ShaderProgram} */ var programInvalid = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, ''));
   1105                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
   1106                /** @type {number} */ var maxTransformFeedbackVaryings = 0;
   1107 
   1108                /** @type {number} */ var length;
   1109                /** @type {number} */ var size;
   1110                /** @type {number} */ var type;
   1111                /** @type {WebGLActiveInfo} */ var name;
   1112 
   1113                tfID = gl.createTransformFeedback();
   1114 
   1115                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
   1116                this.expectError(gl.NO_ERROR);
   1117                gl.linkProgram(program.getProgram());
   1118                this.expectError(gl.NO_ERROR);
   1119 
   1120                gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
   1121                this.expectError(gl.NO_ERROR);
   1122 
   1123                bufferedLogToConsole('An exception is thrown if program is null.');
   1124                this.expectThrowNoError(function() {
   1125                    gl.getTransformFeedbackVarying(null, 0);
   1126                });
   1127 
   1128                bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater or equal to the value of gl.TRANSFORM_FEEDBACK_VARYINGS.');
   1129                maxTransformFeedbackVaryings = /** @type {number} */ (gl.getProgramParameter(program.getProgram(), gl.TRANSFORM_FEEDBACK_VARYINGS));
   1130                name = gl.getTransformFeedbackVarying(program.getProgram(), maxTransformFeedbackVaryings);
   1131                this.expectError(gl.INVALID_VALUE);
   1132 
   1133                bufferedLogToConsole('gl.INVALID_OPERATION or gl.INVALID_VALUE is generated program has not been linked.');
   1134                name = gl.getTransformFeedbackVarying(programInvalid.getProgram(), 0);
   1135                this.expectError([gl.INVALID_OPERATION, gl.INVALID_VALUE]);
   1136 
   1137                gl.deleteTransformFeedback(tfID);
   1138                this.expectError(gl.NO_ERROR);
   1139            }
   1140        ));
   1141 
   1142        testGroup.addChild(new es3fApiCase.ApiCaseCallback('transform_feedback_varyings', 'Invalid gl.transformFeedbackVaryings() usage', gl,
   1143            function() {
   1144                /** @type {WebGLTransformFeedback} */ var tfID;
   1145                /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
   1146                /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
   1147                /** @type {number} */ var maxTransformFeedbackSeparateAttribs = 0;
   1148 
   1149                tfID = gl.createTransformFeedback();
   1150                this.expectError(gl.NO_ERROR);
   1151 
   1152                bufferedLogToConsole('An exception is thrown if program is null.');
   1153                this.expectThrowNoError(function() {
   1154                    gl.transformFeedbackVaryings(null, tfVarying, gl.INTERLEAVED_ATTRIBS);
   1155                });
   1156 
   1157                bufferedLogToConsole('gl.INVALID_VALUE is generated if bufferMode is gl.SEPARATE_ATTRIBS and count is greater than gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.');
   1158                maxTransformFeedbackSeparateAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS));
   1159                for (var count = 0; count < maxTransformFeedbackSeparateAttribs; ++count) {
   1160                    tfVarying = tfVarying.concat(['gl_Position']);
   1161                }
   1162                gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.SEPARATE_ATTRIBS);
   1163                this.expectError(gl.INVALID_VALUE);
   1164 
   1165                gl.deleteTransformFeedback(tfID);
   1166                this.expectError(gl.NO_ERROR);
   1167            }
   1168        ));
   1169    };
   1170 
   1171    /**
   1172     * Run test
   1173     * @param {WebGL2RenderingContext} gl
   1174     */
   1175     es3fNegativeShaderApiTests.run = function(gl) {
   1176        //Set up Test Root parameters
   1177        var testName = 'negative_shader_api';
   1178        var testDescription = 'Negative Shader Api Tests';
   1179        var state = tcuTestCase.runner;
   1180 
   1181        state.testName = testName;
   1182        state.testCases = tcuTestCase.newTest(testName, testDescription, null);
   1183 
   1184        //Set up name and description of this test series.
   1185        setCurrentTestName(testName);
   1186        description(testDescription);
   1187        try {
   1188            es3fNegativeShaderApiTests.init(gl);
   1189            tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
   1190        } catch (err) {
   1191            bufferedLogToConsole(err);
   1192            tcuTestCase.runner.terminate();
   1193        }
   1194    };
   1195 });