tor-browser

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

es3fDrawTests.js (53537B)


      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.es3fDrawTests');
     23 goog.require('framework.common.tcuLogImage');
     24 goog.require('framework.common.tcuRGBA');
     25 goog.require('framework.common.tcuSurface');
     26 goog.require('framework.common.tcuTestCase');
     27 goog.require('framework.common.tcuTexture');
     28 goog.require('framework.delibs.debase.deMath');
     29 goog.require('framework.delibs.debase.deRandom');
     30 goog.require('framework.delibs.debase.deString');
     31 goog.require('framework.delibs.debase.deUtil');
     32 goog.require('framework.opengl.gluDrawUtil');
     33 goog.require('framework.opengl.gluShaderProgram');
     34 goog.require('framework.opengl.gluShaderUtil');
     35 goog.require('framework.opengl.gluTexture');
     36 goog.require('framework.opengl.gluVarType');
     37 goog.require('framework.opengl.simplereference.sglrGLContext');
     38 goog.require('framework.opengl.simplereference.sglrShaderProgram');
     39 goog.require('framework.referencerenderer.rrFragmentOperations');
     40 goog.require('framework.referencerenderer.rrGenericVector');
     41 goog.require('framework.referencerenderer.rrShadingContext');
     42 goog.require('framework.referencerenderer.rrVertexAttrib');
     43 goog.require('framework.referencerenderer.rrVertexPacket');
     44 goog.require('modules.shared.glsDrawTests');
     45 
     46 goog.scope(function() {
     47 
     48    var es3fDrawTests = functional.gles3.es3fDrawTests;
     49    var gluDrawUtil = framework.opengl.gluDrawUtil;
     50    var gluShaderUtil = framework.opengl.gluShaderUtil;
     51    var gluShaderProgram = framework.opengl.gluShaderProgram;
     52    var gluTexture = framework.opengl.gluTexture;
     53    var gluVarType = framework.opengl.gluVarType;
     54    var tcuLogImage = framework.common.tcuLogImage;
     55    var tcuRGBA = framework.common.tcuRGBA;
     56    var tcuTestCase = framework.common.tcuTestCase;
     57    var tcuSurface = framework.common.tcuSurface;
     58    var tcuTexture = framework.common.tcuTexture;
     59    var deMath = framework.delibs.debase.deMath;
     60    var deString = framework.delibs.debase.deString;
     61    var deRandom = framework.delibs.debase.deRandom;
     62    var deUtil = framework.delibs.debase.deUtil;
     63    var glsDrawTests = modules.shared.glsDrawTests;
     64    var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
     65    var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
     66    var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
     67    var rrGenericVector = framework.referencerenderer.rrGenericVector;
     68    var rrShadingContext = framework.referencerenderer.rrShadingContext;
     69    var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
     70    var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
     71 
     72    /** @type {WebGL2RenderingContext}*/ var gl;
     73 
     74    /**
     75     * @enum
     76     */
     77    es3fDrawTests.TestIterationType = {
     78        DRAW_COUNT: 0, // !< test with 2, 6, and 26 primitives
     79        INSTANCE_COUNT: 1, // !< test with 2, 4, and 12 instances
     80        INDEX_RANGE: 2
     81    };
     82 
     83    /**
     84     * @param {glsDrawTests.DrawTest} test
     85     * @param {glsDrawTests.DrawTestSpec} baseSpec
     86     * @param {?es3fDrawTests.TestIterationType} type
     87     */
     88    es3fDrawTests.addTestIterations = function(test, baseSpec, type) {
     89        var spec = /** @type {glsDrawTests.DrawTestSpec} */ (deUtil.clone(baseSpec));
     90 
     91        if (type == es3fDrawTests.TestIterationType.DRAW_COUNT) {
     92            spec.primitiveCount = 1;
     93            test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
     94 
     95            spec.primitiveCount = 5;
     96            test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
     97 
     98            spec.primitiveCount = 25;
     99            test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
    100        } else if (type == es3fDrawTests.TestIterationType.INSTANCE_COUNT) {
    101            spec.instanceCount = 1;
    102            test.addIteration(spec, 'instance count = ' + spec.instanceCount);
    103 
    104            spec.instanceCount = 4;
    105            test.addIteration(spec, 'instance count = ' + spec.instanceCount);
    106 
    107            spec.instanceCount = 11;
    108            test.addIteration(spec, 'instance count = ' + spec.instanceCount);
    109        } else if (type == es3fDrawTests.TestIterationType.INDEX_RANGE) {
    110            spec.indexMin = 0;
    111            spec.indexMax = 23;
    112            test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
    113 
    114            spec.indexMin = 23;
    115            spec.indexMax = 40;
    116            test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
    117 
    118            // Only makes sense with points
    119            if (spec.primitive == glsDrawTests.DrawTestSpec.Primitive.POINTS) {
    120                spec.indexMin = 5;
    121                spec.indexMax = 5;
    122                test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
    123            }
    124        } else
    125            throw new Error('Invalid test iteration type');
    126    };
    127 
    128    /**
    129     * @param {glsDrawTests.DrawTestSpec} spec
    130     * @param {?glsDrawTests.DrawTestSpec.DrawMethod} method
    131     */
    132    es3fDrawTests.genBasicSpec = function(spec, method) {
    133        //spec.apiType = glu::ApiType::es(3,0);
    134        spec.primitive = glsDrawTests.DrawTestSpec.Primitive.TRIANGLES;
    135        spec.primitiveCount = 6;
    136        spec.drawMethod = method;
    137        spec.indexType = null;
    138        spec.indexPointerOffset = 0;
    139        spec.indexStorage = null;
    140        spec.first = 0;
    141        spec.indexMin = 0;
    142        spec.indexMax = 0;
    143        spec.instanceCount = 1;
    144 
    145        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    146 
    147        spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    148        spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    149        spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    150        spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    151        spec.attribs[0].componentCount = 4;
    152        spec.attribs[0].offset = 0;
    153        spec.attribs[0].stride = 0;
    154        spec.attribs[0].normalize = false;
    155        spec.attribs[0].instanceDivisor = 0;
    156        spec.attribs[0].useDefaultAttribute = false;
    157 
    158        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    159 
    160        spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    161        spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    162        spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    163        spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    164        spec.attribs[1].componentCount = 2;
    165        spec.attribs[1].offset = 0;
    166        spec.attribs[1].stride = 0;
    167        spec.attribs[1].normalize = false;
    168        spec.attribs[1].instanceDivisor = 0;
    169        spec.attribs[1].useDefaultAttribute = false;
    170    };
    171 
    172    /**
    173     * @constructor
    174     * @extends {tcuTestCase.DeqpTest}
    175     * @param {string} name
    176     * @param {string} descr
    177     * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
    178     * @param {?glsDrawTests.DrawTestSpec.Primitive} primitive
    179     * @param {?glsDrawTests.DrawTestSpec.IndexType} indexType
    180     * @param {?glsDrawTests.DrawTestSpec.Storage} indexStorage
    181     */
    182    es3fDrawTests.AttributeGroup = function(name, descr, drawMethod, primitive, indexType, indexStorage) {
    183        tcuTestCase.DeqpTest.call(this, name, descr);
    184        this.m_method = drawMethod;
    185        this.m_primitive = primitive;
    186        this.m_indexType = indexType;
    187        this.m_indexStorage = indexStorage;
    188        this.makeExecutable();
    189    };
    190 
    191    es3fDrawTests.AttributeGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    192    es3fDrawTests.AttributeGroup.prototype.constructor = es3fDrawTests.AttributeGroup;
    193 
    194    es3fDrawTests.AttributeGroup.prototype.init = function() {
    195        // select test type
    196        /** @type {boolean} */ var instanced = this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED ||
    197            this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED;
    198        /** @type {boolean} */ var ranged = this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED;
    199        /** @type {es3fDrawTests.TestIterationType} */ var testType = instanced ? es3fDrawTests.TestIterationType.INSTANCE_COUNT :
    200            (ranged ? es3fDrawTests.TestIterationType.INDEX_RANGE : es3fDrawTests.TestIterationType.DRAW_COUNT);
    201 
    202        // Single attribute
    203        /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, 'single_attribute', 'Single attribute array.');
    204        /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
    205 
    206        //spec.apiType = glu::ApiType::es(3,0);
    207        spec.primitive = this.m_primitive;
    208        spec.primitiveCount = 5;
    209        spec.drawMethod = this.m_method;
    210        spec.indexType = this.m_indexType;
    211        spec.indexPointerOffset = 0;
    212        spec.indexStorage = this.m_indexStorage;
    213        spec.first = 0;
    214        spec.indexMin = 0;
    215        spec.indexMax = 0;
    216        spec.instanceCount = 1;
    217 
    218        spec.attribs.length = 0;
    219 
    220        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    221        spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    222        spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    223        spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    224        spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    225        spec.attribs[0].componentCount = 2;
    226        spec.attribs[0].offset = 0;
    227        spec.attribs[0].stride = 0;
    228        spec.attribs[0].normalize = false;
    229        spec.attribs[0].instanceDivisor = 0;
    230        spec.attribs[0].useDefaultAttribute = false;
    231 
    232        es3fDrawTests.addTestIterations(test, spec, testType);
    233 
    234        this.addChild(test);
    235 
    236        // Multiple attribute
    237 
    238        test = new glsDrawTests.DrawTest(null, 'multiple_attributes', 'Multiple attribute arrays.');
    239        spec.primitive = this.m_primitive;
    240        spec.primitiveCount = 5;
    241        spec.drawMethod = this.m_method;
    242        spec.indexType = this.m_indexType;
    243        spec.indexPointerOffset = 0;
    244        spec.indexStorage = this.m_indexStorage;
    245        spec.first = 0;
    246        spec.indexMin = 0;
    247        spec.indexMax = 0;
    248        spec.instanceCount = 1;
    249 
    250        spec.attribs.length = 0;
    251 
    252        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    253        spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    254        spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    255        spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    256        spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    257        spec.attribs[0].componentCount = 4;
    258        spec.attribs[0].offset = 0;
    259        spec.attribs[0].stride = 0;
    260        spec.attribs[0].normalize = false;
    261        spec.attribs[0].instanceDivisor = 0;
    262        spec.attribs[0].useDefaultAttribute = false;
    263 
    264        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    265        spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    266        spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    267        spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    268        spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    269        spec.attribs[1].componentCount = 2;
    270        spec.attribs[1].offset = 0;
    271        spec.attribs[1].stride = 0;
    272        spec.attribs[1].normalize = false;
    273        spec.attribs[1].instanceDivisor = 0;
    274        spec.attribs[1].useDefaultAttribute = false;
    275 
    276        es3fDrawTests.addTestIterations(test, spec, testType);
    277 
    278        this.addChild(test);
    279 
    280        // Multiple attribute, second one divided
    281 
    282        test = new glsDrawTests.DrawTest(null, 'instanced_attributes', 'Instanced attribute array.');
    283 
    284        //spec.apiType = glu::ApiType::es(3,0);
    285        spec.primitive = this.m_primitive;
    286        spec.primitiveCount = 5;
    287        spec.drawMethod = this.m_method;
    288        spec.indexType = this.m_indexType;
    289        spec.indexPointerOffset = 0;
    290        spec.indexStorage = this.m_indexStorage;
    291        spec.first = 0;
    292        spec.indexMin = 0;
    293        spec.indexMax = 0;
    294        spec.instanceCount = 1;
    295 
    296        spec.attribs.length = 0;
    297 
    298        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    299        spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    300        spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    301        spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    302        spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    303        spec.attribs[0].componentCount = 4;
    304        spec.attribs[0].offset = 0;
    305        spec.attribs[0].stride = 0;
    306        spec.attribs[0].normalize = false;
    307        spec.attribs[0].instanceDivisor = 0;
    308        spec.attribs[0].useDefaultAttribute = false;
    309 
    310        // Add another position component so the instances wont be drawn on each other
    311        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    312        spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    313        spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    314        spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    315        spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    316        spec.attribs[1].componentCount = 2;
    317        spec.attribs[1].offset = 0;
    318        spec.attribs[1].stride = 0;
    319        spec.attribs[1].normalize = false;
    320        spec.attribs[1].instanceDivisor = 1;
    321        spec.attribs[1].useDefaultAttribute = false;
    322        spec.attribs[1].additionalPositionAttribute = true;
    323 
    324        // Instanced color
    325        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    326        spec.attribs[2].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    327        spec.attribs[2].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    328        spec.attribs[2].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    329        spec.attribs[2].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    330        spec.attribs[2].componentCount = 3;
    331        spec.attribs[2].offset = 0;
    332        spec.attribs[2].stride = 0;
    333        spec.attribs[2].normalize = false;
    334        spec.attribs[2].instanceDivisor = 1;
    335        spec.attribs[2].useDefaultAttribute = false;
    336 
    337        es3fDrawTests.addTestIterations(test, spec, testType);
    338 
    339        this.addChild(test);
    340 
    341        // Multiple attribute, second one default
    342        test = new glsDrawTests.DrawTest(null, 'default_attribute', 'Attribute specified with glVertexAttrib*.');
    343 
    344        //spec.apiType = glu::ApiType::es(3,0);
    345        spec.primitive = this.m_primitive;
    346        spec.primitiveCount = 5;
    347        spec.drawMethod = this.m_method;
    348        spec.indexType = this.m_indexType;
    349        spec.indexPointerOffset = 0;
    350        spec.indexStorage = this.m_indexStorage;
    351        spec.first = 0;
    352        spec.indexMin = 0;
    353        spec.indexMax = 17; // \note addTestIterations is not called for the spec, so we must ensure [indexMin, indexMax] is a good range
    354        spec.instanceCount = 1;
    355 
    356        spec.attribs.length = 0;
    357 
    358        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    359        spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
    360        spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
    361        spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    362        spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    363        spec.attribs[0].componentCount = 2;
    364        spec.attribs[0].offset = 0;
    365        spec.attribs[0].stride = 0;
    366        spec.attribs[0].normalize = false;
    367        spec.attribs[0].instanceDivisor = 0;
    368        spec.attribs[0].useDefaultAttribute = false;
    369 
    370        /** @type {Array<{input:?glsDrawTests.DrawTestSpec.InputType, output:?glsDrawTests.DrawTestSpec.OutputType, componentCount:number}>} */ var iopairs = [
    371            {input: glsDrawTests.DrawTestSpec.InputType.FLOAT, output: glsDrawTests.DrawTestSpec.OutputType.VEC2, componentCount: 4},
    372            {input: glsDrawTests.DrawTestSpec.InputType.FLOAT, output: glsDrawTests.DrawTestSpec.OutputType.VEC4, componentCount: 2},
    373            {input: glsDrawTests.DrawTestSpec.InputType.INT, output: glsDrawTests.DrawTestSpec.OutputType.IVEC3, componentCount: 4},
    374            {input: glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT, output: glsDrawTests.DrawTestSpec.OutputType.UVEC2, componentCount: 4}
    375        ];
    376 
    377        spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
    378        for (var ioNdx = 0; ioNdx < iopairs.length; ++ioNdx) {
    379            /** @type {string} */ var desc = glsDrawTests.DrawTestSpec.inputTypeToString(iopairs[ioNdx].input) + iopairs[ioNdx].componentCount + ' to ' + glsDrawTests.DrawTestSpec.outputTypeToString(iopairs[ioNdx].output);
    380 
    381            spec.attribs[1].inputType = iopairs[ioNdx].input;
    382            spec.attribs[1].outputType = iopairs[ioNdx].output;
    383            spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
    384            spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
    385            spec.attribs[1].componentCount = iopairs[ioNdx].componentCount;
    386            spec.attribs[1].offset = 0;
    387            spec.attribs[1].stride = 0;
    388            spec.attribs[1].normalize = false;
    389            spec.attribs[1].instanceDivisor = 0;
    390            spec.attribs[1].useDefaultAttribute = true;
    391 
    392            test.addIteration(spec, desc);
    393        }
    394 
    395        this.addChild(test);
    396    };
    397 
    398    /**
    399     * @constructor
    400     * @extends {tcuTestCase.DeqpTest}
    401     * @param {string} name
    402     * @param {string} descr
    403     * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
    404     */
    405    es3fDrawTests.IndexGroup = function(name, descr, drawMethod) {
    406        tcuTestCase.DeqpTest.call(this, name, descr);
    407        /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
    408        this.makeExecutable();
    409    };
    410 
    411    es3fDrawTests.IndexGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    412    es3fDrawTests.IndexGroup.prototype.constructor = es3fDrawTests.IndexGroup;
    413 
    414    es3fDrawTests.IndexGroup.prototype.init = function() {
    415        /** @type {Array<{storage: ?glsDrawTests.DrawTestSpec.Storage, type: ?glsDrawTests.DrawTestSpec.IndexType, aligned: boolean, offsets: Array<number>}>} */ var tests = [
    416            {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.BYTE, aligned: true, offsets: [0, 1, -1]},
    417            {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.SHORT, aligned: true, offsets: [0, 2, -1]},
    418            {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.INT, aligned: true, offsets: [0, 4, -1]},
    419 
    420            {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.SHORT, aligned: false, offsets: [1, 3, -1]},
    421            {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.INT, aligned: false, offsets: [2, 3, -1]}
    422        ];
    423 
    424        /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
    425        es3fDrawTests.genBasicSpec(spec, this.m_method);
    426 
    427        /** @type {tcuTestCase.DeqpTest} */ var bufferGroup = new tcuTestCase.DeqpTest('buffer', 'buffer');
    428        /** @type {tcuTestCase.DeqpTest} */ var unalignedBufferGroup = new tcuTestCase.DeqpTest('unaligned_buffer', 'unaligned buffer');
    429 
    430        this.addChild(bufferGroup);
    431        this.addChild(unalignedBufferGroup);
    432 
    433        for (var testNdx = 0; testNdx < tests.length; ++testNdx) {
    434            /** @type {{storage: ?glsDrawTests.DrawTestSpec.Storage, type: ?glsDrawTests.DrawTestSpec.IndexType, aligned: boolean, offsets: Array<number>}} */
    435            var indexTest = tests[testNdx];
    436            /** @type {tcuTestCase.DeqpTest} */ var group = indexTest.aligned ? bufferGroup : unalignedBufferGroup;
    437 
    438            /** @type {string} */ var name = 'index_' + glsDrawTests.DrawTestSpec.indexTypeToString(indexTest.type);
    439            /** @type {string} */ var desc = 'index ' + glsDrawTests.DrawTestSpec.indexTypeToString(indexTest.type) + ' in ' + glsDrawTests.DrawTestSpec.storageToString(indexTest.storage);
    440            /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, name, desc);
    441 
    442            spec.indexType = indexTest.type;
    443            spec.indexStorage = indexTest.storage;
    444 
    445            for (var iterationNdx = 0; iterationNdx < indexTest.offsets.length && indexTest.offsets[iterationNdx] != -1; ++iterationNdx) {
    446                /** @type {string} */ var iterationDesc = 'offset ' + indexTest.offsets[iterationNdx];
    447                spec.indexPointerOffset = indexTest.offsets[iterationNdx];
    448                test.addIteration(spec, iterationDesc);
    449            }
    450 
    451            if (spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_OFFSET &&
    452                spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_STRIDE)
    453                group.addChild(test);
    454        }
    455    };
    456 
    457    /**
    458     * @constructor
    459     * @extends {tcuTestCase.DeqpTest}
    460     * @param {string} name
    461     * @param {string} descr
    462     * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
    463     */
    464    es3fDrawTests.FirstGroup = function(name, descr, drawMethod) {
    465        tcuTestCase.DeqpTest.call(this, name, descr);
    466        /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
    467        this.makeExecutable();
    468    };
    469 
    470    es3fDrawTests.FirstGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    471    es3fDrawTests.FirstGroup.prototype.constructor = es3fDrawTests.FirstGroup;
    472 
    473    /**
    474     * init
    475     */
    476    es3fDrawTests.FirstGroup.prototype.init = function() {
    477        var firsts =
    478        [
    479            1, 3, 17
    480        ];
    481 
    482        /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
    483        es3fDrawTests.genBasicSpec(spec, this.m_method);
    484 
    485        for (var firstNdx = 0; firstNdx < firsts.length; ++firstNdx) {
    486            var name = 'first_' + firsts[firstNdx];
    487            var desc = 'first ' + firsts[firstNdx];
    488            /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, name, desc);
    489 
    490            spec.first = firsts[firstNdx];
    491 
    492            es3fDrawTests.addTestIterations(test, spec, es3fDrawTests.TestIterationType.DRAW_COUNT);
    493 
    494            this.addChild(test);
    495        }
    496    };
    497 
    498    /**
    499     * @constructor
    500     * @extends {tcuTestCase.DeqpTest}
    501     * @param {string} name
    502     * @param {string} descr
    503     * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
    504     */
    505    es3fDrawTests.MethodGroup = function(name, descr, drawMethod) {
    506        tcuTestCase.DeqpTest.call(this, name, descr);
    507        /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
    508        this.makeExecutable();
    509    };
    510 
    511    es3fDrawTests.MethodGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    512    es3fDrawTests.MethodGroup.prototype.constructor = es3fDrawTests.MethodGroup;
    513 
    514    /**
    515     * init
    516     */
    517    es3fDrawTests.MethodGroup.prototype.init = function() {
    518        var indexed = (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED);
    519        var hasFirst = (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED);
    520 
    521        var primitive =
    522        [
    523            glsDrawTests.DrawTestSpec.Primitive.POINTS,
    524            glsDrawTests.DrawTestSpec.Primitive.TRIANGLES,
    525            glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN,
    526            glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP,
    527            glsDrawTests.DrawTestSpec.Primitive.LINES,
    528            glsDrawTests.DrawTestSpec.Primitive.LINE_STRIP,
    529            glsDrawTests.DrawTestSpec.Primitive.LINE_LOOP
    530        ];
    531 
    532        if (hasFirst) {
    533            // First-tests
    534            this.addChild(new es3fDrawTests.FirstGroup('first', 'First tests', this.m_method));
    535        }
    536 
    537        if (indexed) {
    538            // Index-tests
    539            if (this.m_method != glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED)
    540                this.addChild(new es3fDrawTests.IndexGroup('indices', 'Index tests', this.m_method));
    541        }
    542 
    543        for (var ndx = 0; ndx < primitive.length; ++ndx) {
    544            var name = glsDrawTests.DrawTestSpec.primitiveToString(primitive[ndx]);
    545            var desc = glsDrawTests.DrawTestSpec.primitiveToString(primitive[ndx]);
    546 
    547            this.addChild(new es3fDrawTests.AttributeGroup(name, desc, this.m_method, primitive[ndx], glsDrawTests.DrawTestSpec.IndexType.SHORT, glsDrawTests.DrawTestSpec.Storage.BUFFER));
    548        }
    549    };
    550 
    551    /**
    552     * es3fDrawTests.GridProgram
    553     * @constructor
    554     * @extends {sglrShaderProgram.ShaderProgram}
    555     */
    556    es3fDrawTests.GridProgram = function() {
    557        /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
    558 
    559        decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
    560        decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_offset', rrGenericVector.GenericVecType.FLOAT));
    561        decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_color', rrGenericVector.GenericVecType.FLOAT));
    562 
    563        decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
    564        decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
    565 
    566        decl.pushVertexSource(new sglrShaderProgram.VertexSource(
    567            '#version 300 es\n' +
    568            'in highp vec4 a_position;\n' +
    569            'in highp vec4 a_offset;\n' +
    570            'in highp vec4 a_color;\n' +
    571            'out mediump vec4 v_color;\n' +
    572            'void main(void)\n' +
    573            '{\n' +
    574            ' gl_Position = a_position + a_offset;\n' +
    575            ' v_color = a_color;\n' +
    576            '}\n'
    577        ));
    578        decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
    579            '#version 300 es\n' +
    580            'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
    581            'in mediump vec4 v_color;\n' +
    582            'void main(void)\n' +
    583            '{\n' +
    584            ' dEQP_FragColor = v_color;\n' +
    585            '}\n'
    586        ));
    587 
    588        sglrShaderProgram.ShaderProgram.call(this, decl);
    589    };
    590 
    591    es3fDrawTests.GridProgram.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
    592    es3fDrawTests.GridProgram.prototype.constructor = es3fDrawTests.GridProgram;
    593 
    594    /**
    595     * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
    596     * @param {Array<rrVertexPacket.VertexPacket>} packets
    597     * @param {number} numPackets
    598     */
    599    es3fDrawTests.GridProgram.prototype.shadeVertices = function(inputs, packets, numPackets) {
    600        for (var ndx = 0; ndx < numPackets; ++ndx) {
    601            packets[ndx].position = deMath.add(
    602                rrVertexAttrib.readVertexAttrib(inputs[0], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT),
    603                rrVertexAttrib.readVertexAttrib(inputs[1], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT)
    604            );
    605            packets[ndx].outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[2], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT);
    606        }
    607    };
    608 
    609    /**
    610     * @param {Array<rrFragmentOperations.Fragment>} packets
    611     * @param {rrShadingContext.FragmentShadingContext} context
    612     */
    613    es3fDrawTests.GridProgram.prototype.shadeFragments = function(packets, context) {
    614        for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx)
    615        for (var fragNdx = 0; fragNdx < 4; ++fragNdx)
    616            packets[packetNdx].value = rrShadingContext.readTriangleVarying(packets[packetNdx], context, fragNdx);
    617    };
    618 
    619    /**
    620     * InstancedGridRenderTest
    621     * @constructor
    622     * @extends {tcuTestCase.DeqpTest}
    623     * @param {string} name
    624     * @param {string} desc
    625     * @param {number} gridSide
    626     * @param {boolean} useIndices
    627     */
    628    es3fDrawTests.InstancedGridRenderTest = function(name, desc, gridSide, useIndices) {
    629        tcuTestCase.DeqpTest.call(this, name, desc);
    630        this.m_gridSide = gridSide;
    631        this.m_useIndices = useIndices;
    632    };
    633 
    634    es3fDrawTests.InstancedGridRenderTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    635    es3fDrawTests.InstancedGridRenderTest.prototype.constructor = es3fDrawTests.InstancedGridRenderTest;
    636 
    637    /**
    638     * iterate
    639     * @return {tcuTestCase.IterateResult}
    640     */
    641    es3fDrawTests.InstancedGridRenderTest.prototype.iterate = function() {
    642        var renderTargetWidth = Math.min(1024, gl.canvas.width);
    643        var renderTargetHeight = Math.min(1024, gl.canvas.height);
    644 
    645        /** @type {sglrGLContext.GLContext} */ var ctx = new sglrGLContext.GLContext(gl);
    646        /** @type {tcuSurface.Surface} */ var surface = new tcuSurface.Surface(renderTargetWidth, renderTargetHeight);
    647        /** @type {es3fDrawTests.GridProgram} */ var program = new es3fDrawTests.GridProgram();
    648 
    649        // render
    650 
    651        this.renderTo(ctx, program, surface);
    652 
    653        // verify image
    654 
    655        if (this.verifyImage(surface))
    656            testPassed('');
    657        else
    658            testFailed('Incorrect rendering result');
    659        return tcuTestCase.IterateResult.STOP;
    660    };
    661 
    662    /**
    663     * @param {sglrGLContext.GLContext} ctx
    664     * @param {sglrShaderProgram.ShaderProgram} program
    665     * @param {tcuSurface.Surface} dst
    666     */
    667    es3fDrawTests.InstancedGridRenderTest.prototype.renderTo = function(ctx, program, dst) {
    668        var green = [0, 1, 0, 1];
    669        var yellow = [1, 1, 0, 1];
    670 
    671        /** @type {WebGLBuffer} */ var positionBuf = null;
    672        /** @type {WebGLBuffer} */ var offsetBuf = null;
    673        /** @type {WebGLBuffer} */ var colorBuf = null;
    674        /** @type {WebGLBuffer} */ var indexBuf = null;
    675        /** @type {WebGLProgram} */ var programID = ctx.createProgram(program);
    676        /** @type {number} */ var posLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_position');
    677        /** @type {number} */ var offsetLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_offset');
    678        /** @type {number} */ var colorLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_color');
    679 
    680        var cellW = 2.0 / this.m_gridSide;
    681        var cellH = 2.0 / this.m_gridSide;
    682        var vertexPositions = new Float32Array([
    683            0, 0, 0, 1,
    684            cellW, 0, 0, 1,
    685            0, cellH, 0, 1,
    686 
    687            0, cellH, 0, 1,
    688            cellW, 0, 0, 1,
    689            cellW, cellH, 0, 1
    690        ]);
    691 
    692        var indices = new Uint16Array([
    693            0, 4, 3,
    694            2, 1, 5
    695        ]);
    696 
    697        var offsets = [];
    698        for (var x = 0; x < this.m_gridSide; ++x)
    699        for (var y = 0; y < this.m_gridSide; ++y) {
    700            offsets.push(x * cellW - 1.0);
    701            offsets.push(y * cellW - 1.0);
    702            offsets.push(0, 0);
    703        }
    704        offsets = new Float32Array(offsets);
    705 
    706        var colors = [];
    707        for (var x = 0; x < this.m_gridSide; ++x)
    708        for (var y = 0; y < this.m_gridSide; ++y) {
    709            var colorToPush = ((x + y) % 2 == 0) ? (green) : (yellow);
    710            colors.push(colorToPush[0]);
    711            colors.push(colorToPush[1]);
    712            colors.push(colorToPush[2]);
    713            colors.push(colorToPush[3]);
    714        }
    715        colors = new Float32Array(colors);
    716 
    717        positionBuf = ctx.createBuffer();
    718        ctx.bindBuffer(gl.ARRAY_BUFFER, positionBuf);
    719        ctx.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);
    720        ctx.vertexAttribPointer(posLocation, 4, gl.FLOAT, false, 0, 0);
    721        ctx.vertexAttribDivisor(posLocation, 0);
    722        ctx.enableVertexAttribArray(posLocation);
    723 
    724        offsetBuf = ctx.createBuffer();
    725        ctx.bindBuffer(gl.ARRAY_BUFFER, offsetBuf);
    726        ctx.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
    727        ctx.vertexAttribPointer(offsetLocation, 4, gl.FLOAT, false, 0, 0);
    728        ctx.vertexAttribDivisor(offsetLocation, 1);
    729        ctx.enableVertexAttribArray(offsetLocation);
    730 
    731        colorBuf = ctx.createBuffer();
    732        ctx.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
    733        ctx.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
    734        ctx.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
    735        ctx.vertexAttribDivisor(colorLocation, 1);
    736        ctx.enableVertexAttribArray(colorLocation);
    737 
    738        if (this.m_useIndices) {
    739            indexBuf = ctx.createBuffer();
    740            ctx.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuf);
    741            ctx.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
    742        }
    743 
    744        ctx.clearColor(0, 0, 0, 1);
    745        ctx.clear(gl.COLOR_BUFFER_BIT);
    746 
    747        ctx.viewport(0, 0, dst.getWidth(), dst.getHeight());
    748 
    749        ctx.useProgram(programID);
    750        if (this.m_useIndices)
    751            ctx.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, this.m_gridSide * this.m_gridSide);
    752        else
    753            ctx.drawArraysInstanced(gl.TRIANGLES, 0, 6, this.m_gridSide * this.m_gridSide);
    754        ctx.useProgram(null);
    755 
    756        if (this.m_useIndices)
    757            ctx.deleteBuffer(indexBuf);
    758        ctx.deleteBuffer(colorBuf);
    759        ctx.deleteBuffer(offsetBuf);
    760        ctx.deleteBuffer(positionBuf);
    761        ctx.deleteProgram(programID);
    762 
    763        ctx.finish();
    764        dst.readViewport(ctx, [0 , 0, dst.getWidth(), dst.getHeight()]);
    765    };
    766 
    767    /**
    768     * @param {tcuSurface.Surface} image
    769     * @return {boolean}
    770     */
    771    es3fDrawTests.InstancedGridRenderTest.prototype.verifyImage = function(image) {
    772        // \note the green/yellow pattern is only for clarity. The test will only verify that all instances were drawn by looking for anything non-green/yellow.
    773 
    774        var green = [0, 255, 0, 255];
    775        var yellow = [255, 255, 0, 255];
    776        var colorThreshold = 20;
    777 
    778        /** @type {tcuSurface.Surface} */ var error = new tcuSurface.Surface(image.getWidth(), image.getHeight());
    779        var isOk = true;
    780 
    781        for (var y = 1; y < image.getHeight() - 1; y++)
    782        for (var x = 1; x < image.getWidth() - 1; x++) {
    783            /** @type {tcuRGBA.RGBA} */ var pixel = new tcuRGBA.RGBA(image.getPixel(x, y));
    784            var pixelOk = true;
    785 
    786            // Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
    787            if (Math.abs(pixel.getGreen() - 255) > colorThreshold)
    788                pixelOk = false;
    789 
    790            // Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
    791            if (Math.abs(pixel.getBlue() - 0) > colorThreshold)
    792                pixelOk = false;
    793 
    794            error.setPixel(x, y, pixelOk ? [0, 255, 0, 255] : [255, 0, 0, 255]);
    795            isOk = isOk && pixelOk;
    796        }
    797 
    798        if (!isOk) {
    799            bufferedLogToConsole('Image verification failed.');
    800            debug('Verfication result');
    801            tcuLogImage.logImageWithInfo(image.getAccess(), 'Result');
    802            tcuLogImage.logImageWithInfo(error.getAccess(), 'Error mask');
    803        } else {
    804            debug('Verfication result');
    805        }
    806 
    807        return isOk;
    808    };
    809 
    810    /**
    811     * InstancingGroup
    812     * @constructor
    813     * @extends {tcuTestCase.DeqpTest}
    814     */
    815    es3fDrawTests.InstancingGroup = function(name, descr) {
    816        tcuTestCase.DeqpTest.call(this, name, descr);
    817        this.makeExecutable();
    818    };
    819 
    820    es3fDrawTests.InstancingGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    821    es3fDrawTests.InstancingGroup.prototype.constructor = es3fDrawTests.InstancingGroup;
    822 
    823    /**
    824     * init
    825     */
    826    es3fDrawTests.InstancingGroup.prototype.init = function() {
    827        var gridWidths = [
    828            2,
    829            5,
    830            10,
    831            32,
    832            100
    833        ];
    834 
    835        // drawArrays
    836        for (var ndx = 0; ndx < gridWidths.length; ++ndx) {
    837            var name = 'draw_arrays_instanced_grid_' + gridWidths[ndx] + 'x' + gridWidths[ndx];
    838            var desc = 'DrawArraysInstanced, Grid size ' + gridWidths[ndx] + 'x' + gridWidths[ndx];
    839 
    840            this.addChild(new es3fDrawTests.InstancedGridRenderTest(name, desc, gridWidths[ndx], false));
    841        }
    842 
    843        // drawElements
    844        for (var ndx = 0; ndx < gridWidths.length; ++ndx) {
    845            var name = 'draw_elements_instanced_grid_' + gridWidths[ndx] + 'x' + gridWidths[ndx];
    846            var desc = 'DrawElementsInstanced, Grid size ' + gridWidths[ndx] + 'x' + gridWidths[ndx];
    847 
    848            this.addChild(new es3fDrawTests.InstancedGridRenderTest(name, desc, gridWidths[ndx], true));
    849        }
    850    };
    851 
    852    /**
    853     * @constructor
    854     * @param {number} size
    855     */
    856    es3fDrawTests.UniformWeightArray = function(size) {
    857        this.weights = [];
    858 
    859        for (var i = 0; i < size; ++i)
    860            this.weights[i] = 1.0;
    861    };
    862 
    863    /**
    864     * RandomGroup
    865     * @constructor
    866     * @extends {tcuTestCase.DeqpTest}
    867     * @param {string} name
    868     * @param {string} descr
    869     */
    870    es3fDrawTests.RandomGroup = function(name, descr) {
    871        tcuTestCase.DeqpTest.call(this, name, descr);
    872        this.makeExecutable();
    873    };
    874 
    875    es3fDrawTests.RandomGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    876    es3fDrawTests.RandomGroup.prototype.constructor = es3fDrawTests.RandomGroup;
    877 
    878    /**
    879     * init
    880     */
    881    es3fDrawTests.RandomGroup.prototype.init = function() {
    882        /** @type {number} */ var numAttempts = 300;
    883 
    884        /** @type {Array<number>} */ var attribCounts = [1, 2, 5];
    885        /** @type {Array<number>} */ var attribWeights = [30, 10, 1];
    886        /** @type {Array<number>} */ var primitiveCounts = [2, 6, 64];
    887        /** @type {Array<number>} */ var primitiveCountWeights = [20, 10, 1];
    888        /** @type {Array<number>} */ var indexOffsets = [0, 7, 13];
    889        /** @type {Array<number>} */ var indexOffsetWeights = [20, 20, 1];
    890        /** @type {Array<number>} */ var firsts = [0, 6, 12];
    891        /** @type {Array<number>} */ var firstWeights = [20, 20, 1];
    892        /** @type {Array<number>} */ var instanceCounts = [1, 2, 16, 17];
    893        /** @type {Array<number>} */ var instanceWeights = [20, 10, 5, 1];
    894        /** @type {Array<number>} */ var indexMins = [0, 1, 3, 9];
    895        /** @type {Array<number>} */ var indexMaxs = [5, 9, 129, 257];
    896        /** @type {Array<number>} */ var indexWeights = [50, 50, 50, 50];
    897        /** @type {Array<number>} */ var offsets = [0, 1, 5, 12];
    898        /** @type {Array<number>} */ var offsetWeights = [50, 10, 10, 10];
    899        /** @type {Array<number>} */ var strides = [0, 7, 16, 17];
    900        /** @type {Array<number>} */ var strideWeights = [50, 10, 10, 10];
    901        /** @type {Array<number>} */ var instanceDivisors = [0, 1, 3, 129];
    902        /** @type {Array<number>} */ var instanceDivisorWeights = [70, 30, 10, 10];
    903 
    904        /** @type {Array<glsDrawTests.DrawTestSpec.Primitive>} */ var primitives = [
    905            glsDrawTests.DrawTestSpec.Primitive.POINTS,
    906            glsDrawTests.DrawTestSpec.Primitive.TRIANGLES,
    907            glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN,
    908            glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP,
    909            glsDrawTests.DrawTestSpec.Primitive.LINES,
    910            glsDrawTests.DrawTestSpec.Primitive.LINE_STRIP,
    911            glsDrawTests.DrawTestSpec.Primitive.LINE_LOOP
    912        ];
    913        /** @type {es3fDrawTests.UniformWeightArray} */ var primitiveWeights = new es3fDrawTests.UniformWeightArray(primitives.length);
    914 
    915        /** @type {Array<glsDrawTests.DrawTestSpec.DrawMethod>} */ var drawMethods = [
    916            glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS,
    917            glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED,
    918            glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS,
    919            glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED,
    920            glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED
    921        ];
    922        /** @type {es3fDrawTests.UniformWeightArray} */ var drawMethodWeights = new es3fDrawTests.UniformWeightArray(drawMethods.length);
    923 
    924        /** @type {Array<glsDrawTests.DrawTestSpec.IndexType>} */ var indexTypes = [
    925            glsDrawTests.DrawTestSpec.IndexType.BYTE,
    926            glsDrawTests.DrawTestSpec.IndexType.SHORT,
    927            glsDrawTests.DrawTestSpec.IndexType.INT
    928        ];
    929        /** @type {es3fDrawTests.UniformWeightArray} */ var indexTypeWeights = new es3fDrawTests.UniformWeightArray(indexTypes.length);
    930 
    931        /** @type {Array<glsDrawTests.DrawTestSpec.Storage>} */ var storages = [
    932            //glsDrawTests.DrawTestSpec.Storage.USER,
    933            glsDrawTests.DrawTestSpec.Storage.BUFFER
    934        ];
    935        /** @type {es3fDrawTests.UniformWeightArray} */ var storageWeights = new es3fDrawTests.UniformWeightArray(storages.length);
    936 
    937        /** @type {Array<glsDrawTests.DrawTestSpec.InputType>} */ var inputTypes = [
    938            glsDrawTests.DrawTestSpec.InputType.FLOAT,
    939            //glsDrawTests.DrawTestSpec.InputType.FIXED,
    940            glsDrawTests.DrawTestSpec.InputType.BYTE,
    941            glsDrawTests.DrawTestSpec.InputType.SHORT,
    942            glsDrawTests.DrawTestSpec.InputType.UNSIGNED_BYTE,
    943            glsDrawTests.DrawTestSpec.InputType.UNSIGNED_SHORT,
    944            glsDrawTests.DrawTestSpec.InputType.INT,
    945            glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT,
    946            glsDrawTests.DrawTestSpec.InputType.HALF,
    947            glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT_2_10_10_10,
    948            glsDrawTests.DrawTestSpec.InputType.INT_2_10_10_10
    949        ];
    950        /** @type {es3fDrawTests.UniformWeightArray} */ var inputTypeWeights = new es3fDrawTests.UniformWeightArray(inputTypes.length);
    951 
    952        /** @type {Array<glsDrawTests.DrawTestSpec.OutputType>} */ var outputTypes = [
    953            glsDrawTests.DrawTestSpec.OutputType.FLOAT,
    954            glsDrawTests.DrawTestSpec.OutputType.VEC2,
    955            glsDrawTests.DrawTestSpec.OutputType.VEC3,
    956            glsDrawTests.DrawTestSpec.OutputType.VEC4,
    957            glsDrawTests.DrawTestSpec.OutputType.INT,
    958            glsDrawTests.DrawTestSpec.OutputType.UINT,
    959            glsDrawTests.DrawTestSpec.OutputType.IVEC2,
    960            glsDrawTests.DrawTestSpec.OutputType.IVEC3,
    961            glsDrawTests.DrawTestSpec.OutputType.IVEC4,
    962            glsDrawTests.DrawTestSpec.OutputType.UVEC2,
    963            glsDrawTests.DrawTestSpec.OutputType.UVEC3,
    964            glsDrawTests.DrawTestSpec.OutputType.UVEC4
    965        ];
    966        /** @type {es3fDrawTests.UniformWeightArray} */ var outputTypeWeights = new es3fDrawTests.UniformWeightArray(outputTypes.length);
    967 
    968        /** @type {Array<glsDrawTests.DrawTestSpec.Usage>} */ var usages = [
    969            glsDrawTests.DrawTestSpec.Usage.DYNAMIC_DRAW,
    970            glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW,
    971            glsDrawTests.DrawTestSpec.Usage.STREAM_DRAW,
    972            glsDrawTests.DrawTestSpec.Usage.STREAM_READ,
    973            glsDrawTests.DrawTestSpec.Usage.STREAM_COPY,
    974            glsDrawTests.DrawTestSpec.Usage.STATIC_READ,
    975            glsDrawTests.DrawTestSpec.Usage.STATIC_COPY,
    976            glsDrawTests.DrawTestSpec.Usage.DYNAMIC_READ,
    977            glsDrawTests.DrawTestSpec.Usage.DYNAMIC_COPY
    978        ];
    979        /** @type {es3fDrawTests.UniformWeightArray} */ var usageWeights = new es3fDrawTests.UniformWeightArray(usages.length);
    980 
    981        /** @type {Array<number>} */ var insertedHashes = []; //'set' structure
    982        /** @type {number} */ var insertedCount = 0;
    983 
    984        for (var ndx = 0; ndx < numAttempts; ++ndx) {
    985            /** @type {deRandom.Random} */ var random = new deRandom.Random(0xc551393 + ndx); // random does not depend on previous cases
    986 
    987            /** @type {number} */ var attributeCount = random.chooseWeighted(attribCounts, attribWeights);
    988            /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
    989 
    990            //spec.apiType = glu::ApiType::es(3,0);
    991            spec.primitive = /** @type {glsDrawTests.DrawTestSpec.Primitive} */ (random.chooseWeighted(primitives, primitiveWeights.weights));
    992            spec.primitiveCount = random.chooseWeighted(primitiveCounts, primitiveCountWeights);
    993            spec.drawMethod = /** @type {glsDrawTests.DrawTestSpec.DrawMethod} */ (random.chooseWeighted(drawMethods, drawMethodWeights.weights));
    994            spec.indexType = /** @type {glsDrawTests.DrawTestSpec.IndexType} */ (random.chooseWeighted(indexTypes, indexTypeWeights.weights));
    995            spec.indexPointerOffset = random.chooseWeighted(indexOffsets, indexOffsetWeights);
    996            spec.indexStorage = /** @type {glsDrawTests.DrawTestSpec.Storage} */ (random.chooseWeighted(storages, storageWeights.weights));
    997            spec.first = random.chooseWeighted(firsts, firstWeights);
    998            spec.indexMin = random.chooseWeighted(indexMins, indexWeights);
    999            spec.indexMax = random.chooseWeighted(indexMaxs, indexWeights);
   1000            spec.instanceCount = random.chooseWeighted(instanceCounts, instanceWeights);
   1001 
   1002            // check spec is legal
   1003            if (!spec.valid())
   1004                continue;
   1005 
   1006            var hasZeroDivisor = false;
   1007            for (var attrNdx = 0; attrNdx < attributeCount;) {
   1008                /** @type {boolean} */ var valid;
   1009                /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attribSpec = new glsDrawTests.DrawTestSpec.AttributeSpec();
   1010 
   1011                attribSpec.inputType = /** @type {glsDrawTests.DrawTestSpec.InputType} */ (random.chooseWeighted(inputTypes, inputTypeWeights.weights));
   1012                attribSpec.outputType = /** @type {glsDrawTests.DrawTestSpec.OutputType} */ (random.chooseWeighted(outputTypes, outputTypeWeights.weights));
   1013                attribSpec.storage = /** @type {glsDrawTests.DrawTestSpec.Storage} */ (random.chooseWeighted(storages, storageWeights.weights));
   1014                attribSpec.usage = /** @type {glsDrawTests.DrawTestSpec.Usage} */ (random.chooseWeighted(usages, usageWeights.weights));
   1015                attribSpec.componentCount = random.getInt(1, 4);
   1016                attribSpec.offset = random.chooseWeighted(offsets, offsetWeights);
   1017                attribSpec.stride = random.chooseWeighted(strides, strideWeights);
   1018                attribSpec.normalize = random.getBool();
   1019                attribSpec.instanceDivisor = random.chooseWeighted(instanceDivisors, instanceDivisorWeights);
   1020                attribSpec.useDefaultAttribute = random.getBool();
   1021 
   1022                // check spec is legal
   1023                valid = attribSpec.valid(/*spec.apiType*/);
   1024 
   1025                // we do not want interleaved elements. (Might result in some weird floating point values)
   1026                if (attribSpec.stride && attribSpec.componentCount * glsDrawTests.DrawTestSpec.inputTypeSize(attribSpec.inputType) > attribSpec.stride)
   1027                    valid = false;
   1028 
   1029                // try again if not valid
   1030                if (valid) {
   1031                    spec.attribs.push(attribSpec);
   1032                    ++attrNdx;
   1033                    if (attribSpec.instanceDivisor == 0)
   1034                        hasZeroDivisor = true;
   1035                }
   1036            }
   1037 
   1038            // Do not collapse all vertex positions to a single positions
   1039            if (spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS) {
   1040                spec.attribs[0].instanceDivisor = 0;
   1041                hasZeroDivisor = true;
   1042            }
   1043 
   1044            // There should be at least one enabled vertex attribute array that has a divisor of zero in WebGL.
   1045            // This limitation is added to keep compatible with D3D. It differs from the feature in gles.
   1046            // See the section <Enabled Attribute> in WebGL spec: https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.6
   1047            if (hasZeroDivisor == false)
   1048                continue;
   1049 
   1050            // Is render result meaningful?
   1051            // Only one vertex
   1052            if (spec.drawMethod == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS)
   1053                continue;
   1054            if (spec.attribs[0].useDefaultAttribute && spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS)
   1055                continue;
   1056 
   1057            // Triangle only on one axis
   1058            if (spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLES || spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN || spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP) {
   1059                if (spec.attribs[0].componentCount == 1)
   1060                    continue;
   1061                if (spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.FLOAT || spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.INT || spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.UINT)
   1062                    continue;
   1063                if (spec.drawMethod == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
   1064                    continue;
   1065            }
   1066 
   1067            // Add case
   1068            /** @type {number} */ var hash = spec.hash();
   1069            for (var attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
   1070                hash = deMath.binaryOp(deMath.shiftLeft(hash, 2), spec.attribs[attrNdx].hash(), deMath.BinaryOp.XOR);
   1071 
   1072            if (insertedHashes.indexOf(hash) == -1) {
   1073                // Only properly aligned
   1074                if (spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_OFFSET &&
   1075                    spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_STRIDE) {
   1076                    this.addChild(new glsDrawTests.DrawTest(spec, insertedCount + '', spec.getDesc()));
   1077                }
   1078                deUtil.dePushUniqueToArray(insertedHashes, hash);
   1079 
   1080                ++insertedCount;
   1081            }
   1082        }
   1083    };
   1084 
   1085    /**
   1086     * @constructor
   1087     * @extends {tcuTestCase.DeqpTest}
   1088     */
   1089    es3fDrawTests.DrawTest = function() {
   1090        tcuTestCase.DeqpTest.call(this, 'draw', 'Drawing tests');
   1091        this.makeExecutable();
   1092    };
   1093 
   1094    es3fDrawTests.DrawTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1095    es3fDrawTests.DrawTest.prototype.constructor = es3fDrawTests.DrawTest;
   1096 
   1097    /**
   1098     * init
   1099     */
   1100    es3fDrawTests.DrawTest.prototype.init = function() {
   1101        // Basic
   1102        /** @type {Array<glsDrawTests.DrawTestSpec.DrawMethod>} */ var basicMethods = [
   1103            glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS,
   1104            glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS,
   1105            glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED,
   1106            glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED,
   1107            glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED
   1108        ];
   1109 
   1110        for (var ndx = 0; ndx < basicMethods.length; ++ndx) {
   1111            var name = glsDrawTests.DrawTestSpec.drawMethodToString(basicMethods[ndx]);
   1112            var desc = glsDrawTests.DrawTestSpec.drawMethodToString(basicMethods[ndx]);
   1113 
   1114            this.addChild(new es3fDrawTests.MethodGroup(name, desc, basicMethods[ndx]));
   1115        }
   1116 
   1117        // extreme instancing
   1118 
   1119        this.addChild(new es3fDrawTests.InstancingGroup('instancing', 'draw tests with a large instance count.'));
   1120 
   1121        // Random
   1122 
   1123        this.addChild(new es3fDrawTests.RandomGroup('random', 'random draw commands.'));
   1124    };
   1125 
   1126    /**
   1127     * Create and execute the test cases
   1128     * @param {WebGL2RenderingContext} context
   1129     */
   1130    es3fDrawTests.run = function(context, range) {
   1131        gl = context;
   1132        //Set up Test Root parameters
   1133        var state = tcuTestCase.runner;
   1134 
   1135        var rootTest = new es3fDrawTests.DrawTest();
   1136        state.setRoot(rootTest);
   1137 
   1138        //Set up name and description of this test series.
   1139        setCurrentTestName(rootTest.fullName());
   1140        description(rootTest.getDescription());
   1141 
   1142        try {
   1143            if (range) {
   1144                state.setRange(range);
   1145            }
   1146            //Run test cases
   1147            tcuTestCase.runTestCases();
   1148        }
   1149        catch (err) {
   1150            testFailedOptions('Failed to run draw tests', false);
   1151            tcuTestCase.runner.terminate();
   1152        }
   1153    };
   1154 
   1155 });