tor-browser

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

es3fVertexArrayObjectTests.js (30997B)


      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.es3fVertexArrayObjectTests');
     23 goog.require('framework.common.tcuImageCompare');
     24 goog.require('framework.common.tcuSurface');
     25 goog.require('framework.common.tcuTestCase');
     26 goog.require('framework.delibs.debase.deRandom');
     27 goog.require('framework.delibs.debase.deString');
     28 goog.require('framework.delibs.debase.deUtil');
     29 goog.require('framework.opengl.gluShaderProgram');
     30 
     31 goog.scope(function() {
     32 var es3fVertexArrayObjectTests = functional.gles3.es3fVertexArrayObjectTests;
     33 var tcuTestCase = framework.common.tcuTestCase;
     34 var deRandom = framework.delibs.debase.deRandom;
     35 var deString = framework.delibs.debase.deString;
     36 var gluShaderProgram = framework.opengl.gluShaderProgram;
     37 var tcuSurface = framework.common.tcuSurface;
     38 var tcuImageCompare = framework.common.tcuImageCompare;
     39 var deUtil = framework.delibs.debase.deUtil;
     40 
     41 /**
     42 * @constructor
     43 */
     44 es3fVertexArrayObjectTests.Attribute = function() {
     45    this.enabled = false;
     46    this.size = 1;
     47    this.stride = 0;
     48    this.type = gl.FLOAT;
     49    this.integer = false;
     50    this.divisor = 0;
     51    this.offset = 0;
     52    this.normalized = false;
     53    this.bufferNdx = 0;
     54 };
     55 
     56 /**
     57 * @constructor
     58 * @struct
     59 */
     60 es3fVertexArrayObjectTests.VertexArrayState = function() {
     61    this.attributes = [];
     62    this.elementArrayBuffer = 0;
     63 };
     64 
     65 /**
     66 * @constructor
     67 * @struct
     68 */
     69 es3fVertexArrayObjectTests.BufferSpec = function(count, size, componentCount, stride, offset, type, intRangeMin, intRangeMax, floatRangeMin, floatRangeMax) {
     70    this.count = count;
     71    this.size = size;
     72    this.componentCount = componentCount;
     73    this.stride = stride;
     74    this.offset = offset;
     75 
     76    this.type = type;
     77 
     78    this.intRangeMin = intRangeMin;
     79    this.intRangeMax = intRangeMax;
     80 
     81    this.floatRangeMin = floatRangeMin;
     82    this.floatRangeMax = floatRangeMax;
     83 };
     84 
     85 /**
     86 * @constructor
     87 */
     88 es3fVertexArrayObjectTests.Spec = function() {
     89    this.count = -1;
     90    this.instances = -1;
     91    this.useDrawElements = false;
     92    this.indexType = gl.NONE;
     93    this.indexOffset = -1;
     94    this.indexRangeMin = -1;
     95    this.indexRangeMax = -1;
     96    this.indexCount = -1;
     97    this.buffers = [];
     98 };
     99 
    100 /**
    101 * @constructor
    102 * @extends {tcuTestCase.DeqpTest}
    103 * @param {es3fVertexArrayObjectTests.Spec} spec
    104 * @param {string} name
    105 * @param {string} description
    106 */
    107 es3fVertexArrayObjectTests.VertexArrayObjectTest = function(spec, name, description) {
    108    tcuTestCase.DeqpTest.call(this, name, description);
    109    this.m_spec = spec;
    110    this.m_random = new deRandom.Random(deString.deStringHash(name));
    111    /** @type Array<WebGLBuffer>} */ this.m_buffers = [];
    112    // mapping 0 -> null object
    113    this.m_buffers.push(null);
    114 };
    115 
    116 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    117 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.constructor = es3fVertexArrayObjectTests.VertexArrayObjectTest;
    118 
    119 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.init = function() {
    120    this.m_vaoProgram = this.createProgram(this.m_spec.vao);
    121    // m_log << tcu::TestLog::Message << "Program used with Vertex Array Object" << tcu::TestLog::EndMessage;
    122    // m_log << *m_vaoProgram;
    123    this.m_stateProgram = this.createProgram(this.m_spec.state);
    124    // m_log << tcu::TestLog::Message << "Program used with Vertex Array State" << tcu::TestLog::EndMessage;
    125    // m_log << *m_stateProgram;
    126 
    127    if (!this.m_vaoProgram.isOk() || !this.m_stateProgram.isOk())
    128        testFailedOptions('Failed to compile shaders', true);
    129 };
    130 
    131 /**
    132 * @param {number} target GL target
    133 * @param {number} index Index of the buffer to bind
    134 */
    135 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.bindBuffer = function(target, index) {
    136    if (typeof this.m_buffers[index] === 'undefined') {
    137        var data = this.createRandomBufferData(this.m_spec.buffers[index - 1]);
    138        var buffer = gl.createBuffer();
    139        this.m_buffers[index] = buffer;
    140 
    141        gl.bindBuffer(target, buffer);
    142        gl.bufferData(target, data, gl.DYNAMIC_DRAW);
    143        gl.bindBuffer(target, null);
    144    }
    145 
    146    gl.bindBuffer(target, this.m_buffers[index]);
    147 };
    148 
    149 /**
    150 * @param {es3fVertexArrayObjectTests.BufferSpec} buffer
    151 */
    152 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.createRandomBufferData = function(buffer) {
    153    var typedArray;
    154    switch (buffer.type) {
    155        case gl.FLOAT: typedArray = Float32Array; break;
    156        case gl.INT: typedArray = Int32Array; break;
    157        case gl.UNSIGNED_INT: typedArray = Uint32Array; break;
    158        case gl.SHORT: typedArray = Int16Array; break;
    159        case gl.UNSIGNED_SHORT: typedArray = Uint16Array; break;
    160        case gl.BYTE: typedArray = Int8Array; break;
    161        case gl.UNSIGNED_BYTE: typedArray = Uint8Array; break;
    162        default:
    163            throw new Error('Invalid type: ' + buffer.type);
    164    }
    165 
    166    var raw = new ArrayBuffer(buffer.size);
    167    var stride;
    168 
    169    if (buffer.stride != 0) {
    170        stride = buffer.stride;
    171    } else {
    172        switch (buffer.type) {
    173            case gl.FLOAT: stride = buffer.componentCount * 4; break;
    174            case gl.INT: stride = buffer.componentCount * 4; break;
    175            case gl.UNSIGNED_INT: stride = buffer.componentCount * 4; break;
    176            case gl.SHORT: stride = buffer.componentCount * 2; break;
    177            case gl.UNSIGNED_SHORT: stride = buffer.componentCount * 2; break;
    178            case gl.BYTE: stride = buffer.componentCount * 1; break;
    179            case gl.UNSIGNED_BYTE: stride = buffer.componentCount * 1; break;
    180        }
    181    }
    182 
    183    var offset = 0;
    184 
    185    for (var pos = 0; pos < buffer.count; pos++) {
    186        var data = new typedArray(raw, offset, buffer.componentCount);
    187        for (var componentNdx = 0; componentNdx < buffer.componentCount; componentNdx++) {
    188            switch (buffer.type) {
    189                case gl.FLOAT: {
    190                    data[componentNdx] = this.m_random.getFloat(buffer.floatRangeMin, buffer.floatRangeMax);
    191                    break;
    192                }
    193                default: {
    194                    data[componentNdx] = this.m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
    195                }
    196            }
    197        }
    198 
    199        offset += stride;
    200    }
    201 
    202    return new typedArray(raw);
    203 };
    204 
    205 /**
    206 * @param {es3fVertexArrayObjectTests.VertexArrayState} state
    207 */
    208 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.createProgram = function(state) {
    209    var vtx = '';
    210    var value = '';
    211 
    212    vtx += '#version 300 es\n';
    213 
    214    for (var attribNdx = 0; attribNdx < state.attributes.length; attribNdx++) {
    215        if (state.attributes[attribNdx].integer)
    216            vtx += 'layout(location = ' + attribNdx + ') in mediump ivec4 a_attrib' + attribNdx + ';\n';
    217        else
    218            vtx += 'layout(location = ' + attribNdx + ') in mediump vec4 a_attrib' + attribNdx + ';\n';
    219 
    220        if (state.attributes[attribNdx].integer) {
    221            var scale = 0.0;
    222 
    223            // TODO: Should it be state.attributes[attribNdx].type?
    224            switch (state.attributes[attribNdx].type) {
    225                case gl.SHORT: scale = (1.0 / ((1 << 14) - 1)); break;
    226                case gl.UNSIGNED_SHORT: scale = (1.0 / ((1 << 15) - 1)); break;
    227                case gl.INT: scale = (1.0 / ((1 << 30) - 1)); break;
    228                case gl.UNSIGNED_INT: scale = (1.0 / ((1 << 31) - 1)); break;
    229                case gl.BYTE: scale = (1.0 / ((1 << 6) - 1)); break;
    230                case gl.UNSIGNED_BYTE: scale = (1.0 / ((1 << 7) - 1)); break;
    231 
    232                default:
    233                    throw new Error('Invalid type: ' + state.attributes[0].type);
    234            }
    235            value += (attribNdx != 0 ? ' + ' : '') + scale + ' * vec4(a_attrib' + attribNdx + ')';
    236        } else if (state.attributes[attribNdx].type != gl.FLOAT && !state.attributes[attribNdx].normalized) {
    237            var scale = 0.0;
    238 
    239            switch (state.attributes[attribNdx].type) {
    240                case gl.SHORT: scale = (0.5 / ((1 << 14) - 1)); break;
    241                case gl.UNSIGNED_SHORT: scale = (0.5 / ((1 << 15) - 1)); break;
    242                case gl.INT: scale = (0.5 / ((1 << 30) - 1)); break;
    243                case gl.UNSIGNED_INT: scale = (0.5 / ((1 << 31) - 1)); break;
    244                case gl.BYTE: scale = (0.5 / ((1 << 6) - 1)); break;
    245                case gl.UNSIGNED_BYTE: scale = (0.5 / ((1 << 7) - 1)); break;
    246 
    247                default:
    248                    throw new Error('Invalid type: ' + state.attributes[0].type);
    249            }
    250            value += (attribNdx != 0 ? ' + ' : '') + scale + ' * a_attrib' + attribNdx;
    251        } else
    252            value += (attribNdx != 0 ? ' + ' : '') + 'a_attrib' + attribNdx;
    253    }
    254 
    255    vtx +=
    256        'out mediump vec4 v_value;\n' +
    257        'void main (void)\n' +
    258        '{\n' +
    259        '\tv_value = ' + value + ';\n';
    260 
    261    if (state.attributes[0].integer) {
    262        var scale = 0.0;
    263 
    264        switch (state.attributes[0].type) {
    265            case gl.SHORT: scale = (1.0 / ((1 << 14) - 1)); break;
    266            case gl.UNSIGNED_SHORT: scale = (1.0 / ((1 << 15) - 1)); break;
    267            case gl.INT: scale = (1.0 / ((1 << 30) - 1)); break;
    268            case gl.UNSIGNED_INT: scale = (1.0 / ((1 << 31) - 1)); break;
    269            case gl.BYTE: scale = (1.0 / ((1 << 6) - 1)); break;
    270            case gl.UNSIGNED_BYTE: scale = (1.0 / ((1 << 7) - 1)); break;
    271 
    272            default:
    273                throw new Error('Invalid type: ' + state.attributes[0].type);
    274        }
    275 
    276        vtx +=
    277            '\tgl_Position = vec4(' + scale + ' * ' + 'vec3(a_attrib0.xyz), 1.0);\n' +
    278            '}';
    279    } else {
    280        if (state.attributes[0].normalized || state.attributes[0].type == gl.FLOAT) {
    281            vtx +=
    282                '\tgl_Position = vec4(a_attrib0.xyz, 1.0);\n' +
    283                '}';
    284        } else {
    285            var scale = 0.0;
    286 
    287            switch (state.attributes[0].type) {
    288                case gl.SHORT: scale = (1.0 / ((1 << 14) - 1)); break;
    289                case gl.UNSIGNED_SHORT: scale = (1.0 / ((1 << 15) - 1)); break;
    290                case gl.INT: scale = (1.0 / ((1 << 30) - 1)); break;
    291                case gl.UNSIGNED_INT: scale = (1.0 / ((1 << 31) - 1)); break;
    292                case gl.BYTE: scale = (1.0 / ((1 << 6) - 1)); break;
    293                case gl.UNSIGNED_BYTE: scale = (1.0 / ((1 << 7) - 1)); break;
    294 
    295                default:
    296                    throw new Error('Invalid type: ' + state.attributes[0].type);
    297            }
    298 
    299            scale *= 0.5;
    300 
    301            vtx +=
    302                '\tgl_Position = vec4(' + scale + ' * ' + 'a_attrib0.xyz, 1.0);\n' +
    303                '}';
    304        }
    305    }
    306 
    307    var fragmentShader =
    308        '#version 300 es\n' +
    309        'in mediump vec4 v_value;\n' +
    310        'layout(location = 0) out mediump vec4 fragColor;\n' +
    311        'void main (void)\n' +
    312        '{\n' +
    313        '\tfragColor = vec4(v_value.xyz, 1.0);\n' +
    314        '}';
    315 
    316    return new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtx, fragmentShader));
    317 };
    318 
    319 /**
    320 * @param {es3fVertexArrayObjectTests.VertexArrayState} state
    321 */
    322 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.setState = function(state) {
    323    this.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, state.elementArrayBuffer);
    324 
    325    for (var attribNdx = 0; attribNdx < state.attributes.length; attribNdx++) {
    326        this.bindBuffer(gl.ARRAY_BUFFER, state.attributes[attribNdx].bufferNdx);
    327        if (state.attributes[attribNdx].enabled)
    328            gl.enableVertexAttribArray(attribNdx);
    329        else
    330            gl.disableVertexAttribArray(attribNdx);
    331 
    332        if (state.attributes[attribNdx].integer)
    333            gl.vertexAttribIPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].stride, state.attributes[attribNdx].offset);
    334        else
    335            gl.vertexAttribPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].normalized, state.attributes[attribNdx].stride, state.attributes[attribNdx].offset);
    336 
    337        gl.vertexAttribDivisor(attribNdx, state.attributes[attribNdx].divisor);
    338    }
    339 };
    340 
    341 /**
    342 * @param {es3fVertexArrayObjectTests.VertexArrayState} state
    343 */
    344 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.makeDrawCall = function(state) {
    345    gl.clearColor(0.7, 0.7, 0.7, 1.0);
    346    gl.clear(gl.COLOR_BUFFER_BIT);
    347    var spec = this.m_spec;
    348 
    349    if (spec.useDrawElements) {
    350        if (spec.instances == 0)
    351            gl.drawElements(gl.TRIANGLES, spec.count, spec.indexType, spec.indexOffset);
    352        else
    353            gl.drawElementsInstanced(gl.TRIANGLES, spec.count, spec.indexType, spec.indexOffset, spec.instances);
    354    } else {
    355        if (spec.instances == 0)
    356            gl.drawArrays(gl.TRIANGLES, 0, spec.count);
    357        else
    358            gl.drawArraysInstanced(gl.TRIANGLES, 0, spec.count, spec.instances);
    359    }
    360 };
    361 
    362 /**
    363 * @param {tcuSurface.Surface} vaoResult
    364 * @param {tcuSurface.Surface} defaultResult
    365 */
    366 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.render = function(vaoResult, defaultResult) {
    367   var vao = gl.createVertexArray();
    368 
    369    gl.bindVertexArray(vao);
    370    this.setState(this.m_spec.vao);
    371    gl.bindVertexArray(null);
    372 
    373    this.setState(this.m_spec.state);
    374 
    375    gl.bindVertexArray(vao);
    376    gl.useProgram(this.m_vaoProgram.getProgram());
    377    this.makeDrawCall(this.m_spec.vao);
    378    vaoResult.readViewport();
    379    this.setState(this.m_spec.vao);
    380    gl.bindVertexArray(null);
    381 
    382    gl.useProgram(this.m_stateProgram.getProgram());
    383    this.makeDrawCall(this.m_spec.state);
    384    defaultResult.readViewport();
    385 
    386    gl.deleteVertexArray(vao);
    387 };
    388 
    389 /**
    390 * @param {tcuSurface.Surface} vaoRef
    391 * @param {tcuSurface.Surface} defaultRef
    392 */
    393 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.genReferences = function(vaoRef, defaultRef) {
    394    this.setState(this.m_spec.vao);
    395    gl.useProgram(this.m_vaoProgram.getProgram());
    396    this.makeDrawCall(this.m_spec.vao);
    397    vaoRef.readViewport();
    398 
    399    this.setState(this.m_spec.state);
    400    gl.useProgram(this.m_stateProgram.getProgram());
    401    this.makeDrawCall(this.m_spec.state);
    402    defaultRef.readViewport();
    403 };
    404 
    405 es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.iterate = function() {
    406    var vaoReference = new tcuSurface.Surface();
    407    var stateReference = new tcuSurface.Surface();
    408    var vaoResult = new tcuSurface.Surface();
    409    var stateResult = new tcuSurface.Surface();
    410 
    411    var isOk;
    412 
    413    // logVertexArrayState(m_log, m_spec.vao, "Vertex Array Object State");
    414    // logVertexArrayState(m_log, m_spec.state, "OpenGL Vertex Array State");
    415    this.genReferences(stateReference, vaoReference);
    416    this.render(stateResult, vaoResult);
    417 
    418    isOk = tcuImageCompare.pixelThresholdCompare('Results', 'Comparison result from rendering with Vertex Array State', stateReference, stateResult, [0, 0, 0, 0]);
    419    isOk = isOk && tcuImageCompare.pixelThresholdCompare('Results', 'Comparison result from rendering with Vertex Array Object', vaoReference, vaoResult, [0, 0, 0, 0]);
    420 
    421    if (!isOk)
    422        testFailedOptions('Result comparison failed', false);
    423    else
    424        testPassedOptions('Pass', true);
    425 
    426    return tcuTestCase.IterateResult.STOP;
    427 };
    428 
    429 /**
    430 * @constructor
    431 * @extends {tcuTestCase.DeqpTest}
    432 */
    433 es3fVertexArrayObjectTests.VertexArrayObjectTests = function() {
    434    tcuTestCase.DeqpTest.call(this, 'vertex_array_objects', 'Vertex array object test cases');
    435 };
    436 
    437 es3fVertexArrayObjectTests.VertexArrayObjectTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    438 es3fVertexArrayObjectTests.VertexArrayObjectTests.prototype.constructor = es3fVertexArrayObjectTests.VertexArrayObjectTests;
    439 
    440 es3fVertexArrayObjectTests.VertexArrayObjectTests.prototype.init = function() {
    441    var floatCoordBuffer48_1 = new es3fVertexArrayObjectTests.BufferSpec(48, 384, 2, 0, 0, gl.FLOAT, 0, 0, -1.0, 1.0);
    442    var floatCoordBuffer48_2 = new es3fVertexArrayObjectTests.BufferSpec(48, 384, 2, 0, 0, gl.FLOAT, 0, 0, -1.0, 1.0);
    443 
    444    var shortCoordBuffer48 = new es3fVertexArrayObjectTests.BufferSpec(48, 192, 2, 0, 0, gl.SHORT, -32768, 32768, 0.0, 0.0);
    445 
    446    var spec;
    447    var state;
    448    // Different buffer
    449    spec = new es3fVertexArrayObjectTests.Spec();
    450 
    451    state = new es3fVertexArrayObjectTests.VertexArrayState();
    452 
    453    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    454 
    455    state.attributes[0].enabled = true;
    456    state.attributes[0].size = 2;
    457    state.attributes[0].stride = 0;
    458    state.attributes[0].type = gl.FLOAT;
    459    state.attributes[0].integer = false;
    460    state.attributes[0].divisor = 0;
    461    state.attributes[0].offset = 0;
    462    state.attributes[0].normalized = false;
    463 
    464    state.elementArrayBuffer = 0;
    465 
    466    spec.buffers.push(floatCoordBuffer48_1);
    467    spec.buffers.push(floatCoordBuffer48_2);
    468 
    469    spec.useDrawElements = false;
    470    spec.instances = 0;
    471    spec.count = 48;
    472    spec.vao = state;
    473    spec.state = deUtil.clone(state);
    474    spec.indexOffset = 0;
    475    spec.indexRangeMin = 0;
    476    spec.indexRangeMax = 0;
    477    spec.indexType = gl.NONE;
    478    spec.indexCount = 0;
    479 
    480    spec.state.attributes[0].bufferNdx = 1;
    481    spec.vao.attributes[0].bufferNdx = 2;
    482    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_buffer', 'diff_buffer'));
    483 
    484    // Different size
    485    spec = new es3fVertexArrayObjectTests.Spec();
    486 
    487    state = new es3fVertexArrayObjectTests.VertexArrayState();
    488 
    489    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    490 
    491    state.attributes[0].enabled = true;
    492    state.attributes[0].size = 2;
    493    state.attributes[0].stride = 0;
    494    state.attributes[0].type = gl.FLOAT;
    495    state.attributes[0].integer = false;
    496    state.attributes[0].divisor = 0;
    497    state.attributes[0].offset = 0;
    498    state.attributes[0].normalized = false;
    499    state.attributes[0].bufferNdx = 1;
    500 
    501    state.elementArrayBuffer = 0;
    502 
    503    spec.buffers.push(floatCoordBuffer48_1);
    504 
    505    spec.useDrawElements = false;
    506    spec.instances = 0;
    507    spec.count = 24;
    508    spec.vao = state;
    509    spec.state = deUtil.clone(state);
    510    spec.indexOffset = 0;
    511    spec.indexRangeMin = 0;
    512    spec.indexRangeMax = 0;
    513    spec.indexType = gl.NONE;
    514    spec.indexCount = 0;
    515 
    516    spec.state.attributes[0].size = 2;
    517    spec.vao.attributes[0].size = 3;
    518    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_size', 'diff_size'));
    519 
    520    // Different stride
    521    spec = new es3fVertexArrayObjectTests.Spec();
    522 
    523    state = new es3fVertexArrayObjectTests.VertexArrayState();
    524 
    525    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    526 
    527    state.attributes[0].enabled = true;
    528    state.attributes[0].size = 2;
    529    state.attributes[0].stride = 0;
    530    state.attributes[0].type = gl.SHORT;
    531    state.attributes[0].integer = false;
    532    state.attributes[0].divisor = 0;
    533    state.attributes[0].offset = 0;
    534    state.attributes[0].normalized = true;
    535    state.attributes[0].bufferNdx = 1;
    536 
    537    state.elementArrayBuffer = 0;
    538 
    539    spec.buffers.push(shortCoordBuffer48);
    540 
    541    spec.useDrawElements = false;
    542    spec.instances = 0;
    543    spec.count = 24;
    544    spec.vao = state;
    545    spec.state = deUtil.clone(state);
    546    spec.indexOffset = 0;
    547    spec.indexRangeMin = 0;
    548    spec.indexRangeMax = 0;
    549    spec.indexType = gl.NONE;
    550    spec.indexCount = 0;
    551 
    552    spec.vao.attributes[0].stride = 2;
    553    spec.state.attributes[0].stride = 4;
    554    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_stride', 'diff_stride'));
    555 
    556    // Different types
    557    spec = new es3fVertexArrayObjectTests.Spec();
    558 
    559    state = new es3fVertexArrayObjectTests.VertexArrayState();
    560 
    561    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    562 
    563    state.attributes[0].enabled = true;
    564    state.attributes[0].size = 2;
    565    state.attributes[0].stride = 0;
    566    state.attributes[0].type = gl.SHORT;
    567    state.attributes[0].integer = false;
    568    state.attributes[0].divisor = 0;
    569    state.attributes[0].offset = 0;
    570    state.attributes[0].normalized = true;
    571    state.attributes[0].bufferNdx = 1;
    572 
    573    state.elementArrayBuffer = 0;
    574 
    575    spec.buffers.push(shortCoordBuffer48);
    576 
    577    spec.useDrawElements = false;
    578    spec.instances = 0;
    579    spec.count = 24;
    580    spec.vao = state;
    581    spec.state = deUtil.clone(state);
    582    spec.indexOffset = 0;
    583    spec.indexRangeMin = 0;
    584    spec.indexRangeMax = 0;
    585    spec.indexType = gl.NONE;
    586    spec.indexCount = 0;
    587 
    588    spec.vao.attributes[0].type = gl.SHORT;
    589    spec.state.attributes[0].type = gl.BYTE;
    590    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_type', 'diff_type'));
    591 
    592    // Different "integer"
    593    spec = new es3fVertexArrayObjectTests.Spec();
    594 
    595    state = new es3fVertexArrayObjectTests.VertexArrayState();
    596 
    597    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    598 
    599    state.attributes[0].enabled = true;
    600    state.attributes[0].size = 2;
    601    state.attributes[0].stride = 0;
    602    state.attributes[0].type = gl.BYTE;
    603    state.attributes[0].integer = true;
    604    state.attributes[0].divisor = 0;
    605    state.attributes[0].offset = 0;
    606    state.attributes[0].normalized = false;
    607    state.attributes[0].bufferNdx = 1;
    608 
    609    state.elementArrayBuffer = 0;
    610 
    611    spec.buffers.push(shortCoordBuffer48);
    612 
    613    spec.useDrawElements = false;
    614    spec.count = 24;
    615    spec.vao = state;
    616    spec.state = deUtil.clone(state);
    617    spec.instances = 0;
    618    spec.indexOffset = 0;
    619    spec.indexRangeMin = 0;
    620    spec.indexRangeMax = 0;
    621    spec.indexType = gl.NONE;
    622    spec.indexCount = 0;
    623 
    624    spec.state.attributes[0].integer = false;
    625    spec.vao.attributes[0].integer = true;
    626    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_integer', 'diff_integer'));
    627 
    628    // Different divisor
    629    spec = new es3fVertexArrayObjectTests.Spec();
    630 
    631    state = new es3fVertexArrayObjectTests.VertexArrayState();
    632 
    633    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    634    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    635 
    636    state.attributes[0].enabled = true;
    637    state.attributes[0].size = 2;
    638    state.attributes[0].stride = 0;
    639    state.attributes[0].type = gl.SHORT;
    640    state.attributes[0].integer = false;
    641    state.attributes[0].divisor = 0;
    642    state.attributes[0].offset = 0;
    643    state.attributes[0].normalized = true;
    644    state.attributes[0].bufferNdx = 1;
    645 
    646    state.attributes[1].enabled = true;
    647    state.attributes[1].size = 4;
    648    state.attributes[1].stride = 0;
    649    state.attributes[1].type = gl.FLOAT;
    650    state.attributes[1].integer = false;
    651    state.attributes[1].divisor = 0;
    652    state.attributes[1].offset = 0;
    653    state.attributes[1].normalized = false;
    654    state.attributes[1].bufferNdx = 2;
    655 
    656    state.elementArrayBuffer = 0;
    657 
    658    spec.buffers.push(shortCoordBuffer48);
    659    spec.buffers.push(floatCoordBuffer48_1);
    660 
    661    spec.useDrawElements = false;
    662    spec.instances = 10;
    663    spec.count = 12;
    664    spec.vao = state;
    665    spec.state = deUtil.clone(state);
    666    spec.indexOffset = 0;
    667    spec.indexRangeMin = 0;
    668    spec.indexRangeMax = 0;
    669    spec.indexType = gl.NONE;
    670    spec.indexCount = 0;
    671 
    672    spec.vao.attributes[1].divisor = 3;
    673    spec.state.attributes[1].divisor = 2;
    674 
    675    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_divisor', 'diff_divisor'));
    676 
    677    // Different offset
    678    spec = new es3fVertexArrayObjectTests.Spec();
    679 
    680    state = new es3fVertexArrayObjectTests.VertexArrayState();
    681 
    682    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    683 
    684    state.attributes[0].enabled = true;
    685    state.attributes[0].size = 2;
    686    state.attributes[0].stride = 0;
    687    state.attributes[0].type = gl.SHORT;
    688    state.attributes[0].integer = false;
    689    state.attributes[0].divisor = 0;
    690    state.attributes[0].offset = 0;
    691    state.attributes[0].normalized = true;
    692    state.attributes[0].bufferNdx = 1;
    693 
    694    state.elementArrayBuffer = 0;
    695 
    696    spec.buffers.push(shortCoordBuffer48);
    697 
    698    spec.useDrawElements = false;
    699    spec.instances = 0;
    700    spec.count = 24;
    701    spec.vao = state;
    702    spec.state = deUtil.clone(state);
    703    spec.indexOffset = 0;
    704    spec.indexRangeMin = 0;
    705    spec.indexRangeMax = 0;
    706    spec.indexType = gl.NONE;
    707    spec.indexCount = 0;
    708 
    709    spec.vao.attributes[0].offset = 2;
    710    spec.state.attributes[0].offset = 4;
    711    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_offset', 'diff_offset'));
    712 
    713    // Different normalize
    714    spec = new es3fVertexArrayObjectTests.Spec();
    715 
    716    state = new es3fVertexArrayObjectTests.VertexArrayState();
    717 
    718    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    719 
    720    state.attributes[0].enabled = true;
    721    state.attributes[0].size = 2;
    722    state.attributes[0].stride = 0;
    723    state.attributes[0].type = gl.SHORT;
    724    state.attributes[0].integer = false;
    725    state.attributes[0].divisor = 0;
    726    state.attributes[0].offset = 0;
    727    state.attributes[0].normalized = true;
    728    state.attributes[0].bufferNdx = 1;
    729 
    730    state.elementArrayBuffer = 0;
    731 
    732    spec.buffers.push(shortCoordBuffer48);
    733 
    734    spec.useDrawElements = false;
    735    spec.instances = 0;
    736    spec.count = 48;
    737    spec.vao = state;
    738    spec.state = deUtil.clone(state);
    739    spec.indexOffset = 0;
    740    spec.indexRangeMin = 0;
    741    spec.indexRangeMax = 0;
    742    spec.indexType = gl.NONE;
    743    spec.indexCount = 0;
    744 
    745    spec.vao.attributes[0].normalized = true;
    746    spec.state.attributes[0].normalized = false;
    747    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_normalize', 'diff_normalize'));
    748 
    749    // DrawElements with buffer
    750    spec = new es3fVertexArrayObjectTests.Spec();
    751 
    752    state = new es3fVertexArrayObjectTests.VertexArrayState();
    753 
    754    state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    755 
    756    state.attributes[0].enabled = true;
    757    state.attributes[0].size = 2;
    758    state.attributes[0].stride = 0;
    759    state.attributes[0].type = gl.FLOAT;
    760    state.attributes[0].integer = false;
    761    state.attributes[0].divisor = 0;
    762    state.attributes[0].offset = 0;
    763    state.attributes[0].normalized = true;
    764    state.attributes[0].bufferNdx = 1;
    765 
    766    state.elementArrayBuffer = 0;
    767 
    768    spec.buffers.push(floatCoordBuffer48_1);
    769 
    770    var indexBuffer = new es3fVertexArrayObjectTests.BufferSpec(24, 192, 1, 0, 0, gl.UNSIGNED_SHORT, 0, 47, 0.0, 0.0);
    771    spec.buffers.push(indexBuffer);
    772    spec.buffers.push(indexBuffer);
    773 
    774    spec.useDrawElements = true;
    775    spec.count = 24;
    776    spec.vao = state;
    777    spec.state = deUtil.clone(state);
    778    spec.instances = 0;
    779    spec.indexOffset = 0;
    780    spec.indexRangeMin = 0;
    781    spec.indexRangeMax = 48;
    782    spec.indexType = gl.UNSIGNED_SHORT;
    783    spec.indexCount = 24;
    784 
    785    spec.state.elementArrayBuffer = 3;
    786    spec.vao.elementArrayBuffer = 2;
    787    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_indices', 'diff_indices'));
    788 
    789    var attribCount = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    790    var random = new deRandom.Random(attribCount);
    791    spec = new es3fVertexArrayObjectTests.Spec();
    792 
    793    state = new es3fVertexArrayObjectTests.VertexArrayState();
    794 
    795    spec.useDrawElements = false;
    796    spec.instances = 0;
    797    spec.count = 24;
    798    spec.vao = state;
    799    spec.state = deUtil.clone(state);
    800    spec.indexOffset = 0;
    801    spec.indexRangeMin = 0;
    802    spec.indexRangeMax = 0;
    803    spec.indexType = gl.NONE;
    804    spec.indexCount = 0;
    805    spec.vao.elementArrayBuffer = 0;
    806    spec.state.elementArrayBuffer = 0;
    807 
    808    // Use all attributes
    809    for (var attribNdx = 0; attribNdx < attribCount; attribNdx++) {
    810        spec.buffers.push(shortCoordBuffer48);
    811 
    812        spec.state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    813        spec.state.attributes[attribNdx].enabled = (random.getInt(0, 4) == 0) ? false : true;
    814        spec.state.attributes[attribNdx].size = random.getInt(2, 4);
    815        spec.state.attributes[attribNdx].stride = 2 * random.getInt(1, 3);
    816        spec.state.attributes[attribNdx].type = gl.SHORT;
    817        spec.state.attributes[attribNdx].integer = random.getBool();
    818        spec.state.attributes[attribNdx].divisor = random.getInt(0, 1);
    819        spec.state.attributes[attribNdx].offset = 2 * random.getInt(0, 2);
    820        spec.state.attributes[attribNdx].normalized = random.getBool();
    821        spec.state.attributes[attribNdx].bufferNdx = attribNdx + 1;
    822 
    823        if (attribNdx == 0) {
    824            spec.state.attributes[attribNdx].divisor = 0;
    825            spec.state.attributes[attribNdx].enabled = true;
    826            spec.state.attributes[attribNdx].size = 2;
    827        }
    828 
    829        spec.vao.attributes.push(new es3fVertexArrayObjectTests.Attribute());
    830        spec.vao.attributes[attribNdx].enabled = (random.getInt(0, 4) == 0) ? false : true;
    831        spec.vao.attributes[attribNdx].size = random.getInt(2, 4);
    832        spec.vao.attributes[attribNdx].stride = 2 * random.getInt(1, 3);
    833        spec.vao.attributes[attribNdx].type = gl.SHORT;
    834        spec.vao.attributes[attribNdx].integer = random.getBool();
    835        spec.vao.attributes[attribNdx].divisor = random.getInt(0, 1);
    836        spec.vao.attributes[attribNdx].offset = 2 * random.getInt(0, 2);
    837        spec.vao.attributes[attribNdx].normalized = random.getBool();
    838        spec.vao.attributes[attribNdx].bufferNdx = attribCount - attribNdx;
    839 
    840        if (attribNdx == 0) {
    841            spec.vao.attributes[attribNdx].divisor = 0;
    842            spec.vao.attributes[attribNdx].enabled = true;
    843            spec.vao.attributes[attribNdx].size = 2;
    844        }
    845 
    846    }
    847    this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'all_attributes', 'all_attributes'));
    848 
    849 };
    850 
    851 /**
    852 * Run test
    853 * @param {WebGL2RenderingContext} context
    854 */
    855 es3fVertexArrayObjectTests.run = function(context) {
    856    gl = context;
    857    //Set up Test Root parameters
    858    var state = tcuTestCase.runner;
    859    state.setRoot(new es3fVertexArrayObjectTests.VertexArrayObjectTests());
    860 
    861    //Set up name and description of this test series.
    862    setCurrentTestName(state.testCases.fullName());
    863    description(state.testCases.getDescription());
    864 
    865    try {
    866        //Run test cases
    867        tcuTestCase.runTestCases();
    868    }
    869    catch (err) {
    870        testFailedOptions('Failed to es3fVertexArrayObjectTests.run tests', false);
    871        tcuTestCase.runner.terminate();
    872    }
    873 };
    874 
    875 });