tor-browser

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

es3fTextureSpecificationTests.js (287040B)


      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.es3fTextureSpecificationTests');
     23 goog.require('framework.common.tcuImageCompare');
     24 goog.require('framework.common.tcuLogImage');
     25 goog.require('framework.common.tcuPixelFormat');
     26 goog.require('framework.common.tcuSurface');
     27 goog.require('framework.common.tcuTestCase');
     28 goog.require('framework.common.tcuTexture');
     29 goog.require('framework.common.tcuTextureUtil');
     30 goog.require('framework.delibs.debase.deMath');
     31 goog.require('framework.delibs.debase.deRandom');
     32 goog.require('framework.delibs.debase.deString');
     33 goog.require('framework.opengl.gluShaderUtil');
     34 goog.require('framework.opengl.gluTextureUtil');
     35 goog.require('framework.opengl.simplereference.sglrGLContext');
     36 goog.require('framework.opengl.simplereference.sglrReferenceContext');
     37 goog.require('framework.referencerenderer.rrUtil');
     38 goog.require('functional.gles3.es3fFboTestUtil');
     39 
     40 goog.scope(function() {
     41    var es3fTextureSpecificationTests =
     42        functional.gles3.es3fTextureSpecificationTests;
     43    var tcuPixelFormat = framework.common.tcuPixelFormat;
     44    var tcuImageCompare = framework.common.tcuImageCompare;
     45    var tcuSurface = framework.common.tcuSurface;
     46    var tcuTestCase = framework.common.tcuTestCase;
     47    var tcuTexture = framework.common.tcuTexture;
     48    var tcuTextureUtil = framework.common.tcuTextureUtil;
     49    var deMath = framework.delibs.debase.deMath;
     50    var deRandom = framework.delibs.debase.deRandom;
     51    var deString = framework.delibs.debase.deString;
     52    var gluShaderUtil = framework.opengl.gluShaderUtil;
     53    var gluTextureUtil = framework.opengl.gluTextureUtil;
     54    var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
     55    var sglrReferenceContext =
     56        framework.opengl.simplereference.sglrReferenceContext;
     57    var rrUtil = framework.referencerenderer.rrUtil;
     58    var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
     59    var tcuLogImage = framework.common.tcuLogImage;
     60 
     61    /**
     62     * @param {number} internalFormat
     63     * @return {tcuTexture.TextureFormat}
     64     */
     65    es3fTextureSpecificationTests.mapGLUnsizedInternalFormat = function(
     66        internalFormat
     67    ) {
     68        switch (internalFormat) {
     69            case gl.ALPHA:
     70                return new tcuTexture.TextureFormat(
     71                    tcuTexture.ChannelOrder.A,
     72                    tcuTexture.ChannelType.UNORM_INT8
     73                );
     74            case gl.LUMINANCE:
     75                return new tcuTexture.TextureFormat(
     76                    tcuTexture.ChannelOrder.L,
     77                    tcuTexture.ChannelType.UNORM_INT8
     78                );
     79            case gl.LUMINANCE_ALPHA:
     80                return new tcuTexture.TextureFormat(
     81                    tcuTexture.ChannelOrder.LA,
     82                    tcuTexture.ChannelType.UNORM_INT8
     83                );
     84            case gl.RGB:
     85                return new tcuTexture.TextureFormat(
     86                    tcuTexture.ChannelOrder.RGB,
     87                    tcuTexture.ChannelType.UNORM_INT8
     88                );
     89            case gl.RGBA:
     90                return new tcuTexture.TextureFormat(
     91                    tcuTexture.ChannelOrder.RGBA,
     92                    tcuTexture.ChannelType.UNORM_INT8
     93                );
     94            default:
     95                throw new Error(
     96                    'Can\'t map GL unsized internal format (' +
     97                    internalFormat.toString(16) + ') to texture format'
     98                );
     99        }
    100    };
    101 
    102    var VIEWPORT_WIDTH = 256;
    103    var VIEWPORT_HEIGHT = 256;
    104 
    105    /**
    106     * @param {number} width
    107     * @param {number} height
    108     * @param {number=} depth
    109     * @return {number}
    110     */
    111    es3fTextureSpecificationTests.maxLevelCount = function(
    112        width, height, depth
    113    ) {
    114        depth = depth || 0;
    115        return deMath.logToFloor(Math.max(width, Math.max(height, depth))) + 1;
    116    };
    117 
    118    /**
    119     * @param {deRandom.Random} rnd
    120     * @param {Array<number>} minVal
    121     * @param {Array<number>} maxVal
    122     * @param {number} size
    123     * @return {Array<number>}
    124     */
    125    es3fTextureSpecificationTests.randomVector = function(
    126        rnd, minVal, maxVal, size
    127    ) {
    128        var res = [];
    129        for (var ndx = 0; ndx < size; ndx++)
    130            res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
    131        return res;
    132    };
    133 
    134    /**
    135     * @param {tcuPixelFormat.PixelFormat} pixelFormat
    136     * @param {tcuTexture.TextureFormat} textureFormat
    137     * @return {Array<number>} (ivec4)
    138     */
    139    es3fTextureSpecificationTests.getPixelFormatCompareDepth = function(
    140        pixelFormat, textureFormat
    141    ) {
    142        switch (textureFormat.order) {
    143            case tcuTexture.ChannelOrder.L:
    144            case tcuTexture.ChannelOrder.LA:
    145                return [
    146                    pixelFormat.redBits, pixelFormat.redBits,
    147                    pixelFormat.redBits, pixelFormat.alphaBits
    148                ];
    149            default:
    150                return [
    151                    pixelFormat.redBits, pixelFormat.greenBits,
    152                    pixelFormat.blueBits, pixelFormat.alphaBits
    153                ];
    154        }
    155    };
    156 
    157    /**
    158     * @param {tcuPixelFormat.PixelFormat} pixelFormat
    159     * @param {tcuTexture.TextureFormat} textureFormat
    160     * @return {Array<number>} (uvec4)
    161     */
    162    es3fTextureSpecificationTests.computeCompareThreshold = function(
    163        pixelFormat, textureFormat
    164    ) {
    165        /** @type {Array<number>} */
    166        var texFormatBits = tcuTextureUtil.getTextureFormatBitDepth(
    167            textureFormat
    168        );
    169        /** @type {Array<number>} */
    170        var pixelFormatBits =
    171            es3fTextureSpecificationTests.getPixelFormatCompareDepth(
    172                pixelFormat, textureFormat
    173            );
    174        /** @type {Array<number>} */
    175        var accurateFmtBits = deMath.min(pixelFormatBits, texFormatBits);
    176        /** @type {Array<number>} */
    177        var compareBits = deMath.addScalar(
    178            tcuTextureUtil.select(
    179                accurateFmtBits, [8, 8, 8, 8],
    180                deMath.greaterThan(accurateFmtBits, [0, 0, 0, 0])
    181            ), - 1
    182        );
    183 
    184        var result = [];
    185        for (var i = 0; i < compareBits.length; i++)
    186            result.push(1 << compareBits[i]);
    187        return result;
    188    };
    189 
    190    /**
    191     * @constructor
    192     * @extends {tcuTestCase.DeqpTest}
    193     * @param {string} name
    194     * @param {string} desc
    195     * context
    196     */
    197    es3fTextureSpecificationTests.TextureSpecCase = function(name, desc) {
    198        tcuTestCase.DeqpTest.call(this, name, desc);
    199        /**
    200         * @type {
    201         *     ?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext
    202         * }
    203         */
    204         this.m_context = null;
    205    };
    206 
    207    es3fTextureSpecificationTests.TextureSpecCase.prototype = Object.create(
    208        tcuTestCase.DeqpTest.prototype
    209    );
    210 
    211    es3fTextureSpecificationTests.TextureSpecCase.prototype.constructor =
    212        es3fTextureSpecificationTests.TextureSpecCase;
    213 
    214    /**
    215     * deinit
    216     */
    217    es3fTextureSpecificationTests.TextureSpecCase.prototype.deinit =
    218    function() {
    219        gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
    220        gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0);
    221        gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0);
    222        gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
    223        gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
    224        gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);
    225 
    226        gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
    227    }
    228 
    229    /**
    230     * createTexture - Needs to be overridden
    231     */
    232    es3fTextureSpecificationTests.TextureSpecCase.prototype.createTexture =
    233    function() {
    234        throw new Error('Must override');
    235    };
    236 
    237    /**
    238     * verifyTexture - Needs to be overridden
    239     * @param {sglrGLContext.GLContext} webgl2Context
    240     * @param {sglrReferenceContext.ReferenceContext} refContext
    241     * @return {boolean}
    242     */
    243    es3fTextureSpecificationTests.TextureSpecCase.prototype.verifyTexture =
    244    function(
    245        webgl2Context, refContext
    246    ) {
    247        throw new Error('Must override');
    248    };
    249 
    250    /**
    251     * @return {tcuTestCase.IterateResult}
    252     */
    253    es3fTextureSpecificationTests.TextureSpecCase.prototype.iterate = function() {
    254        if (gl.canvas.width < VIEWPORT_WIDTH ||
    255            gl.canvas.height < VIEWPORT_HEIGHT)
    256            throw new Error('Too small viewport', '');
    257 
    258        // Context size, and viewport for GLES3
    259        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
    260        var width = Math.min(gl.canvas.width, VIEWPORT_WIDTH);
    261        var height = Math.min(gl.canvas.height, VIEWPORT_HEIGHT);
    262        var x = rnd.getInt(0, gl.canvas.width - width);
    263        var y = rnd.getInt(0, gl.canvas.height - height);
    264 
    265        // Contexts.
    266        /** @type {sglrGLContext.GLContext} */
    267        var webgl2Context = new sglrGLContext.GLContext(
    268            gl, [x, y, width, height]
    269        );
    270 
    271        /** @type {sglrReferenceContext.ReferenceContextBuffers} */
    272        var refBuffers = new sglrReferenceContext.ReferenceContextBuffers(
    273            new tcuPixelFormat.PixelFormat(
    274                8, 8, 8, gl.getParameter(gl.ALPHA_BITS) ? 8 : 0
    275            ), 0 /* depth */, 0 /* stencil */, width, height
    276        );
    277 
    278        /** @type {sglrReferenceContext.ReferenceContext} */
    279        var refContext = new sglrReferenceContext.ReferenceContext(
    280            new sglrReferenceContext.ReferenceContextLimits(gl),
    281            refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(),
    282            refBuffers.getStencilbuffer()
    283        );
    284 
    285        // Clear color buffer.
    286        for (var ndx = 0; ndx < 2; ndx++) {
    287            this.m_context = ndx ? refContext : webgl2Context;
    288            // C++ port uses (0.125, 0.25, 0.5, 1.0), but here we use (0, 0, 0, 0)
    289            // in order to optimize the `clear' op in ReferenceContext.
    290            this.m_context.clearColor(0, 0, 0, 0);
    291            this.m_context.clear(
    292                gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT |
    293                gl.STENCIL_BUFFER_BIT
    294            );
    295        }
    296 
    297        // Construct texture using both GLES3 and reference contexts.
    298        for (var ndx = 0; ndx < 2; ndx++) {
    299            this.m_context = ndx ? refContext : webgl2Context;
    300            this.createTexture();
    301            checkMessage(
    302                this.m_context.getError() == gl.NO_ERROR,
    303                'Problem creating texture.'
    304            );
    305        }
    306 
    307        // Verify results.
    308        if (this.verifyTexture(webgl2Context, refContext))
    309            testPassed();
    310        else
    311            testFailed('Verification failed');
    312 
    313        return tcuTestCase.IterateResult.STOP;
    314    };
    315 
    316    /**
    317     * @param {tcuSurface.Surface} dst
    318     * @param {
    319     *  ?WebGLProgram|
    320     *  framework.opengl.simplereference.sglrShaderProgram.ShaderProgram
    321     * } program
    322     * @param {number} width
    323     * @param {number} height
    324     */
    325    es3fTextureSpecificationTests.TextureSpecCase.prototype.renderTex =
    326    function(dst, program, width, height) {
    327        var targetW = this.m_context.getWidth();
    328        var targetH = this.m_context.getHeight();
    329 
    330        var w = width / targetW;
    331        var h = height / targetH;
    332 
    333        rrUtil.drawQuad(
    334            this.m_context, program, [-1.0, -1.0, 0.0],
    335            [-1.0 + w * 2.0, -1.0 + h * 2.0, 0.0]
    336        );
    337 
    338        // Read pixels back.
    339        dst.readViewport(this.m_context, [0, 0, width, height]);
    340    };
    341 
    342    /**
    343     * @constructor
    344     * @extends {es3fTextureSpecificationTests.TextureSpecCase}
    345     * @param {string} name
    346     * @param {string} desc
    347     * @param {tcuTexture.TextureFormat} format
    348     * @param {number} width
    349     * @param {number} height
    350     * @param {number} numLevels
    351     */
    352    es3fTextureSpecificationTests.Texture2DSpecCase = function(
    353        name, desc, format, width, height, numLevels
    354    ) {
    355        es3fTextureSpecificationTests.TextureSpecCase.call(this, name, desc);
    356 
    357        this.m_texFormat = format;
    358        this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
    359        this.m_width = width;
    360        this.m_height = height;
    361        this.m_numLevels = numLevels;
    362    };
    363 
    364    es3fTextureSpecificationTests.Texture2DSpecCase.prototype = Object.create(
    365        es3fTextureSpecificationTests.TextureSpecCase.prototype
    366    );
    367 
    368    es3fTextureSpecificationTests.Texture2DSpecCase.prototype.constructor =
    369        es3fTextureSpecificationTests.Texture2DSpecCase;
    370 
    371    /**
    372     * @param {sglrGLContext.GLContext} webgl2Context
    373     * @param {sglrReferenceContext.ReferenceContext} refContext
    374     */
    375    es3fTextureSpecificationTests.Texture2DSpecCase.prototype.verifyTexture =
    376    function(
    377        webgl2Context, refContext
    378    ) {
    379        /** @type {es3fFboTestUtil.Texture2DShader} */
    380        var shader = new es3fFboTestUtil.Texture2DShader(
    381            [gluTextureUtil.getSampler2DType(this.m_texFormat)],
    382            gluShaderUtil.DataType.FLOAT_VEC4
    383        );
    384 
    385        var shaderIDgles = webgl2Context.createProgram(shader);
    386        var shaderIDRef = refContext.createProgram(shader);
    387 
    388        shader.setTexScaleBias(
    389            0, this.m_texFormatInfo.lookupScale,
    390            this.m_texFormatInfo.lookupBias
    391        );
    392 
    393        // Set state.
    394        for (var ndx = 0; ndx < 2; ndx++) {
    395            var ctx = ndx ? refContext : webgl2Context;
    396 
    397            this.m_context = ctx;
    398 
    399            this.m_context.texParameteri(
    400                gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST
    401            );
    402            this.m_context.texParameteri(
    403                gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
    404            );
    405            this.m_context.texParameteri(
    406                gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE
    407            );
    408            this.m_context.texParameteri(
    409                gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE
    410            );
    411            this.m_context.texParameteri(
    412                gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, this.m_numLevels - 1
    413            );
    414        }
    415 
    416        for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
    417            var levelW = Math.max(1, this.m_width >> levelNdx);
    418            var levelH = Math.max(1, this.m_height >> levelNdx);
    419            /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface();
    420            /** @type {tcuSurface.Surface} */ var result = new tcuSurface.Surface();
    421 
    422            for (var ndx = 0; ndx < 2; ndx++) {
    423                /** @type {tcuSurface.Surface} */
    424                var dst = ndx ? reference : result;
    425                var ctx = ndx ? refContext : webgl2Context;
    426                var shaderID = ndx ? shaderIDRef : shaderIDgles;
    427 
    428                this.m_context = ctx;
    429                shader.setUniforms(ctx, shaderID);
    430                this.renderTex(dst, shaderID, levelW, levelH);
    431            }
    432 
    433            var threshold =
    434            es3fTextureSpecificationTests.computeCompareThreshold(
    435                tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
    436            );
    437            var levelStr = levelNdx.toString();
    438            var name = 'Level' + levelStr;
    439            var desc = 'Level ' + levelStr;
    440            var isOk = tcuImageCompare.intThresholdCompare(
    441                name, desc, reference.getAccess(), result.getAccess(),
    442                threshold, levelNdx == 0 ?
    443                tcuImageCompare.CompareLogMode.RESULT :
    444                tcuImageCompare.CompareLogMode.ON_ERROR
    445            );
    446 
    447            if (!isOk) {
    448                testFailed('Image comparison failed');
    449                return false;
    450            } else {
    451                // tcuLogImage.logImageWithInfo(result.getAccess(),'Comparison OK on level: ' + levelNdx);
    452            }
    453        }
    454        return true;
    455    };
    456 
    457    /**
    458     * @constructor
    459     * @extends {es3fTextureSpecificationTests.TextureSpecCase}
    460     * @param {string} name
    461     * @param {string} desc
    462     * @param {tcuTexture.TextureFormat} format
    463     * @param {number} size
    464     * @param {number} numLevels
    465     */
    466    es3fTextureSpecificationTests.TextureCubeSpecCase = function(
    467        name, desc, format, size, numLevels
    468    ) {
    469        es3fTextureSpecificationTests.TextureSpecCase.call(
    470            this, name, desc
    471        );
    472        this.m_texFormat = format;
    473        this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
    474        this.m_size = size;
    475        this.m_numLevels = numLevels;
    476    };
    477 
    478    es3fTextureSpecificationTests.TextureCubeSpecCase.prototype =
    479        Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
    480 
    481    es3fTextureSpecificationTests.TextureCubeSpecCase.prototype.constructor =
    482        es3fTextureSpecificationTests.TextureCubeSpecCase;
    483 
    484    /**
    485     * @param {sglrGLContext.GLContext} webgl2Context
    486     * @param {sglrReferenceContext.ReferenceContext} refContext
    487     */
    488    es3fTextureSpecificationTests.TextureCubeSpecCase.prototype.verifyTexture =
    489    function(
    490        webgl2Context, refContext
    491    ) {
    492        /** @type {es3fFboTestUtil.TextureCubeShader} */
    493        var shader = new es3fFboTestUtil.TextureCubeShader(
    494            gluTextureUtil.getSamplerCubeType(this.m_texFormat),
    495            gluShaderUtil.DataType.FLOAT_VEC4
    496        );
    497        var shaderIDgles = webgl2Context.createProgram(shader);
    498        var shaderIDRef = refContext.createProgram(shader);
    499 
    500        shader.setTexScaleBias(
    501            this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
    502        );
    503 
    504        // Set state.
    505        for (var ndx = 0; ndx < 2; ndx++) {
    506            var ctx = ndx ? refContext : webgl2Context;
    507 
    508            this.m_context = ctx;
    509 
    510            this.m_context.texParameteri(
    511                gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER,
    512                gl.NEAREST_MIPMAP_NEAREST
    513            );
    514            this.m_context.texParameteri(
    515                gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER,
    516                gl.NEAREST
    517            );
    518            this.m_context.texParameteri(
    519                gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S,
    520                gl.CLAMP_TO_EDGE
    521            );
    522            this.m_context.texParameteri(
    523                gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T,
    524                gl.CLAMP_TO_EDGE
    525            );
    526            this.m_context.texParameteri(
    527                gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAX_LEVEL,
    528                this.m_numLevels - 1
    529            );
    530        }
    531 
    532        for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
    533            var levelSize = Math.max(1, this.m_size >> levelNdx);
    534            var isOk = true;
    535 
    536            for (var f in tcuTexture.CubeFace) {
    537                var face = tcuTexture.CubeFace[f];
    538                /** @type {tcuSurface.Surface} */
    539                var reference = new tcuSurface.Surface();
    540                /** @type {tcuSurface.Surface} */
    541                var result = new tcuSurface.Surface();
    542 
    543                if (levelSize <= 2)
    544                    continue; // Fuzzy compare doesn't work for images this small.
    545 
    546                shader.setFace(face);
    547 
    548                for (var ndx = 0; ndx < 2; ndx++) {
    549                    /** @type {tcuSurface.Surface} */
    550                    var dst = ndx ? reference : result;
    551                    ctx = ndx ? refContext : webgl2Context;
    552                    var shaderID = ndx ? shaderIDRef : shaderIDgles;
    553 
    554                    this.m_context = ctx;
    555                    shader.setUniforms(ctx, shaderID);
    556                    this.renderTex(dst, shaderID, levelSize, levelSize);
    557                }
    558 
    559                var threshold = 0.02;
    560                var faceStr = face.toString();
    561                var levelStr = levelNdx.toString();
    562                var name = 'Level' + levelStr;
    563                var desc = 'Level ' + levelStr + ', face ' + faceStr;
    564                var isFaceOk = tcuImageCompare.fuzzyCompare(
    565                    name, desc, reference.getAccess(), result.getAccess(),
    566                    threshold, levelNdx == 0 ?
    567                    tcuImageCompare.CompareLogMode.RESULT :
    568                    tcuImageCompare.CompareLogMode.ON_ERROR
    569                );
    570 
    571                if (!isFaceOk) {
    572                    testFailed('Image comparison failed');
    573                    return false;
    574                }
    575            }
    576 
    577        }
    578        return true;
    579    };
    580 
    581    /**
    582     * @constructor
    583     * @extends {es3fTextureSpecificationTests.TextureSpecCase}
    584     * @param {string} name
    585     * @param {string} desc
    586     * @param {tcuTexture.TextureFormat} format
    587     * @param {number} width
    588     * @param {number} height
    589     * @param {number} numLayers
    590     * @param {number} numLevels
    591     */
    592    es3fTextureSpecificationTests.Texture2DArraySpecCase = function(
    593        name, desc, format, width, height, numLayers, numLevels
    594    ) {
    595        es3fTextureSpecificationTests.TextureSpecCase.call(
    596            this, name, desc
    597        );
    598        this.m_texFormat = format;
    599        this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
    600        this.m_width = width;
    601        this.m_height = height;
    602        this.m_numLayers = numLayers;
    603        this.m_numLevels = numLevels;
    604    };
    605 
    606    es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype =
    607        Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
    608 
    609    es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype.constructor =
    610        es3fTextureSpecificationTests.Texture2DArraySpecCase;
    611 
    612    /**
    613     * @param {sglrGLContext.GLContext} webgl2Context
    614     * @param {sglrReferenceContext.ReferenceContext} refContext
    615     */
    616    es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype.verifyTexture =
    617    function(
    618        webgl2Context, refContext
    619    ) {
    620        /** @type {es3fFboTestUtil.Texture2DArrayShader} */
    621        var shader = new es3fFboTestUtil.Texture2DArrayShader(
    622            gluTextureUtil.getSampler2DArrayType(this.m_texFormat),
    623            gluShaderUtil.DataType.FLOAT_VEC4
    624        );
    625        var shaderIDgles = webgl2Context.createProgram(shader);
    626        var shaderIDRef = refContext.createProgram(shader);
    627 
    628        shader.setTexScaleBias(
    629            this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
    630        );
    631 
    632        // Set state.
    633        for (var ndx = 0; ndx < 2; ndx++) {
    634            var ctx = ndx ? refContext : webgl2Context;
    635 
    636            this.m_context = ctx;
    637 
    638            this.m_context.texParameteri(
    639                gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER,
    640                gl.NEAREST_MIPMAP_NEAREST
    641            );
    642            this.m_context.texParameteri(
    643                gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER,
    644                gl.NEAREST
    645            );
    646            this.m_context.texParameteri(
    647                gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S,
    648                gl.CLAMP_TO_EDGE
    649            );
    650            this.m_context.texParameteri(
    651                gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T,
    652                gl.CLAMP_TO_EDGE
    653            );
    654            this.m_context.texParameteri(
    655                gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_R,
    656                gl.CLAMP_TO_EDGE
    657            );
    658            this.m_context.texParameteri(
    659                gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAX_LEVEL,
    660                this.m_numLevels - 1
    661            );
    662        }
    663 
    664        for (var layerNdx = 0; layerNdx < this.m_numLayers; layerNdx++) {
    665            var layerOk = true;
    666 
    667            shader.setLayer(layerNdx);
    668            for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
    669                var levelW = Math.max(1, this.m_width >> levelNdx);
    670                var levelH = Math.max(1, this.m_height >> levelNdx);
    671 
    672                if (levelW == 1 || levelH == 1) {
    673                    // Rendering to texture of size x1 is problematic in referencerenderer
    674                    // due to its deviation from c++ code: crbug.com/613206
    675                    continue;
    676                }
    677                /** @type {tcuSurface.Surface} */
    678                var reference = new tcuSurface.Surface();
    679                /** @type {tcuSurface.Surface} */
    680                var result = new tcuSurface.Surface();
    681 
    682                var isOk = true;
    683 
    684                for (var ndx = 0; ndx < 2; ndx++) {
    685                    /** @type {tcuSurface.Surface} */
    686                    var dst = ndx ? reference : result;
    687                    ctx = ndx ? refContext : webgl2Context;
    688                    var shaderID = ndx ? shaderIDRef : shaderIDgles;
    689 
    690                    this.m_context = ctx;
    691                    shader.setUniforms(ctx, shaderID);
    692                    this.renderTex(dst, shaderID, levelW, levelH);
    693                }
    694 
    695                var threshold =
    696                es3fTextureSpecificationTests.computeCompareThreshold(
    697                    tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
    698                );
    699                var levelStr = levelNdx.toString();
    700                var layerStr = layerNdx.toString();
    701                var name = 'Layer' + layerStr + 'Level' + levelStr;
    702                var desc = 'Layer ' + layerStr + ', Level ' + levelStr;
    703                var depthOk = tcuImageCompare.intThresholdCompare(
    704                    name, desc, reference.getAccess(), result.getAccess(),
    705                    threshold, (levelNdx == 0 && layerNdx == 0) ?
    706                    tcuImageCompare.CompareLogMode.RESULT :
    707                    tcuImageCompare.CompareLogMode.ON_ERROR
    708                );
    709 
    710                if (!depthOk) {
    711                    testFailed('Image comparison failed');
    712                    return false;
    713                }
    714            }
    715 
    716        }
    717        return true;
    718    };
    719 
    720    /**
    721     * @constructor
    722     * @extends {es3fTextureSpecificationTests.TextureSpecCase}
    723     * @param {string} name
    724     * @param {string} desc
    725     * @param {tcuTexture.TextureFormat} format
    726     * @param {number} width
    727     * @param {number} height
    728     * @param {number} depth
    729     * @param {number} numLevels
    730     */
    731    es3fTextureSpecificationTests.Texture3DSpecCase = function(
    732        name, desc, format, width, height, depth, numLevels
    733    ) {
    734        es3fTextureSpecificationTests.TextureSpecCase.call(
    735            this, name, desc
    736        );
    737        this.m_texFormat = format;
    738        this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
    739        this.m_width = width;
    740        this.m_height = height;
    741        this.m_depth = depth;
    742        this.m_numLevels = numLevels;
    743    };
    744 
    745    es3fTextureSpecificationTests.Texture3DSpecCase.prototype =
    746        Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
    747 
    748    es3fTextureSpecificationTests.Texture3DSpecCase.prototype.constructor =
    749        es3fTextureSpecificationTests.Texture3DSpecCase;
    750 
    751    /**
    752     * @param {sglrGLContext.GLContext} webgl2Context
    753     * @param {sglrReferenceContext.ReferenceContext} refContext
    754     */
    755    es3fTextureSpecificationTests.Texture3DSpecCase.prototype.verifyTexture =
    756    function(
    757        webgl2Context, refContext
    758    ) {
    759        /** @type {es3fFboTestUtil.Texture3DShader} */
    760        var shader = new es3fFboTestUtil.Texture3DShader(
    761            gluTextureUtil.getSampler3D(this.m_texFormat),
    762            gluShaderUtil.DataType.FLOAT_VEC4
    763        );
    764        var shaderIDgles = webgl2Context.createProgram(shader);
    765        var shaderIDRef = refContext.createProgram(shader);
    766 
    767        shader.setTexScaleBias(
    768            this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
    769        );
    770 
    771        // Set state.
    772        for (var ndx = 0; ndx < 2; ndx++) {
    773            var ctx = ndx ? refContext : webgl2Context;
    774 
    775            this.m_context = ctx;
    776 
    777            this.m_context.texParameteri(
    778                gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER,
    779                gl.NEAREST_MIPMAP_NEAREST
    780            );
    781            this.m_context.texParameteri(
    782                gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER,
    783                gl.NEAREST
    784            );
    785            this.m_context.texParameteri(
    786                gl.TEXTURE_3D, gl.TEXTURE_WRAP_S,
    787                gl.CLAMP_TO_EDGE
    788            );
    789            this.m_context.texParameteri(
    790                gl.TEXTURE_3D, gl.TEXTURE_WRAP_T,
    791                gl.CLAMP_TO_EDGE
    792            );
    793            this.m_context.texParameteri(
    794                gl.TEXTURE_3D, gl.TEXTURE_WRAP_R,
    795                gl.CLAMP_TO_EDGE
    796            );
    797            this.m_context.texParameteri(
    798                gl.TEXTURE_3D, gl.TEXTURE_MAX_LEVEL,
    799                this.m_numLevels - 1
    800            );
    801        }
    802 
    803        for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
    804            var levelW = Math.max(1, this.m_width >> levelNdx);
    805            var levelH = Math.max(1, this.m_height >> levelNdx);
    806            var levelD = Math.max(1, this.m_depth >> levelNdx);
    807            var levelOk = true;
    808 
    809            if (levelW == 1 || levelH == 1) {
    810                // Rendering to texture of size x1 is problematic in referencerenderer
    811                // due to its deviation from c++ code: crbug.com/613206
    812                continue;
    813            }
    814 
    815            for (var depth = 0; depth < levelD; depth++) {
    816                /** @type {tcuSurface.Surface} */
    817                var reference = new tcuSurface.Surface();
    818                /** @type {tcuSurface.Surface} */
    819                var result = new tcuSurface.Surface();
    820 
    821                shader.setDepth((depth + 0.5) / levelD);
    822 
    823                for (var ndx = 0; ndx < 2; ndx++) {
    824                    /** @type {tcuSurface.Surface} */
    825                    var dst = ndx ? reference : result;
    826                    ctx = ndx ? refContext : webgl2Context;
    827                    var shaderID = ndx ? shaderIDRef : shaderIDgles;
    828 
    829                    this.m_context = ctx;
    830                    shader.setUniforms(ctx, shaderID);
    831                    this.renderTex(dst, shaderID, levelW, levelH);
    832                }
    833 
    834                var threshold =
    835                es3fTextureSpecificationTests.computeCompareThreshold(
    836                    tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
    837                );
    838                var levelStr = levelNdx.toString();
    839                var sliceStr = depth.toString();
    840                var name = 'Layer' + levelStr + 'Slice' + sliceStr;
    841                var desc = 'Layer ' + levelStr + ', Slice ' + sliceStr;
    842                var depthOk = tcuImageCompare.intThresholdCompare(
    843                    name, desc, reference.getAccess(), result.getAccess(),
    844                    threshold, (levelNdx == 0 && depth == 0) ?
    845                    tcuImageCompare.CompareLogMode.RESULT :
    846                    tcuImageCompare.CompareLogMode.ON_ERROR
    847                );
    848 
    849                if (!depthOk) {
    850                    testFailed('Image comparison failed');
    851                    return false;
    852                }
    853            }
    854 
    855        }
    856        return true;
    857    };
    858 
    859    // Basic TexImage2D() with 2D texture usage
    860    /**
    861     * @constructor
    862     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
    863     * @param {string} name
    864     * @param {string} desc
    865     * @param {number} format
    866     * @param {number} dataType
    867     * @param {number} width
    868     * @param {number} height
    869     */
    870    es3fTextureSpecificationTests.BasicTexImage2DCase = function(
    871        name, desc, format, dataType, width, height
    872    ) {
    873        // Unsized internal format.
    874        es3fTextureSpecificationTests.Texture2DSpecCase.call(
    875            this, name, desc, gluTextureUtil.mapGLTransferFormat(
    876                format, dataType
    877            ), width, height,
    878            es3fTextureSpecificationTests.maxLevelCount(
    879                width, height
    880            )
    881        );
    882 
    883        this.m_internalFormat = format;
    884        this.m_format = format;
    885        this.m_dataType = dataType;
    886    };
    887 
    888    es3fTextureSpecificationTests.BasicTexImage2DCase.prototype = Object.create(
    889        es3fTextureSpecificationTests.Texture2DSpecCase.prototype
    890    );
    891 
    892    es3fTextureSpecificationTests.BasicTexImage2DCase.prototype.constructor =
    893        es3fTextureSpecificationTests.BasicTexImage2DCase;
    894 
    895    /**
    896     * @param {string} name
    897     * @param {string} desc
    898     * @param {number} internalFormat
    899     * @param {number} width
    900     * @param {number} height
    901     * @return {es3fTextureSpecificationTests.BasicTexImage2DCase}
    902     */
    903    es3fTextureSpecificationTests.newBasicTexImage2DCaseInternal = function(
    904        name, desc, internalFormat, width, height
    905    ) {
    906        // Sized internal format.
    907        var fmt = gluTextureUtil.getTransferFormat(
    908            gluTextureUtil.mapGLInternalFormat(internalFormat)
    909        );
    910        var testcase = new es3fTextureSpecificationTests.BasicTexImage2DCase(
    911            name, desc, fmt.format, fmt.dataType, width, height
    912        );
    913        testcase.m_internalFormat = internalFormat;
    914        return testcase;
    915    };
    916 
    917    /**
    918     * createTexture
    919     */
    920    es3fTextureSpecificationTests.BasicTexImage2DCase.prototype.createTexture =
    921    function() {
    922        var tex = null;
    923        var levelData = new tcuTexture.TextureLevel(
    924            this.m_texFormat, this.m_width, this.m_height
    925        );
    926        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
    927 
    928        tex = this.m_context.createTexture();
    929        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
    930        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
    931 
    932        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
    933            var levelW = Math.max(1, this.m_width >> ndx);
    934            var levelH = Math.max(1, this.m_height >> ndx);
    935            var gMin = es3fTextureSpecificationTests.randomVector(
    936                rnd, this.m_texFormatInfo.valueMin,
    937                this.m_texFormatInfo.valueMax, 4
    938            );
    939            var gMax = es3fTextureSpecificationTests.randomVector(
    940                rnd, this.m_texFormatInfo.valueMin,
    941                this.m_texFormatInfo.valueMax, 4
    942            );
    943 
    944            levelData.setSize(levelW, levelH);
    945            tcuTextureUtil.fillWithComponentGradients(
    946                levelData.getAccess(), gMin, gMax
    947            );
    948 
    949            this.m_context.texImage2D(
    950                gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
    951                this.m_format, this.m_dataType,
    952                levelData.getAccess().getDataPtr()
    953            );
    954        }
    955    };
    956 
    957    // Basic TexImage2D() with cubemap usage
    958    /**
    959     * @constructor
    960     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
    961     * @param {string} name
    962     * @param {string} desc
    963     * @param {number} format
    964     * @param {number} dataType
    965     * @param {number} size
    966     */
    967    es3fTextureSpecificationTests.BasicTexImageCubeCase = function(
    968        name, desc, format, dataType, size
    969    ) {
    970        // Unsized internal format.
    971        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
    972            this, name, desc, gluTextureUtil.mapGLTransferFormat(
    973                format, dataType
    974            ), size, deMath.logToFloor(size) + 1
    975        );
    976 
    977        this.m_internalFormat = format;
    978        this.m_format = format;
    979        this.m_dataType = dataType;
    980    };
    981 
    982    es3fTextureSpecificationTests.BasicTexImageCubeCase.prototype =
    983        Object.create(
    984            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
    985        );
    986 
    987    es3fTextureSpecificationTests.
    988    BasicTexImageCubeCase.prototype.constructor =
    989        es3fTextureSpecificationTests.BasicTexImageCubeCase;
    990 
    991    /**
    992     * @param {string} name
    993     * @param {string} desc
    994     * @param {number} internalFormat
    995     * @param {number} size
    996     * @return {es3fTextureSpecificationTests.BasicTexImageCubeCase}
    997     */
    998    es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal = function(
    999        name, desc, internalFormat, size
   1000    ) {
   1001        // Sized internal format.
   1002        var fmt = gluTextureUtil.getTransferFormat(
   1003            gluTextureUtil.mapGLInternalFormat(internalFormat)
   1004        );
   1005        var testcase = new es3fTextureSpecificationTests.BasicTexImageCubeCase(
   1006            name, desc, fmt.format, fmt.dataType, size
   1007        );
   1008        testcase.m_internalFormat = internalFormat;
   1009        return testcase;
   1010    };
   1011 
   1012    /**
   1013     * createTexture
   1014     */
   1015    es3fTextureSpecificationTests.
   1016    BasicTexImageCubeCase.prototype.createTexture =
   1017    function() {
   1018        var tex = null;
   1019        var levelData = new tcuTexture.TextureLevel(
   1020            this.m_texFormat, this.m_size, this.m_size
   1021        );
   1022        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   1023 
   1024        tex = this.m_context.createTexture();
   1025        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   1026        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   1027 
   1028        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1029            var levelSize = Math.max(1, this.m_size >> ndx);
   1030 
   1031            levelData.setSize(levelSize, levelSize);
   1032 
   1033            for (var f in tcuTexture.CubeFace) {
   1034                var face = tcuTexture.CubeFace[f];
   1035                var gMin = es3fTextureSpecificationTests.randomVector(
   1036                    rnd, this.m_texFormatInfo.valueMin,
   1037                    this.m_texFormatInfo.valueMax, 4
   1038                );
   1039                var gMax = es3fTextureSpecificationTests.randomVector(
   1040                    rnd, this.m_texFormatInfo.valueMin,
   1041                    this.m_texFormatInfo.valueMax, 4
   1042                );
   1043 
   1044                tcuTextureUtil.fillWithComponentGradients(
   1045                    levelData.getAccess(), gMin, gMax
   1046                );
   1047 
   1048                this.m_context.texImage2D(
   1049                    es3fTextureSpecificationTests.s_cubeMapFaces[face],
   1050                    ndx, this.m_internalFormat, levelSize, levelSize, 0,
   1051                    this.m_format, this.m_dataType,
   1052                    levelData.getAccess().getDataPtr()
   1053                );
   1054            }
   1055        }
   1056    };
   1057 
   1058    // Basic TexImage3D() with 2D array texture usage
   1059    /**
   1060     * @constructor
   1061     * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
   1062     * @param {string} name
   1063     * @param {string} desc
   1064     * @param {number} internalFormat
   1065     * @param {number} width
   1066     * @param {number} height
   1067     * @param {number} numLayers
   1068     */
   1069    es3fTextureSpecificationTests.BasicTexImage2DArrayCase = function(
   1070        name, desc, internalFormat, width, height, numLayers
   1071    ) {
   1072        es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
   1073            this, name, desc,
   1074            gluTextureUtil.mapGLInternalFormat(internalFormat), width, height,
   1075            numLayers, es3fTextureSpecificationTests.maxLevelCount(
   1076                width, height
   1077            )
   1078        );
   1079 
   1080        this.m_internalFormat = internalFormat;
   1081    };
   1082 
   1083    es3fTextureSpecificationTests.BasicTexImage2DArrayCase.prototype =
   1084        Object.create(
   1085            es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
   1086        );
   1087 
   1088    es3fTextureSpecificationTests.
   1089    BasicTexImage2DArrayCase.prototype.constructor =
   1090        es3fTextureSpecificationTests.BasicTexImage2DArrayCase;
   1091 
   1092    /**
   1093     * createTexture
   1094     */
   1095    es3fTextureSpecificationTests.
   1096    BasicTexImage2DArrayCase.prototype.createTexture =
   1097    function() {
   1098        var tex = null;
   1099        var levelData = new tcuTexture.TextureLevel(
   1100            this.m_texFormat, this.m_width, this.m_height
   1101        );
   1102        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   1103        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   1104 
   1105        tex = this.m_context.createTexture();
   1106        this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
   1107        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   1108 
   1109        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1110            var levelW = Math.max(1, this.m_width >> ndx);
   1111            var levelH = Math.max(1, this.m_height >> ndx);
   1112 
   1113            var gMin = es3fTextureSpecificationTests.randomVector(
   1114                rnd, this.m_texFormatInfo.valueMin,
   1115                this.m_texFormatInfo.valueMax, 4
   1116            );
   1117            var gMax = es3fTextureSpecificationTests.randomVector(
   1118                rnd, this.m_texFormatInfo.valueMin,
   1119                this.m_texFormatInfo.valueMax, 4
   1120            );
   1121 
   1122            levelData.setSize(levelW, levelH, this.m_numLayers);
   1123            tcuTextureUtil.fillWithComponentGradients(
   1124                levelData.getAccess(), gMin, gMax
   1125            );
   1126 
   1127            this.m_context.texImage3D(
   1128                gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
   1129                this.m_numLayers, 0, transferFmt.format,
   1130                transferFmt.dataType, levelData.getAccess().getDataPtr()
   1131            );
   1132        }
   1133    };
   1134 
   1135    // Basic TexImage3D() with 3D texture usage
   1136    /**
   1137     * @constructor
   1138     * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
   1139     * @param {string} name
   1140     * @param {string} desc
   1141     * @param {number} internalFormat
   1142     * @param {number} width
   1143     * @param {number} height
   1144     * @param {number} depth
   1145     */
   1146    es3fTextureSpecificationTests.BasicTexImage3DCase = function(
   1147        name, desc, internalFormat, width, height, depth
   1148    ) {
   1149        es3fTextureSpecificationTests.Texture3DSpecCase.call(
   1150            this, name, desc,
   1151            gluTextureUtil.mapGLInternalFormat(internalFormat), width, height,
   1152            depth, es3fTextureSpecificationTests.maxLevelCount(
   1153                width, height, depth
   1154            )
   1155        );
   1156 
   1157        this.m_internalFormat = internalFormat;
   1158    };
   1159 
   1160    es3fTextureSpecificationTests.BasicTexImage3DCase.prototype =
   1161        Object.create(
   1162            es3fTextureSpecificationTests.Texture3DSpecCase.prototype
   1163        );
   1164 
   1165    es3fTextureSpecificationTests.
   1166    BasicTexImage3DCase.prototype.constructor =
   1167        es3fTextureSpecificationTests.BasicTexImage3DCase;
   1168 
   1169    /**
   1170     * createTexture
   1171     */
   1172    es3fTextureSpecificationTests.
   1173    BasicTexImage3DCase.prototype.createTexture =
   1174    function() {
   1175        var tex = null;
   1176        var levelData = new tcuTexture.TextureLevel(
   1177            this.m_texFormat, this.m_width, this.m_height
   1178        );
   1179        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   1180        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   1181 
   1182        tex = this.m_context.createTexture();
   1183        this.m_context.bindTexture(gl.TEXTURE_3D, tex);
   1184        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   1185 
   1186        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1187            var levelW = Math.max(1, this.m_width >> ndx);
   1188            var levelH = Math.max(1, this.m_height >> ndx);
   1189            var levelD = Math.max(1, this.m_depth >> ndx);
   1190 
   1191            var gMin = es3fTextureSpecificationTests.randomVector(
   1192                rnd, this.m_texFormatInfo.valueMin,
   1193                this.m_texFormatInfo.valueMax, 4
   1194            );
   1195            var gMax = es3fTextureSpecificationTests.randomVector(
   1196                rnd, this.m_texFormatInfo.valueMin,
   1197                this.m_texFormatInfo.valueMax, 4
   1198            );
   1199 
   1200            levelData.setSize(levelW, levelH, levelD);
   1201            tcuTextureUtil.fillWithComponentGradients(
   1202                levelData.getAccess(), gMin, gMax
   1203            );
   1204 
   1205            this.m_context.texImage3D(
   1206                gl.TEXTURE_3D, ndx, this.m_internalFormat, levelW, levelH,
   1207                levelD, 0, transferFmt.format, transferFmt.dataType,
   1208                levelData.getAccess().getDataPtr()
   1209            );
   1210        }
   1211    };
   1212 
   1213    // Randomized 2D texture specification using TexImage2D
   1214    /**
   1215     * @constructor
   1216     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   1217     * @param {string} name
   1218     * @param {string} desc
   1219     * @param {number} format
   1220     * @param {number} dataType
   1221     * @param {number} width
   1222     * @param {number} height
   1223     */
   1224    es3fTextureSpecificationTests.RandomOrderTexImage2DCase = function(
   1225        name, desc, format, dataType, width, height
   1226    ) {
   1227        // Unsized internal format.
   1228        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   1229            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   1230                format, dataType
   1231            ), width, height,
   1232            es3fTextureSpecificationTests.maxLevelCount(
   1233                width, height
   1234            )
   1235        );
   1236 
   1237        this.m_internalFormat = format;
   1238        this.m_format = format;
   1239        this.m_dataType = dataType;
   1240    };
   1241 
   1242    es3fTextureSpecificationTests.RandomOrderTexImage2DCase.prototype = Object.create(
   1243        es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   1244    );
   1245 
   1246    es3fTextureSpecificationTests.
   1247    RandomOrderTexImage2DCase.prototype.constructor =
   1248        es3fTextureSpecificationTests.RandomOrderTexImage2DCase;
   1249 
   1250    /**
   1251     * @param {string} name
   1252     * @param {string} desc
   1253     * @param {number} internalFormat
   1254     * @param {number} width
   1255     * @param {number} height
   1256     * @return {es3fTextureSpecificationTests.RandomOrderTexImage2DCase}
   1257     */
   1258    es3fTextureSpecificationTests.newRandomOrderTexImage2DCaseInternal =
   1259    function(name, desc, internalFormat, width, height) {
   1260        // Sized internal format.
   1261        var fmt = gluTextureUtil.getTransferFormat(
   1262            gluTextureUtil.mapGLInternalFormat(internalFormat)
   1263        );
   1264        var testcase = new es3fTextureSpecificationTests.RandomOrderTexImage2DCase(
   1265            name, desc, fmt.format, fmt.dataType, width, height
   1266        );
   1267        testcase.m_internalFormat = internalFormat;
   1268        return testcase;
   1269    };
   1270 
   1271    /**
   1272     * createTexture
   1273     */
   1274    es3fTextureSpecificationTests.
   1275    RandomOrderTexImage2DCase.prototype.createTexture = function() {
   1276        var tex = null;
   1277        var levelData = new tcuTexture.TextureLevel(
   1278            this.m_texFormat, this.m_width, this.m_height
   1279        );
   1280        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   1281 
   1282        tex = this.m_context.createTexture();
   1283        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   1284        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   1285 
   1286        var levels = [];
   1287        for (var i = 0; i < this.m_numLevels; i++)
   1288            levels[i] = i;
   1289        levels = rnd.shuffle(levels);
   1290 
   1291        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1292            var levelNdx = levels[ndx];
   1293            var levelW = Math.max(1, this.m_width >> levelNdx);
   1294            var levelH = Math.max(1, this.m_height >> levelNdx);
   1295            var gMin = es3fTextureSpecificationTests.randomVector(
   1296                rnd, this.m_texFormatInfo.valueMin,
   1297                this.m_texFormatInfo.valueMax, 4
   1298            );
   1299            var gMax = es3fTextureSpecificationTests.randomVector(
   1300                rnd, this.m_texFormatInfo.valueMin,
   1301                this.m_texFormatInfo.valueMax, 4
   1302            );
   1303 
   1304            levelData.setSize(levelW, levelH);
   1305            tcuTextureUtil.fillWithComponentGradients(
   1306                levelData.getAccess(), gMin, gMax
   1307            );
   1308 
   1309            this.m_context.texImage2D(
   1310                gl.TEXTURE_2D, levelNdx, this.m_internalFormat, levelW, levelH, 0,
   1311                this.m_format, this.m_dataType,
   1312                levelData.getAccess().getDataPtr()
   1313            );
   1314        }
   1315    };
   1316 
   1317    // Randomized cubemap texture specification using TexImage2D
   1318    /**
   1319     * @constructor
   1320     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   1321     * @param {string} name
   1322     * @param {string} desc
   1323     * @param {number} format
   1324     * @param {number} dataType
   1325     * @param {number} size
   1326     */
   1327    es3fTextureSpecificationTests.RandomOrderTexImageCubeCase = function(
   1328        name, desc, format, dataType, size
   1329    ) {
   1330        // Unsized internal format.
   1331        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   1332            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   1333                format, dataType
   1334            ), size, deMath.logToFloor(size) + 1
   1335        );
   1336 
   1337        this.m_internalFormat = format;
   1338        this.m_format = format;
   1339        this.m_dataType = dataType;
   1340    };
   1341 
   1342    es3fTextureSpecificationTests.RandomOrderTexImageCubeCase.prototype =
   1343        Object.create(
   1344            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   1345        );
   1346 
   1347    es3fTextureSpecificationTests.
   1348    RandomOrderTexImageCubeCase.prototype.constructor =
   1349        es3fTextureSpecificationTests.RandomOrderTexImageCubeCase;
   1350 
   1351    /**
   1352     * @param {string} name
   1353     * @param {string} desc
   1354     * @param {number} internalFormat
   1355     * @param {number} size
   1356     * @return {es3fTextureSpecificationTests.RandomOrderTexImageCubeCase}
   1357     */
   1358    es3fTextureSpecificationTests.newRandomOrderTexImageCubeCaseInternal =
   1359    function(name, desc, internalFormat, size) {
   1360        // Sized internal format.
   1361        var fmt = gluTextureUtil.getTransferFormat(
   1362            gluTextureUtil.mapGLInternalFormat(internalFormat)
   1363        );
   1364        var testcase = new es3fTextureSpecificationTests.RandomOrderTexImageCubeCase(
   1365            name, desc, fmt.format, fmt.dataType, size
   1366        );
   1367        testcase.m_internalFormat = internalFormat;
   1368        return testcase;
   1369    };
   1370 
   1371    /**
   1372     * createTexture
   1373     */
   1374    es3fTextureSpecificationTests.
   1375    RandomOrderTexImageCubeCase.prototype.createTexture =
   1376    function() {
   1377        var tex = null;
   1378        var levelData = new tcuTexture.TextureLevel(
   1379            this.m_texFormat, this.m_size, this.m_size
   1380        );
   1381        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   1382 
   1383        tex = this.m_context.createTexture();
   1384        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   1385        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   1386 
   1387        // Level-face pairs.
   1388        var images = [];
   1389 
   1390        for (var ndx = 0; ndx < this.m_numLevels; ndx++)
   1391            for (var f in tcuTexture.CubeFace) {
   1392                var face = tcuTexture.CubeFace[f];
   1393                images[ndx * 6 + face] = {ndx: ndx, face: face};
   1394            }
   1395 
   1396        images = rnd.shuffle(images);
   1397 
   1398        for (var ndx = 0; ndx < images.length; ndx++) {
   1399            var levelNdx = images[ndx].ndx;
   1400            /** @type {framework.common.tcuTexture.CubeFace} */
   1401            var face = images[ndx].face;
   1402            var levelSize = Math.max(1, this.m_size >> levelNdx);
   1403 
   1404            var gMin = es3fTextureSpecificationTests.randomVector(
   1405                rnd, this.m_texFormatInfo.valueMin,
   1406                this.m_texFormatInfo.valueMax, 4
   1407            );
   1408            var gMax = es3fTextureSpecificationTests.randomVector(
   1409                rnd, this.m_texFormatInfo.valueMin,
   1410                this.m_texFormatInfo.valueMax, 4
   1411            );
   1412 
   1413            levelData.setSize(levelSize, levelSize);
   1414            tcuTextureUtil.fillWithComponentGradients(
   1415                levelData.getAccess(), gMin, gMax
   1416            );
   1417 
   1418            this.m_context.texImage2D(
   1419                es3fTextureSpecificationTests.s_cubeMapFaces[face],
   1420                levelNdx, this.m_internalFormat, levelSize, levelSize, 0,
   1421                this.m_format, this.m_dataType,
   1422                levelData.getAccess().getDataPtr()
   1423            );
   1424        }
   1425    };
   1426 
   1427    // TexImage2D() unpack alignment case.
   1428    /**
   1429     * @constructor
   1430     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   1431     * @param {string} name
   1432     * @param {string} desc
   1433     * @param {number} format
   1434     * @param {number} dataType
   1435     * @param {number} width
   1436     * @param {number} height
   1437     * @param {number} numLevels
   1438     * @param {number} alignment
   1439     */
   1440    es3fTextureSpecificationTests.TexImage2DAlignCase = function(
   1441        name, desc, format, dataType, width, height, numLevels, alignment
   1442    ) {
   1443        // Unsized internal format.
   1444        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   1445            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   1446                format, dataType
   1447            ), width, height, numLevels
   1448        );
   1449 
   1450        this.m_internalFormat = format;
   1451        this.m_format = format;
   1452        this.m_dataType = dataType;
   1453        this.m_alignment = alignment;
   1454    };
   1455 
   1456    es3fTextureSpecificationTests.TexImage2DAlignCase.prototype = Object.create(
   1457        es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   1458    );
   1459 
   1460    es3fTextureSpecificationTests.
   1461    TexImage2DAlignCase.prototype.constructor =
   1462        es3fTextureSpecificationTests.TexImage2DAlignCase;
   1463 
   1464    /**
   1465    * @param {string} name
   1466    * @param {string} desc
   1467    * @param {number} internalFormat
   1468    * @param {number} width
   1469    * @param {number} height
   1470    * @param {number} numLevels
   1471    * @param {number} alignment
   1472     * @return {es3fTextureSpecificationTests.TexImage2DAlignCase}
   1473     */
   1474    es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal = function(
   1475        name, desc, internalFormat, width, height, numLevels, alignment
   1476    ) {
   1477        // Sized internal format.
   1478        var fmt = gluTextureUtil.getTransferFormat(
   1479            gluTextureUtil.mapGLInternalFormat(internalFormat)
   1480        );
   1481        var testcase = new es3fTextureSpecificationTests.TexImage2DAlignCase(
   1482            name, desc, fmt.format, fmt.dataType,
   1483            width, height, numLevels, alignment
   1484        );
   1485        testcase.m_internalFormat = internalFormat;
   1486        return testcase;
   1487    };
   1488 
   1489    /**
   1490     * createTexture
   1491     */
   1492    es3fTextureSpecificationTests.TexImage2DAlignCase.prototype.createTexture =
   1493    function() {
   1494        var tex = null;
   1495        /** @type {ArrayBuffer} */ var data;
   1496 
   1497        tex = this.m_context.createTexture();
   1498        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   1499        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   1500 
   1501        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1502            var levelW = Math.max(1, this.m_width >> ndx);
   1503            var levelH = Math.max(1, this.m_height >> ndx);
   1504            var colorA = deMath.add(
   1505                deMath.multiply(
   1506                    [1.0, 0.0, 0.0, 1.0],
   1507                    deMath.subtract(
   1508                        this.m_texFormatInfo.valueMax,
   1509                        this.m_texFormatInfo.valueMin
   1510                    )
   1511                ), this.m_texFormatInfo.valueMin
   1512            );
   1513            var colorB = deMath.add(
   1514                deMath.multiply(
   1515                    [0.0, 1.0, 0.0, 1.0],
   1516                    deMath.subtract(
   1517                        this.m_texFormatInfo.valueMax,
   1518                        this.m_texFormatInfo.valueMin
   1519                    )
   1520                ), this.m_texFormatInfo.valueMin
   1521            );
   1522 
   1523            var rowPitch = deMath.deAlign32(
   1524                levelW * this.m_texFormat.getPixelSize(), this.m_alignment
   1525            );
   1526            var cellSize = Math.max(1, Math.min(levelW >> 2, levelH >> 2));
   1527            data = new ArrayBuffer(rowPitch * levelH);
   1528            var access = new tcuTexture.PixelBufferAccess({format: this.m_texFormat, width: levelW,
   1529                    height: levelH, rowPitch: rowPitch, data: data}
   1530                );
   1531            tcuTextureUtil.fillWithGrid(access, cellSize, colorA, colorB
   1532            );
   1533 
   1534            this.m_context.texImage2D(
   1535                gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
   1536                this.m_format, this.m_dataType,
   1537                access.getDataPtr()
   1538            );
   1539        }
   1540    };
   1541 
   1542    // TexImageCube unpack alignment case.
   1543    /**
   1544     * @constructor
   1545     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   1546     * @param {string} name
   1547     * @param {string} desc
   1548     * @param {number} format
   1549     * @param {number} dataType
   1550     * @param {number} size
   1551     * @param {number} numLevels
   1552     * @param {number} alignment
   1553     */
   1554    es3fTextureSpecificationTests.TexImageCubeAlignCase = function(
   1555        name, desc, format, dataType, size, numLevels, alignment
   1556    ) {
   1557        // Unsized internal format.
   1558        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   1559            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   1560                format, dataType
   1561            ), size, numLevels
   1562        );
   1563 
   1564        this.m_internalFormat = format;
   1565        this.m_format = format;
   1566        this.m_dataType = dataType;
   1567        this.m_alignment = alignment;
   1568    };
   1569 
   1570    es3fTextureSpecificationTests.TexImageCubeAlignCase.prototype =
   1571        Object.create(
   1572            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   1573        );
   1574 
   1575    es3fTextureSpecificationTests.
   1576    TexImageCubeAlignCase.prototype.constructor =
   1577        es3fTextureSpecificationTests.TexImageCubeAlignCase;
   1578 
   1579    /**
   1580     * @param {string} name
   1581     * @param {string} desc
   1582     * @param {number} internalFormat
   1583     * @param {number} size
   1584     * @param {number} numLevels
   1585     * @param {number} alignment
   1586     * @return {es3fTextureSpecificationTests.TexImageCubeAlignCase}
   1587     */
   1588    es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal =
   1589    function(name, desc, internalFormat, size, numLevels, alignment) {
   1590        // Sized internal format.
   1591        var fmt = gluTextureUtil.getTransferFormat(
   1592            gluTextureUtil.mapGLInternalFormat(internalFormat)
   1593        );
   1594        var testcase = new es3fTextureSpecificationTests.TexImageCubeAlignCase(
   1595            name, desc, fmt.format, fmt.dataType, size, numLevels, alignment
   1596        );
   1597        testcase.m_internalFormat = internalFormat;
   1598        return testcase;
   1599    };
   1600 
   1601    /**
   1602     * createTexture
   1603     */
   1604    es3fTextureSpecificationTests.
   1605    TexImageCubeAlignCase.prototype.createTexture =
   1606    function() {
   1607        var tex = null;
   1608        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   1609        /** @type {ArrayBuffer} */ var data;
   1610 
   1611        tex = this.m_context.createTexture();
   1612        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   1613        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   1614 
   1615        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1616            var levelSize = Math.max(1, this.m_size >> ndx);
   1617            var cellSize = Math.max(1, levelSize >> 2);
   1618            var rowPitch = deMath.deAlign32(
   1619                this.m_texFormat.getPixelSize() * levelSize, this.m_alignment
   1620            );
   1621            var colorA = deMath.add(deMath.multiply(
   1622                [1.0, 0.0, 0.0, 1.0], deMath.subtract(
   1623                    this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
   1624                )), this.m_texFormatInfo.valueMin
   1625            );
   1626            var colorB = deMath.add(deMath.multiply(
   1627                [0.0, 1.0, 0.0, 1.0], deMath.subtract(
   1628                    this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
   1629                )), this.m_texFormatInfo.valueMin
   1630            );
   1631 
   1632            data = new ArrayBuffer(rowPitch * levelSize);
   1633            var access = new tcuTexture.PixelBufferAccess({format: this.m_texFormat, width: levelSize,
   1634                    height: levelSize, rowPitch: rowPitch, data: data}
   1635                );
   1636            tcuTextureUtil.fillWithGrid(access, cellSize, colorA, colorB
   1637            );
   1638 
   1639            for (var f in tcuTexture.CubeFace) {
   1640                var face = tcuTexture.CubeFace[f];
   1641                this.m_context.texImage2D(
   1642                    es3fTextureSpecificationTests.s_cubeMapFaces[face],
   1643                    ndx, this.m_internalFormat, levelSize, levelSize, 0,
   1644                    this.m_format, this.m_dataType,
   1645                    access.getDataPtr()
   1646                );
   1647            }
   1648        }
   1649    };
   1650 
   1651    // TexImage2D() unpack parameters case.
   1652    /**
   1653     * @constructor
   1654     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   1655     * @param {string} name
   1656     * @param {string} desc
   1657     * @param {number} internalFormat
   1658     * @param {number} width
   1659     * @param {number} height
   1660     * @param {number} rowLength
   1661     * @param {number} skipRows
   1662     * @param {number} skipPixels
   1663     * @param {number} alignment
   1664     */
   1665    es3fTextureSpecificationTests.TexImage2DParamsCase = function(
   1666        name, desc, internalFormat, width, height, rowLength, skipRows,
   1667        skipPixels, alignment
   1668    ) {
   1669        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   1670            this, name, desc,
   1671            gluTextureUtil.mapGLInternalFormat(internalFormat),
   1672            width, height, 1
   1673        );
   1674        this.m_internalFormat = internalFormat;
   1675        this.m_rowLength = rowLength;
   1676        this.m_skipRows = skipRows;
   1677        this.m_skipPixels = skipPixels;
   1678        this.m_alignment = alignment;
   1679    };
   1680 
   1681    es3fTextureSpecificationTests.TexImage2DParamsCase.prototype =
   1682    Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
   1683 
   1684    es3fTextureSpecificationTests.TexImage2DParamsCase.prototype.constructor =
   1685        es3fTextureSpecificationTests.TexImage2DParamsCase;
   1686 
   1687    /**
   1688     * createTexture
   1689     */
   1690    es3fTextureSpecificationTests.TexImage2DParamsCase.prototype.createTexture =
   1691    function() {
   1692        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   1693        var pixelSize = this.m_texFormat.getPixelSize();
   1694        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
   1695        var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
   1696        var height = this.m_height + this.m_skipRows;
   1697        var tex = null;
   1698        /** @type {ArrayBuffer} */ var data;
   1699 
   1700        assertMsgOptions(
   1701            this.m_numLevels == 1, 'Number of levels different to 1',
   1702            false, true
   1703        );
   1704 
   1705        // Fill data with grid.
   1706        data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize);
   1707 
   1708        var cScale = deMath.subtract(
   1709            this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
   1710        );
   1711        var cBias = this.m_texFormatInfo.valueMin;
   1712        var colorA = deMath.add(
   1713            deMath.multiply(
   1714                [1.0, 0.0, 0.0, 1.0], cScale
   1715            ), cBias
   1716        );
   1717        var colorB = deMath.add(
   1718            deMath.multiply(
   1719                [0.0, 1.0, 0.0, 1.0], cScale
   1720            ), cBias
   1721        );
   1722 
   1723        var accessWithOffset = new tcuTexture.PixelBufferAccess({
   1724                format: this.m_texFormat,
   1725                width: this.m_width,
   1726                height: this.m_height,
   1727                rowPitch: rowPitch,
   1728                data: data,
   1729                offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
   1730                });
   1731        tcuTextureUtil.fillWithGrid(accessWithOffset, 4, colorA, colorB
   1732        );
   1733        var access = new tcuTexture.PixelBufferAccess({
   1734                format: this.m_texFormat,
   1735                width: this.m_width,
   1736                height: this.m_height,
   1737                rowPitch: rowPitch,
   1738                data: data,
   1739                });
   1740 
   1741        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   1742        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   1743        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   1744        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   1745 
   1746        tex = this.m_context.createTexture();
   1747        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   1748        this.m_context.texImage2D(
   1749            gl.TEXTURE_2D, 0, this.m_internalFormat,
   1750            this.m_width, this.m_height, 0,
   1751            transferFmt.format, transferFmt.dataType, access.getDataPtr()
   1752        );
   1753    };
   1754 
   1755    // TexImage3D() unpack parameters case.
   1756    /**
   1757     * @constructor
   1758     * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
   1759     * @param {string} name
   1760     * @param {string} desc
   1761     * @param {number} internalFormat
   1762     * @param {number} width
   1763     * @param {number} height
   1764     * @param {number} depth
   1765     * @param {number} imageHeight
   1766     * @param {number} rowLength
   1767     * @param {number} skipImages
   1768     * @param {number} skipRows
   1769     * @param {number} skipPixels
   1770     * @param {number} alignment
   1771     */
   1772    es3fTextureSpecificationTests.TexImage3DParamsCase = function(
   1773        name, desc, internalFormat, width, height, depth, imageHeight,
   1774        rowLength, skipImages, skipRows, skipPixels, alignment
   1775    ) {
   1776        es3fTextureSpecificationTests.Texture3DSpecCase.call(
   1777            this, name, desc,
   1778            gluTextureUtil.mapGLInternalFormat(internalFormat),
   1779            width, height, depth, 1
   1780        );
   1781 
   1782        this.m_internalFormat = internalFormat;
   1783        this.m_imageHeight = imageHeight;
   1784        this.m_rowLength = rowLength;
   1785        this.m_skipImages = skipImages;
   1786        this.m_skipRows = skipRows;
   1787        this.m_skipPixels = skipPixels;
   1788        this.m_alignment = alignment;
   1789    };
   1790 
   1791    es3fTextureSpecificationTests.TexImage3DParamsCase.prototype =
   1792    Object.create(es3fTextureSpecificationTests.Texture3DSpecCase.prototype);
   1793 
   1794    es3fTextureSpecificationTests.TexImage3DParamsCase.prototype.constructor =
   1795        es3fTextureSpecificationTests.Texture3DSpecCase;
   1796 
   1797    /**
   1798     * createTexture
   1799     */
   1800    es3fTextureSpecificationTests.TexImage3DParamsCase.prototype.createTexture =
   1801    function() {
   1802        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   1803        var pixelSize = this.m_texFormat.getPixelSize();
   1804        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
   1805        var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
   1806        var imageHeight = this.m_imageHeight > 0 ?
   1807            this.m_imageHeight : this.m_height;
   1808        var slicePitch = imageHeight * rowPitch;
   1809 
   1810        var tex = null;
   1811        /** @type {ArrayBuffer} */ var data;
   1812 
   1813        assertMsgOptions(
   1814            this.m_numLevels == 1, 'Number of levels different to 1',
   1815            false, true
   1816        );
   1817 
   1818        // Fill data with grid.
   1819        data = new ArrayBuffer(slicePitch * (this.m_depth + this.m_skipImages) +
   1820                               this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize);
   1821 
   1822        var cScale = deMath.subtract(
   1823            this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
   1824        );
   1825        var cBias = this.m_texFormatInfo.valueMin;
   1826        var colorA = deMath.add(
   1827            deMath.multiply(
   1828                [1.0, 0.0, 0.0, 1.0], cScale
   1829            ), cBias
   1830        );
   1831        var colorB = deMath.add(
   1832            deMath.multiply(
   1833                [0.0, 1.0, 0.0, 1.0], cScale
   1834            ), cBias
   1835        );
   1836 
   1837        var accessWithOffset = new tcuTexture.PixelBufferAccess({
   1838                format: this.m_texFormat,
   1839                width: this.m_width,
   1840                height: this.m_height,
   1841                depth: this.m_depth,
   1842                rowPitch: rowPitch,
   1843                slicePitch: slicePitch,
   1844                data: data,
   1845                offset: this.m_skipImages * slicePitch + this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
   1846            });
   1847        var access = new tcuTexture.PixelBufferAccess({
   1848                format: this.m_texFormat,
   1849                width: this.m_width,
   1850                height: this.m_height,
   1851                depth: this.m_depth,
   1852                rowPitch: rowPitch,
   1853                slicePitch: slicePitch,
   1854                data: data
   1855            });
   1856        tcuTextureUtil.fillWithGrid(
   1857            accessWithOffset, 4, colorA, colorB
   1858        );
   1859 
   1860        this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
   1861        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   1862        this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
   1863        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   1864        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   1865        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   1866 
   1867        tex = this.m_context.createTexture();
   1868        this.m_context.bindTexture(gl.TEXTURE_3D, tex);
   1869        this.m_context.texImage3D(
   1870            gl.TEXTURE_3D, 0, this.m_internalFormat,
   1871            this.m_width, this.m_height, this.m_depth, 0,
   1872            transferFmt.format, transferFmt.dataType, access.getDataPtr()
   1873        );
   1874    };
   1875 
   1876    /**
   1877     * @constructor
   1878     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   1879     * @param {string} name
   1880     * @param {string} desc
   1881     * @param {number} format
   1882     * @param {number} dataType
   1883     * @param {number} width
   1884     * @param {number} height
   1885     */
   1886    es3fTextureSpecificationTests.BasicTexSubImage2DCase = function(
   1887        name, desc, format, dataType, width, height
   1888    ) {
   1889        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   1890            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   1891                format, dataType
   1892            ), width, height, es3fTextureSpecificationTests.maxLevelCount(
   1893                width, height
   1894            )
   1895        );
   1896 
   1897        this.m_format = format;
   1898        this.m_internalFormat = format;
   1899        this.m_dataType = dataType;
   1900    };
   1901 
   1902    es3fTextureSpecificationTests.BasicTexSubImage2DCase.prototype =
   1903    Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
   1904 
   1905    es3fTextureSpecificationTests.BasicTexSubImage2DCase.prototype.constructor =
   1906        es3fTextureSpecificationTests.BasicTexSubImage2DCase;
   1907 
   1908    /**
   1909     * @param {string} name
   1910     * @param {string} desc
   1911     * @param {number} internalFormat
   1912     * @param {number} width
   1913     * @param {number} height
   1914     * @return {es3fTextureSpecificationTests.BasicTexSubImage2DCase}
   1915     */
   1916    es3fTextureSpecificationTests.newBasicTexSubImage2DCaseInternal =
   1917    function(name, desc, internalFormat, width, height) {
   1918        // Sized internal format.
   1919        var fmt = gluTextureUtil.getTransferFormat(
   1920            gluTextureUtil.mapGLInternalFormat(internalFormat)
   1921        );
   1922        var testcase = new es3fTextureSpecificationTests.BasicTexSubImage2DCase(
   1923            name, desc, fmt.format, fmt.dataType, width, height
   1924        );
   1925        testcase.m_internalFormat = internalFormat;
   1926        return testcase;
   1927    };
   1928 
   1929    /**
   1930     */
   1931    es3fTextureSpecificationTests.
   1932    BasicTexSubImage2DCase.prototype.createTexture = function() {
   1933        var tex = null;
   1934        var data = new tcuTexture.TextureLevel(
   1935            this.m_texFormat, this.m_width, this.m_height
   1936        );
   1937        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   1938 
   1939        tex = this.m_context.createTexture();
   1940        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   1941        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   1942 
   1943        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1944            var levelW = Math.max(1, this.m_width >> ndx);
   1945            var levelH = Math.max(1, this.m_height >> ndx);
   1946            var gMin = es3fTextureSpecificationTests.randomVector(
   1947                rnd, this.m_texFormatInfo.valueMin,
   1948                this.m_texFormatInfo.valueMax, 4
   1949            );
   1950            var gMax = es3fTextureSpecificationTests.randomVector(
   1951                rnd, this.m_texFormatInfo.valueMin,
   1952                this.m_texFormatInfo.valueMax, 4
   1953            );
   1954 
   1955            data.setSize(levelW, levelH);
   1956            tcuTextureUtil.fillWithComponentGradients(
   1957                data.getAccess(), gMin, gMax
   1958            );
   1959 
   1960            this.m_context.texImage2D(
   1961                gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
   1962                this.m_format, this.m_dataType,
   1963                data.getAccess().getDataPtr()
   1964            );
   1965        }
   1966 
   1967        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   1968            var levelW = Math.max(1, this.m_width >> ndx);
   1969            var levelH = Math.max(1, this.m_height >> ndx);
   1970 
   1971            var w = rnd.getInt(1, levelW);
   1972            var h = rnd.getInt(1, levelH);
   1973            var x = rnd.getInt(0, levelW - w);
   1974            var y = rnd.getInt(0, levelH - h);
   1975 
   1976            var colorA = es3fTextureSpecificationTests.randomVector(
   1977                rnd, this.m_texFormatInfo.valueMin,
   1978                this.m_texFormatInfo.valueMax, 4
   1979            );
   1980            var colorB = es3fTextureSpecificationTests.randomVector(
   1981                rnd, this.m_texFormatInfo.valueMin,
   1982                this.m_texFormatInfo.valueMax, 4
   1983            );
   1984            var cellSize = rnd.getInt(2, 16);
   1985 
   1986            data.setSize(w, h);
   1987            tcuTextureUtil.fillWithGrid(
   1988                data.getAccess(), cellSize, colorA, colorB
   1989            );
   1990 
   1991            this.m_context.texSubImage2D(
   1992                gl.TEXTURE_2D, ndx, x, y, w, h, this.m_format, this.m_dataType,
   1993                data.getAccess().getDataPtr()
   1994            );
   1995        }
   1996    };
   1997 
   1998    /**
   1999     * @constructor
   2000     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   2001     * @param {string} name
   2002     * @param {string} desc
   2003     * @param {number} format
   2004     * @param {number} dataType
   2005     * @param {number} size
   2006     */
   2007    es3fTextureSpecificationTests.BasicTexSubImageCubeCase = function(
   2008        name, desc, format, dataType, size
   2009    ) {
   2010        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   2011            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   2012                format, dataType
   2013            ), size, deMath.logToFloor(size) + 1
   2014        );
   2015 
   2016        this.m_internalFormat = format;
   2017        this.m_format = format;
   2018        this.m_dataType = dataType;
   2019    };
   2020 
   2021    es3fTextureSpecificationTests.BasicTexSubImageCubeCase.prototype =
   2022    Object.create(es3fTextureSpecificationTests.TextureCubeSpecCase.prototype);
   2023 
   2024    es3fTextureSpecificationTests.
   2025    BasicTexSubImageCubeCase.prototype.constructor =
   2026        es3fTextureSpecificationTests.BasicTexSubImageCubeCase;
   2027 
   2028    /**
   2029     * @param {string} name
   2030     * @param {string} desc
   2031     * @param {number} internalFormat
   2032     * @param {number} size
   2033     */
   2034    es3fTextureSpecificationTests.newBasicTexSubImageCubeCaseInternal =
   2035    function(name, desc, internalFormat, size) {
   2036        // Sized internal format.
   2037        var fmt = gluTextureUtil.getTransferFormat(
   2038            gluTextureUtil.mapGLInternalFormat(internalFormat)
   2039        );
   2040        var testcase =
   2041            new es3fTextureSpecificationTests.BasicTexSubImageCubeCase(
   2042            name, desc, fmt.format, fmt.dataType,
   2043            size);
   2044        testcase.m_internalFormat = internalFormat;
   2045        return testcase;
   2046    };
   2047 
   2048    /**
   2049     * createTexture
   2050     */
   2051    es3fTextureSpecificationTests.
   2052    BasicTexSubImageCubeCase.prototype.createTexture = function() {
   2053        var tex = null;
   2054        var data = new tcuTexture.TextureLevel(
   2055            this.m_texFormat, this.m_size, this.m_size
   2056        );
   2057        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   2058 
   2059        tex = this.m_context.createTexture();
   2060        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   2061        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   2062 
   2063        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2064            var levelSize = Math.max(1, this.m_size >> ndx);
   2065            data.setSize(levelSize, levelSize);
   2066 
   2067            for (var face = /** @type {tcuTexture.CubeFace} */ (0);
   2068                face < es3fTextureSpecificationTests.s_cubeMapFaces.length;
   2069                face++) {
   2070                var gMin = es3fTextureSpecificationTests.randomVector(
   2071                    rnd, this.m_texFormatInfo.valueMin,
   2072                    this.m_texFormatInfo.valueMax, 4
   2073                );
   2074                var gMax = es3fTextureSpecificationTests.randomVector(
   2075                    rnd, this.m_texFormatInfo.valueMin,
   2076                    this.m_texFormatInfo.valueMax, 4
   2077                );
   2078 
   2079                tcuTextureUtil.fillWithComponentGradients(
   2080                    data.getAccess(), gMin, gMax
   2081                );
   2082 
   2083                this.m_context.texImage2D(
   2084                    es3fTextureSpecificationTests.s_cubeMapFaces[face], ndx,
   2085                    this.m_internalFormat, levelSize, levelSize, 0,
   2086                    this.m_format, this.m_dataType,
   2087                    data.getAccess().getDataPtr()
   2088                );
   2089            }
   2090        }
   2091 
   2092        // Re-specify parts of each face and level.
   2093        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2094            var levelSize = Math.max(1, this.m_size >> ndx);
   2095 
   2096            for (var f in tcuTexture.CubeFace) {
   2097                var face = tcuTexture.CubeFace[f];
   2098 
   2099                var w = rnd.getInt(1, levelSize);
   2100                var h = rnd.getInt(1, levelSize);
   2101                var x = rnd.getInt(0, levelSize - w);
   2102                var y = rnd.getInt(0, levelSize - h);
   2103 
   2104                var colorA = es3fTextureSpecificationTests.randomVector(
   2105                    rnd, this.m_texFormatInfo.valueMin,
   2106                    this.m_texFormatInfo.valueMax, 4
   2107                );
   2108                var colorB = es3fTextureSpecificationTests.randomVector(
   2109                    rnd, this.m_texFormatInfo.valueMin,
   2110                    this.m_texFormatInfo.valueMax, 4
   2111                );
   2112                var cellSize = rnd.getInt(2, 16);
   2113 
   2114                data.setSize(w, h);
   2115                tcuTextureUtil.fillWithGrid(
   2116                    data.getAccess(), cellSize, colorA, colorB
   2117                );
   2118 
   2119                this.m_context.texSubImage2D(
   2120                    es3fTextureSpecificationTests.s_cubeMapFaces[face],
   2121                    ndx, x, y, w, h, this.m_format,
   2122                    this.m_dataType, data.getAccess().getDataPtr()
   2123                );
   2124            }
   2125        }
   2126    };
   2127 
   2128    // TexSubImage2D() unpack parameters case.
   2129    /**
   2130     * @constructor
   2131     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   2132     * @param {string} name
   2133     * @param {string} desc
   2134     * @param {number} internalFormat
   2135     * @param {number} width
   2136     * @param {number} height
   2137     * @param {number} subX
   2138     * @param {number} subY
   2139     * @param {number} subW
   2140     * @param {number} subH
   2141     * @param {number} rowLength
   2142     * @param {number} skipRows
   2143     * @param {number} skipPixels
   2144     * @param {number} alignment
   2145     */
   2146    es3fTextureSpecificationTests.TexSubImage2DParamsCase = function(
   2147        name, desc, internalFormat, width, height, subX, subY, subW, subH,
   2148        rowLength, skipRows, skipPixels, alignment
   2149    ) {
   2150        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   2151            this, name, desc,
   2152            gluTextureUtil.mapGLInternalFormat(internalFormat),
   2153            width, height, 1
   2154        );
   2155        this.m_internalFormat = internalFormat;
   2156        this.m_subX = subX;
   2157        this.m_subY = subY;
   2158        this.m_subW = subW;
   2159        this.m_subH = subH;
   2160        this.m_rowLength = rowLength;
   2161        this.m_skipRows = skipRows;
   2162        this.m_skipPixels = skipPixels;
   2163        this.m_alignment = alignment;
   2164    };
   2165 
   2166    es3fTextureSpecificationTests.TexSubImage2DParamsCase.prototype =
   2167        Object.create(
   2168            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   2169        );
   2170 
   2171    es3fTextureSpecificationTests.
   2172    TexSubImage2DParamsCase.prototype.constructor =
   2173        es3fTextureSpecificationTests.TexSubImage2DParamsCase;
   2174 
   2175    /**
   2176     * createTexture
   2177     */
   2178    es3fTextureSpecificationTests.
   2179    TexSubImage2DParamsCase.prototype.createTexture = function() {
   2180        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   2181        var pixelSize = this.m_texFormat.getPixelSize();
   2182        var tex = null;
   2183        /** @type {ArrayBuffer} */ var data;
   2184 
   2185        assertMsgOptions(
   2186            this.m_numLevels == 1, 'Number of levels different to 1',
   2187            false, true
   2188        );
   2189 
   2190        tex = this.m_context.createTexture();
   2191        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   2192 
   2193        // First fill texture with gradient.
   2194        data = new ArrayBuffer(
   2195            deMath.deAlign32(this.m_width * pixelSize, 4) * this.m_height
   2196        );
   2197        var access = new tcuTexture.PixelBufferAccess({
   2198                format: this.m_texFormat,
   2199                width: this.m_width,
   2200                height: this.m_height,
   2201                rowPitch: deMath.deAlign32(this.m_width * pixelSize, 4),
   2202                data: data
   2203            });
   2204        tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
   2205        );
   2206        this.m_context.texImage2D(
   2207            gl.TEXTURE_2D, 0, this.m_internalFormat, this.m_width,
   2208            this.m_height, 0, transferFmt.format, transferFmt.dataType,
   2209            access.getDataPtr()
   2210        );
   2211 
   2212        // Fill data with grid.
   2213        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
   2214        var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
   2215        var height = this.m_subH + this.m_skipRows;
   2216        var cScale = deMath.subtract(
   2217            this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
   2218        );
   2219        var cBias = this.m_texFormatInfo.valueMin;
   2220        var colorA = deMath.add(
   2221            deMath.multiply(
   2222                [1.0, 0.0, 0.0, 1.0], cScale
   2223            ), cBias
   2224        );
   2225        var colorB = deMath.add(
   2226            deMath.multiply(
   2227                [0.0, 1.0, 0.0, 1.0], cScale
   2228            ), cBias
   2229        );
   2230 
   2231        data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize);
   2232        tcuTextureUtil.fillWithGrid(
   2233            new tcuTexture.PixelBufferAccess({
   2234                format: this.m_texFormat,
   2235                width: this.m_subW,
   2236                height: this.m_subH,
   2237                rowPitch: rowPitch,
   2238                data: data,
   2239                offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
   2240                }) ,
   2241            4, colorA, colorB
   2242        );
   2243 
   2244        access = new tcuTexture.PixelBufferAccess({
   2245                format: this.m_texFormat,
   2246                width: this.m_subW,
   2247                height: this.m_subH,
   2248                rowPitch: rowPitch,
   2249                data: data
   2250            });
   2251        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   2252        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   2253        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   2254        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   2255        this.m_context.texSubImage2D(
   2256            gl.TEXTURE_2D, 0, this.m_subX, this.m_subY,
   2257            this.m_subW, this.m_subH,
   2258            transferFmt.format, transferFmt.dataType,
   2259            access.getDataPtr()
   2260        );
   2261    };
   2262 
   2263    // Basic TexSubImage3D() with 3D texture usage
   2264    /**
   2265     * @constructor
   2266     * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
   2267     * @param {string} name
   2268     * @param {string} desc
   2269     * @param {number} internalFormat
   2270     * @param {number} width
   2271     * @param {number} height
   2272     * @param {number} depth
   2273     */
   2274    es3fTextureSpecificationTests.BasicTexSubImage3DCase = function(
   2275        name, desc, internalFormat, width, height, depth
   2276    ) {
   2277        es3fTextureSpecificationTests.Texture3DSpecCase.call(
   2278            this, name, desc,
   2279            gluTextureUtil.mapGLInternalFormat(internalFormat),
   2280            width, height, depth, es3fTextureSpecificationTests.maxLevelCount(
   2281                width, height, depth
   2282            )
   2283        );
   2284 
   2285        this.m_internalFormat = internalFormat;
   2286    };
   2287 
   2288    es3fTextureSpecificationTests.BasicTexSubImage3DCase.prototype =
   2289        Object.create(
   2290            es3fTextureSpecificationTests.Texture3DSpecCase.prototype
   2291        );
   2292 
   2293    es3fTextureSpecificationTests.BasicTexSubImage3DCase.prototype.constructor =
   2294    es3fTextureSpecificationTests.BasicTexSubImage3DCase;
   2295 
   2296    /**
   2297     * createTexture
   2298     */
   2299    es3fTextureSpecificationTests.
   2300    BasicTexSubImage3DCase.prototype.createTexture = function() {
   2301        var tex = null;
   2302        var data = new tcuTexture.TextureLevel(
   2303            this.m_texFormat, this.m_width, this.m_height
   2304        );
   2305        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   2306        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   2307 
   2308        tex = this.m_context.createTexture();
   2309        this.m_context.bindTexture(gl.TEXTURE_3D, tex);
   2310        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   2311 
   2312        // First specify full texture.
   2313        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2314            var levelW = Math.max(1, this.m_width >> ndx);
   2315            var levelH = Math.max(1, this.m_height >> ndx);
   2316            var levelD = Math.max(1, this.m_depth >> ndx);
   2317 
   2318            var gMin = es3fTextureSpecificationTests.randomVector(
   2319                rnd, this.m_texFormatInfo.valueMin,
   2320                this.m_texFormatInfo.valueMax, 4
   2321            );
   2322            var gMax = es3fTextureSpecificationTests.randomVector(
   2323                rnd, this.m_texFormatInfo.valueMin,
   2324                this.m_texFormatInfo.valueMax, 4
   2325            );
   2326 
   2327            data.setSize(levelW, levelH, levelD);
   2328            tcuTextureUtil.fillWithComponentGradients(
   2329                data.getAccess(), gMin, gMax
   2330            );
   2331 
   2332            this.m_context.texImage3D(
   2333                gl.TEXTURE_3D, ndx, this.m_internalFormat, levelW, levelH,
   2334                levelD, 0, transferFmt.format, transferFmt.dataType,
   2335                data.getAccess().getDataPtr()
   2336            );
   2337        }
   2338 
   2339        // Re-specify parts of each level.
   2340        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2341            var levelW = Math.max(1, this.m_width >> ndx);
   2342            var levelH = Math.max(1, this.m_height >> ndx);
   2343            var levelD = Math.max(1, this.m_depth >> ndx);
   2344 
   2345            var w = rnd.getInt(1, levelW);
   2346            var h = rnd.getInt(1, levelH);
   2347            var d = rnd.getInt(1, levelD);
   2348            var x = rnd.getInt(0, levelW - w);
   2349            var y = rnd.getInt(0, levelH - h);
   2350            var z = rnd.getInt(0, levelD - d);
   2351 
   2352            var colorA = es3fTextureSpecificationTests.randomVector(
   2353                rnd, this.m_texFormatInfo.valueMin,
   2354                this.m_texFormatInfo.valueMax, 4
   2355            );
   2356            var colorB = es3fTextureSpecificationTests.randomVector(
   2357                rnd, this.m_texFormatInfo.valueMin,
   2358                this.m_texFormatInfo.valueMax, 4
   2359            );
   2360            var cellSize = rnd.getInt(2, 16);
   2361 
   2362            data.setSize(w, h, d);
   2363            tcuTextureUtil.fillWithGrid(
   2364                data.getAccess(), cellSize, colorA, colorB
   2365            );
   2366 
   2367            this.m_context.texSubImage3D(
   2368                gl.TEXTURE_3D, ndx, x, y, z, w, h, d,
   2369                transferFmt.format, transferFmt.dataType,
   2370                data.getAccess().getDataPtr()
   2371            );
   2372        }
   2373    };
   2374 
   2375    // TexSubImage2D() to texture initialized with empty data
   2376    /**
   2377     * @constructor
   2378     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   2379     * @param {string} name
   2380     * @param {string} desc
   2381     * @param {number} format
   2382     * @param {number} dataType
   2383     * @param {number} width
   2384     * @param {number} height
   2385     */
   2386    es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase = function(
   2387        name, desc, format, dataType, width, height
   2388    ) {
   2389        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   2390            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   2391                format, dataType
   2392            ), width, height, es3fTextureSpecificationTests.maxLevelCount(
   2393                width, height
   2394            )
   2395        );
   2396 
   2397        this.m_format = format;
   2398        this.m_internalFormat = format;
   2399        this.m_dataType = dataType;
   2400    };
   2401 
   2402    es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase.prototype =
   2403    Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
   2404 
   2405    es3fTextureSpecificationTests.
   2406    TexSubImage2DEmptyTexCase.prototype.constructor =
   2407        es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase;
   2408 
   2409    /**
   2410     * @param {string} name
   2411     * @param {string} desc
   2412     * @param {number} internalFormat
   2413     * @param {number} width
   2414     * @param {number} height
   2415     */
   2416    es3fTextureSpecificationTests.newTexSubImage2DEmptyTexCaseInternal =
   2417    function(name, desc, internalFormat, width, height) {
   2418        // Sized internal format.
   2419        var fmt = gluTextureUtil.getTransferFormat(
   2420            gluTextureUtil.mapGLInternalFormat(internalFormat)
   2421        );
   2422        var testcase =
   2423            new es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase(
   2424                name, desc, fmt.format, fmt.dataType, width, height
   2425            );
   2426        testcase.m_internalFormat = internalFormat;
   2427        return testcase;
   2428    };
   2429 
   2430    /**
   2431     * createTexture
   2432     */
   2433    es3fTextureSpecificationTests.
   2434    TexSubImage2DEmptyTexCase.prototype.createTexture = function() {
   2435        var tex = null;
   2436        var data = new tcuTexture.TextureLevel(
   2437            this.m_texFormat, this.m_width, this.m_height
   2438        );
   2439        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   2440 
   2441        tex = this.m_context.createTexture();
   2442        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   2443        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   2444 
   2445        // First allocate storage for each level.
   2446        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2447            var levelW = Math.max(1, this.m_width >> ndx);
   2448            var levelH = Math.max(1, this.m_height >> ndx);
   2449 
   2450            this.m_context.texImage2D(
   2451                gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
   2452                this.m_format, this.m_dataType,
   2453                null
   2454            );
   2455        }
   2456 
   2457        // Specify pixel data to all levels using glTexSubImage2D()
   2458        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2459            var levelW = Math.max(1, this.m_width >> ndx);
   2460            var levelH = Math.max(1, this.m_height >> ndx);
   2461            var gMin = es3fTextureSpecificationTests.randomVector(
   2462                rnd, this.m_texFormatInfo.valueMin,
   2463                this.m_texFormatInfo.valueMax, 4
   2464            );
   2465            var gMax = es3fTextureSpecificationTests.randomVector(
   2466                rnd, this.m_texFormatInfo.valueMin,
   2467                this.m_texFormatInfo.valueMax, 4
   2468            );
   2469 
   2470            data.setSize(levelW, levelH);
   2471            tcuTextureUtil.fillWithComponentGradients(
   2472                data.getAccess(), gMin, gMax
   2473            );
   2474 
   2475            this.m_context.texSubImage2D(
   2476                gl.TEXTURE_2D, ndx, 0, 0, levelW, levelH,
   2477                this.m_format, this.m_dataType,
   2478                data.getAccess().getDataPtr()
   2479            );
   2480        }
   2481    };
   2482 
   2483    // TexSubImage2D() to empty cubemap texture
   2484    /**
   2485     * @constructor
   2486     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   2487     * @param {string} name
   2488     * @param {string} desc
   2489     * @param {number} format
   2490     * @param {number} dataType
   2491     * @param {number} size
   2492     */
   2493    es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase = function(
   2494        name, desc, format, dataType, size
   2495    ) {
   2496        // Unsized internal format.
   2497        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   2498            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   2499                format, dataType
   2500            ), size, deMath.logToFloor(size) + 1
   2501        );
   2502 
   2503        this.m_internalFormat = format;
   2504        this.m_format = format;
   2505        this.m_dataType = dataType;
   2506    };
   2507 
   2508    es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase.prototype =
   2509        Object.create(
   2510            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   2511        );
   2512 
   2513    es3fTextureSpecificationTests.
   2514    TexSubImageCubeEmptyTexCase.prototype.constructor =
   2515        es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase;
   2516 
   2517    /**
   2518     * @param {string} name
   2519     * @param {string} desc
   2520     * @param {number} internalFormat
   2521     * @param {number} size
   2522     * @return {es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase}
   2523     */
   2524    es3fTextureSpecificationTests.newTexSubImageCubeEmptyTexCaseInternal =
   2525    function(name, desc, internalFormat, size) {
   2526        // Sized internal format.
   2527        var fmt = gluTextureUtil.getTransferFormat(
   2528            gluTextureUtil.mapGLInternalFormat(internalFormat)
   2529        );
   2530        var testcase =
   2531            new es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase(
   2532                name, desc, fmt.format, fmt.dataType, size
   2533            );
   2534        testcase.m_internalFormat = internalFormat;
   2535        return testcase;
   2536    };
   2537 
   2538    /**
   2539     * createTexture
   2540     */
   2541    es3fTextureSpecificationTests.
   2542    TexSubImageCubeEmptyTexCase.prototype.createTexture =
   2543    function() {
   2544        var tex = null;
   2545        var data = new tcuTexture.TextureLevel(
   2546            this.m_texFormat, this.m_size, this.m_size
   2547        );
   2548        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   2549 
   2550        tex = this.m_context.createTexture();
   2551        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   2552        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   2553 
   2554        // Specify storage for each level.
   2555        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2556            var levelSize = Math.max(1, this.m_size >> ndx);
   2557 
   2558            for (var f in tcuTexture.CubeFace) {
   2559                var face = tcuTexture.CubeFace[f];
   2560                this.m_context.texImage2D(
   2561                    es3fTextureSpecificationTests.s_cubeMapFaces[face],
   2562                    ndx, this.m_internalFormat, levelSize, levelSize, 0,
   2563                    this.m_format, this.m_dataType,
   2564                    null
   2565                );
   2566            }
   2567        }
   2568 
   2569        // Specify data using glTexSubImage2D()
   2570        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   2571            var levelSize = Math.max(1, this.m_size >> ndx);
   2572 
   2573            data.setSize(levelSize, levelSize);
   2574 
   2575            for (var f in tcuTexture.CubeFace) {
   2576                var face = tcuTexture.CubeFace[f];
   2577                var gMin = es3fTextureSpecificationTests.randomVector(
   2578                    rnd, this.m_texFormatInfo.valueMin,
   2579                    this.m_texFormatInfo.valueMax, 4
   2580                );
   2581                var gMax = es3fTextureSpecificationTests.randomVector(
   2582                    rnd, this.m_texFormatInfo.valueMin,
   2583                    this.m_texFormatInfo.valueMax, 4
   2584                );
   2585 
   2586                tcuTextureUtil.fillWithComponentGradients(
   2587                    data.getAccess(), gMin, gMax
   2588                );
   2589 
   2590                this.m_context.texSubImage2D(
   2591                    es3fTextureSpecificationTests.s_cubeMapFaces[face],
   2592                    ndx, 0, 0, levelSize, levelSize, this.m_format,
   2593                    this.m_dataType, data.getAccess().getDataPtr()
   2594                );
   2595            }
   2596        }
   2597    };
   2598 
   2599    // TexSubImage2D() unpack alignment with 2D texture
   2600    /**
   2601     * @constructor
   2602     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   2603     * @param {string} name
   2604     * @param {string} desc
   2605     * @param {number} format
   2606     * @param {number} dataType
   2607     * @param {number} width
   2608     * @param {number} height
   2609     * @param {number} subX
   2610     * @param {number} subY
   2611     * @param {number} subW
   2612     * @param {number} subH
   2613     * @param {number} alignment
   2614     */
   2615    es3fTextureSpecificationTests.TexSubImage2DAlignCase = function(
   2616        name, desc, format, dataType, width, height, subX, subY, subW, subH,
   2617        alignment
   2618    ) {
   2619        // Unsized internal format.
   2620        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   2621            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   2622                format, dataType
   2623            ), width, height, 1
   2624        );
   2625 
   2626        this.m_internalFormat = format;
   2627        this.m_format = format;
   2628        this.m_dataType = dataType;
   2629        this.m_subX = subX;
   2630        this.m_subY = subY;
   2631        this.m_subW = subW;
   2632        this.m_subH = subH;
   2633        this.m_alignment = alignment;
   2634    };
   2635 
   2636    es3fTextureSpecificationTests.TexSubImage2DAlignCase.prototype =
   2637        Object.create(
   2638            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   2639        );
   2640 
   2641    es3fTextureSpecificationTests.
   2642    TexSubImage2DAlignCase.prototype.constructor =
   2643        es3fTextureSpecificationTests.TexSubImage2DAlignCase;
   2644 
   2645    /**
   2646     * @param {string} name
   2647     * @param {string} desc
   2648     * @param {number} internalFormat
   2649     * @param {number} width
   2650     * @param {number} height
   2651     * @param {number} subX
   2652     * @param {number} subY
   2653     * @param {number} subW
   2654     * @param {number} subH
   2655     * @param {number} alignment
   2656     * @return {es3fTextureSpecificationTests.TexSubImage2DAlignCase}
   2657     */
   2658    es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal = function(
   2659        name, desc, internalFormat, width, height, subX, subY, subW, subH,
   2660        alignment
   2661    ) {
   2662        // Sized internal format.
   2663        var fmt = gluTextureUtil.getTransferFormat(
   2664            gluTextureUtil.mapGLInternalFormat(internalFormat)
   2665        );
   2666        var testcase = new es3fTextureSpecificationTests.TexSubImage2DAlignCase(
   2667            name, desc, fmt.format, fmt.dataType,
   2668            width, height, subX, subY, subW, subH, alignment
   2669        );
   2670        testcase.m_internalFormat = internalFormat;
   2671        return testcase;
   2672    };
   2673 
   2674    /**
   2675     * createTexture
   2676     */
   2677    es3fTextureSpecificationTests.
   2678    TexSubImage2DAlignCase.prototype.createTexture = function() {
   2679        var tex = null;
   2680        /** @type {ArrayBuffer} */ var data;
   2681 
   2682        tex = this.m_context.createTexture();
   2683        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   2684 
   2685        // Specify base level.
   2686        data = new ArrayBuffer(this.m_texFormat.getPixelSize() *
   2687            this.m_width * this.m_height
   2688        );
   2689        var access = new tcuTexture.PixelBufferAccess({
   2690                format: this.m_texFormat,
   2691                width: this.m_width,
   2692                height: this.m_height,
   2693                data: data
   2694            });
   2695        tcuTextureUtil.fillWithComponentGradients(access, [0, 0, 0, 0], [1, 1, 1, 1]);
   2696 
   2697        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   2698        this.m_context.texImage2D(gl.TEXTURE_2D, 0, this.m_internalFormat,
   2699            this.m_width, this.m_height, 0, this.m_format, this.m_dataType,
   2700            access.getDataPtr()
   2701        );
   2702 
   2703        // Re-specify subrectangle.
   2704        var rowPitch = deMath.deAlign32(
   2705            this.m_texFormat.getPixelSize() * this.m_subW, this.m_alignment
   2706        );
   2707        data = new ArrayBuffer(rowPitch * this.m_subH);
   2708        access = new tcuTexture.PixelBufferAccess({
   2709                format: this.m_texFormat,
   2710                width: this.m_subW,
   2711                height: this.m_subH,
   2712                rowPitch: rowPitch,
   2713                data: data
   2714            });
   2715        tcuTextureUtil.fillWithGrid(access, 4, [1, 0, 0, 1], [0, 1, 0, 1]
   2716        );
   2717 
   2718        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   2719        this.m_context.texSubImage2D(
   2720            gl.TEXTURE_2D, 0, this.m_subX, this.m_subY, this.m_subW,
   2721            this.m_subH, this.m_format, this.m_dataType, access.getDataPtr()
   2722        );
   2723    };
   2724 
   2725    // TexSubImage2D() unpack alignment with cubemap texture
   2726    /**
   2727     * @constructor
   2728     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   2729     * @param {string} name
   2730     * @param {string} desc
   2731     * @param {number} format
   2732     * @param {number} dataType
   2733     * @param {number} size
   2734     * @param {number} subX
   2735     * @param {number} subY
   2736     * @param {number} subW
   2737     * @param {number} subH
   2738     * @param {number} alignment
   2739     */
   2740    es3fTextureSpecificationTests.TexSubImageCubeAlignCase = function(
   2741        name, desc, format, dataType, size, subX, subY, subW, subH, alignment
   2742    ) {
   2743        // Unsized internal format.
   2744        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   2745            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   2746                format, dataType
   2747            ), size, 1
   2748        );
   2749 
   2750        this.m_internalFormat = format;
   2751        this.m_format = format;
   2752        this.m_dataType = dataType;
   2753        this.m_subX = subX;
   2754        this.m_subY = subY;
   2755        this.m_subW = subW;
   2756        this.m_subH = subH;
   2757        this.m_alignment = alignment;
   2758    };
   2759 
   2760    es3fTextureSpecificationTests.TexSubImageCubeAlignCase.prototype =
   2761        Object.create(
   2762            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   2763        );
   2764 
   2765    es3fTextureSpecificationTests.
   2766    TexSubImageCubeAlignCase.prototype.constructor =
   2767        es3fTextureSpecificationTests.TexSubImageCubeAlignCase;
   2768 
   2769    /**
   2770     * @param {string} name
   2771     * @param {string} desc
   2772     * @param {number} internalFormat
   2773     * @param {number} size
   2774     * @param {number} subX
   2775     * @param {number} subY
   2776     * @param {number} subW
   2777     * @param {number} subH
   2778     * @param {number} alignment
   2779     * @return {es3fTextureSpecificationTests.TexSubImageCubeAlignCase}
   2780     */
   2781    es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal =
   2782    function(
   2783        name, desc, internalFormat, size,
   2784        subX, subY, subW, subH, alignment
   2785    ) {
   2786        // Sized internal format.
   2787        var fmt = gluTextureUtil.getTransferFormat(
   2788            gluTextureUtil.mapGLInternalFormat(internalFormat)
   2789        );
   2790        var testcase =
   2791            new es3fTextureSpecificationTests.TexSubImageCubeAlignCase(
   2792                name, desc, fmt.format, fmt.dataType, size,
   2793                subX, subY, subW, subH, alignment
   2794            );
   2795        testcase.m_internalFormat = internalFormat;
   2796        return testcase;
   2797    };
   2798 
   2799    /**
   2800     * createTexture
   2801     */
   2802    es3fTextureSpecificationTests.
   2803    TexSubImageCubeAlignCase.prototype.createTexture =
   2804    function() {
   2805        var tex = null;
   2806        tex = this.m_context.createTexture();
   2807        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   2808 
   2809        var data = new ArrayBuffer(this.m_texFormat.getPixelSize() * this.m_size * this.m_size);
   2810        var access = new tcuTexture.PixelBufferAccess({
   2811                format: this.m_texFormat,
   2812                width: this.m_size,
   2813                height: this.m_size,
   2814                data: data
   2815            });
   2816        tcuTextureUtil.fillWithComponentGradients(access, [0, 0, 0, 0], [1, 1, 1, 1]
   2817        );
   2818 
   2819        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   2820        for (var f in tcuTexture.CubeFace) {
   2821            var face = tcuTexture.CubeFace[f];
   2822            this.m_context.texImage2D(
   2823                es3fTextureSpecificationTests.s_cubeMapFaces[face],
   2824                0, this.m_internalFormat, this.m_size, this.m_size, 0,
   2825                this.m_format, this.m_dataType,
   2826                access.getDataPtr()
   2827            );
   2828        }
   2829 
   2830        // Re-specify subrectangle.
   2831        var rowPitch = deMath.deAlign32(
   2832            this.m_texFormat.getPixelSize() * this.m_subW, this.m_alignment
   2833        );
   2834        data = new ArrayBuffer(rowPitch * this.m_subH);
   2835        access = new tcuTexture.PixelBufferAccess({
   2836                format: this.m_texFormat,
   2837                width: this.m_subW,
   2838                height: this.m_subH,
   2839                rowPitch: rowPitch,
   2840                data: data
   2841        });
   2842        tcuTextureUtil.fillWithGrid(access, 4, [1, 0, 0, 1], [0, 1, 0, 1]
   2843        );
   2844        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   2845        for (var f in tcuTexture.CubeFace) {
   2846            var face = tcuTexture.CubeFace[f];
   2847            this.m_context.texSubImage2D(
   2848                es3fTextureSpecificationTests.s_cubeMapFaces[face],
   2849                0, this.m_subX, this.m_subY, this.m_subW, this.m_subH,
   2850                this.m_format, this.m_dataType, access.getDataPtr()
   2851            );
   2852        }
   2853    };
   2854 
   2855    // TexSubImage3D() unpack parameters case.
   2856    /**
   2857     * @constructor
   2858     * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
   2859     * @param {string} name
   2860     * @param {string} desc
   2861     * @param {number} internalFormat
   2862     * @param {number} width
   2863     * @param {number} height
   2864     * @param {number} depth
   2865     * @param {number} subX ,
   2866     * @param {number} subY ,
   2867     * @param {number} subZ ,
   2868     * @param {number} subW ,
   2869     * @param {number} subH ,
   2870     * @param {number} subD ,
   2871     * @param {number} imageHeight ,
   2872     * @param {number} rowLength ,
   2873     * @param {number} skipImages ,
   2874     * @param {number} skipRows ,
   2875     * @param {number} skipPixels ,
   2876     * @param {number} alignment
   2877     */
   2878    es3fTextureSpecificationTests.TexSubImage3DParamsCase = function(
   2879        name, desc, internalFormat, width, height, depth,
   2880        subX, subY, subZ, subW, subH, subD,
   2881        imageHeight, rowLength, skipImages, skipRows, skipPixels, alignment
   2882    ) {
   2883        es3fTextureSpecificationTests.Texture3DSpecCase.call(
   2884            this, name, desc,
   2885            gluTextureUtil.mapGLInternalFormat(internalFormat),
   2886            width, height, depth, 1
   2887        );
   2888 
   2889        this.m_internalFormat = internalFormat;
   2890        this.m_subX = subX;
   2891        this.m_subY = subY;
   2892        this.m_subZ = subZ;
   2893        this.m_subW = subW;
   2894        this.m_subH = subH;
   2895        this.m_subD = subD;
   2896        this.m_imageHeight = imageHeight;
   2897        this.m_rowLength = rowLength;
   2898        this.m_skipImages = skipImages;
   2899        this.m_skipRows = skipRows;
   2900        this.m_skipPixels = skipPixels;
   2901        this.m_alignment = alignment;
   2902    };
   2903 
   2904    es3fTextureSpecificationTests.TexSubImage3DParamsCase.prototype =
   2905        Object.create(
   2906            es3fTextureSpecificationTests.Texture3DSpecCase.prototype
   2907        );
   2908 
   2909    es3fTextureSpecificationTests.
   2910    TexSubImage3DParamsCase.prototype.constructor =
   2911        es3fTextureSpecificationTests.TexSubImage3DParamsCase;
   2912 
   2913    /**
   2914     * createTexture
   2915     */
   2916    es3fTextureSpecificationTests.
   2917    TexSubImage3DParamsCase.prototype.createTexture = function() {
   2918        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   2919        var pixelSize = this.m_texFormat.getPixelSize();
   2920        var tex = null;
   2921        var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
   2922        var slicePitch = rowPitch * this.m_height;
   2923        assertMsgOptions(
   2924            this.m_numLevels == 1, 'Numbel of levels different than 1',
   2925            false, true
   2926        );
   2927 
   2928        tex = this.m_context.createTexture();
   2929        this.m_context.bindTexture(gl.TEXTURE_3D, tex);
   2930 
   2931        // Fill with gradient.
   2932 
   2933        var data = new ArrayBuffer(slicePitch * this.m_depth);
   2934        var access = new tcuTexture.PixelBufferAccess({
   2935                            format: this.m_texFormat,
   2936                            width: this.m_width,
   2937                            height: this.m_height,
   2938                            depth: this.m_depth,
   2939                            rowPitch: rowPitch,
   2940                            slicePitch: slicePitch,
   2941                            data: data
   2942                        });
   2943        tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax);
   2944 
   2945        this.m_context.texImage3D(
   2946            gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
   2947            this.m_height, this.m_depth, 0, transferFmt.format,
   2948            transferFmt.dataType, access.getDataPtr()
   2949        );
   2950 
   2951        // Fill data with grid.
   2952        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
   2953        rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
   2954        var imageHeight = this.m_imageHeight > 0 ? this.m_imageHeight : this.m_subH;
   2955        slicePitch = imageHeight * rowPitch;
   2956        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   2957        var cBias = this.m_texFormatInfo.valueMin;
   2958        var colorA = deMath.add(
   2959            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   2960        );
   2961        var colorB = deMath.add(
   2962            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   2963        );
   2964 
   2965        data = new ArrayBuffer(slicePitch * (this.m_depth + this.m_skipImages) +
   2966                               this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize);
   2967        var accessWithOffset = new tcuTexture.PixelBufferAccess({
   2968                format: this.m_texFormat,
   2969                width: this.m_subW,
   2970                height: this.m_subH,
   2971                depth: this.m_subD,
   2972                rowPitch: rowPitch,
   2973                slicePitch: slicePitch,
   2974                data: data,
   2975                offset: this.m_skipImages * slicePitch + this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
   2976            });
   2977        access = new tcuTexture.PixelBufferAccess({
   2978                format: this.m_texFormat,
   2979                width: this.m_subW,
   2980                height: this.m_subH,
   2981                depth: this.m_subD,
   2982                rowPitch: rowPitch,
   2983                slicePitch: slicePitch,
   2984                data: data
   2985            });
   2986        tcuTextureUtil.fillWithGrid(accessWithOffset, 4, colorA, colorB);
   2987 
   2988        this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
   2989        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   2990        this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
   2991        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   2992        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   2993        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   2994        this.m_context.texSubImage3D(
   2995            gl.TEXTURE_3D, 0, this.m_subX, this.m_subY, this.m_subZ,
   2996            this.m_subW, this.m_subH, this.m_subD,
   2997            transferFmt.format, transferFmt.dataType, access.getDataPtr()
   2998        );
   2999    };
   3000 
   3001    // Basic CopyTexImage2D() with 2D texture usage
   3002    /**
   3003     * @constructor
   3004     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   3005     * @param {string} name
   3006     * @param {string} desc
   3007     * @param {number} internalFormat
   3008     * @param {number} width
   3009     * @param {number} height
   3010     */
   3011    es3fTextureSpecificationTests.BasicCopyTexImage2DCase = function(
   3012        name, desc, internalFormat, width, height
   3013    ) {
   3014        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   3015            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   3016                internalFormat, gl.UNSIGNED_BYTE
   3017            ), width, height, es3fTextureSpecificationTests.maxLevelCount(
   3018                width, height
   3019            )
   3020        );
   3021 
   3022        this.m_internalFormat = internalFormat;
   3023    };
   3024 
   3025    es3fTextureSpecificationTests.BasicCopyTexImage2DCase.prototype =
   3026        Object.create(
   3027            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   3028        );
   3029 
   3030    es3fTextureSpecificationTests.
   3031    BasicCopyTexImage2DCase.prototype.constructor =
   3032        es3fTextureSpecificationTests.BasicCopyTexImage2DCase;
   3033 
   3034    /**
   3035     * createTexture
   3036     */
   3037    es3fTextureSpecificationTests.
   3038    BasicCopyTexImage2DCase.prototype.createTexture = function() {
   3039        var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
   3040        var targetHasRGB = pixelFormat.redBits > 0 &&
   3041            pixelFormat.greenBits > 0 &&
   3042            pixelFormat.blueBits > 0;
   3043        var targetHasAlpha = pixelFormat.alphaBits > 0;
   3044        var fmt = es3fTextureSpecificationTests.mapGLUnsizedInternalFormat(
   3045                this.m_internalFormat
   3046        );
   3047        var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
   3048        var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
   3049            fmt.order == tcuTexture.ChannelOrder.LA ||
   3050            fmt.order == tcuTexture.ChannelOrder.A;
   3051        var tex = null;
   3052        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3053        /** @type {es3fFboTestUtil.GradientShader} */
   3054        var shader = new es3fFboTestUtil.GradientShader(
   3055            gluShaderUtil.DataType.FLOAT_VEC4
   3056        );
   3057        var shaderID = this.m_context.createProgram(shader);
   3058 
   3059        if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   3060            throw new Error(
   3061                'Copying from current framebuffer is not supported'
   3062            );
   3063 
   3064        // Fill render target with gradient.
   3065        shader.setGradient(
   3066            this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
   3067        );
   3068        rrUtil.drawQuad(
   3069            this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
   3070        );
   3071 
   3072        tex = this.m_context.createTexture();
   3073        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   3074 
   3075        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3076            var levelW = Math.max(1, this.m_width >> ndx);
   3077            var levelH = Math.max(1, this.m_height >> ndx);
   3078            var x = rnd.getInt(0, this.m_width - levelW);
   3079            var y = rnd.getInt(0, this.m_height - levelH);
   3080 
   3081            this.m_context.copyTexImage2D(
   3082                gl.TEXTURE_2D, ndx, this.m_internalFormat, x, y,
   3083                levelW, levelH, 0
   3084            );
   3085        }
   3086    };
   3087 
   3088    // Basic CopyTexImage2D() with cubemap usage
   3089    /**
   3090     * @constructor
   3091     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   3092     * @param {string} name
   3093     * @param {string} desc
   3094     * @param {number} internalFormat
   3095     * @param {number} size
   3096     */
   3097    es3fTextureSpecificationTests.BasicCopyTexImageCubeCase = function(
   3098        name, desc, internalFormat, size
   3099    ) {
   3100        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   3101            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   3102                internalFormat, gl.UNSIGNED_BYTE
   3103            ), size, deMath.logToFloor(size) + 1
   3104        );
   3105 
   3106        this.m_internalFormat = internalFormat;
   3107    };
   3108 
   3109    es3fTextureSpecificationTests.BasicCopyTexImageCubeCase.prototype =
   3110        Object.create(
   3111            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   3112        );
   3113 
   3114    es3fTextureSpecificationTests.
   3115    BasicCopyTexImageCubeCase.prototype.constructor =
   3116        es3fTextureSpecificationTests.BasicCopyTexImageCubeCase;
   3117 
   3118    es3fTextureSpecificationTests.
   3119    BasicCopyTexImageCubeCase.prototype.createTexture = function() {
   3120        var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
   3121        var targetHasRGB = pixelFormat.redBits > 0 &&
   3122            pixelFormat.greenBits > 0 &&
   3123            pixelFormat.blueBits > 0;
   3124        var targetHasAlpha = pixelFormat.alphaBits > 0;
   3125        var fmt = es3fTextureSpecificationTests.mapGLUnsizedInternalFormat(
   3126                this.m_internalFormat
   3127        );
   3128        var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
   3129        var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
   3130            fmt.order == tcuTexture.ChannelOrder.LA ||
   3131            fmt.order == tcuTexture.ChannelOrder.A;
   3132        var tex = null;
   3133        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3134        /** @type {es3fFboTestUtil.GradientShader} */
   3135        var shader = new es3fFboTestUtil.GradientShader(
   3136            gluShaderUtil.DataType.FLOAT_VEC4
   3137        );
   3138        var shaderID = this.m_context.createProgram(shader);
   3139 
   3140        if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   3141            throw new Error(
   3142                'Copying from current framebuffer is not supported'
   3143            );
   3144 
   3145        // Fill render target with gradient.
   3146        shader.setGradient(
   3147            this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
   3148        );
   3149        rrUtil.drawQuad(
   3150            this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
   3151        );
   3152 
   3153        tex = this.m_context.createTexture();
   3154        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   3155 
   3156        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3157            var levelSize = Math.max(1, this.m_size >> ndx);
   3158 
   3159            for (var f in tcuTexture.CubeFace) {
   3160                var face = tcuTexture.CubeFace[f];
   3161                var x = rnd.getInt(0, this.m_size - levelSize);
   3162                var y = rnd.getInt(0, this.m_size - levelSize);
   3163 
   3164                this.m_context.copyTexImage2D(
   3165                    es3fTextureSpecificationTests.s_cubeMapFaces[face], ndx,
   3166                    this.m_internalFormat, x, y, levelSize, levelSize, 0
   3167                );
   3168            }
   3169        }
   3170    };
   3171 
   3172    // Basic CopyTexSubImage2D() with 2D texture usage
   3173    /**
   3174     * @constructor
   3175     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   3176     * @param {string} name
   3177     * @param {string} desc
   3178     * @param {number} format
   3179     * @param {number} dataType
   3180     * @param {number} width
   3181     * @param {number} height
   3182     */
   3183    es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase = function(
   3184        name, desc, format, dataType, width, height
   3185    ) {
   3186        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   3187            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   3188                format, dataType
   3189            ), width, height, es3fTextureSpecificationTests.maxLevelCount(
   3190                width, height
   3191            )
   3192        );
   3193 
   3194        this.m_format = format;
   3195        this.m_dataType = dataType;
   3196    };
   3197 
   3198    es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase.prototype =
   3199        Object.create(
   3200            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   3201        );
   3202 
   3203    es3fTextureSpecificationTests.
   3204    BasicCopyTexSubImage2DCase.prototype.constructor =
   3205        es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase;
   3206 
   3207    /**
   3208     * createTexture
   3209     */
   3210    es3fTextureSpecificationTests.
   3211    BasicCopyTexSubImage2DCase.prototype.createTexture = function() {
   3212        var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
   3213        var targetHasRGB = pixelFormat.redBits > 0 &&
   3214            pixelFormat.greenBits > 0 &&
   3215            pixelFormat.blueBits > 0;
   3216        var targetHasAlpha = pixelFormat.alphaBits > 0;
   3217        var fmt = gluTextureUtil.mapGLTransferFormat(
   3218                this.m_format, this.m_dataType
   3219        );
   3220        var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
   3221        var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
   3222            fmt.order == tcuTexture.ChannelOrder.LA ||
   3223            fmt.order == tcuTexture.ChannelOrder.A;
   3224        var tex = null;
   3225        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3226        /** @type {es3fFboTestUtil.GradientShader} */
   3227        var shader = new es3fFboTestUtil.GradientShader(
   3228            gluShaderUtil.DataType.FLOAT_VEC4
   3229        );
   3230        var shaderID = this.m_context.createProgram(shader);
   3231 
   3232        if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   3233            throw new Error(
   3234                'Copying from current framebuffer is not supported'
   3235            );
   3236 
   3237        tex = this.m_context.createTexture();
   3238        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   3239        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   3240 
   3241        // First specify full texture.
   3242        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3243            var levelW = Math.max(1, this.m_width >> ndx);
   3244            var levelH = Math.max(1, this.m_height >> ndx);
   3245 
   3246            var colorA = es3fTextureSpecificationTests.randomVector(
   3247                rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
   3248            );
   3249            var colorB = es3fTextureSpecificationTests.randomVector(
   3250                rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
   3251            );
   3252            var cellSize = rnd.getInt(2, 16);
   3253 
   3254            var data = new tcuTexture.TextureLevel(fmt, levelW, levelH);
   3255            tcuTextureUtil.fillWithGrid(
   3256                data.getAccess(), cellSize, colorA, colorB
   3257            );
   3258 
   3259            this.m_context.texImage2D(
   3260                gl.TEXTURE_2D, ndx, this.m_format, levelW, levelH, 0, this.m_format, this.m_dataType, data.getAccess().getDataPtr()
   3261            );
   3262        }
   3263 
   3264        // Fill render target with gradient.
   3265        shader.setGradient(
   3266            this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
   3267        );
   3268        rrUtil.drawQuad(
   3269            this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
   3270        );
   3271 
   3272        // Re-specify parts of each level.
   3273        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3274            var levelW = Math.max(1, this.m_width >> ndx);
   3275            var levelH = Math.max(1, this.m_height >> ndx);
   3276 
   3277            var w = rnd.getInt(1, levelW);
   3278            var h = rnd.getInt(1, levelH);
   3279            var xo = rnd.getInt(0, levelW - w);
   3280            var yo = rnd.getInt(0, levelH - h);
   3281 
   3282            var x = rnd.getInt(0, this.m_width - w);
   3283            var y = rnd.getInt(0, this.m_height - h);
   3284 
   3285            this.m_context.copyTexSubImage2D(
   3286                gl.TEXTURE_2D, ndx, xo, yo, x, y, w, h
   3287            );
   3288        }
   3289    };
   3290 
   3291    // Basic CopyTexSubImage2D() with cubemap usage
   3292    /**
   3293     * @constructor
   3294     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   3295     * @param {string} name
   3296     * @param {string} desc
   3297     * @param {number} format
   3298     * @param {number} dataType
   3299     * @param {number} size
   3300     */
   3301    es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase = function(
   3302        name, desc, format, dataType, size
   3303    ) {
   3304        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   3305            this, name, desc, gluTextureUtil.mapGLTransferFormat(
   3306                format, dataType
   3307            ), size, deMath.logToFloor(size) + 1
   3308        );
   3309 
   3310        this.m_format = format;
   3311        this.m_dataType = dataType;
   3312    };
   3313 
   3314    es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase.prototype =
   3315        Object.create(
   3316            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   3317        );
   3318 
   3319    es3fTextureSpecificationTests.
   3320    BasicCopyTexSubImageCubeCase.prototype.constructor =
   3321        es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase;
   3322 
   3323    es3fTextureSpecificationTests.
   3324    BasicCopyTexSubImageCubeCase.prototype.createTexture = function() {
   3325        var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
   3326        var targetHasRGB = pixelFormat.redBits > 0 &&
   3327            pixelFormat.greenBits > 0 &&
   3328            pixelFormat.blueBits > 0;
   3329        var targetHasAlpha = pixelFormat.alphaBits > 0;
   3330        var fmt = gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_dataType);
   3331        var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
   3332        var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
   3333            fmt.order == tcuTexture.ChannelOrder.LA ||
   3334            fmt.order == tcuTexture.ChannelOrder.A;
   3335        var tex = null;
   3336        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3337        /** @type {es3fFboTestUtil.GradientShader} */
   3338        var shader = new es3fFboTestUtil.GradientShader(
   3339            gluShaderUtil.DataType.FLOAT_VEC4
   3340        );
   3341        var shaderID = this.m_context.createProgram(shader);
   3342 
   3343        if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   3344            throw new Error(
   3345                'Copying from current framebuffer is not supported'
   3346            );
   3347 
   3348        tex = this.m_context.createTexture();
   3349        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   3350        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   3351 
   3352        var data = new tcuTexture.TextureLevel(fmt);
   3353 
   3354        // First specify full texture.
   3355        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3356            var levelSize = Math.max(1, this.m_size >> ndx);
   3357 
   3358            data.setSize(levelSize, levelSize);
   3359 
   3360            for (var f in tcuTexture.CubeFace) {
   3361                var face = tcuTexture.CubeFace[f];
   3362                var colorA = es3fTextureSpecificationTests.randomVector(
   3363                    rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
   3364                );
   3365                var colorB = es3fTextureSpecificationTests.randomVector(
   3366                    rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
   3367                );
   3368                var cellSize = rnd.getInt(2, 16);
   3369 
   3370                tcuTextureUtil.fillWithGrid(
   3371                    data.getAccess(), cellSize, colorA, colorB
   3372                );
   3373 
   3374                this.m_context.texImage2D(
   3375                    es3fTextureSpecificationTests.s_cubeMapFaces[face],
   3376                    ndx, this.m_format, levelSize, levelSize, 0, this.m_format,
   3377                    this.m_dataType, data.getAccess().getDataPtr()
   3378                );
   3379            }
   3380        }
   3381 
   3382        // Fill render target with gradient.
   3383        shader.setGradient(
   3384            this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
   3385        );
   3386        rrUtil.drawQuad(
   3387            this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
   3388        );
   3389 
   3390        // Re-specify parts of each face and level.
   3391        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3392            var levelSize = Math.max(1, this.m_size >> ndx);
   3393 
   3394            for (var f in es3fTextureSpecificationTests.s_cubeMapFaces) {
   3395                var w = rnd.getInt(1, levelSize);
   3396                var h = rnd.getInt(1, levelSize);
   3397                var xo = rnd.getInt(0, levelSize - w);
   3398                var yo = rnd.getInt(0, levelSize - h);
   3399 
   3400                var x = rnd.getInt(0, this.m_size - w);
   3401                var y = rnd.getInt(0, this.m_size - h);
   3402 
   3403                this.m_context.copyTexSubImage2D(
   3404                    es3fTextureSpecificationTests.s_cubeMapFaces[f],
   3405                    ndx, xo, yo, x, y, w, h
   3406                );
   3407            }
   3408        }
   3409    };
   3410 
   3411    // Basic glTexStorage2D() with 2D texture usage
   3412    /**
   3413     * @constructor
   3414     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   3415     * @param {string} name
   3416     * @param {string} desc
   3417     * @param {number} internalFormat
   3418     * @param {number} width
   3419     * @param {number} height
   3420     * @param {number} numLevels
   3421     */
   3422    es3fTextureSpecificationTests.BasicTexStorage2DCase = function(
   3423        name, desc, internalFormat, width, height, numLevels
   3424    ) {
   3425        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   3426            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   3427                internalFormat
   3428            ), width, height, numLevels
   3429        );
   3430 
   3431        this.m_internalFormat = internalFormat;
   3432    };
   3433 
   3434    es3fTextureSpecificationTests.BasicTexStorage2DCase.prototype =
   3435        Object.create(
   3436            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   3437        );
   3438 
   3439    es3fTextureSpecificationTests.BasicTexStorage2DCase.prototype.constructor =
   3440        es3fTextureSpecificationTests.BasicTexStorage2DCase;
   3441 
   3442    /**
   3443     * createTexture
   3444     */
   3445    es3fTextureSpecificationTests.
   3446    BasicTexStorage2DCase.prototype.createTexture = function() {
   3447        var fmt = gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
   3448        var transferFmt = gluTextureUtil.getTransferFormat(fmt);
   3449        var tex = null;
   3450        var levelData = new tcuTexture.TextureLevel(
   3451            fmt, this.m_width, this.m_height
   3452        );
   3453        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3454 
   3455        tex = this.m_context.createTexture();
   3456        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   3457        this.m_context.texStorage2D(
   3458            gl.TEXTURE_2D, this.m_numLevels, this.m_internalFormat,
   3459            this.m_width, this.m_height
   3460        );
   3461 
   3462        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   3463 
   3464        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3465            var levelW = Math.max(1, this.m_width >> ndx);
   3466            var levelH = Math.max(1, this.m_height >> ndx);
   3467            var gMin = es3fTextureSpecificationTests.randomVector(
   3468                rnd, this.m_texFormatInfo.valueMin,
   3469                this.m_texFormatInfo.valueMax, 4
   3470            );
   3471            var gMax = es3fTextureSpecificationTests.randomVector(
   3472                rnd, this.m_texFormatInfo.valueMin,
   3473                this.m_texFormatInfo.valueMax, 4
   3474            );
   3475 
   3476            levelData.setSize(levelW, levelH);
   3477            tcuTextureUtil.fillWithComponentGradients(
   3478                levelData.getAccess(), gMin, gMax
   3479            );
   3480 
   3481            this.m_context.texSubImage2D(
   3482                gl.TEXTURE_2D, ndx, 0, 0, levelW, levelH,
   3483                transferFmt.format, transferFmt.dataType,
   3484                levelData.getAccess().getDataPtr()
   3485            );
   3486        }
   3487    };
   3488 
   3489    // Basic glTexStorage2D() with cubemap usage
   3490    /**
   3491     * @constructor
   3492     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   3493     * @param {string} name
   3494     * @param {string} desc
   3495     * @param {number} internalFormat
   3496     * @param {number} size
   3497     * @param {number} numLevels
   3498     */
   3499    es3fTextureSpecificationTests.BasicTexStorageCubeCase = function(
   3500        name, desc, internalFormat, size, numLevels
   3501    ) {
   3502        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   3503            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   3504                internalFormat
   3505            ), size, numLevels
   3506        );
   3507 
   3508        this.m_internalFormat = internalFormat;
   3509    };
   3510 
   3511    es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype =
   3512        Object.create(
   3513            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   3514        );
   3515 
   3516    es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype.constructor =
   3517        es3fTextureSpecificationTests.BasicTexStorageCubeCase;
   3518 
   3519    /**
   3520     * createTexture
   3521     */
   3522    es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype.createTexture = function() {
   3523        var fmt = gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
   3524        var transferFmt = gluTextureUtil.getTransferFormat(fmt);
   3525        var tex = null;
   3526        var levelData = new tcuTexture.TextureLevel(
   3527            fmt, this.m_size, this.m_size
   3528        );
   3529        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3530 
   3531        tex = this.m_context.createTexture();
   3532        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   3533        this.m_context.texStorage2D(
   3534            gl.TEXTURE_CUBE_MAP, this.m_numLevels, this.m_internalFormat,
   3535            this.m_size, this.m_size
   3536        );
   3537 
   3538        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   3539 
   3540        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3541            var levelSize = Math.max(1, this.m_size >> ndx);
   3542 
   3543            levelData.setSize(levelSize, levelSize);
   3544 
   3545            for (var f in tcuTexture.CubeFace) {
   3546                var face = tcuTexture.CubeFace[f];
   3547                var gMin = es3fTextureSpecificationTests.randomVector(
   3548                    rnd, this.m_texFormatInfo.valueMin,
   3549                    this.m_texFormatInfo.valueMax, 4
   3550                );
   3551                var gMax = es3fTextureSpecificationTests.randomVector(
   3552                    rnd, this.m_texFormatInfo.valueMin,
   3553                    this.m_texFormatInfo.valueMax, 4
   3554                );
   3555 
   3556                tcuTextureUtil.fillWithComponentGradients(
   3557                    levelData.getAccess(), gMin, gMax
   3558                );
   3559 
   3560                this.m_context.texSubImage2D(
   3561                    es3fTextureSpecificationTests.s_cubeMapFaces[face],
   3562                    ndx, 0, 0, levelSize, levelSize,
   3563                    transferFmt.format, transferFmt.dataType,
   3564                    levelData.getAccess().getDataPtr()
   3565                );
   3566            }
   3567        }
   3568    };
   3569 
   3570    // Basic glTexStorage3D() with 2D array texture usage
   3571    /**
   3572     * @constructor
   3573     * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
   3574     * @param {string} name
   3575     * @param {string} desc
   3576     * @param {number} internalFormat
   3577     * @param {number} width
   3578     * @param {number} height
   3579     * @param {number} numLayers
   3580     * @param {number} numLevels
   3581     */
   3582    es3fTextureSpecificationTests.BasicTexStorage2DArrayCase = function(
   3583        name, desc, internalFormat, width, height, numLayers, numLevels
   3584    ) {
   3585        es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
   3586            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   3587                internalFormat
   3588            ), width, height, numLayers, numLevels
   3589        );
   3590        this.m_internalFormat = internalFormat;
   3591    };
   3592 
   3593    es3fTextureSpecificationTests.BasicTexStorage2DArrayCase.prototype =
   3594        Object.create(
   3595            es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
   3596        );
   3597 
   3598    es3fTextureSpecificationTests.
   3599    BasicTexStorage2DArrayCase.prototype.constructor =
   3600        es3fTextureSpecificationTests.BasicTexStorage2DArrayCase;
   3601 
   3602    /**
   3603     * createTexture
   3604     */
   3605    es3fTextureSpecificationTests.BasicTexStorage2DArrayCase.prototype.createTexture = function() {
   3606        var tex = null;
   3607        var levelData = new tcuTexture.TextureLevel(
   3608            this.m_texFormat, this.m_width, this.m_height
   3609        );
   3610        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3611        var transferFmt = gluTextureUtil.getTransferFormat(
   3612            this.m_texFormat
   3613        );
   3614 
   3615        tex = this.m_context.createTexture();
   3616        this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
   3617        this.m_context.texStorage3D(
   3618            gl.TEXTURE_2D_ARRAY, this.m_numLevels, this.m_internalFormat,
   3619            this.m_width, this.m_height, this.m_numLayers
   3620        );
   3621 
   3622        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   3623 
   3624        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3625            var levelW = Math.max(1, this.m_width >> ndx);
   3626            var levelH = Math.max(1, this.m_height >> ndx);
   3627            var gMin = es3fTextureSpecificationTests.randomVector(
   3628                rnd, this.m_texFormatInfo.valueMin,
   3629                this.m_texFormatInfo.valueMax, 4
   3630            );
   3631            var gMax = es3fTextureSpecificationTests.randomVector(
   3632                rnd, this.m_texFormatInfo.valueMin,
   3633                this.m_texFormatInfo.valueMax, 4
   3634            );
   3635 
   3636            levelData.setSize(levelW, levelH, this.m_numLayers);
   3637            tcuTextureUtil.fillWithComponentGradients(
   3638                levelData.getAccess(), gMin, gMax
   3639            );
   3640 
   3641            this.m_context.texSubImage3D(
   3642                gl.TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH,
   3643                this.m_numLayers, transferFmt.format, transferFmt.dataType,
   3644                levelData.getAccess().getDataPtr()
   3645            );
   3646        }
   3647    };
   3648 
   3649    // Basic TexStorage3D() with 3D texture usage
   3650    /**
   3651     * @constructor
   3652     * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
   3653     * @param {string} name
   3654     * @param {string} desc
   3655     * @param {number} internalFormat
   3656     * @param {number} width
   3657     * @param {number} height
   3658     * @param {number} depth
   3659     * @param {number} numLevels
   3660     */
   3661    es3fTextureSpecificationTests.BasicTexStorage3DCase = function(
   3662        name, desc, internalFormat, width, height, depth, numLevels
   3663    ) {
   3664        es3fTextureSpecificationTests.Texture3DSpecCase.call(
   3665            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   3666                internalFormat
   3667            ), width, height, depth, numLevels
   3668        );
   3669 
   3670        this.m_internalFormat = internalFormat;
   3671    };
   3672 
   3673    es3fTextureSpecificationTests.BasicTexStorage3DCase.prototype =
   3674        Object.create(
   3675            es3fTextureSpecificationTests.Texture3DSpecCase.prototype
   3676        );
   3677 
   3678    es3fTextureSpecificationTests.
   3679    BasicTexStorage3DCase.prototype.constructor =
   3680        es3fTextureSpecificationTests.BasicTexStorage3DCase;
   3681 
   3682    /**
   3683     * createTexture
   3684     */
   3685    es3fTextureSpecificationTests.
   3686    BasicTexStorage3DCase.prototype.createTexture = function() {
   3687        var tex = null;
   3688        var levelData = new tcuTexture.TextureLevel(
   3689            this.m_texFormat, this.m_width, this.m_height
   3690        );
   3691        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3692        var transferFmt = gluTextureUtil.getTransferFormat(
   3693            this.m_texFormat
   3694        );
   3695 
   3696        tex = this.m_context.createTexture();
   3697        this.m_context.bindTexture(gl.TEXTURE_3D, tex);
   3698        this.m_context.texStorage3D(
   3699            gl.TEXTURE_3D, this.m_numLevels, this.m_internalFormat,
   3700            this.m_width, this.m_height, this.m_depth
   3701        );
   3702 
   3703        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   3704 
   3705        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   3706            var levelW = Math.max(1, this.m_width >> ndx);
   3707            var levelH = Math.max(1, this.m_height >> ndx);
   3708            var levelD = Math.max(1, this.m_depth >> ndx);
   3709            var gMin = es3fTextureSpecificationTests.randomVector(
   3710                rnd, this.m_texFormatInfo.valueMin,
   3711                this.m_texFormatInfo.valueMax, 4
   3712            );
   3713            var gMax = es3fTextureSpecificationTests.randomVector(
   3714                rnd, this.m_texFormatInfo.valueMin,
   3715                this.m_texFormatInfo.valueMax, 4
   3716            );
   3717 
   3718            levelData.setSize(levelW, levelH, levelD);
   3719            tcuTextureUtil.fillWithComponentGradients(
   3720                levelData.getAccess(), gMin, gMax
   3721            );
   3722 
   3723            this.m_context.texSubImage3D(
   3724                gl.TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH,
   3725                levelD, transferFmt.format, transferFmt.dataType,
   3726                levelData.getAccess().getDataPtr()
   3727            );
   3728        }
   3729    };
   3730 
   3731    // Pixel buffer object cases.
   3732 
   3733    // TexImage2D() from pixel buffer object.
   3734    /**
   3735     * @constructor
   3736     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   3737     * @param {string} name
   3738     * @param {string} desc
   3739     * @param {number} internalFormat
   3740     * @param {number} width
   3741     * @param {number} height
   3742     * @param {number} rowLength
   3743     * @param {number} skipRows
   3744     * @param {number} skipPixels
   3745     * @param {number} alignment
   3746     * @param {number} offset
   3747     */
   3748    es3fTextureSpecificationTests.TexImage2DBufferCase = function(
   3749        name, desc, internalFormat, width, height, rowLength,
   3750        skipRows, skipPixels, alignment, offset
   3751    ) {
   3752        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   3753            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   3754                internalFormat
   3755            ), width, height, 1
   3756        );
   3757 
   3758        this.m_internalFormat = internalFormat;
   3759        this.m_rowLength = rowLength;
   3760        this.m_skipRows = skipRows;
   3761        this.m_skipPixels = skipPixels;
   3762        this.m_alignment = alignment;
   3763        this.m_offset = offset;
   3764    };
   3765 
   3766    es3fTextureSpecificationTests.TexImage2DBufferCase.prototype =
   3767        Object.create(
   3768            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   3769        );
   3770 
   3771    es3fTextureSpecificationTests.
   3772    TexImage2DBufferCase.prototype.constructor =
   3773        es3fTextureSpecificationTests.TexImage2DBufferCase;
   3774 
   3775    /**
   3776     * createTexture
   3777     */
   3778    es3fTextureSpecificationTests.TexImage2DBufferCase.prototype.createTexture =
   3779    function() {
   3780        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   3781        var pixelSize = this.m_texFormat.getPixelSize();
   3782        var rowLength = this.m_rowLength > 0 ?
   3783            this.m_rowLength :
   3784            this.m_width + this.m_skipPixels;
   3785        var rowPitch = deMath.deAlign32(
   3786            rowLength * pixelSize, this.m_alignment
   3787        );
   3788        var height = this.m_height + this.m_skipRows;
   3789        var buf = null;
   3790        var tex = null;
   3791        var data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
   3792 
   3793        assertMsgOptions(
   3794            this.m_numLevels == 1, 'Number of levels different than 1',
   3795            false, true
   3796        );
   3797 
   3798        // Fill data with grid.
   3799        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   3800        var cBias = this.m_texFormatInfo.valueMin;
   3801        var colorA = deMath.add(
   3802            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   3803        );
   3804        var colorB = deMath.add(
   3805            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   3806        );
   3807 
   3808        var access = new tcuTexture.PixelBufferAccess({
   3809                    format: this.m_texFormat,
   3810                    width: this.m_width,
   3811                    height: this.m_height,
   3812                    rowPitch: rowPitch,
   3813                    data: data,
   3814                    offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
   3815                    });
   3816        tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
   3817 
   3818        // Create buffer and upload.
   3819        buf = this.m_context.createBuffer();
   3820        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   3821        this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
   3822        );
   3823 
   3824        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   3825        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   3826        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   3827        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   3828 
   3829        tex = this.m_context.createTexture();
   3830        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   3831        this.m_context.texImage2D(gl.TEXTURE_2D, 0, this.m_internalFormat,
   3832            this.m_width, this.m_height, 0, transferFmt.format, transferFmt.dataType,
   3833            this.m_offset
   3834        );
   3835    };
   3836 
   3837    // TexImage2D() cubemap from pixel buffer object case
   3838    /**
   3839     * @constructor
   3840     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   3841     * @param {string} name
   3842     * @param {string} desc
   3843     * @param {number} internalFormat
   3844     * @param {number} size
   3845     * @param {number} rowLength
   3846     * @param {number} skipRows
   3847     * @param {number} skipPixels
   3848     * @param {number} alignment
   3849     * @param {number} offset
   3850     */
   3851    es3fTextureSpecificationTests.TexImageCubeBufferCase = function(
   3852        name, desc, internalFormat, size, rowLength, skipRows, skipPixels,
   3853        alignment, offset
   3854    ) {
   3855        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   3856            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   3857                internalFormat
   3858            ), size, 1
   3859        );
   3860 
   3861        this.m_internalFormat = internalFormat;
   3862        this.m_rowLength = rowLength;
   3863        this.m_skipRows = skipRows;
   3864        this.m_skipPixels = skipPixels;
   3865        this.m_alignment = alignment;
   3866        this.m_offset = offset;
   3867    };
   3868 
   3869    es3fTextureSpecificationTests.TexImageCubeBufferCase.prototype =
   3870        Object.create(
   3871            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   3872        );
   3873 
   3874    es3fTextureSpecificationTests.
   3875    TexImageCubeBufferCase.prototype.constructor =
   3876        es3fTextureSpecificationTests.TexImageCubeBufferCase;
   3877 
   3878    /**
   3879     * createTexture
   3880     */
   3881    es3fTextureSpecificationTests.
   3882    TexImageCubeBufferCase.prototype.createTexture = function() {
   3883        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   3884        var tex = null;
   3885        var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   3886        var pixelSize = this.m_texFormat.getPixelSize();
   3887        var rowLength = this.m_rowLength > 0 ?
   3888            this.m_rowLength : this.m_size + this.m_skipPixels;
   3889        var rowPitch = deMath.deAlign32(
   3890            rowLength * pixelSize, this.m_alignment
   3891        );
   3892        var height = this.m_size + this.m_skipRows;
   3893 
   3894        var data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
   3895        var access = new tcuTexture.PixelBufferAccess({
   3896                            format: this.m_texFormat,
   3897                            width: this.m_size,
   3898                            height: this.m_size,
   3899                            rowPitch: rowPitch,
   3900                            data: data,
   3901                            offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
   3902                        });
   3903 
   3904        assertMsgOptions(
   3905            this.m_numLevels == 1, 'Number of levels is different than 1',
   3906            false, true
   3907        );
   3908 
   3909        tex = this.m_context.createTexture();
   3910        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   3911        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   3912 
   3913        for (var f in tcuTexture.CubeFace) {
   3914            var face = tcuTexture.CubeFace[f];
   3915            var buf = null;
   3916 
   3917            var gMin = es3fTextureSpecificationTests.randomVector(
   3918                rnd, this.m_texFormatInfo.valueMin,
   3919                this.m_texFormatInfo.valueMax, 4
   3920            );
   3921            var gMax = es3fTextureSpecificationTests.randomVector(
   3922                rnd, this.m_texFormatInfo.valueMin,
   3923                this.m_texFormatInfo.valueMax, 4
   3924            );
   3925 
   3926            tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
   3927 
   3928            // Create buffer and upload.
   3929            buf = this.m_context.createBuffer();
   3930            this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   3931            this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
   3932 
   3933            this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   3934            this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   3935            this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   3936            this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   3937 
   3938            this.m_context.texImage2D(
   3939                es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
   3940                this.m_internalFormat, this.m_size, this.m_size, 0, fmt.format,
   3941                fmt.dataType, this.m_offset);
   3942        }
   3943    };
   3944 
   3945    // TexImage3D() 2D array from pixel buffer object.
   3946    /**
   3947     * @constructor
   3948     * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
   3949     * @param {string} name
   3950     * @param {string} desc
   3951     * @param {number} internalFormat
   3952     * @param {number} width
   3953     * @param {number} height
   3954     * @param {number} depth
   3955     * @param {number} imageHeight
   3956     * @param {number} rowLength
   3957     * @param {number} skipImages
   3958     * @param {number} skipRows
   3959     * @param {number} skipPixels
   3960     * @param {number} alignment
   3961     * @param {number} offset
   3962     */
   3963    es3fTextureSpecificationTests.TexImage2DArrayBufferCase = function(
   3964        name, desc, internalFormat, width, height, depth, imageHeight,
   3965        rowLength, skipImages, skipRows, skipPixels, alignment, offset
   3966    ) {
   3967        es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
   3968            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   3969                internalFormat
   3970            ), width, height, depth, 1
   3971        );
   3972 
   3973        this.m_internalFormat = internalFormat;
   3974        this.m_imageHeight = imageHeight;
   3975        this.m_rowLength = rowLength;
   3976        this.m_skipImages = skipImages;
   3977        this.m_skipRows = skipRows;
   3978        this.m_skipPixels = skipPixels;
   3979        this.m_alignment = alignment;
   3980        this.m_offset = offset;
   3981    };
   3982 
   3983    es3fTextureSpecificationTests.TexImage2DArrayBufferCase.prototype =
   3984        Object.create(
   3985            es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
   3986        );
   3987 
   3988    es3fTextureSpecificationTests.
   3989    TexImage2DArrayBufferCase.prototype.constructor =
   3990        es3fTextureSpecificationTests.TexImage2DArrayBufferCase;
   3991 
   3992    /**
   3993     * createTexture
   3994     */
   3995    es3fTextureSpecificationTests.
   3996    TexImage2DArrayBufferCase.prototype.createTexture = function() {
   3997        var transferFmt = gluTextureUtil.getTransferFormat(
   3998            this.m_texFormat
   3999        );
   4000        var pixelSize = this.m_texFormat.getPixelSize();
   4001        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
   4002        var rowPitch = deMath.deAlign32(
   4003            rowLength * pixelSize, this.m_alignment
   4004        );
   4005        var imageHeight = this.m_imageHeight > 0 ?
   4006            this.m_imageHeight : this.m_height;
   4007        var slicePitch = imageHeight * rowPitch;
   4008        var tex = null;
   4009        var buf = null;
   4010        var data = new ArrayBuffer(
   4011            slicePitch * (this.m_numLayers + this.m_skipImages) +
   4012            this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
   4013        );
   4014 
   4015        assertMsgOptions(
   4016            this.m_numLevels == 1, 'Number of levels is different than 1',
   4017            false, true
   4018        );
   4019 
   4020        // Fill data with grid.
   4021        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   4022        var cBias = this.m_texFormatInfo.valueMin;
   4023        var colorA = deMath.add(
   4024            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   4025        );
   4026        var colorB = deMath.add(
   4027            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   4028        );
   4029 
   4030        var access = new tcuTexture.PixelBufferAccess({
   4031                        format: this.m_texFormat,
   4032                        width: this.m_width,
   4033                        height: this.m_height,
   4034                        depth: this.m_numLayers,
   4035                        rowPitch: rowPitch,
   4036                        slicePitch: slicePitch,
   4037                        data: data,
   4038                        offset: this.m_skipImages * slicePitch +
   4039                            this.m_skipRows * rowPitch +
   4040                            this.m_skipPixels * pixelSize +
   4041                            this.m_offset
   4042                        });
   4043        tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
   4044 
   4045        // Create buffer and upload.
   4046        buf = this.m_context.createBuffer();
   4047        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   4048        this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
   4049 
   4050        this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
   4051        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   4052        this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
   4053        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   4054        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   4055        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   4056 
   4057        tex = this.m_context.createTexture();
   4058        this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
   4059        this.m_context.texImage3D(
   4060            gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width,
   4061            this.m_height, this.m_numLayers, 0, transferFmt.format,
   4062            transferFmt.dataType, this.m_offset
   4063        );
   4064    };
   4065 
   4066    // TexImage3D() from pixel buffer object.
   4067    /**
   4068     * @constructor
   4069     * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
   4070     * @param {string} name
   4071     * @param {string} desc
   4072     * @param {number} internalFormat
   4073     * @param {number} width
   4074     * @param {number} height
   4075     * @param {number} depth
   4076     * @param {number} imageHeight
   4077     * @param {number} rowLength
   4078     * @param {number} skipImages
   4079     * @param {number} skipRows
   4080     * @param {number} skipPixels
   4081     * @param {number} alignment
   4082     * @param {number} offset
   4083     */
   4084    es3fTextureSpecificationTests.TexImage3DBufferCase = function(
   4085        name, desc, internalFormat, width, height, depth, imageHeight,
   4086        rowLength, skipImages, skipRows, skipPixels, alignment, offset
   4087    ) {
   4088        es3fTextureSpecificationTests.Texture3DSpecCase.call(
   4089            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4090                internalFormat
   4091            ), width, height, depth, 1
   4092        );
   4093 
   4094        this.m_internalFormat = internalFormat;
   4095        this.m_imageHeight = imageHeight;
   4096        this.m_rowLength = rowLength;
   4097        this.m_skipImages = skipImages;
   4098        this.m_skipRows = skipRows;
   4099        this.m_skipPixels = skipPixels;
   4100        this.m_alignment = alignment;
   4101        this.m_offset = offset;
   4102    };
   4103 
   4104    es3fTextureSpecificationTests.TexImage3DBufferCase.prototype =
   4105        Object.create(
   4106            es3fTextureSpecificationTests.Texture3DSpecCase.prototype
   4107        );
   4108 
   4109    es3fTextureSpecificationTests.
   4110    TexImage3DBufferCase.prototype.constructor =
   4111        es3fTextureSpecificationTests.TexImage3DBufferCase;
   4112 
   4113    /**
   4114     * createTexture
   4115     */
   4116    es3fTextureSpecificationTests.
   4117    TexImage3DBufferCase.prototype.createTexture = function() {
   4118        var transferFmt = gluTextureUtil.getTransferFormat(
   4119            this.m_texFormat
   4120        );
   4121        var pixelSize = this.m_texFormat.getPixelSize();
   4122        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
   4123        var rowPitch = deMath.deAlign32(
   4124            rowLength * pixelSize, this.m_alignment
   4125        );
   4126        var imageHeight = this.m_imageHeight > 0 ?
   4127            this.m_imageHeight : this.m_height;
   4128        var slicePitch = imageHeight * rowPitch;
   4129        var tex = null;
   4130        var buf = null;
   4131        var data = new ArrayBuffer(
   4132            slicePitch * (this.m_depth + this.m_skipImages) +
   4133            rowPitch * this.m_skipRows + pixelSize * this.m_skipPixels + this.m_offset
   4134        );
   4135 
   4136        assertMsgOptions(
   4137            this.m_numLevels == 1, 'Number of levels is different than 1',
   4138            false, true
   4139        );
   4140 
   4141        // Fill data with grid.
   4142        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   4143        var cBias = this.m_texFormatInfo.valueMin;
   4144        var colorA = deMath.add(
   4145            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   4146        );
   4147        var colorB = deMath.add(
   4148            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   4149        );
   4150 
   4151        var access = new tcuTexture.PixelBufferAccess({
   4152                        format: this.m_texFormat,
   4153                        width: this.m_width,
   4154                        height: this.m_height,
   4155                        depth: this.m_depth,
   4156                        rowPitch: rowPitch,
   4157                        slicePitch: slicePitch,
   4158                        data: data,
   4159                        offset: this.m_skipImages * slicePitch +
   4160                            this.m_skipRows * rowPitch +
   4161                            this.m_skipPixels * pixelSize +
   4162                            this.m_offset
   4163                        });
   4164        tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
   4165 
   4166        // Create buffer and upload.
   4167        buf = this.m_context.createBuffer();
   4168        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   4169        this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
   4170 
   4171        this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
   4172        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   4173        this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
   4174        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   4175        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   4176        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   4177 
   4178        tex = this.m_context.createTexture();
   4179        this.m_context.bindTexture(gl.TEXTURE_3D, tex);
   4180        this.m_context.texImage3D(
   4181            gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
   4182            this.m_height, this.m_depth, 0, transferFmt.format,
   4183            transferFmt.dataType, this.m_offset
   4184        );
   4185    };
   4186 
   4187    // TexSubImage2D() PBO case.
   4188    /**
   4189     * @constructor
   4190     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   4191     * @param {string} name
   4192     * @param {string} desc
   4193     * @param {number} internalFormat
   4194     * @param {number} width
   4195     * @param {number} height
   4196     * @param {number} subX
   4197     * @param {number} subY
   4198     * @param {number} subW
   4199     * @param {number} subH
   4200     * @param {number} rowLength
   4201     * @param {number} skipRows
   4202     * @param {number} skipPixels
   4203     * @param {number} alignment
   4204     * @param {number} offset
   4205     */
   4206    es3fTextureSpecificationTests.TexSubImage2DBufferCase = function(
   4207        name, desc, internalFormat, width, height, subX, subY, subW, subH,
   4208        rowLength, skipRows, skipPixels, alignment, offset
   4209    ) {
   4210        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   4211            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4212                internalFormat
   4213            ), width, height, 1
   4214        );
   4215        this.m_internalFormat = internalFormat;
   4216        this.m_subX = subX;
   4217        this.m_subY = subY;
   4218        this.m_subW = subW;
   4219        this.m_subH = subH;
   4220        this.m_rowLength = rowLength;
   4221        this.m_skipRows = skipRows;
   4222        this.m_skipPixels = skipPixels;
   4223        this.m_alignment = alignment;
   4224        this.m_offset = offset;
   4225    };
   4226 
   4227    es3fTextureSpecificationTests.TexSubImage2DBufferCase.prototype =
   4228        Object.create(
   4229            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   4230        );
   4231 
   4232    es3fTextureSpecificationTests.
   4233    TexSubImage2DBufferCase.prototype.constructor =
   4234        es3fTextureSpecificationTests.TexSubImage2DBufferCase;
   4235 
   4236    /**
   4237     * createTexture
   4238     */
   4239    es3fTextureSpecificationTests.
   4240    TexSubImage2DBufferCase.prototype.createTexture = function() {
   4241        var transferFmt = gluTextureUtil.getTransferFormat(
   4242            this.m_texFormat
   4243        );
   4244        var pixelSize = this.m_texFormat.getPixelSize();
   4245        var tex = null;
   4246        var buf = null;
   4247        var data = new ArrayBuffer(
   4248            deMath.deAlign32(this.m_width * pixelSize, 4) * this.m_height
   4249        );
   4250 
   4251        assertMsgOptions(
   4252            this.m_numLevels == 1, 'Number of levels is different than 1',
   4253            false, true
   4254        );
   4255 
   4256        tex = this.m_context.createTexture();
   4257        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   4258 
   4259        var access = new tcuTexture.PixelBufferAccess({
   4260                        format: this.m_texFormat,
   4261                        width: this.m_width,
   4262                        height: this.m_height,
   4263                        rowPitch: deMath.deAlign32(this.m_width * pixelSize, 4),
   4264                        data: data
   4265                        });
   4266        // First fill texture with gradient.
   4267        tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax);
   4268        this.m_context.texImage2D(
   4269            gl.TEXTURE_2D, 0, this.m_internalFormat,
   4270            this.m_width, this.m_height, 0, transferFmt.format,
   4271            transferFmt.dataType, access.getDataPtr()
   4272        );
   4273 
   4274        // Fill data with grid.
   4275        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
   4276        var rowPitch = deMath.deAlign32(
   4277            rowLength * pixelSize, this.m_alignment
   4278        );
   4279        var height = this.m_subH + this.m_skipRows;
   4280        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   4281        var cBias = this.m_texFormatInfo.valueMin;
   4282        var colorA = deMath.add(
   4283            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   4284        );
   4285        var colorB = deMath.add(
   4286            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   4287        );
   4288 
   4289        access = new tcuTexture.PixelBufferAccess({
   4290                        format: this.m_texFormat,
   4291                        width: this.m_subW,
   4292                        height: this.m_subH,
   4293                        rowPitch: rowPitch,
   4294                        data: new ArrayBuffer(rowPitch * height + this.m_offset),
   4295                        offset: this.m_skipRows * rowPitch +
   4296                                this.m_skipPixels * pixelSize +
   4297                                this.m_offset
   4298                        });
   4299        tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
   4300 
   4301        buf = this.m_context.createBuffer();
   4302        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   4303        this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW);
   4304 
   4305        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   4306        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   4307        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   4308        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   4309 
   4310        this.m_context.texSubImage2D(
   4311            gl.TEXTURE_2D, 0, this.m_subX, this.m_subY,
   4312            this.m_subW, this.m_subH, transferFmt.format,
   4313            transferFmt.dataType, this.m_offset
   4314        );
   4315    };
   4316 
   4317    // TexSubImage2D() cubemap PBO case.
   4318    /**
   4319     * @constructor
   4320     * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
   4321     * @param {string} name
   4322     * @param {string} desc
   4323     * @param {number} internalFormat
   4324     * @param {number} size
   4325     * @param {number} subX
   4326     * @param {number} subY
   4327     * @param {number} subW
   4328     * @param {number} subH
   4329     * @param {number} rowLength
   4330     * @param {number} skipRows
   4331     * @param {number} skipPixels
   4332     * @param {number} alignment
   4333     * @param {number} offset
   4334     */
   4335    es3fTextureSpecificationTests.TexSubImageCubeBufferCase = function(
   4336        name, desc, internalFormat, size, subX, subY, subW, subH, rowLength,
   4337        skipRows, skipPixels, alignment, offset
   4338    ) {
   4339        es3fTextureSpecificationTests.TextureCubeSpecCase.call(
   4340            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4341                internalFormat
   4342            ), size, 1
   4343        );
   4344 
   4345        this.m_internalFormat = internalFormat;
   4346        this.m_subX = subX;
   4347        this.m_subY = subY;
   4348        this.m_subW = subW;
   4349        this.m_subH = subH;
   4350        this.m_rowLength = rowLength;
   4351        this.m_skipRows = skipRows;
   4352        this.m_skipPixels = skipPixels;
   4353        this.m_alignment = alignment;
   4354        this.m_offset = offset;
   4355    };
   4356 
   4357    es3fTextureSpecificationTests.TexSubImageCubeBufferCase.prototype =
   4358        Object.create(
   4359            es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
   4360        );
   4361 
   4362    es3fTextureSpecificationTests.
   4363    TexSubImageCubeBufferCase.prototype.constructor =
   4364        es3fTextureSpecificationTests.TexSubImageCubeBufferCase;
   4365 
   4366    /**
   4367     * createTexture
   4368     */
   4369    es3fTextureSpecificationTests.
   4370    TexSubImageCubeBufferCase.prototype.createTexture = function() {
   4371        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   4372        var transferFmt = gluTextureUtil.getTransferFormat(
   4373            this.m_texFormat
   4374        );
   4375        var pixelSize = this.m_texFormat.getPixelSize();
   4376        var tex = null;
   4377        var buf = null;
   4378        var data = new ArrayBuffer(
   4379            deMath.deAlign32(this.m_size * pixelSize, 4) * this.m_size
   4380        );
   4381        var access = new tcuTexture.PixelBufferAccess({
   4382                            format: this.m_texFormat,
   4383                            width: this.m_size,
   4384                            height: this.m_size,
   4385                            rowPitch: deMath.deAlign32(this.m_size * pixelSize, 4),
   4386                            data: data
   4387                        });
   4388        assertMsgOptions(
   4389            this.m_numLevels == 1, 'Number of levels is different than 1',
   4390            false, true
   4391        );
   4392 
   4393        tex = this.m_context.createTexture();
   4394        this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
   4395 
   4396        // Fill faces with different gradients.
   4397 
   4398        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   4399 
   4400        for (var f in tcuTexture.CubeFace) {
   4401            var face = tcuTexture.CubeFace[f];
   4402            var gMin = es3fTextureSpecificationTests.randomVector(
   4403                rnd, this.m_texFormatInfo.valueMin,
   4404                this.m_texFormatInfo.valueMax, 4
   4405            );
   4406            var gMax = es3fTextureSpecificationTests.randomVector(
   4407                rnd, this.m_texFormatInfo.valueMin,
   4408                this.m_texFormatInfo.valueMax, 4
   4409            );
   4410 
   4411            tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
   4412 
   4413            this.m_context.texImage2D(
   4414                es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
   4415                this.m_internalFormat, this.m_size, this.m_size, 0,
   4416                transferFmt.format, transferFmt.dataType,
   4417                access.getDataPtr()
   4418            );
   4419        }
   4420 
   4421        // Fill data with grid.
   4422        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
   4423        var rowPitch = deMath.deAlign32(
   4424            rowLength * pixelSize, this.m_alignment
   4425        );
   4426        var height = this.m_subH + this.m_skipRows;
   4427        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   4428        var cBias = this.m_texFormatInfo.valueMin;
   4429        var colorA = deMath.add(
   4430            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   4431        );
   4432        var colorB = deMath.add(
   4433            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   4434        );
   4435 
   4436        data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
   4437        var accessSub = new tcuTexture.PixelBufferAccess({
   4438                        format: this.m_texFormat,
   4439                        width: this.m_subW,
   4440                        height: this.m_subH,
   4441                        rowPitch: rowPitch,
   4442                        data: data,
   4443                        offset: this.m_skipRows * rowPitch +
   4444                            this.m_skipPixels * pixelSize +
   4445                            this.m_offset
   4446                        });
   4447        tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB);
   4448 
   4449        buf = this.m_context.createBuffer();
   4450        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   4451        this.m_context.bufferData(
   4452            gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
   4453        );
   4454 
   4455        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   4456        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   4457        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   4458        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   4459 
   4460        for (var f in tcuTexture.CubeFace) {
   4461            var face = tcuTexture.CubeFace[f];
   4462            this.m_context.texSubImage2D(
   4463                es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
   4464                this.m_subX, this.m_subY, this.m_subW, this.m_subH,
   4465                transferFmt.format, transferFmt.dataType, this.m_offset
   4466            );
   4467        }
   4468    };
   4469 
   4470    // TexSubImage3D() 2D array PBO case.
   4471    /**
   4472     * @constructor
   4473     * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
   4474     * @param {string} name
   4475     * @param {string} desc
   4476     * @param {number} internalFormat
   4477     * @param {number} width
   4478     * @param {number} height
   4479     * @param {number} depth
   4480     * @param {number} subX
   4481     * @param {number} subY
   4482     * @param {number} subZ
   4483     * @param {number} subW
   4484     * @param {number} subH
   4485     * @param {number} subD
   4486     * @param {number} imageHeight
   4487     * @param {number} rowLength
   4488     * @param {number} skipImages
   4489     * @param {number} skipRows
   4490     * @param {number} skipPixels
   4491     * @param {number} alignment
   4492     * @param {number} offset
   4493     */
   4494    es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase = function(
   4495        name, desc, internalFormat, width, height, depth, subX, subY, subZ,
   4496        subW, subH, subD, imageHeight, rowLength, skipImages, skipRows,
   4497        skipPixels, alignment, offset
   4498    ) {
   4499        es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
   4500            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4501                internalFormat
   4502            ), width, height, depth, 1
   4503        );
   4504        this.m_internalFormat = internalFormat;
   4505        this.m_subX = subX;
   4506        this.m_subY = subY;
   4507        this.m_subZ = subZ;
   4508        this.m_subW = subW;
   4509        this.m_subH = subH;
   4510        this.m_subD = subD;
   4511        this.m_imageHeight = imageHeight;
   4512        this.m_rowLength = rowLength;
   4513        this.m_skipImages = skipImages;
   4514        this.m_skipRows = skipRows;
   4515        this.m_skipPixels = skipPixels;
   4516        this.m_alignment = alignment;
   4517        this.m_offset = offset;
   4518    };
   4519 
   4520    es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase.prototype =
   4521        Object.create(
   4522            es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
   4523        );
   4524 
   4525    es3fTextureSpecificationTests.
   4526    TexSubImage2DArrayBufferCase.prototype.constructor =
   4527        es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase;
   4528 
   4529    /**
   4530     * createTexture
   4531     */
   4532    es3fTextureSpecificationTests.
   4533    TexSubImage2DArrayBufferCase.prototype.createTexture = function() {
   4534        var transferFmt = gluTextureUtil.getTransferFormat(
   4535            this.m_texFormat
   4536        );
   4537        var pixelSize = this.m_texFormat.getPixelSize();
   4538        var tex = null;
   4539        var buf = null;
   4540        /** @type {ArrayBuffer} */ var data;
   4541 
   4542        assertMsgOptions(
   4543            this.m_numLevels == 1, 'Number of levels is different than 1',
   4544            false, true
   4545        );
   4546 
   4547        tex = this.m_context.createTexture();
   4548        this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
   4549 
   4550        // Fill with gradient.
   4551        var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
   4552        var slicePitch = rowPitch * this.m_height;
   4553 
   4554        data = new ArrayBuffer(slicePitch * this.m_numLayers);
   4555        var access = new tcuTexture.PixelBufferAccess({
   4556                        format: this.m_texFormat,
   4557                        width: this.m_width,
   4558                        height: this.m_height,
   4559                        depth: this.m_numLayers,
   4560                        rowPitch: rowPitch,
   4561                        slicePitch: slicePitch,
   4562                        data: data
   4563                    });
   4564        tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
   4565        );
   4566 
   4567        this.m_context.texImage3D(gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width, this.m_height,
   4568            this.m_numLayers, 0, transferFmt.format, transferFmt.dataType, access.getDataPtr());
   4569 
   4570        // Fill data with grid.
   4571        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
   4572        rowPitch = deMath.deAlign32(
   4573            rowLength * pixelSize, this.m_alignment
   4574        );
   4575        var height = this.m_subH + this.m_skipRows;
   4576        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   4577 
   4578        var cBias = this.m_texFormatInfo.valueMin;
   4579        var colorA = deMath.add(
   4580            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   4581        );
   4582        var colorB = deMath.add(
   4583            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   4584        );
   4585 
   4586        var accessSub = new tcuTexture.PixelBufferAccess({
   4587                        format: this.m_texFormat,
   4588                        width: this.m_subW,
   4589                        height: this.m_subH,
   4590                        rowPitch: rowPitch,
   4591                        data: new ArrayBuffer(rowPitch * height + this.m_offset),
   4592                        offset: this.m_skipRows * rowPitch +
   4593                                this.m_skipPixels * pixelSize +
   4594                                this.m_offset
   4595                    });
   4596        tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB);
   4597 
   4598        buf = this.m_context.createBuffer();
   4599        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   4600        this.m_context.bufferData(
   4601            gl.PIXEL_UNPACK_BUFFER, accessSub.getBuffer(), gl.STATIC_DRAW
   4602        );
   4603 
   4604        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   4605        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   4606        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   4607        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   4608    };
   4609 
   4610    // TexSubImage3D() PBO case.
   4611    /**
   4612     * @constructor
   4613     * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
   4614     * @param {string} name
   4615     * @param {string} desc
   4616     * @param {number} internalFormat
   4617     * @param {number} width
   4618     * @param {number} height
   4619     * @param {number} depth
   4620     * @param {number} subX
   4621     * @param {number} subY
   4622     * @param {number} subZ
   4623     * @param {number} subW
   4624     * @param {number} subH
   4625     * @param {number} subD
   4626     * @param {number} imageHeight
   4627     * @param {number} rowLength
   4628     * @param {number} skipImages
   4629     * @param {number} skipRows
   4630     * @param {number} skipPixels
   4631     * @param {number} alignment
   4632     * @param {number} offset
   4633     */
   4634    es3fTextureSpecificationTests.TexSubImage3DBufferCase = function(
   4635        name, desc, internalFormat, width, height, depth, subX, subY, subZ,
   4636        subW, subH, subD, imageHeight, rowLength, skipImages, skipRows,
   4637        skipPixels, alignment, offset
   4638    ) {
   4639        es3fTextureSpecificationTests.Texture3DSpecCase.call(
   4640            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4641                internalFormat
   4642            ), width, height, depth, 1
   4643        );
   4644 
   4645        this.m_internalFormat = internalFormat;
   4646        this.m_subX = subX;
   4647        this.m_subY = subY;
   4648        this.m_subZ = subZ;
   4649        this.m_subW = subW;
   4650        this.m_subH = subH;
   4651        this.m_subD = subD;
   4652        this.m_imageHeight = imageHeight;
   4653        this.m_rowLength = rowLength;
   4654        this.m_skipImages = skipImages;
   4655        this.m_skipRows = skipRows;
   4656        this.m_skipPixels = skipPixels;
   4657        this.m_alignment = alignment;
   4658        this.m_offset = offset;
   4659    };
   4660 
   4661    es3fTextureSpecificationTests.TexSubImage3DBufferCase.prototype =
   4662        Object.create(
   4663            es3fTextureSpecificationTests.Texture3DSpecCase.prototype
   4664        );
   4665 
   4666    es3fTextureSpecificationTests.
   4667    TexSubImage3DBufferCase.prototype.constructor =
   4668        es3fTextureSpecificationTests.TexSubImage3DBufferCase;
   4669 
   4670    /**
   4671     * createTexture
   4672     */
   4673    es3fTextureSpecificationTests.
   4674    TexSubImage3DBufferCase.prototype.createTexture = function() {
   4675        var transferFmt = gluTextureUtil.getTransferFormat(
   4676            this.m_texFormat
   4677        );
   4678        var pixelSize = this.m_texFormat.getPixelSize();
   4679        var tex = null;
   4680        var buf = null;
   4681        /** @type {ArrayBuffer} */ var data;
   4682 
   4683        assertMsgOptions(
   4684            this.m_numLevels == 1, 'Number of levels is different than 1',
   4685            false, true
   4686        );
   4687 
   4688        tex = this.m_context.createTexture();
   4689        this.m_context.bindTexture(gl.TEXTURE_3D, tex);
   4690 
   4691        // Fill with gradient.
   4692        var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
   4693        var slicePitch = rowPitch * this.m_height;
   4694 
   4695        data = new ArrayBuffer(slicePitch * this.m_depth);
   4696        var access = new tcuTexture.PixelBufferAccess({
   4697                        format: this.m_texFormat,
   4698                        width: this.m_width,
   4699                        height: this.m_height,
   4700                        depth: this.m_depth,
   4701                        rowPitch: rowPitch,
   4702                        slicePitch: slicePitch,
   4703                        data: data});
   4704        tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
   4705        );
   4706 
   4707        this.m_context.texImage3D(
   4708            gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
   4709            this.m_height, this.m_depth, 0, transferFmt.format,
   4710            transferFmt.dataType, access.getDataPtr()
   4711        );
   4712 
   4713        // Fill data with grid.
   4714        var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
   4715        rowPitch = deMath.deAlign32(
   4716            rowLength * pixelSize, this.m_alignment
   4717        );
   4718        var imageHeight = this.m_imageHeight > 0 ?
   4719            this.m_imageHeight : this.m_subH;
   4720        slicePitch = imageHeight * rowPitch;
   4721        var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
   4722        var cBias = this.m_texFormatInfo.valueMin;
   4723        var colorA = deMath.add(
   4724            deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
   4725        );
   4726        var colorB = deMath.add(
   4727            deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
   4728        );
   4729 
   4730        data = new ArrayBuffer(slicePitch * (this.m_subD + this.m_skipImages) +
   4731                               rowPitch * this.m_skipRows + pixelSize * this.m_skipPixels + this.m_offset);
   4732        var accessSub = new tcuTexture.PixelBufferAccess({
   4733                        format: this.m_texFormat,
   4734                        width: this.m_subW,
   4735                        height: this.m_subH,
   4736                        depth: this.m_subD,
   4737                        rowPitch: rowPitch,
   4738                        slicePitch: slicePitch,
   4739                        data: data,
   4740                        offset: this.m_skipImages * slicePitch +
   4741                                this.m_skipRows * rowPitch +
   4742                                this.m_skipPixels * pixelSize +
   4743                                this.m_offset
   4744                    });
   4745        tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB
   4746        );
   4747 
   4748        buf = this.m_context.createBuffer();
   4749        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   4750        this.m_context.bufferData(
   4751            gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
   4752        );
   4753 
   4754        this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
   4755        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
   4756        this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
   4757        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
   4758        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
   4759        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
   4760        this.m_context.texSubImage3D(
   4761            gl.TEXTURE_3D, 0, this.m_subX, this.m_subY, this.m_subZ,
   4762            this.m_subW, this.m_subH, this.m_subD, transferFmt.format,
   4763            transferFmt.dataType, this.m_offset
   4764        );
   4765    };
   4766 
   4767    // TexImage2D() depth case.
   4768    /**
   4769     * @constructor
   4770     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   4771     * @param {string} name
   4772     * @param {string} desc
   4773     * @param {number} internalFormat
   4774     * @param {number} imageWidth
   4775     * @param {number} imageHeight
   4776     */
   4777    es3fTextureSpecificationTests.TexImage2DDepthCase = function(
   4778        name, desc, internalFormat, imageWidth, imageHeight
   4779    ) {
   4780        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   4781            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4782                internalFormat
   4783            ), imageWidth, imageHeight,
   4784            es3fTextureSpecificationTests.maxLevelCount(
   4785                imageWidth, imageHeight
   4786            )
   4787        );
   4788 
   4789        this.m_internalFormat = internalFormat;
   4790        // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   4791        this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
   4792        this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
   4793    };
   4794 
   4795    es3fTextureSpecificationTests.TexImage2DDepthCase.prototype =
   4796        Object.create(
   4797            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   4798        );
   4799 
   4800    es3fTextureSpecificationTests.
   4801    TexImage2DDepthCase.prototype.constructor =
   4802        es3fTextureSpecificationTests.TexImage2DDepthCase;
   4803 
   4804    /**
   4805     * createTexture
   4806     */
   4807    es3fTextureSpecificationTests.TexImage2DDepthCase.prototype.createTexture =
   4808    function() {
   4809        var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   4810        var tex = null;
   4811        var levelData = new tcuTexture.TextureLevel(
   4812            this.m_texFormat, this.m_width, this.m_height
   4813        );
   4814 
   4815        tex = this.m_context.createTexture();
   4816        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   4817        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   4818 
   4819        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   4820            var levelW = Math.max(1, this.m_width >> ndx);
   4821            var levelH = Math.max(1, this.m_height >> ndx);
   4822            var gMin = [-1.5, -2.0, 1.7, -1.5];
   4823            var gMax = [2.0, 1.5, -1.0, 2.0];
   4824 
   4825            levelData.setSize(levelW, levelH);
   4826            tcuTextureUtil.fillWithComponentGradients(
   4827                levelData.getAccess(), gMin, gMax
   4828            );
   4829 
   4830            this.m_context.texImage2D(
   4831                gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
   4832                fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()
   4833            );
   4834        }
   4835    };
   4836 
   4837    // TexImage3D() depth case.
   4838    /**
   4839     * @constructor
   4840     * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
   4841     * @param {string} name
   4842     * @param {string} desc
   4843     * @param {number} internalFormat
   4844     * @param {number} imageWidth
   4845     * @param {number} imageHeight
   4846     * @param {number} numLayers
   4847     */
   4848    es3fTextureSpecificationTests.TexImage2DArrayDepthCase = function(
   4849        name, desc, internalFormat, imageWidth, imageHeight, numLayers
   4850    ) {
   4851        es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
   4852            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4853                internalFormat
   4854            ), imageWidth, imageHeight, numLayers,
   4855            es3fTextureSpecificationTests.maxLevelCount(
   4856                imageWidth, imageHeight
   4857            )
   4858        );
   4859 
   4860        this.m_internalFormat = internalFormat;
   4861        // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   4862        this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
   4863        this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
   4864    };
   4865 
   4866    es3fTextureSpecificationTests.TexImage2DArrayDepthCase.prototype =
   4867        Object.create(
   4868            es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
   4869        );
   4870 
   4871    es3fTextureSpecificationTests.
   4872    TexImage2DArrayDepthCase.prototype.constructor =
   4873        es3fTextureSpecificationTests.TexImage2DArrayDepthCase;
   4874 
   4875    /**
   4876     * createTexture
   4877     */
   4878    es3fTextureSpecificationTests.
   4879    TexImage2DArrayDepthCase.prototype.createTexture = function() {
   4880        var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   4881        var tex = null;
   4882        var levelData = new tcuTexture.TextureLevel(
   4883            this.m_texFormat, this.m_width, this.m_height
   4884        );
   4885 
   4886        tex = this.m_context.createTexture();
   4887        this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
   4888        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   4889 
   4890        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   4891            var levelW = Math.max(1, this.m_width >> ndx);
   4892            var levelH = Math.max(1, this.m_height >> ndx);
   4893            var gMin = [-1.5, -2.0, 1.7, -1.5];
   4894            var gMax = [2.0, 1.5, -1.0, 2.0];
   4895 
   4896            levelData.setSize(levelW, levelH, this.m_numLayers);
   4897            tcuTextureUtil.fillWithComponentGradients(
   4898                levelData.getAccess(), gMin, gMax
   4899            );
   4900 
   4901            this.m_context.texImage3D(
   4902                gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
   4903                this.m_numLayers, 0, fmt.format, fmt.dataType,
   4904                levelData.getAccess().getDataPtr()
   4905            );
   4906        }
   4907    };
   4908 
   4909    // TexSubImage2D() depth case.
   4910    /**
   4911     * @constructor
   4912     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   4913     * @param {string} name
   4914     * @param {string} desc
   4915     * @param {number} internalFormat
   4916     * @param {number} imageWidth
   4917     * @param {number} imageHeight
   4918     */
   4919    es3fTextureSpecificationTests.TexSubImage2DDepthCase = function(
   4920        name, desc, internalFormat, imageWidth, imageHeight
   4921    ) {
   4922        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   4923            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   4924                internalFormat
   4925            ), imageWidth, imageHeight,
   4926            es3fTextureSpecificationTests.maxLevelCount(
   4927                imageWidth, imageHeight
   4928            )
   4929        );
   4930 
   4931        this.m_internalFormat = internalFormat;
   4932        // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   4933        this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
   4934        this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
   4935    };
   4936 
   4937    es3fTextureSpecificationTests.TexSubImage2DDepthCase.prototype =
   4938        Object.create(
   4939            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   4940        );
   4941 
   4942    es3fTextureSpecificationTests.
   4943    TexSubImage2DDepthCase.prototype.constructor =
   4944        es3fTextureSpecificationTests.TexSubImage2DDepthCase;
   4945 
   4946    /**
   4947     * createTexture
   4948     */
   4949    es3fTextureSpecificationTests.
   4950    TexSubImage2DDepthCase.prototype.createTexture = function() {
   4951        var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   4952        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   4953        var tex = null;
   4954        var levelData = new tcuTexture.TextureLevel(
   4955            this.m_texFormat, this.m_width, this.m_height
   4956        );
   4957 
   4958        tex = this.m_context.createTexture();
   4959        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   4960        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   4961 
   4962        // First specify full texture.
   4963        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   4964            var levelW = Math.max(1, this.m_width >> ndx);
   4965            var levelH = Math.max(1, this.m_height >> ndx);
   4966            var gMin = [-1.5, -2.0, 1.7, -1.5];
   4967            var gMax = [2.0, 1.5, -1.0, 2.0];
   4968 
   4969            levelData.setSize(levelW, levelH);
   4970            tcuTextureUtil.fillWithComponentGradients(
   4971                levelData.getAccess(), gMin, gMax
   4972            );
   4973 
   4974            this.m_context.texImage2D(
   4975                gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
   4976                fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()
   4977            );
   4978        }
   4979 
   4980        // Re-specify parts of each level.
   4981        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   4982            var levelW = Math.max(1, this.m_width >> ndx);
   4983            var levelH = Math.max(1, this.m_height >> ndx);
   4984 
   4985            var w = rnd.getInt(1, levelW);
   4986            var h = rnd.getInt(1, levelH);
   4987            var x = rnd.getInt(0, levelW - w);
   4988            var y = rnd.getInt(0, levelH - h);
   4989 
   4990             var colorA = [2.0, 1.5, -1.0, 2.0];
   4991             var colorB = [-1.5, -2.0, 1.7, -1.5];
   4992             var cellSize = rnd.getInt(2, 16);
   4993 
   4994            levelData.setSize(w, h);
   4995            tcuTextureUtil.fillWithGrid(
   4996                levelData.getAccess(), cellSize, colorA, colorB
   4997            );
   4998 
   4999            this.m_context.texSubImage2D(
   5000                gl.TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType,
   5001                levelData.getAccess().getDataPtr()
   5002            );
   5003        }
   5004    };
   5005 
   5006    // TexSubImage3D() depth case.
   5007    /**
   5008     * @constructor
   5009     * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
   5010     * @param {string} name
   5011     * @param {string} desc
   5012     * @param {number} internalFormat
   5013     * @param {number} imageWidth
   5014     * @param {number} imageHeight
   5015     * @param {number} numLayers
   5016     */
   5017    es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase = function(
   5018        name, desc, internalFormat, imageWidth, imageHeight, numLayers
   5019    ) {
   5020        es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
   5021            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   5022                internalFormat
   5023            ), imageWidth, imageHeight, numLayers,
   5024            es3fTextureSpecificationTests.maxLevelCount(
   5025                imageWidth, imageHeight
   5026            )
   5027        );
   5028 
   5029        this.m_internalFormat = internalFormat;
   5030        // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   5031        this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
   5032        this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
   5033    };
   5034 
   5035    es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase.prototype =
   5036        Object.create(
   5037            es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
   5038        );
   5039 
   5040    es3fTextureSpecificationTests.
   5041    TexSubImage2DArrayDepthCase.prototype.constructor =
   5042        es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase;
   5043 
   5044    /**
   5045     * createTexture
   5046     */
   5047    es3fTextureSpecificationTests.
   5048    TexSubImage2DArrayDepthCase.prototype.createTexture = function() {
   5049        var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   5050        var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
   5051        var tex = null;
   5052        var levelData = new tcuTexture.TextureLevel(
   5053            this.m_texFormat, this.m_width, this.m_height
   5054        );
   5055 
   5056        tex = this.m_context.createTexture();
   5057        this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
   5058        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
   5059 
   5060        // First specify full texture.
   5061        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   5062            var levelW = Math.max(1, this.m_width >> ndx);
   5063            var levelH = Math.max(1, this.m_height >> ndx);
   5064            var gMin = [-1.5, -2.0, 1.7, -1.5];
   5065            var gMax = [2.0, 1.5, -1.0, 2.0];
   5066 
   5067            levelData.setSize(levelW, levelH, this.m_numLayers);
   5068            tcuTextureUtil.fillWithComponentGradients(
   5069                levelData.getAccess(), gMin, gMax
   5070            );
   5071            this.m_context.texImage3D(
   5072                gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
   5073                this.m_numLayers, 0, fmt.format, fmt.dataType,
   5074                levelData.getAccess().getDataPtr()
   5075            );
   5076        }
   5077 
   5078        // Re-specify parts of each level.
   5079        for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
   5080            var levelW = Math.max(1, this.m_width >> ndx);
   5081            var levelH = Math.max(1, this.m_height >> ndx);
   5082 
   5083            var w = rnd.getInt(1, levelW);
   5084            var h = rnd.getInt(1, levelH);
   5085            var d = rnd.getInt(1, this.m_numLayers);
   5086            var x = rnd.getInt(0, levelW - w);
   5087            var y = rnd.getInt(0, levelH - h);
   5088            var z = rnd.getInt(0, this.m_numLayers - d);
   5089 
   5090             var colorA = [2.0, 1.5, -1.0, 2.0];
   5091             var colorB = [-1.5, -2.0, 1.7, -1.5];
   5092             var cellSize = rnd.getInt(2, 16);
   5093 
   5094            levelData.setSize(w, h, d);
   5095            tcuTextureUtil.fillWithGrid(
   5096                levelData.getAccess(), cellSize, colorA, colorB
   5097            );
   5098 
   5099            this.m_context.texSubImage3D(
   5100                gl.TEXTURE_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format,
   5101                fmt.dataType, levelData.getAccess().getDataPtr()
   5102            );
   5103        }
   5104    };
   5105 
   5106    // TexImage2D() depth case with pbo.
   5107    /**
   5108     * @constructor
   5109     * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
   5110     * @param {string} name
   5111     * @param {string} desc
   5112     * @param {number} internalFormat
   5113     * @param {number} imageWidth
   5114     * @param {number} imageHeight
   5115     */
   5116    es3fTextureSpecificationTests.TexImage2DDepthBufferCase = function(
   5117        name, desc, internalFormat, imageWidth, imageHeight
   5118    ) {
   5119        es3fTextureSpecificationTests.Texture2DSpecCase.call(
   5120            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   5121                internalFormat
   5122            ), imageWidth, imageHeight, 1
   5123        );
   5124 
   5125        this.m_internalFormat = internalFormat;
   5126        // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   5127        this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
   5128        this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
   5129    };
   5130 
   5131    es3fTextureSpecificationTests.TexImage2DDepthBufferCase.prototype =
   5132        Object.create(
   5133            es3fTextureSpecificationTests.Texture2DSpecCase.prototype
   5134        );
   5135 
   5136    es3fTextureSpecificationTests.
   5137    TexImage2DDepthBufferCase.prototype.constructor =
   5138        es3fTextureSpecificationTests.TexImage2DDepthBufferCase;
   5139 
   5140    /**
   5141     * createTexture
   5142     */
   5143    es3fTextureSpecificationTests.
   5144    TexImage2DDepthBufferCase.prototype.createTexture = function() {
   5145        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   5146        var pixelSize = this.m_texFormat.getPixelSize();
   5147        var rowLength = this.m_width;
   5148        var alignment = 4;
   5149        var rowPitch = deMath.deAlign32(rowLength * pixelSize, alignment);
   5150        var height = this.m_height;
   5151        var buf = null;
   5152        var tex = null;
   5153        var data = new ArrayBuffer(rowPitch * height);
   5154 
   5155        assertMsgOptions(
   5156            this.m_numLevels == 1, 'Number of levels is different than 1',
   5157            false, true
   5158        );
   5159 
   5160        // Fill data with gradient
   5161        var gMin = [-1.5, -2.0, 1.7, -1.5];
   5162        var gMax = [2.0, 1.5, -1.0, 2.0];
   5163 
   5164        var access = new tcuTexture.PixelBufferAccess({
   5165                        format: this.m_texFormat,
   5166                        width: this.m_width,
   5167                        height: this.m_height,
   5168                        rowPitch: rowPitch,
   5169                        data: data
   5170                    });
   5171        tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
   5172 
   5173        // Create buffer and upload.
   5174        buf = this.m_context.createBuffer();
   5175        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   5176        this.m_context.bufferData(
   5177            gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW
   5178        );
   5179 
   5180        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, rowLength);
   5181        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
   5182        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
   5183        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);
   5184 
   5185        tex = this.m_context.createTexture();
   5186        this.m_context.bindTexture(gl.TEXTURE_2D, tex);
   5187        this.m_context.texImage2D(
   5188            gl.TEXTURE_2D, 0, this.m_internalFormat, this.m_width,
   5189            this.m_height, 0, transferFmt.format, transferFmt.dataType, 0
   5190        );
   5191        this.m_context.deleteBuffer(buf);
   5192    };
   5193 
   5194    // TexImage3D() depth case with pbo.
   5195    /**
   5196     * @constructor
   5197     * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
   5198     * @param {string} name
   5199     * @param {string} desc
   5200     * @param {number} internalFormat
   5201     * @param {number} imageWidth
   5202     * @param {number} imageHeight
   5203     */
   5204    es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase = function(
   5205        name, desc, internalFormat, imageWidth, imageHeight, numLayers
   5206    ) {
   5207        es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
   5208            this, name, desc, gluTextureUtil.mapGLInternalFormat(
   5209                internalFormat
   5210            ), imageWidth, imageHeight, numLayers, 1
   5211        );
   5212 
   5213        this.m_internalFormat = internalFormat;
   5214        // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   5215        this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
   5216        this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
   5217    };
   5218 
   5219    es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase.prototype =
   5220        Object.create(
   5221            es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
   5222        );
   5223 
   5224    es3fTextureSpecificationTests.
   5225    TexImage2DArrayDepthBufferCase.prototype.constructor =
   5226        es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase;
   5227 
   5228    /**
   5229     * createTexture
   5230     */
   5231    es3fTextureSpecificationTests.
   5232    TexImage2DArrayDepthBufferCase.prototype.createTexture = function() {
   5233        var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
   5234        var pixelSize = this.m_texFormat.getPixelSize();
   5235        var rowLength = this.m_width;
   5236        var alignment = 4;
   5237        var rowPitch = deMath.deAlign32(rowLength * pixelSize, alignment);
   5238        var imageHeight = this.m_height;
   5239        var slicePitch = imageHeight * rowPitch;
   5240        var tex = null;
   5241        var buf = null;
   5242        var data = new ArrayBuffer(slicePitch * this.m_numLayers);
   5243 
   5244        assertMsgOptions(
   5245            this.m_numLevels == 1, 'Number of levels is different than 1',
   5246            false, true
   5247        );
   5248 
   5249        // Fill data with gradient
   5250        var gMin = [-1.5, -2.0, 1.7, -1.5];
   5251        var gMax = [2.0, 1.5, -1.0, 2.0];
   5252 
   5253        var access = new tcuTexture.PixelBufferAccess({
   5254                        format: this.m_texFormat,
   5255                        width: this.m_width,
   5256                        height: this.m_height,
   5257                        depth: this.m_numLayers,
   5258                        rowPitch: rowPitch,
   5259                        slicePitch: slicePitch,
   5260                        data: data
   5261                    });
   5262        tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
   5263 
   5264        buf = this.m_context.createBuffer();
   5265        this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
   5266        this.m_context.bufferData(
   5267            gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW
   5268        );
   5269 
   5270        this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, rowLength);
   5271        this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, rowLength);
   5272        this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);
   5273        this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
   5274        this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
   5275        this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);
   5276 
   5277        tex = this.m_context.createTexture();
   5278        this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
   5279        this.m_context.texImage3D(
   5280            gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width,
   5281            this.m_height, this.m_numLayers, 0, transferFmt.format,
   5282            transferFmt.dataType, 0
   5283        );
   5284        this.m_context.deleteBuffer(buf);
   5285    };
   5286 
   5287    /**
   5288     * @constructor
   5289     * @extends {tcuTestCase.DeqpTest}
   5290     */
   5291    es3fTextureSpecificationTests.TextureSpecificationTests = function() {
   5292        tcuTestCase.DeqpTest.call(
   5293            this, 'specification', 'Texture Specification Tests'
   5294        );
   5295    };
   5296 
   5297    es3fTextureSpecificationTests.TextureSpecificationTests.prototype =
   5298        Object.create(tcuTestCase.DeqpTest.prototype);
   5299    es3fTextureSpecificationTests.TextureSpecificationTests.prototype.constructor =
   5300        es3fTextureSpecificationTests.TextureSpecificationTests;
   5301 
   5302    es3fTextureSpecificationTests.TextureSpecificationTests.prototype.init = function() {
   5303        /**
   5304         * @type {Array<number>}
   5305         */
   5306        es3fTextureSpecificationTests.s_cubeMapFaces = [
   5307            gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
   5308            gl.TEXTURE_CUBE_MAP_POSITIVE_X,
   5309            gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
   5310            gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
   5311            gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,
   5312            gl.TEXTURE_CUBE_MAP_POSITIVE_Z
   5313        ];
   5314 
   5315        /** @type {Array<{name: string, format: number, dataType: number}>} */
   5316        var unsizedFormats = [{
   5317                name: 'alpha_unsigned_byte',
   5318                format: gl.ALPHA,
   5319                dataType: gl.UNSIGNED_BYTE
   5320            }, {
   5321                name: 'luminance_unsigned_byte',
   5322                format: gl.LUMINANCE,
   5323                dataType: gl.UNSIGNED_BYTE
   5324            }, {
   5325                name: 'luminance_alpha_unsigned_byte',
   5326                format: gl.LUMINANCE_ALPHA,
   5327                dataType: gl.UNSIGNED_BYTE
   5328            }, {
   5329                name: 'rgb_unsigned_short_5_6_5',
   5330                format: gl.RGB,
   5331                dataType: gl.UNSIGNED_SHORT_5_6_5
   5332            }, {
   5333                name: 'rgb_unsigned_byte',
   5334                format: gl.RGB,
   5335                dataType: gl.UNSIGNED_BYTE
   5336            }, {
   5337                name: 'rgba_unsigned_short_4_4_4_4',
   5338                format: gl.RGBA,
   5339                dataType: gl.UNSIGNED_SHORT_4_4_4_4
   5340            }, {
   5341                name: 'rgba_unsigned_short_5_5_5_1',
   5342                format: gl.RGBA,
   5343                dataType: gl.UNSIGNED_SHORT_5_5_5_1
   5344            }, {
   5345                name: 'rgba_unsigned_byte',
   5346                format: gl.RGBA,
   5347                dataType: gl.UNSIGNED_BYTE
   5348            }
   5349        ];
   5350 
   5351        /** @type {Array<{name: string, internalFormat: number}>} */
   5352        var colorFormats = [{
   5353                name: 'rgba32f', internalFormat: gl.RGBA32F
   5354            }, {
   5355                name: 'rgba32i', internalFormat: gl.RGBA32I
   5356            }, {
   5357                name: 'rgba32ui', internalFormat: gl.RGBA32UI
   5358            }, {
   5359                name: 'rgba16f', internalFormat: gl.RGBA16F
   5360            }, {
   5361                name: 'rgba16i', internalFormat: gl.RGBA16I
   5362            }, {
   5363                name: 'rgba16ui', internalFormat: gl.RGBA16UI
   5364            }, {
   5365                name: 'rgba8', internalFormat: gl.RGBA8
   5366            }, {
   5367                name: 'rgba8i', internalFormat: gl.RGBA8I
   5368            }, {
   5369                name: 'rgba8ui', internalFormat: gl.RGBA8UI
   5370            }, {
   5371                name: 'srgb8_alpha8', internalFormat: gl.SRGB8_ALPHA8
   5372            }, {
   5373                name: 'rgb10_a2', internalFormat: gl.RGB10_A2
   5374            }, {
   5375                name: 'rgb10_a2ui', internalFormat: gl.RGB10_A2UI
   5376            }, {
   5377                name: 'rgba4', internalFormat: gl.RGBA4
   5378            }, {
   5379                name: 'rgb5_a1', internalFormat: gl.RGB5_A1
   5380            }, {
   5381                name: 'rgba8_snorm', internalFormat: gl.RGBA8_SNORM
   5382            }, {
   5383                name: 'rgb8', internalFormat: gl.RGB8
   5384            }, {
   5385                name: 'rgb565', internalFormat: gl.RGB565
   5386            }, {
   5387                name: 'r11f_g11f_b10f', internalFormat: gl.R11F_G11F_B10F
   5388            }, {
   5389                name: 'rgb32f', internalFormat: gl.RGB32F
   5390            }, {
   5391                name: 'rgb32i', internalFormat: gl.RGB32I
   5392            }, {
   5393                name: 'rgb32ui', internalFormat: gl.RGB32UI
   5394            }, {
   5395                name: 'rgb16f', internalFormat: gl.RGB16F
   5396            }, {
   5397                name: 'rgb16i', internalFormat: gl.RGB16I
   5398            }, {
   5399                name: 'rgb16ui', internalFormat: gl.RGB16UI
   5400            }, {
   5401                name: 'rgb8_snorm', internalFormat: gl.RGB8_SNORM
   5402            }, {
   5403                name: 'rgb8i', internalFormat: gl.RGB8I
   5404            }, {
   5405                name: 'rgb8ui', internalFormat: gl.RGB8UI
   5406            }, {
   5407                name: 'srgb8', internalFormat: gl.SRGB8
   5408            }, {
   5409                name: 'rgb9_e5', internalFormat: gl.RGB9_E5
   5410            }, {
   5411                name: 'rg32f', internalFormat: gl.RG32F
   5412            }, {
   5413                name: 'rg32i', internalFormat: gl.RG32I
   5414            }, {
   5415                name: 'rg32ui', internalFormat: gl.RG32UI
   5416            }, {
   5417                name: 'rg16f', internalFormat: gl.RG16F
   5418            }, {
   5419                name: 'rg16i', internalFormat: gl.RG16I
   5420            }, {
   5421                name: 'rg16ui', internalFormat: gl.RG16UI
   5422            }, {
   5423                name: 'rg8', internalFormat: gl.RG8
   5424            }, {
   5425                name: 'rg8i', internalFormat: gl.RG8I
   5426            }, {
   5427                name: 'rg8ui', internalFormat: gl.RG8UI
   5428            }, {
   5429                name: 'rg8_snorm', internalFormat: gl.RG8_SNORM
   5430            }, {
   5431                name: 'r32f', internalFormat: gl.R32F
   5432            }, {
   5433                name: 'r32i', internalFormat: gl.R32I
   5434            }, {
   5435                name: 'r32ui', internalFormat: gl.R32UI
   5436            }, {
   5437                name: 'r16f', internalFormat: gl.R16F
   5438            }, {
   5439                name: 'r16i', internalFormat: gl.R16I
   5440            }, {
   5441                name: 'r16ui', internalFormat: gl.R16UI
   5442            }, {
   5443                name: 'r8', internalFormat: gl.R8
   5444            }, {
   5445                name: 'r8i', internalFormat: gl.R8I
   5446            }, {
   5447                name: 'r8ui', internalFormat: gl.R8UI
   5448            }, {
   5449                name: 'r8_snorm', internalFormat: gl.R8_SNORM
   5450            }
   5451        ];
   5452 
   5453        // Depth and stencil formats
   5454        /** @type {Array<{name: string, internalFormat: number}>} */
   5455        var depthStencilFormats = [{
   5456                name: 'depth_component32f',
   5457                internalFormat: gl.DEPTH_COMPONENT32F
   5458            }, {
   5459                name: 'depth_component24',
   5460                internalFormat: gl.DEPTH_COMPONENT24
   5461            }, {
   5462                name: 'depth_component16',
   5463                internalFormat: gl.DEPTH_COMPONENT16
   5464            }, {
   5465                name: 'depth32f_stencil8',
   5466                internalFormat: gl.DEPTH32F_STENCIL8
   5467            }, {
   5468                name: 'depth24_stencil8',
   5469                internalFormat: gl.DEPTH24_STENCIL8
   5470            }
   5471        ];
   5472 
   5473        // Basic TexImage2D usage.
   5474        var splitBasicTex2D = 2, splitBasicTexCube = 5;
   5475        /** @type {Array<{tcuTestCase.DeqpTest}>} */
   5476        var basicTexImageGroup2D = [];
   5477        for (var ii = 0; ii < splitBasicTex2D; ++ii) {
   5478            basicTexImageGroup2D.push(
   5479                new tcuTestCase.DeqpTest('basic_teximage2d', 'Basic glTexImage2D() usage')
   5480            );
   5481            this.addChild(basicTexImageGroup2D[ii]);
   5482        }
   5483        /** @type {Array<{tcuTestCase.DeqpTest}>} */
   5484        var basicTexImageGroupCube = [];
   5485        for (var ii = 0; ii < splitBasicTexCube; ++ii) {
   5486            basicTexImageGroupCube.push(
   5487                new tcuTestCase.DeqpTest('basic_teximage2d', 'Basic glTexImage2D() usage')
   5488            );
   5489            this.addChild(basicTexImageGroupCube[ii]);
   5490        }
   5491        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   5492            /** @type {string} */
   5493            var fmtName = colorFormats[formatNdx].name;
   5494            /** @type {number} */
   5495            var format = colorFormats[formatNdx].internalFormat;
   5496            /** @type {number} */
   5497            var tex2DWidth = 64;
   5498            /** @type {number} */
   5499            var tex2DHeight = 128;
   5500            /** @type {number} */
   5501            var texCubeSize = 64;
   5502 
   5503            basicTexImageGroup2D[formatNdx % splitBasicTex2D].addChild(
   5504                es3fTextureSpecificationTests.newBasicTexImage2DCaseInternal(
   5505                    fmtName + '_2d', '', format, tex2DWidth, tex2DHeight
   5506                )
   5507            );
   5508            basicTexImageGroupCube[formatNdx % splitBasicTexCube].addChild(
   5509                es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal(
   5510                    fmtName + '_cube', '', format, texCubeSize
   5511                )
   5512            );
   5513        }
   5514 
   5515        // Randomized TexImage2D order.
   5516        /** @type {tcuTestCase.DeqpTest} */
   5517        var randomTexImageGroup = new tcuTestCase.DeqpTest(
   5518            'random_teximage2d', 'Randomized glTexImage2D() usage'
   5519        );
   5520        this.addChild(randomTexImageGroup);
   5521        var rnd = new deRandom.Random(9);
   5522 
   5523        // 2D cases.
   5524        for (var ndx = 0; ndx < 10; ndx++) {
   5525            var formatNdx = rnd.getInt(0, colorFormats.length - 1);
   5526            var width = 1 << rnd.getInt(2, 8);
   5527            var height = 1 << rnd.getInt(2, 8);
   5528 
   5529            randomTexImageGroup.addChild(
   5530                es3fTextureSpecificationTests.newRandomOrderTexImage2DCaseInternal(
   5531                    '2d.' + colorFormats[formatNdx].name, '',
   5532                    colorFormats[formatNdx].internalFormat, width, height
   5533                )
   5534            );
   5535        }
   5536 
   5537        // Cubemap cases.
   5538        randomTexImageGroup = new tcuTestCase.DeqpTest(
   5539            'random_teximage2d', 'Randomized glTexImage2D() usage'
   5540        );
   5541        this.addChild(randomTexImageGroup);
   5542 
   5543        for (var ndx = 0; ndx < 10; ndx++) {
   5544            formatNdx = rnd.getInt(0, colorFormats.length - 1);
   5545            /** @type {number} */ var size = 1 << rnd.getInt(2, 8);
   5546 
   5547            randomTexImageGroup.addChild(
   5548                es3fTextureSpecificationTests.newRandomOrderTexImageCubeCaseInternal(
   5549                    'cube.' + colorFormats[formatNdx].name, '',
   5550                    colorFormats[formatNdx].internalFormat, size
   5551                )
   5552            );
   5553        }
   5554 
   5555        // TexImage2D unpack alignment.
   5556        /** @type {tcuTestCase.DeqpTest} */
   5557        var alignGroup = new tcuTestCase.DeqpTest(
   5558            'teximage2d_align', 'glTexImage2D() unpack alignment tests'
   5559        );
   5560        this.addChild(alignGroup);
   5561 
   5562        alignGroup.addChild(
   5563            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5564                '2d_r8_4_8', '', gl.R8, 4, 8, 4, 8
   5565            )
   5566        );
   5567        alignGroup.addChild(
   5568            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5569                '2d_r8_63_1', '', gl.R8, 63, 30, 1, 1
   5570            )
   5571        );
   5572        alignGroup.addChild(
   5573            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5574                '2d_r8_63_2', '', gl.R8, 63, 30, 1, 2
   5575            )
   5576        );
   5577        alignGroup.addChild(
   5578            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5579                '2d_r8_63_4', '', gl.R8, 63, 30, 1, 4
   5580            )
   5581        );
   5582        alignGroup.addChild(
   5583            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5584                '2d_r8_63_8', '', gl.R8, 63, 30, 1, 8
   5585            )
   5586        );
   5587        alignGroup.addChild(
   5588            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5589                '2d_rgba4_51_1', '', gl.RGBA4, 51, 30, 1, 1
   5590            )
   5591        );
   5592        alignGroup.addChild(
   5593            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5594                '2d_rgba4_51_2', '', gl.RGBA4, 51, 30, 1, 2
   5595            )
   5596        );
   5597        alignGroup.addChild(
   5598            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5599                '2d_rgba4_51_4', '', gl.RGBA4, 51, 30, 1, 4
   5600            )
   5601        );
   5602        alignGroup.addChild(
   5603            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5604                '2d_rgba4_51_8', '', gl.RGBA4, 51, 30, 1, 8
   5605            )
   5606        );
   5607        alignGroup.addChild(
   5608            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5609                '2d_rgb8_39_1', '', gl.RGB8, 39, 43, 1, 1
   5610            )
   5611        );
   5612        alignGroup.addChild(
   5613            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5614                '2d_rgb8_39_2', '', gl.RGB8, 39, 43, 1, 2
   5615            )
   5616        );
   5617        alignGroup.addChild(
   5618            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5619                '2d_rgb8_39_4', '', gl.RGB8, 39, 43, 1, 4
   5620            )
   5621        );
   5622        alignGroup.addChild(
   5623            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5624                '2d_rgb8_39_8', '', gl.RGB8, 39, 43, 1, 8
   5625            )
   5626        );
   5627        alignGroup.addChild(
   5628            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5629                '2d_rgba8_47_1', '', gl.RGBA8, 47, 27, 1, 1
   5630            )
   5631        );
   5632        alignGroup.addChild(
   5633            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5634                '2d_rgba8_47_2', '', gl.RGBA8, 47, 27, 1, 2
   5635            )
   5636        );
   5637        alignGroup.addChild(
   5638            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5639                '2d_rgba8_47_4', '', gl.RGBA8, 47, 27, 1, 4
   5640            )
   5641        );
   5642        alignGroup.addChild(
   5643            es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
   5644                '2d_rgba8_47_8', '', gl.RGBA8, 47, 27, 1, 8
   5645            )
   5646        );
   5647        alignGroup.addChild(
   5648            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5649                'cube_r8_4_8', '', gl.R8, 4, 3, 8
   5650            )
   5651        );
   5652        alignGroup.addChild(
   5653            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5654                'cube_r8_63_1', '', gl.R8, 63, 1, 1
   5655            )
   5656        );
   5657        alignGroup.addChild(
   5658            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5659                'cube_r8_63_2', '', gl.R8, 63, 1, 2
   5660            )
   5661        );
   5662        alignGroup.addChild(
   5663            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5664                'cube_r8_63_4', '', gl.R8, 63, 1, 4
   5665            )
   5666        );
   5667        alignGroup.addChild(
   5668            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5669                'cube_r8_63_8', '', gl.R8, 63, 1, 8
   5670            )
   5671        );
   5672        alignGroup.addChild(
   5673            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5674                'cube_rgba4_51_1', '', gl.RGBA4, 51, 1, 1
   5675            )
   5676        );
   5677        alignGroup.addChild(
   5678            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5679                'cube_rgba4_51_2', '', gl.RGBA4, 51, 1, 2
   5680            )
   5681        );
   5682        alignGroup.addChild(
   5683            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5684                'cube_rgba4_51_4', '', gl.RGBA4, 51, 1, 4
   5685            )
   5686        );
   5687        alignGroup.addChild(
   5688            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5689                'cube_rgba4_51_8', '', gl.RGBA4, 51, 1, 8
   5690            )
   5691        );
   5692        alignGroup.addChild(
   5693            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5694                'cube_rgb8_39_1', '', gl.RGB8, 39, 1, 1
   5695            )
   5696        );
   5697        alignGroup.addChild(
   5698            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5699                'cube_rgb8_39_2', '', gl.RGB8, 39, 1, 2
   5700            )
   5701        );
   5702        alignGroup.addChild(
   5703            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5704                'cube_rgb8_39_4', '', gl.RGB8, 39, 1, 4
   5705            )
   5706        );
   5707        alignGroup.addChild(
   5708            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5709                'cube_rgb8_39_8', '', gl.RGB8, 39, 1, 8
   5710            )
   5711        );
   5712        alignGroup.addChild(
   5713            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5714                'cube_rgba8_47_1', '', gl.RGBA8, 47, 1, 1
   5715            )
   5716        );
   5717        alignGroup.addChild(
   5718            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5719                'cube_rgba8_47_2', '', gl.RGBA8, 47, 1, 2
   5720            )
   5721        );
   5722        alignGroup.addChild(
   5723            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5724                'cube_rgba8_47_4', '', gl.RGBA8, 47, 1, 4
   5725            )
   5726        );
   5727        alignGroup.addChild(
   5728            es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
   5729                'cube_rgba8_47_8', '', gl.RGBA8, 47, 1, 8
   5730            )
   5731        );
   5732 
   5733        // glTexImage2D() unpack parameter cases.
   5734        /** @type {tcuTestCase.DeqpTest} */
   5735        var paramGroup = new tcuTestCase.DeqpTest(
   5736            'teximage2d_unpack_params',
   5737            'glTexImage2D() pixel transfer mode cases'
   5738        );
   5739        this.addChild(paramGroup);
   5740 
   5741        var cases = [{
   5742                name: 'rgb8_alignment', format: gl.RGB8, width: 31,
   5743                height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
   5744                alignment: 2
   5745            }, {
   5746                name: 'rgb8_row_length', format: gl.RGB8, width: 31,
   5747                height: 30, rowLength: 50, skipRows: 0, skipPixels: 0,
   5748                alignment: 4
   5749            }, {
   5750                name: 'rgb8_skip_rows', format: gl.RGB8, width: 31,
   5751                height: 30, rowLength: 0, skipRows: 3, skipPixels: 0,
   5752                alignment: 4
   5753            }, {
   5754                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 31,
   5755                height: 30, rowLength: 36, skipRows: 0, skipPixels: 5,
   5756                alignment: 4
   5757            }, {
   5758                name: 'r8_complex1', format: gl.R8, width: 31,
   5759                height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
   5760                alignment: 1
   5761            }, {
   5762                name: 'r8_complex2', format: gl.R8, width: 31,
   5763                height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
   5764                alignment: 2
   5765            }, {
   5766                name: 'r8_complex3', format: gl.R8, width: 31,
   5767                height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
   5768                alignment: 4
   5769            }, {
   5770                name: 'r8_complex4', format: gl.R8, width: 31,
   5771                height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
   5772                alignment: 8
   5773            }, {
   5774                name: 'rgba8_complex1', format: gl.RGBA8, width: 56,
   5775                height: 61, rowLength: 69, skipRows: 0, skipPixels: 0,
   5776                alignment: 8
   5777            }, {
   5778                name: 'rgba8_complex2', format: gl.RGBA8, width: 56,
   5779                height: 61, rowLength: 69, skipRows: 0, skipPixels: 7,
   5780                alignment: 8
   5781            }, {
   5782                name: 'rgba8_complex3', format: gl.RGBA8, width: 56,
   5783                height: 61, rowLength: 69, skipRows: 3, skipPixels: 0,
   5784                alignment: 8
   5785            }, {
   5786                name: 'rgba8_complex4', format: gl.RGBA8, width: 56,
   5787                height: 61, rowLength: 69, skipRows: 3, skipPixels: 7,
   5788                alignment: 8
   5789            }, {
   5790                name: 'rgba32f_complex', format: gl.RGBA32F, width: 19,
   5791                height: 10, rowLength: 27, skipRows: 1, skipPixels: 7,
   5792                alignment: 8
   5793            }
   5794        ];
   5795 
   5796        for (var ndx = 0; ndx < cases.length; ndx++)
   5797            paramGroup.addChild(
   5798                new es3fTextureSpecificationTests.TexImage2DParamsCase(
   5799                    cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
   5800                    cases[ndx].height, cases[ndx].rowLength,
   5801                    cases[ndx].skipRows, cases[ndx].skipPixels,
   5802                    cases[ndx].alignment
   5803                )
   5804            );
   5805 
   5806        // glTexImage2D() pbo cases.
   5807        var splitPboTex2D = 2, splitPboTexCube = 5;
   5808        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup2D = [];
   5809        for (var ii = 0; ii < splitPboTex2D; ++ii) {
   5810            pboGroup2D.push(new tcuTestCase.DeqpTest('teximage2d_pbo', 'glTexImage2D() from PBO'));
   5811            this.addChild(pboGroup2D[ii]);
   5812        }
   5813        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroupCube = [];
   5814        for (var ii = 0; ii < splitPboTexCube; ++ii) {
   5815            pboGroupCube.push(new tcuTestCase.DeqpTest('teximage2d_pbo', 'glTexImage2D() from PBO'));
   5816           this.addChild(pboGroupCube[ii]);
   5817        }
   5818        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   5819            fmtName = colorFormats[formatNdx].name;
   5820            format = colorFormats[formatNdx].internalFormat;
   5821            tex2DWidth = 65;
   5822            tex2DHeight = 37;
   5823            texCubeSize = 64;
   5824 
   5825            pboGroup2D[formatNdx % splitPboTex2D].addChild(
   5826                new es3fTextureSpecificationTests.TexImage2DBufferCase(
   5827                    fmtName + '_2d', '', format,
   5828                    tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0
   5829                )
   5830            );
   5831            pboGroupCube[formatNdx % splitPboTexCube].addChild(
   5832                new es3fTextureSpecificationTests.TexImageCubeBufferCase(
   5833                    fmtName + '_cube', '', format,
   5834                    texCubeSize, 0, 0, 0, 4, 0
   5835                )
   5836            );
   5837        }
   5838 
   5839        // Parameter cases
   5840        var pboGroupParams = new tcuTestCase.DeqpTest(
   5841            'teximage2d_pbo', 'glTexImage2D() from PBO'
   5842        );
   5843        this.addChild(pboGroupParams);
   5844        /**
   5845         * @type {Array<{name: string, format: number, width: number,
   5846         * height: number, rowLength: number, skipRows: number,
   5847         * skipPixels: number, alignment: number, offset: number}>}
   5848         */
   5849        var parameterCases = [{
   5850                name: 'rgb8_offset', format: gl.RGB8, width: 31,
   5851                height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
   5852                alignment: 4, offset: 67
   5853            }, {
   5854                name: 'rgb8_alignment', format: gl.RGB8, width: 31,
   5855                height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
   5856                alignment: 2, offset: 0
   5857            }, {
   5858                name: 'rgb8_row_length', format: gl.RGB8, width: 31,
   5859                height: 30, rowLength: 50, skipRows: 0, skipPixels: 0,
   5860                alignment: 4, offset: 0
   5861            }, {
   5862                name: 'rgb8_skip_rows', format: gl.RGB8, width: 31,
   5863                height: 30, rowLength: 0, skipRows: 3, skipPixels: 0,
   5864                alignment: 4, offset: 0
   5865            }, {
   5866                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 31,
   5867                height: 30, rowLength: 36, skipRows: 0, skipPixels: 5,
   5868                alignment: 4, offset: 0
   5869            }
   5870        ];
   5871        for (var ndx = 0; ndx < parameterCases.length; ndx++) {
   5872            pboGroupParams.addChild(
   5873                new es3fTextureSpecificationTests.TexImage2DBufferCase(
   5874                    parameterCases[ndx].name + '_2d', '',
   5875                    parameterCases[ndx].format, parameterCases[ndx].width,
   5876                    parameterCases[ndx].height, parameterCases[ndx].rowLength,
   5877                    parameterCases[ndx].skipRows,
   5878                    parameterCases[ndx].skipPixels,
   5879                    parameterCases[ndx].alignment,
   5880                    parameterCases[ndx].offset
   5881                )
   5882            );
   5883            pboGroupParams.addChild(
   5884                new es3fTextureSpecificationTests.TexImageCubeBufferCase(
   5885                    parameterCases[ndx].name + '_cube', '',
   5886                    parameterCases[ndx].format, parameterCases[ndx].width,
   5887                    parameterCases[ndx].rowLength, parameterCases[ndx].skipRows,
   5888                    parameterCases[ndx].skipPixels,
   5889                    parameterCases[ndx].alignment, parameterCases[ndx].offset
   5890                )
   5891            );
   5892        }
   5893 
   5894        // glTexImage2D() depth cases.
   5895        /** @type {tcuTestCase.DeqpTest} */
   5896        var shadow2dGroup = new tcuTestCase.DeqpTest(
   5897            'teximage2d_depth',
   5898            'glTexImage2D() with depth or depth/stencil format'
   5899        );
   5900        this.addChild(shadow2dGroup);
   5901 
   5902        for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
   5903            // WebGL 2 specific constraint.
   5904            if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
   5905                continue;
   5906            var tex2DWidth = 64;
   5907            var tex2DHeight = 128;
   5908 
   5909            shadow2dGroup.addChild(
   5910                new es3fTextureSpecificationTests.TexImage2DDepthCase(
   5911                    depthStencilFormats[ndx].name, '',
   5912                    depthStencilFormats[ndx].internalFormat,
   5913                    tex2DWidth, tex2DHeight
   5914                )
   5915            );
   5916        }
   5917 
   5918        // glTexImage2D() depth cases with pbo.
   5919        shadow2dGroup = new tcuTestCase.DeqpTest(
   5920            'teximage2d_depth_pbo',
   5921            'glTexImage2D() with depth or depth/stencil format with pbo'
   5922        );
   5923        this.addChild(shadow2dGroup);
   5924 
   5925        for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
   5926            tex2DWidth = 64;
   5927            tex2DHeight = 128;
   5928 
   5929            shadow2dGroup.addChild(
   5930                new es3fTextureSpecificationTests.TexImage2DDepthBufferCase(
   5931                    depthStencilFormats[ndx].name, '',
   5932                    depthStencilFormats[ndx].internalFormat,
   5933                    tex2DWidth, tex2DHeight
   5934                )
   5935            );
   5936        }
   5937 
   5938        // Basic TexSubImage2D usage.
   5939        splitBasicTex2D = 3;
   5940        splitBasicTexCube = 5;
   5941        /** @type {Array<{tcuTestCase.DeqpTest}>} */
   5942        var basicTexSubImageGroup2D = [];
   5943        for (var ii = 0; ii < splitBasicTex2D; ++ii) {
   5944            basicTexSubImageGroup2D.push(
   5945                new tcuTestCase.DeqpTest('basic_texsubimage2d', 'Basic glTexSubImage2D() usage')
   5946            );
   5947            this.addChild(basicTexSubImageGroup2D[ii]);
   5948        }
   5949        /** @type {Array<{tcuTestCase.DeqpTest}>} */
   5950        var basicTexSubImageGroupCube = [];
   5951        for (var ii = 0; ii < splitBasicTexCube; ++ii) {
   5952            basicTexSubImageGroupCube.push(
   5953                new tcuTestCase.DeqpTest('basic_texsubimage2d', 'Basic glTexSubImage2D() usage')
   5954            );
   5955            this.addChild(basicTexSubImageGroupCube[ii]);
   5956        }
   5957        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   5958            fmtName = colorFormats[formatNdx].name;
   5959            format = colorFormats[formatNdx].internalFormat;
   5960            tex2DWidth = 64;
   5961            tex2DHeight = 128;
   5962            texCubeSize = 64;
   5963 
   5964            basicTexSubImageGroup2D[formatNdx % splitBasicTex2D].addChild(
   5965                es3fTextureSpecificationTests.newBasicTexSubImage2DCaseInternal(
   5966                    fmtName + '_2d', '', format, tex2DWidth, tex2DHeight
   5967                )
   5968            );
   5969            basicTexSubImageGroupCube[formatNdx % splitBasicTexCube].addChild(
   5970                es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal(
   5971                    fmtName + '_cube', '', format, texCubeSize
   5972                )
   5973            );
   5974        }
   5975 
   5976        // TexSubImage2D to empty texture.
   5977        /** @type {tcuTestCase.DeqpTest} */
   5978        var texSubImageEmptyTexGroup = new tcuTestCase.DeqpTest(
   5979            'texsubimage2d_empty_tex',
   5980            'glTexSubImage2D() to texture that has storage but no data'
   5981        );
   5982        this.addChild(texSubImageEmptyTexGroup);
   5983        for (var formatNdx = 0; formatNdx < unsizedFormats.length; formatNdx++) {
   5984            fmtName = unsizedFormats[formatNdx].name;
   5985            format = unsizedFormats[formatNdx].format;
   5986            /** @type {number} */
   5987            var dataType = unsizedFormats[formatNdx].dataType;
   5988            tex2DWidth = 64;
   5989            tex2DHeight = 32;
   5990            texCubeSize = 32;
   5991 
   5992            texSubImageEmptyTexGroup.addChild(
   5993                new es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase(
   5994                    fmtName + '_2d', '', format, dataType, tex2DWidth, tex2DHeight
   5995                )
   5996            );
   5997            texSubImageEmptyTexGroup.addChild(
   5998                new es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase(
   5999                    fmtName + '_cube', '', format, dataType, texCubeSize
   6000                )
   6001            );
   6002        }
   6003 
   6004        // TexSubImage2D alignment cases.
   6005        alignGroup = new tcuTestCase.DeqpTest(
   6006            'texsubimage2d_align', 'glTexSubImage2D() unpack alignment tests'
   6007        );
   6008        this.addChild(alignGroup);
   6009 
   6010        alignGroup.addChild(
   6011            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6012                '2d_r8_1_1', '', gl.R8, 64, 64, 13, 17, 1, 6, 1
   6013            )
   6014        );
   6015        alignGroup.addChild(
   6016            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6017                '2d_r8_1_2', '', gl.R8, 64, 64, 13, 17, 1, 6, 2
   6018            )
   6019        );
   6020        alignGroup.addChild(
   6021            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6022                '2d_r8_1_4', '', gl.R8, 64, 64, 13, 17, 1, 6, 4
   6023            )
   6024        );
   6025        alignGroup.addChild(
   6026            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6027                '2d_r8_1_8', '', gl.R8, 64, 64, 13, 17, 1, 6, 8
   6028            )
   6029        );
   6030        alignGroup.addChild(
   6031            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6032                '2d_r8_63_1', '', gl.R8, 64, 64, 1, 9, 63, 30, 1
   6033            )
   6034        );
   6035        alignGroup.addChild(
   6036            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6037                '2d_r8_63_2', '', gl.R8, 64, 64, 1, 9, 63, 30, 2
   6038            )
   6039        );
   6040        alignGroup.addChild(
   6041            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6042                '2d_r8_63_4', '', gl.R8, 64, 64, 1, 9, 63, 30, 4
   6043            )
   6044        );
   6045        alignGroup.addChild(
   6046            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6047                '2d_r8_63_8', '', gl.R8, 64, 64, 1, 9, 63, 30, 8
   6048            )
   6049        );
   6050        alignGroup.addChild(
   6051            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6052                '2d_rgba4_51_1', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 1
   6053            )
   6054        );
   6055        alignGroup.addChild(
   6056            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6057                '2d_rgba4_51_2', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 2
   6058            )
   6059        );
   6060        alignGroup.addChild(
   6061            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6062                '2d_rgba4_51_4', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 4
   6063            )
   6064        );
   6065        alignGroup.addChild(
   6066            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6067                '2d_rgba4_51_8', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 8
   6068            )
   6069        );
   6070        alignGroup.addChild(
   6071            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6072                '2d_rgb8_39_1', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 1
   6073            )
   6074        );
   6075        alignGroup.addChild(
   6076            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6077                '2d_rgb8_39_2', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 2
   6078            )
   6079        );
   6080        alignGroup.addChild(
   6081            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6082                '2d_rgb8_39_4', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 4
   6083            )
   6084        );
   6085        alignGroup.addChild(
   6086            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6087                '2d_rgb8_39_8', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 8
   6088            )
   6089        );
   6090        alignGroup.addChild(
   6091            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6092                '2d_rgba8_47_1', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 1
   6093            )
   6094        );
   6095        alignGroup.addChild(
   6096            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6097                '2d_rgba8_47_2', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 2
   6098            )
   6099        );
   6100        alignGroup.addChild(
   6101            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6102                '2d_rgba8_47_4', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 4
   6103            )
   6104        );
   6105        alignGroup.addChild(
   6106            es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
   6107                '2d_rgba8_47_8', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 8
   6108            )
   6109        );
   6110 
   6111        alignGroup.addChild(
   6112            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6113                'cube_r8_1_1', '', gl.R8, 64, 13, 17, 1, 6, 1
   6114            )
   6115        );
   6116        alignGroup.addChild(
   6117            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6118                'cube_r8_1_2', '', gl.R8, 64, 13, 17, 1, 6, 2
   6119            )
   6120        );
   6121        alignGroup.addChild(
   6122            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6123                'cube_r8_1_4', '', gl.R8, 64, 13, 17, 1, 6, 4
   6124            )
   6125        );
   6126        alignGroup.addChild(
   6127            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6128                'cube_r8_1_8', '', gl.R8, 64, 13, 17, 1, 6, 8
   6129            )
   6130        );
   6131        alignGroup.addChild(
   6132            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6133                'cube_r8_63_1', '', gl.R8, 64, 1, 9, 63, 30, 1
   6134            )
   6135        );
   6136        alignGroup.addChild(
   6137            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6138                'cube_r8_63_2', '', gl.R8, 64, 1, 9, 63, 30, 2
   6139            )
   6140        );
   6141        alignGroup.addChild(
   6142            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6143                'cube_r8_63_4', '', gl.R8, 64, 1, 9, 63, 30, 4
   6144            )
   6145        );
   6146        alignGroup.addChild(
   6147            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6148                'cube_r8_63_8', '', gl.R8, 64, 1, 9, 63, 30, 8
   6149            )
   6150        );
   6151        alignGroup.addChild(
   6152            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6153                'cube_rgba4_51_1', '', gl.RGBA4, 64, 7, 29, 51, 30, 1
   6154            )
   6155        );
   6156        alignGroup.addChild(
   6157            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6158                'cube_rgba4_51_2', '', gl.RGBA4, 64, 7, 29, 51, 30, 2
   6159            )
   6160        );
   6161        alignGroup.addChild(
   6162            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6163                'cube_rgba4_51_4', '', gl.RGBA4, 64, 7, 29, 51, 30, 4
   6164            )
   6165        );
   6166        alignGroup.addChild(
   6167            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6168                'cube_rgba4_51_8', '', gl.RGBA4, 64, 7, 29, 51, 30, 8
   6169            )
   6170        );
   6171        alignGroup.addChild(
   6172            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6173                'cube_rgb8_39_1', '', gl.RGB8, 64, 11, 8, 39, 43, 1
   6174            )
   6175        );
   6176        alignGroup.addChild(
   6177            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6178                'cube_rgb8_39_2', '', gl.RGB8, 64, 11, 8, 39, 43, 2
   6179            )
   6180        );
   6181        alignGroup.addChild(
   6182            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6183                'cube_rgb8_39_4', '', gl.RGB8, 64, 11, 8, 39, 43, 4
   6184            )
   6185        );
   6186        alignGroup.addChild(
   6187            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6188                'cube_rgb8_39_8', '', gl.RGB8, 64, 11, 8, 39, 43, 8
   6189            )
   6190        );
   6191        alignGroup.addChild(
   6192            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6193                'cube_rgba8_47_1', '', gl.RGBA8, 64, 10, 1, 47, 27, 1
   6194            )
   6195        );
   6196        alignGroup.addChild(
   6197            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6198                'cube_rgba8_47_2', '', gl.RGBA8, 64, 10, 1, 47, 27, 2
   6199            )
   6200        );
   6201        alignGroup.addChild(
   6202            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6203                'cube_rgba8_47_4', '', gl.RGBA8, 64, 10, 1, 47, 27, 4
   6204            )
   6205        );
   6206        alignGroup.addChild(
   6207            es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
   6208                'cube_rgba8_47_8', '', gl.RGBA8, 64, 10, 1, 47, 27, 8
   6209            )
   6210        );
   6211 
   6212        // glTexSubImage2D() pixel transfer mode cases.
   6213        paramGroup = new tcuTestCase.DeqpTest(
   6214            'texsubimage2d_unpack_params',
   6215            'glTexSubImage2D() pixel transfer mode cases'
   6216        );
   6217        this.addChild(paramGroup);
   6218 
   6219        cases = [{
   6220                name: 'rgb8_alignment', format: gl.RGB8, width: 54,
   6221                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6222                rowLength: 0, skipRows: 0, skipPixels: 0, alignment: 2
   6223            }, {
   6224                name: 'rgb8_row_length', format: gl.RGB8, width: 54,
   6225                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6226                rowLength: 50, skipRows: 0, skipPixels: 0, alignment: 4
   6227            }, {
   6228                name: 'rgb8_skip_rows', format: gl.RGB8, width: 54,
   6229                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6230                rowLength: 0, skipRows: 3, skipPixels: 0, alignment: 4
   6231            }, {
   6232                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 54,
   6233                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6234                rowLength: 36, skipRows: 0, skipPixels: 5, alignment: 4
   6235            }, {
   6236                name: 'r8_complex1', format: gl.R8, width: 54,
   6237                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6238                rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 1
   6239            }, {
   6240                name: 'r8_complex2', format: gl.R8, width: 54,
   6241                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6242                rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 2
   6243            }, {
   6244                name: 'r8_complex3', format: gl.R8, width: 54,
   6245                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6246                rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 4
   6247            }, {
   6248                name: 'r8_complex4', format: gl.R8, width: 54,
   6249                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6250                rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 8
   6251            }, {
   6252                name: 'rgba8_complex1', format: gl.RGBA8, width: 92,
   6253                height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
   6254                rowLength: 69, skipRows: 0, skipPixels: 0, alignment: 8
   6255            }, {
   6256                name: 'rgba8_complex2', format: gl.RGBA8, width: 92,
   6257                height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
   6258                rowLength: 69, skipRows: 0, skipPixels: 7, alignment: 8
   6259            }, {
   6260                name: 'rgba8_complex3', format: gl.RGBA8, width: 92,
   6261                height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
   6262                rowLength: 69, skipRows: 3, skipPixels: 0, alignment: 8
   6263            }, {
   6264                name: 'rgba8_complex4', format: gl.RGBA8, width: 92,
   6265                height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
   6266                rowLength: 69, skipRows: 3, skipPixels: 7, alignment: 8
   6267            }, {
   6268                name: 'rgba32f_complex', format: gl.RGBA32F, width: 92,
   6269                height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
   6270                rowLength: 69, skipRows: 3, skipPixels: 7, alignment: 8
   6271            }
   6272        ];
   6273 
   6274        for (var ndx = 0; ndx < cases.length; ndx++)
   6275            paramGroup.addChild(
   6276                new es3fTextureSpecificationTests.TexSubImage2DParamsCase(
   6277                    cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
   6278                    cases[ndx].height, cases[ndx].subX, cases[ndx].subY,
   6279                    cases[ndx].subW, cases[ndx].subH, cases[ndx].rowLength,
   6280                    cases[ndx].skipRows, cases[ndx].skipPixels,
   6281                    cases[ndx].alignment
   6282                )
   6283            );
   6284 
   6285        // glTexSubImage2D() PBO cases.
   6286        splitPboTex2D = 2;
   6287        splitPboTexCube = 5;
   6288        pboGroup2D = [];
   6289        for (var ii = 0; ii < splitPboTex2D; ++ii) {
   6290            pboGroup2D.push(new tcuTestCase.DeqpTest(
   6291                'texsubimage2d_pbo',
   6292                'glTexSubImage2D() pixel buffer object tests'
   6293            ));
   6294            this.addChild(pboGroup2D[ii]);
   6295        }
   6296        pboGroupCube = [];
   6297        for (var ii = 0; ii < splitPboTexCube; ++ii) {
   6298            pboGroupCube.push(new tcuTestCase.DeqpTest(
   6299                'texsubimage2d_pbo',
   6300                'glTexSubImage2D() pixel buffer object tests'
   6301            ));
   6302            this.addChild(pboGroupCube[ii]);
   6303        }
   6304 
   6305        for (var ndx = 0; ndx < colorFormats.length; ndx++) {
   6306            pboGroup2D[ndx % splitPboTex2D].addChild(
   6307                new es3fTextureSpecificationTests.TexSubImage2DBufferCase(
   6308                    colorFormats[ndx].name + '_2d', '',
   6309                    colorFormats[ndx].internalFormat,
   6310                    54, // Width
   6311                    60, // Height
   6312                    11, // Sub X
   6313                    7, // Sub Y
   6314                    31, // Sub W
   6315                    30, // Sub H
   6316                    0, // Row len
   6317                    0, // Skip rows
   6318                    0, // Skip pixels
   6319                    4, // Alignment
   6320                    0 /* offset */
   6321                )
   6322            );
   6323            pboGroupCube[ndx % splitPboTexCube].addChild(
   6324                new es3fTextureSpecificationTests.TexSubImageCubeBufferCase(
   6325                    colorFormats[ndx].name + '_cube', '',
   6326                    colorFormats[ndx].internalFormat,
   6327                    64, // Size
   6328                    11, // Sub X
   6329                    7, // Sub Y
   6330                    31, // Sub W
   6331                    30, // Sub H
   6332                    0, // Row len
   6333                    0, // Skip rows
   6334                    0, // Skip pixels
   6335                    4, // Alignment
   6336                    0 /* offset */
   6337                )
   6338            );
   6339        }
   6340 
   6341        pboGroupParams = new tcuTestCase.DeqpTest(
   6342            'texsubimage2d_pbo',
   6343            'glTexSubImage2D() pixel buffer object tests'
   6344        );
   6345        this.addChild(pboGroupParams);
   6346        /** @type {Array<{name: string, format: number, width: number,
   6347         * height: number, subX: number, subY: number,
   6348         * subW: number, subH: number, rowLength: number, skipRows: number,
   6349         * skipPixels: number, alignment: number, offset: number}>}
   6350         */
   6351        var paramCases = [{
   6352                name: 'rgb8_offset', format: gl.RGB8, width: 54,
   6353                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6354                rowLength: 0, skipRows: 0, skipPixels: 0,
   6355                alignment: 4, offset: 67
   6356            }, {
   6357                name: 'rgb8_alignment', format: gl.RGB8, width: 54,
   6358                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6359                rowLength: 0, skipRows: 0, skipPixels: 0,
   6360                alignment: 2, offset: 0
   6361            }, {
   6362                name: 'rgb8_row_length', format: gl.RGB8, width: 54,
   6363                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6364                rowLength: 50, skipRows: 0, skipPixels: 0,
   6365                alignment: 4, offset: 0
   6366            }, {
   6367                name: 'rgb8_skip_rows', format: gl.RGB8, width: 54,
   6368                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6369                rowLength: 0, skipRows: 3, skipPixels: 0,
   6370                alignment: 4, offset: 0
   6371            }, {
   6372                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 54,
   6373                height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
   6374                rowLength: 36, skipRows: 0, skipPixels: 5,
   6375                alignment: 4, offset: 0
   6376            }
   6377        ];
   6378 
   6379        for (var ndx = 0; ndx < paramCases.length; ndx++) {
   6380            pboGroupParams.addChild(
   6381                new es3fTextureSpecificationTests.TexSubImage2DBufferCase(
   6382                    paramCases[ndx].name + '_2d', '',
   6383                    paramCases[ndx].format,
   6384                    paramCases[ndx].width,
   6385                    paramCases[ndx].height,
   6386                    paramCases[ndx].subX,
   6387                    paramCases[ndx].subY,
   6388                    paramCases[ndx].subW,
   6389                    paramCases[ndx].subH,
   6390                    paramCases[ndx].rowLength,
   6391                    paramCases[ndx].skipRows,
   6392                    paramCases[ndx].skipPixels,
   6393                    paramCases[ndx].alignment,
   6394                    paramCases[ndx].offset));
   6395            pboGroupParams.addChild(
   6396                new es3fTextureSpecificationTests.TexSubImageCubeBufferCase(
   6397                    paramCases[ndx].name + '_cube', '',
   6398                    paramCases[ndx].format,
   6399                    paramCases[ndx].width,
   6400                    paramCases[ndx].subX,
   6401                    paramCases[ndx].subY,
   6402                    paramCases[ndx].subW,
   6403                    paramCases[ndx].subH,
   6404                    paramCases[ndx].rowLength,
   6405                    paramCases[ndx].skipRows,
   6406                    paramCases[ndx].skipPixels,
   6407                    paramCases[ndx].alignment,
   6408                    paramCases[ndx].offset
   6409                )
   6410            );
   6411        }
   6412 
   6413        // glTexSubImage2D() depth cases.
   6414        shadow2dGroup = new tcuTestCase.DeqpTest(
   6415            'texsubimage2d_depth',
   6416            'glTexSubImage2D() with depth or depth/stencil format'
   6417        );
   6418        this.addChild(shadow2dGroup);
   6419 
   6420        for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
   6421            // WebGL 2 specific constraint.
   6422            if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
   6423                continue;
   6424            tex2DWidth = 64;
   6425            tex2DHeight = 32;
   6426 
   6427            shadow2dGroup.addChild(
   6428                new es3fTextureSpecificationTests.TexSubImage2DDepthCase(
   6429                    depthStencilFormats[ndx].name, '',
   6430                    depthStencilFormats[ndx].internalFormat,
   6431                    tex2DWidth, tex2DHeight
   6432                )
   6433            );
   6434        }
   6435 
   6436        // Basic glCopyTexImage2D() cases
   6437        /** @type {tcuTestCase.DeqpTest} */
   6438        var copyTexImageGroup = new tcuTestCase.DeqpTest(
   6439            'basic_copyteximage2d', 'Basic glCopyTexImage2D() usage'
   6440        );
   6441        this.addChild(copyTexImageGroup);
   6442 
   6443        copyTexImageGroup.addChild(
   6444            new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
   6445                '2d_alpha', '', gl.ALPHA, 128, 64
   6446            )
   6447        );
   6448        copyTexImageGroup.addChild(
   6449            new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
   6450                '2d_luminance', '', gl.LUMINANCE, 128, 64
   6451            )
   6452        );
   6453        copyTexImageGroup.addChild(
   6454            new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
   6455                '2d_luminance_alpha', '', gl.LUMINANCE_ALPHA, 128, 64
   6456            )
   6457        );
   6458        copyTexImageGroup.addChild(
   6459            new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
   6460                '2d_rgb', '', gl.RGB, 128, 64
   6461            )
   6462        );
   6463        copyTexImageGroup.addChild(
   6464            new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
   6465                '2d_rgba', '', gl.RGBA, 128, 64
   6466            )
   6467        );
   6468 
   6469        copyTexImageGroup.addChild(
   6470            new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
   6471                'cube_alpha', '', gl.ALPHA, 64
   6472            )
   6473        );
   6474        copyTexImageGroup.addChild(
   6475            new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
   6476                'cube_luminance', '', gl.LUMINANCE, 64
   6477            )
   6478        );
   6479        copyTexImageGroup.addChild(
   6480            new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
   6481                'cube_luminance_alpha', '', gl.LUMINANCE_ALPHA, 64
   6482            )
   6483        );
   6484        copyTexImageGroup.addChild(
   6485            new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
   6486                'cube_rgb', '', gl.RGB, 64
   6487            )
   6488        );
   6489        copyTexImageGroup.addChild(
   6490            new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
   6491                'cube_rgba', '', gl.RGBA, 64
   6492            )
   6493        );
   6494 
   6495        // Basic glCopyTexSubImage2D() cases
   6496        /** @type {tcuTestCase.DeqpTest} */
   6497        var copyTexSubImageGroup = new tcuTestCase.DeqpTest(
   6498            'basic_copytexsubimage2d', 'Basic glCopyTexSubImage2D() usage'
   6499        );
   6500        this.addChild(copyTexSubImageGroup);
   6501 
   6502        copyTexSubImageGroup.addChild(
   6503            new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
   6504                '2d_alpha', '', gl.ALPHA, gl.UNSIGNED_BYTE, 128, 64
   6505            )
   6506        );
   6507        copyTexSubImageGroup.addChild(
   6508            new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
   6509                '2d_luminance', '', gl.LUMINANCE, gl.UNSIGNED_BYTE, 128, 64
   6510            )
   6511        );
   6512        copyTexSubImageGroup.addChild(
   6513            new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
   6514                '2d_luminance_alpha', '', gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, 128, 64
   6515            )
   6516        );
   6517        copyTexSubImageGroup.addChild(
   6518            new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
   6519                '2d_rgb', '', gl.RGB, gl.UNSIGNED_BYTE, 128, 64
   6520            )
   6521        );
   6522        copyTexSubImageGroup.addChild(
   6523            new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
   6524                '2d_rgba', '', gl.RGBA, gl.UNSIGNED_BYTE, 128, 64
   6525            )
   6526        );
   6527 
   6528        copyTexSubImageGroup.addChild(
   6529            new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
   6530                'cube_alpha', '', gl.ALPHA, gl.UNSIGNED_BYTE, 64
   6531            )
   6532        );
   6533        copyTexSubImageGroup.addChild(
   6534            new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
   6535                'cube_luminance', '', gl.LUMINANCE, gl.UNSIGNED_BYTE, 64
   6536            )
   6537        );
   6538        copyTexSubImageGroup.addChild(
   6539            new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
   6540                'cube_luminance_alpha', '', gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, 64
   6541            )
   6542        );
   6543        copyTexSubImageGroup.addChild(
   6544            new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
   6545                'cube_rgb', '', gl.RGB, gl.UNSIGNED_BYTE, 64
   6546            )
   6547        );
   6548        copyTexSubImageGroup.addChild(
   6549            new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
   6550                'cube_rgba', '', gl.RGBA, gl.UNSIGNED_BYTE, 64
   6551            )
   6552        );
   6553 
   6554        // Basic TexImage3D usage.
   6555        var splitBasicTex2DArray = 3, splitBasicTex3D = 5;
   6556        /** @type {Array<{tcuTestCase.DeqpTest}>} */
   6557        var basicTexImageGroup2DArray = [];
   6558        for (var ii = 0; ii < splitBasicTex2DArray; ++ii) {
   6559            basicTexImageGroup2DArray.push(
   6560                new tcuTestCase.DeqpTest('basic_teximage3d', 'Basic glTexImage3D() usage')
   6561            );
   6562            this.addChild(basicTexImageGroup2DArray[ii]);
   6563        }
   6564        /** @type {Array<{tcuTestCase.DeqpTest}>} */
   6565        var basicTexImageGroup3D = [];
   6566        for (var ii = 0; ii < splitBasicTex3D; ++ii) {
   6567            basicTexImageGroup3D.push(
   6568                new tcuTestCase.DeqpTest('basic_teximage3d', 'Basic glTexImage3D() usage')
   6569            );
   6570            this.addChild(basicTexImageGroup3D[ii]);
   6571        }
   6572        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   6573            fmtName = colorFormats[formatNdx].name;
   6574            format = colorFormats[formatNdx].internalFormat;
   6575            /** @type {number} */ var tex2DArrayWidth = 57;
   6576            /** @type {number} */ var tex2DArrayHeight = 44;
   6577            /** @type {number} */ var tex2DArrayLevels = 5;
   6578            /** @type {number} */ var tex3DWidth = 63;
   6579            /** @type {number} */ var tex3DHeight = 29;
   6580            /** @type {number} */ var tex3DDepth = 11;
   6581 
   6582            basicTexImageGroup2DArray[formatNdx % splitBasicTex2DArray].addChild(
   6583                new es3fTextureSpecificationTests.BasicTexImage2DArrayCase(
   6584                    fmtName + '_2d_array', '', format,
   6585                    tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels
   6586                )
   6587            );
   6588            basicTexImageGroup3D[formatNdx % splitBasicTex3D].addChild(
   6589                new es3fTextureSpecificationTests.BasicTexImage3DCase(
   6590                    fmtName + '_3d', '', format,
   6591                    tex3DWidth, tex3DHeight, tex3DDepth
   6592                )
   6593            );
   6594        }
   6595 
   6596        // glTexImage3D() unpack params cases.
   6597        paramGroup = new tcuTestCase.DeqpTest(
   6598            'teximage3d_unpack_params', 'glTexImage3D() unpack parameters'
   6599        );
   6600        this.addChild(paramGroup);
   6601 
   6602        cases = [{
   6603                name: 'rgb8_image_height', format: gl.RGB8, width: 23,
   6604                height: 19, depth: 8, imageHeight: 26, rowLength: 0,
   6605                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
   6606            }, {
   6607                name: 'rgb8_row_length', format: gl.RGB8, width: 23,
   6608                height: 19, depth: 8, imageHeight: 0, rowLength: 27,
   6609                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
   6610            }, {
   6611                name: 'rgb8_skip_images', format: gl.RGB8, width: 23,
   6612                height: 19, depth: 8, imageHeight: 0, rowLength: 0,
   6613                skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4
   6614            }, {
   6615                name: 'rgb8_skip_rows', format: gl.RGB8, width: 23,
   6616                height: 19, depth: 8, imageHeight: 22, rowLength: 0,
   6617                skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4
   6618            }, {
   6619                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 23,
   6620                height: 19, depth: 8, imageHeight: 0, rowLength: 25,
   6621                skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4
   6622            }, {
   6623                name: 'r8_complex1', format: gl.R8, width: 13,
   6624                height: 17, depth: 11, imageHeight: 23, rowLength: 15,
   6625                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 1
   6626            }, {
   6627                name: 'r8_complex2', format: gl.R8, width: 13,
   6628                height: 17, depth: 11, imageHeight: 23, rowLength: 15,
   6629                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 2
   6630            }, {
   6631                name: 'r8_complex3', format: gl.R8, width: 13,
   6632                height: 17, depth: 11, imageHeight: 23, rowLength: 15,
   6633                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 4
   6634            }, {
   6635                name: 'r8_complex4', format: gl.R8, width: 13,
   6636                height: 17, depth: 11, imageHeight: 23, rowLength: 15,
   6637                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 8
   6638            }, {
   6639                name: 'rgba8_complex1', format: gl.RGBA8, width: 11,
   6640                height: 20, depth: 8, imageHeight: 25, rowLength: 14,
   6641                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 8
   6642            }, {
   6643                name: 'rgba8_complex2', format: gl.RGBA8, width: 11,
   6644                height: 20, depth: 8, imageHeight: 25, rowLength: 14,
   6645                skipImages: 0, skipRows: 2, skipPixels: 0, alignment: 8
   6646            }, {
   6647                name: 'rgba8_complex3', format: gl.RGBA8, width: 11,
   6648                height: 20, depth: 8, imageHeight: 25, rowLength: 14,
   6649                skipImages: 0, skipRows: 0, skipPixels: 3, alignment: 8
   6650            }, {
   6651                name: 'rgba8_complex4', format: gl.RGBA8, width: 11,
   6652                height: 20, depth: 8, imageHeight: 25, rowLength: 14,
   6653                skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
   6654            }, {
   6655                name: 'rgba32f_complex', format: gl.RGBA32F, width: 11,
   6656                height: 20, depth: 8, imageHeight: 25, rowLength: 14,
   6657                skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
   6658             }
   6659        ];
   6660 
   6661        for (var ndx = 0; ndx < cases.length; ndx++)
   6662            paramGroup.addChild(
   6663                new es3fTextureSpecificationTests.TexImage3DParamsCase(
   6664                    cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
   6665                    cases[ndx].height, cases[ndx].depth, cases[ndx].imageHeight,
   6666                    cases[ndx].rowLength, cases[ndx].skipImages,
   6667                    cases[ndx].skipRows, cases[ndx].skipPixels,
   6668                    cases[ndx].alignment
   6669                )
   6670            );
   6671 
   6672        // glTexImage3D() pbo cases.
   6673        var splitTex2DArray = 2, splitTex3D = 2;
   6674        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup2DArray = [];
   6675        for (var ii = 0; ii < splitTex2DArray; ++ii) {
   6676            pboGroup2DArray.push(
   6677                new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO')
   6678            );
   6679            this.addChild(pboGroup2DArray[ii]);
   6680        }
   6681        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup3D = [];
   6682        for (var ii = 0; ii < splitTex3D; ++ii) {
   6683            pboGroup3D.push(
   6684                new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO')
   6685            );
   6686            this.addChild(pboGroup3D[ii]);
   6687        }
   6688 
   6689        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   6690            fmtName = colorFormats[formatNdx].name;
   6691            format = colorFormats[formatNdx].internalFormat;
   6692            tex3DWidth = 11;
   6693            tex3DHeight = 20;
   6694            tex3DDepth = 8;
   6695 
   6696            pboGroup2DArray[formatNdx % splitTex2DArray].addChild(
   6697                new es3fTextureSpecificationTests.TexImage2DArrayBufferCase(
   6698                    fmtName + '_2d_array', '', format, tex3DWidth, tex3DHeight,
   6699                    tex3DDepth, 0, 0, 0, 0, 0, 4, 0
   6700                )
   6701            );
   6702            pboGroup3D[formatNdx % splitTex3D].addChild(
   6703                new es3fTextureSpecificationTests.TexImage3DBufferCase(
   6704                    fmtName + '_3d', '', format, tex3DWidth, tex3DHeight,
   6705                    tex3DDepth, 0, 0, 0, 0, 0, 4, 0
   6706                )
   6707            );
   6708        }
   6709 
   6710        // Parameter cases
   6711        parameterCases = [{
   6712                name: 'rgb8_offset', format: gl.RGB8, width: 23,
   6713                height: 19, depth: 8, imageHeight: 0, rowLength: 0,
   6714                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 1,
   6715                offset: 67
   6716            }, {
   6717                name: 'rgb8_alignment', format: gl.RGB8, width: 23,
   6718                height: 19, depth: 8, imageHeight: 0, rowLength: 0,
   6719                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 2,
   6720                offset: 0
   6721            }, {
   6722                name: 'rgb8_image_height', format: gl.RGB8, width: 23,
   6723                height: 19, depth: 8, imageHeight: 26, rowLength: 0,
   6724                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4,
   6725                offset: 0
   6726            }, {
   6727                name: 'rgb8_row_length', format: gl.RGB8, width: 23,
   6728                height: 19, depth: 8, imageHeight: 0, rowLength: 27,
   6729                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4,
   6730                offset: 0
   6731            }, {
   6732                name: 'rgb8_skip_images', format: gl.RGB8, width: 23,
   6733                height: 19, depth: 8, imageHeight: 0, rowLength: 0,
   6734                skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4,
   6735                offset: 0
   6736            }, {
   6737                name: 'rgb8_skip_rows', format: gl.RGB8, width: 23,
   6738                height: 19, depth: 8, imageHeight: 22, rowLength: 0,
   6739                skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4,
   6740                offset: 0
   6741            }, {
   6742                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 23,
   6743                height: 19, depth: 8, imageHeight: 0, rowLength: 25,
   6744                skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4,
   6745                offset: 0
   6746            }
   6747        ];
   6748 
   6749        pboGroupParams = new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO');
   6750        this.addChild(pboGroupParams);
   6751        for (var ndx = 0; ndx < parameterCases.length; ndx++) {
   6752            pboGroupParams.addChild(
   6753                new es3fTextureSpecificationTests.TexImage2DArrayBufferCase(
   6754                    parameterCases[ndx].name + '_2d_array', '',
   6755                    parameterCases[ndx].format, parameterCases[ndx].width,
   6756                    parameterCases[ndx].height, parameterCases[ndx].depth,
   6757                    parameterCases[ndx].imageHeight,
   6758                    parameterCases[ndx].rowLength,
   6759                    parameterCases[ndx].skipImages,
   6760                    parameterCases[ndx].skipRows,
   6761                    parameterCases[ndx].skipPixels,
   6762                    parameterCases[ndx].alignment, parameterCases[ndx].offset
   6763                )
   6764            );
   6765            pboGroupParams.addChild(
   6766                new es3fTextureSpecificationTests.TexImage3DBufferCase(
   6767                    parameterCases[ndx].name + '_3d', '',
   6768                    parameterCases[ndx].format, parameterCases[ndx].width,
   6769                    parameterCases[ndx].height, parameterCases[ndx].depth,
   6770                    parameterCases[ndx].imageHeight,
   6771                    parameterCases[ndx].rowLength,
   6772                    parameterCases[ndx].skipImages,
   6773                    parameterCases[ndx].skipRows,
   6774                    parameterCases[ndx].skipPixels,
   6775                    parameterCases[ndx].alignment, parameterCases[ndx].offset
   6776                )
   6777            );
   6778        }
   6779 
   6780        // glTexImage3D() depth cases.
   6781        /** @type {tcuTestCase.DeqpTest} */
   6782        var shadow3dGroup = new tcuTestCase.DeqpTest(
   6783            'teximage3d_depth',
   6784            'glTexImage3D() with depth or depth/stencil format'
   6785        );
   6786        this.addChild(shadow3dGroup);
   6787 
   6788        for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
   6789            // WebGL 2 specific constraint.
   6790            if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
   6791                continue;
   6792            tex3DWidth = 32;
   6793            tex3DHeight = 64;
   6794            tex3DDepth = 8;
   6795 
   6796            shadow3dGroup.addChild(
   6797                new es3fTextureSpecificationTests.TexImage2DArrayDepthCase(
   6798                    depthStencilFormats[ndx].name + '_2d_array', '',
   6799                    depthStencilFormats[ndx].internalFormat,
   6800                    tex3DWidth, tex3DHeight, tex3DDepth
   6801                )
   6802            );
   6803        }
   6804 
   6805        // glTexImage3D() depth cases with pbo.
   6806        shadow3dGroup = new tcuTestCase.DeqpTest(
   6807            'teximage3d_depth_pbo',
   6808            'glTexImage3D() with depth or depth/stencil format with pbo'
   6809        );
   6810        this.addChild(shadow3dGroup);
   6811 
   6812        for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
   6813            tex3DWidth = 32;
   6814            tex3DHeight = 64;
   6815            tex3DDepth = 8;
   6816 
   6817            shadow3dGroup.addChild(
   6818                new es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase(
   6819                    depthStencilFormats[ndx].name + '_2d_array', '',
   6820                    depthStencilFormats[ndx].internalFormat,
   6821                    tex3DWidth, tex3DHeight, tex3DDepth
   6822                )
   6823            );
   6824        }
   6825 
   6826        // Basic TexSubImage3D usage.
   6827        splitTex3D = 5;
   6828        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var basicTexSubImageGroup = [];
   6829        for (var ii = 0; ii < splitTex3D; ++ii) {
   6830            basicTexSubImageGroup.push(
   6831                new tcuTestCase.DeqpTest('basic_texsubimage3d', 'Basic glTexSubImage3D() usage')
   6832            );
   6833            this.addChild(basicTexSubImageGroup[ii]);
   6834        }
   6835 
   6836        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   6837            fmtName = colorFormats[formatNdx].name;
   6838            format = colorFormats[formatNdx].internalFormat;
   6839            tex3DWidth = 32;
   6840            tex3DHeight = 64;
   6841            tex3DDepth = 8;
   6842 
   6843            basicTexSubImageGroup[formatNdx % splitTex3D].addChild(
   6844                new es3fTextureSpecificationTests.BasicTexSubImage3DCase(
   6845                    fmtName + '_3d', '', format,
   6846                    tex3DWidth, tex3DHeight, tex3DDepth
   6847                )
   6848            );
   6849        }
   6850 
   6851        // glTexSubImage3D() unpack params cases.
   6852        paramGroup = new tcuTestCase.DeqpTest(
   6853            'texsubimage3d_unpack_params', 'glTexSubImage3D() unpack parameters'
   6854        );
   6855        this.addChild(paramGroup);
   6856 
   6857        /** @type {Array<{name: string, format: number, width: number,
   6858         * height: number, depth: number, subX: number, subY: number,
   6859         * subZ: number, subW: number, subH: number, subD: number,
   6860         * imageHeight: number, rowLength: number, skipImages: number,
   6861         * skipRows: number, skipPixels: number, alignment: number}>}
   6862         */
   6863        var casesSubImage3D = [{
   6864                name: 'rgb8_image_height', format: gl.RGB8, width: 26,
   6865                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   6866                subH: 19, subD: 8, imageHeight: 26, rowLength: 0,
   6867                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
   6868            }, {
   6869                name: 'rgb8_row_length', format: gl.RGB8, width: 26,
   6870                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   6871                subH: 19, subD: 8, imageHeight: 0, rowLength: 27,
   6872                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
   6873            }, {
   6874                name: 'rgb8_skip_images', format: gl.RGB8, width: 26,
   6875                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   6876                subH: 19, subD: 8, imageHeight: 0, rowLength: 0,
   6877                skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4
   6878            }, {
   6879                name: 'rgb8_skip_rows', format: gl.RGB8, width: 26,
   6880                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   6881                subH: 19, subD: 8, imageHeight: 22, rowLength: 0,
   6882                skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4
   6883            }, {
   6884                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 26,
   6885                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   6886                subH: 19, subD: 8, imageHeight: 0, rowLength: 25,
   6887                skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4
   6888            }, {
   6889                name: 'r8_complex1', format: gl.R8, width: 15,
   6890                height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
   6891                subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
   6892                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 1
   6893            }, {
   6894                name: 'r8_complex2', format: gl.R8, width: 15,
   6895                height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
   6896                subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
   6897                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 2
   6898            }, {
   6899                name: 'r8_complex3', format: gl.R8, width: 15,
   6900                height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
   6901                subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
   6902                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 4
   6903            }, {
   6904                name: 'r8_complex4', format: gl.R8, width: 15,
   6905                height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
   6906                subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
   6907                skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 8
   6908            }, {
   6909                name: 'rgba8_complex1', format: gl.RGBA8, width: 15,
   6910                height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
   6911                subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
   6912                skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 8
   6913            }, {
   6914                name: 'rgba8_complex2', format: gl.RGBA8, width: 15,
   6915                height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
   6916                subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
   6917                skipImages: 0, skipRows: 2, skipPixels: 0, alignment: 8
   6918            }, {
   6919                name: 'rgba8_complex3', format: gl.RGBA8, width: 15,
   6920                height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
   6921                subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
   6922                skipImages: 0, skipRows: 0, skipPixels: 3, alignment: 8
   6923            }, {
   6924                name: 'rgba8_complex4', format: gl.RGBA8, width: 15,
   6925                height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
   6926                subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
   6927                skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
   6928            }, {
   6929                name: 'rgba32f_complex', format: gl.RGBA32F, width: 15,
   6930                height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
   6931                subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
   6932                skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
   6933            }
   6934        ];
   6935 
   6936        for (var ndx = 0; ndx < casesSubImage3D.length; ndx++)
   6937            paramGroup.addChild(
   6938                new es3fTextureSpecificationTests.TexSubImage3DParamsCase(
   6939                    casesSubImage3D[ndx].name, '', casesSubImage3D[ndx].format,
   6940                    casesSubImage3D[ndx].width, casesSubImage3D[ndx].height, casesSubImage3D[ndx].depth,
   6941                    casesSubImage3D[ndx].subX, casesSubImage3D[ndx].subY, casesSubImage3D[ndx].subZ,
   6942                    casesSubImage3D[ndx].subW, casesSubImage3D[ndx].subH, casesSubImage3D[ndx].subD,
   6943                    casesSubImage3D[ndx].imageHeight, casesSubImage3D[ndx].rowLength,
   6944                    casesSubImage3D[ndx].skipImages, casesSubImage3D[ndx].skipRows,
   6945                    casesSubImage3D[ndx].skipPixels, casesSubImage3D[ndx].alignment
   6946                )
   6947            );
   6948 
   6949        // glTexSubImage3D() PBO cases.
   6950        splitTex2DArray = 2;
   6951        pboGroup2DArray = [];
   6952        for (var ii = 0; ii < splitTex2DArray; ++ii) {
   6953            pboGroup2DArray.push(
   6954                new tcuTestCase.DeqpTest('texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests')
   6955            );
   6956            this.addChild(pboGroup2DArray[ii]);
   6957        }
   6958 
   6959        splitTex3D = 2;
   6960        pboGroup3D = [];
   6961        for (var ii = 0; ii < splitTex3D; ++ii) {
   6962            pboGroup3D.push(
   6963                new tcuTestCase.DeqpTest('texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests')
   6964            );
   6965            this.addChild(pboGroup3D[ii]);
   6966        }
   6967 
   6968        for (var ndx = 0; ndx < colorFormats.length; ndx++) {
   6969            pboGroup2DArray[ndx % splitTex2DArray].addChild(
   6970                new es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase(
   6971                    colorFormats[ndx].name + '_2d_array', '',
   6972                    colorFormats[ndx].internalFormat,
   6973                    26, // Width
   6974                    25, // Height
   6975                    10, // Depth
   6976                    1, // Sub X
   6977                    2, // Sub Y
   6978                    0, // Sub Z
   6979                    23, // Sub W
   6980                    19, // Sub H
   6981                    8, // Sub D
   6982                    0, // Image height
   6983                    0, // Row length
   6984                    0, // Skip images
   6985                    0, // Skip rows
   6986                    0, // Skip pixels
   6987                    4, // Alignment
   6988                    0 // offset
   6989                )
   6990            );
   6991            pboGroup3D[ndx % splitTex3D].addChild(
   6992                new es3fTextureSpecificationTests.TexSubImage3DBufferCase(
   6993                    colorFormats[ndx].name + '_3d', '',
   6994                    colorFormats[ndx].internalFormat,
   6995                    26, // Width
   6996                    25, // Height
   6997                    10, // Depth
   6998                    1, // Sub X
   6999                    2, // Sub Y
   7000                    0, // Sub Z
   7001                    23, // Sub W
   7002                    19, // Sub H
   7003                    8, // Sub D
   7004                    0, // Image height
   7005                    0, // Row length
   7006                    0, // Skip images
   7007                    0, // Skip rows
   7008                    0, // Skip pixels
   7009                    4, // Alignment
   7010                    0 // offset
   7011                )
   7012            );
   7013        }
   7014 
   7015        paramCases = [{
   7016                name: 'rgb8_offset', format: gl.RGB8, width: 26,
   7017                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   7018                subH: 19, subD: 8, imageHeight: 0, rowLength: 0, skipImages: 0,
   7019                skipRows: 0, skipPixels: 0, alignment: 4, offset: 67
   7020            }, {
   7021                name: 'rgb8_image_height', format: gl.RGB8, width: 26,
   7022                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   7023                subH: 19, subD: 8, imageHeight: 26, rowLength: 0, skipImages: 0,
   7024                skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
   7025            }, {
   7026                name: 'rgb8_row_length', format: gl.RGB8, width: 26,
   7027                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   7028                subH: 19, subD: 8, imageHeight: 0, rowLength: 27, skipImages: 0,
   7029                skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
   7030            }, {
   7031                name: 'rgb8_skip_images', format: gl.RGB8, width: 26,
   7032                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   7033                subH: 19, subD: 8, imageHeight: 0, rowLength: 0, skipImages: 3,
   7034                skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
   7035            }, {
   7036                name: 'rgb8_skip_rows', format: gl.RGB8, width: 26,
   7037                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   7038                subH: 19, subD: 8, imageHeight: 22, rowLength: 0, skipImages: 0,
   7039                skipRows: 3, skipPixels: 0, alignment: 4, offset: 0
   7040            }, {
   7041                name: 'rgb8_skip_pixels', format: gl.RGB8, width: 26,
   7042                height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
   7043                subH: 19, subD: 8, imageHeight: 0, rowLength: 25, skipImages: 0,
   7044                skipRows: 0, skipPixels: 2, alignment: 4, offset: 0
   7045            }
   7046        ];
   7047 
   7048        pboGroupParams = new tcuTestCase.DeqpTest(
   7049            'texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests'
   7050        );
   7051        this.addChild(pboGroupParams);
   7052 
   7053        for (var ndx = 0; ndx < paramCases.length; ndx++) {
   7054            pboGroupParams.addChild(
   7055                new es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase(
   7056                    paramCases[ndx].name + '_2d_array', '',
   7057                    paramCases[ndx].format, paramCases[ndx].width,
   7058                    paramCases[ndx].height, paramCases[ndx].depth,
   7059                    paramCases[ndx].subX, paramCases[ndx].subY,
   7060                    paramCases[ndx].subZ, paramCases[ndx].subW,
   7061                    paramCases[ndx].subH, paramCases[ndx].subD,
   7062                    paramCases[ndx].imageHeight, paramCases[ndx].rowLength,
   7063                    paramCases[ndx].skipImages, paramCases[ndx].skipRows,
   7064                    paramCases[ndx].skipPixels, paramCases[ndx].alignment,
   7065                    paramCases[ndx].offset
   7066                )
   7067            );
   7068            pboGroupParams.addChild(
   7069                new es3fTextureSpecificationTests.TexSubImage3DBufferCase(
   7070                    paramCases[ndx].name + '_3d', '',
   7071                    paramCases[ndx].format, paramCases[ndx].width,
   7072                    paramCases[ndx].height, paramCases[ndx].depth,
   7073                    paramCases[ndx].subX, paramCases[ndx].subY,
   7074                    paramCases[ndx].subZ, paramCases[ndx].subW,
   7075                    paramCases[ndx].subH, paramCases[ndx].subD,
   7076                    paramCases[ndx].imageHeight, paramCases[ndx].rowLength,
   7077                    paramCases[ndx].skipImages, paramCases[ndx].skipRows,
   7078                    paramCases[ndx].skipPixels, paramCases[ndx].alignment,
   7079                    paramCases[ndx].offset
   7080                )
   7081            );
   7082        }
   7083 
   7084        // glTexSubImage3D() depth cases.
   7085        shadow3dGroup = new tcuTestCase.DeqpTest(
   7086            'texsubimage3d_depth',
   7087            'glTexSubImage3D() with depth or depth/stencil format'
   7088        );
   7089        this.addChild(shadow3dGroup);
   7090 
   7091        for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
   7092            // WebGL 2 specific constraint.
   7093            if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
   7094                continue;
   7095            tex2DArrayWidth = 57;
   7096            tex2DArrayHeight = 44;
   7097            tex2DArrayLevels = 5;
   7098 
   7099            shadow3dGroup.addChild(
   7100                new es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase(
   7101                    depthStencilFormats[ndx].name + '_2d_array', '',
   7102                    depthStencilFormats[ndx].internalFormat, tex2DArrayWidth,
   7103                    tex2DArrayHeight, tex2DArrayLevels
   7104                )
   7105            );
   7106        }
   7107 
   7108        // glTexStorage2D() cases.
   7109 
   7110        // Color formats
   7111        var splitStorage2D = 3, splitStorageCube = 5;
   7112        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup2D = [];
   7113        for (var ii = 0; ii < splitStorage2D; ++ii) {
   7114            colorFormatGroup2D.push(
   7115                new tcuTestCase.DeqpTest('texstorage2d.format', 'glTexStorage2D() with all formats')
   7116            );
   7117            this.addChild(colorFormatGroup2D[ii]);
   7118        }
   7119        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroupCube = [];
   7120        for (var ii = 0; ii < splitStorageCube; ++ii) {
   7121            colorFormatGroupCube.push(
   7122                new tcuTestCase.DeqpTest('texstorage2d.format', 'glTexStorage2D() with all formats')
   7123            );
   7124            this.addChild(colorFormatGroupCube[ii]);
   7125        }
   7126 
   7127        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   7128            fmtName = colorFormats[formatNdx].name;
   7129            /** @type {number} */ var internalFormat = colorFormats[formatNdx].internalFormat;
   7130            var tex2DWidth = 117;
   7131            var tex2DHeight = 97;
   7132            var tex2DLevels = es3fTextureSpecificationTests.maxLevelCount(tex2DWidth, tex2DHeight);
   7133            /** @type {number} */ var cubeSize = 57;
   7134            /** @type {number} */
   7135            var cubeLevels = es3fTextureSpecificationTests.maxLevelCount(
   7136                cubeSize, cubeSize
   7137            );
   7138 
   7139            colorFormatGroup2D[formatNdx % splitStorage2D].addChild(
   7140                new es3fTextureSpecificationTests.BasicTexStorage2DCase(
   7141                    fmtName + '_2d', '', internalFormat,
   7142                    tex2DWidth, tex2DHeight, tex2DLevels
   7143                )
   7144            );
   7145            colorFormatGroupCube[formatNdx % splitStorageCube].addChild(
   7146                new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
   7147                    fmtName + '_cube', '', internalFormat, cubeSize, cubeLevels
   7148                )
   7149            );
   7150        }
   7151 
   7152        // Depth / stencil formats.
   7153        /** @type {tcuTestCase.DeqpTest} */
   7154        var storageGroup = new tcuTestCase.DeqpTest(
   7155            'texstorage2d.format',
   7156            'glTexStorage2D() with all formats'
   7157        );
   7158        this.addChild(storageGroup);
   7159 
   7160        for (var formatNdx = 0; formatNdx < depthStencilFormats.length; formatNdx++) {
   7161            fmtName = depthStencilFormats[formatNdx].name;
   7162            internalFormat = depthStencilFormats[formatNdx].internalFormat;
   7163            // WebGL 2 specific constraint.
   7164            if (internalFormat == gl.DEPTH32F_STENCIL8)
   7165                continue;
   7166 
   7167            tex2DWidth = 117;
   7168            tex2DHeight = 97;
   7169            tex2DLevels = es3fTextureSpecificationTests.maxLevelCount(
   7170                tex2DWidth, tex2DHeight
   7171            );
   7172            cubeSize = 57;
   7173            cubeLevels = es3fTextureSpecificationTests.maxLevelCount(
   7174                cubeSize, cubeSize
   7175            );
   7176 
   7177            storageGroup.addChild(
   7178                new es3fTextureSpecificationTests.BasicTexStorage2DCase(
   7179                    fmtName + '_2d', '', internalFormat,
   7180                    tex2DWidth, tex2DHeight, tex2DLevels
   7181                )
   7182            );
   7183            storageGroup.addChild(
   7184                new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
   7185                    fmtName + '_cube', '', internalFormat, cubeSize, cubeLevels
   7186                )
   7187            );
   7188        }
   7189 
   7190        // Sizes.
   7191        storageGroup = new tcuTestCase.DeqpTest(
   7192            'texstorage2d.size',
   7193            'glTexStorage2D() with various sizes'
   7194        );
   7195        this.addChild(storageGroup);
   7196 
   7197        //    W H L
   7198        /** @type {Array<{width: number, height: number, levels: number}>} */
   7199        var tex2DSizes = [{
   7200                width: 1, height: 1, levels: 1
   7201            }, {
   7202                width: 2, height: 2, levels: 2
   7203            }, {
   7204                width: 64, height: 32, levels: 7
   7205            }, {
   7206                width: 32, height: 64, levels: 4
   7207            }, {
   7208                width: 57, height: 63, levels: 1
   7209            }, {
   7210                width: 57, height: 63, levels: 2
   7211            }, {
   7212                width: 57, height: 63, levels: 6
   7213            }
   7214        ];
   7215 
   7216        //    S L
   7217        /** @type {Array<{sizes: number, levels: number}>} */
   7218        var cubeSizes = [{
   7219                sizes: 1, levels: 1
   7220            }, {
   7221                sizes: 2, levels: 2
   7222            }, {
   7223                sizes: 57, levels: 1
   7224            }, {
   7225                sizes: 57, levels: 2
   7226            }, {
   7227                sizes: 57, levels: 6
   7228            }, {
   7229                sizes: 64, levels: 4
   7230            }, {
   7231                sizes: 64, levels: 7
   7232            }
   7233        ];
   7234 
   7235        for (var ndx = 0; ndx < tex2DSizes.length; ndx++) {
   7236            format = gl.RGBA8;
   7237            /** @type {number} */ var width = tex2DSizes[ndx].width;
   7238            /** @type {number} */ var height = tex2DSizes[ndx].height;
   7239            /** @type {number} */ var levels = tex2DSizes[ndx].levels;
   7240            /** @type {string} */
   7241            var name = '2d_' + width + 'x' + height + '_' + levels + '_levels';
   7242 
   7243            storageGroup.addChild(
   7244                new es3fTextureSpecificationTests.BasicTexStorage2DCase(
   7245                    name, '', format, width, height, levels
   7246                )
   7247            );
   7248        }
   7249 
   7250        for (var ndx = 0; ndx < cubeSizes.length; ndx++) {
   7251            format = gl.RGBA8;
   7252            size = cubeSizes[ndx].sizes;
   7253            levels = cubeSizes[ndx].levels;
   7254            name = 'cube_' + size + 'x' + size + '_' + levels + '_levels';
   7255 
   7256            storageGroup.addChild(
   7257                new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
   7258                    name, '', format, size, levels
   7259                )
   7260            );
   7261        }
   7262 
   7263        // glTexStorage3D() cases.
   7264 
   7265        // Color formats.
   7266        var splitStorage2DArray = 3, splitStorage3D = 4;
   7267        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup2DArray = [];
   7268        for (var ii = 0; ii < splitStorage2DArray; ++ii) {
   7269            colorFormatGroup2DArray.push(
   7270                new tcuTestCase.DeqpTest('texstorage3d.format', 'glTexStorage3D() with all formats')
   7271            );
   7272            this.addChild(colorFormatGroup2DArray[ii]);
   7273        }
   7274        /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup3D = [];
   7275        for (var ii = 0; ii < splitStorage3D; ++ii) {
   7276            colorFormatGroup3D.push(
   7277                new tcuTestCase.DeqpTest('texstorage3d.format', 'glTexStorage3D() with all formats')
   7278            );
   7279            this.addChild(colorFormatGroup3D[ii]);
   7280        }
   7281 
   7282        // Color formats.
   7283        for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
   7284            fmtName = colorFormats[formatNdx].name;
   7285            internalFormat = colorFormats[formatNdx].internalFormat;
   7286            tex2DArrayWidth = 57;
   7287            tex2DArrayHeight = 13;
   7288            var tex2DArrayLayers = 7;
   7289            tex2DArrayLevels = es3fTextureSpecificationTests.maxLevelCount(
   7290                tex2DArrayWidth, tex2DArrayHeight
   7291            );
   7292            tex3DWidth = 59;
   7293            tex3DHeight = 37;
   7294            tex3DDepth = 11;
   7295            var tex3DLevels = es3fTextureSpecificationTests.maxLevelCount(
   7296                tex3DWidth, tex3DHeight, tex3DDepth
   7297            );
   7298 
   7299            colorFormatGroup2DArray[formatNdx % splitStorage2DArray].addChild(
   7300                new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
   7301                    fmtName + '_2d_array', '', internalFormat, tex2DArrayWidth,
   7302                    tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels
   7303                )
   7304            );
   7305            colorFormatGroup3D[formatNdx % splitStorage3D].addChild(
   7306                new es3fTextureSpecificationTests.BasicTexStorage3DCase(
   7307                    fmtName + '_3d', '', internalFormat, tex3DWidth,
   7308                    tex3DHeight, tex3DDepth, tex3DLevels
   7309                )
   7310            );
   7311        }
   7312 
   7313        storageGroup = new tcuTestCase.DeqpTest(
   7314            'texstorage3d.format',
   7315            'glTexStorage3D() with all formats'
   7316        );
   7317        this.addChild(storageGroup);
   7318 
   7319        // Depth/stencil formats (only 2D texture array is supported).
   7320        for (var formatNdx = 0;
   7321            formatNdx < depthStencilFormats.length;
   7322            formatNdx++) {
   7323            fmtName = depthStencilFormats[formatNdx].name;
   7324            internalFormat = depthStencilFormats[formatNdx].internalFormat;
   7325            // WebGL 2 specific constraint.
   7326            if (internalFormat == gl.DEPTH32F_STENCIL8)
   7327                continue;
   7328 
   7329            tex2DArrayWidth = 57;
   7330            tex2DArrayHeight = 13;
   7331            tex2DArrayLayers = 7;
   7332            tex2DArrayLevels = es3fTextureSpecificationTests.maxLevelCount(
   7333                tex2DArrayWidth, tex2DArrayHeight
   7334            );
   7335 
   7336            storageGroup.addChild(
   7337                new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
   7338                    fmtName + '_2d_array', '', internalFormat, tex2DArrayWidth,
   7339                    tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels
   7340                )
   7341            );
   7342        }
   7343 
   7344        // Sizes.
   7345        //    W H La Le
   7346        /**
   7347         * @type {Array<{width: number, height: number,
   7348         * layers: number, levels: number}>}
   7349         */
   7350        var tex2DArraySizes = [{
   7351                width: 1, height: 1, layers: 1, levels: 1
   7352            }, {
   7353                width: 2, height: 2, layers: 2, levels: 2
   7354            }, {
   7355                width: 64, height: 32, layers: 3, levels: 7
   7356            }, {
   7357                width: 32, height: 64, layers: 3, levels: 4
   7358            }, {
   7359                width: 57, height: 63, layers: 5, levels: 1
   7360            }, {
   7361                width: 57, height: 63, layers: 5, levels: 2
   7362            }, {
   7363                width: 57, height: 63, layers: 5, levels: 6
   7364            }
   7365        ];
   7366 
   7367        //    W H D L
   7368        /**
   7369         * @type {Array<{width: number, height: number,
   7370         * depth: number, levels: number}>}
   7371         */
   7372        var tex3DSizes = [{
   7373                width: 1, height: 1, depth: 1, levels: 1
   7374            }, {
   7375                width: 2, height: 2, depth: 2, levels: 2
   7376            }, {
   7377                width: 64, height: 32, depth: 16, levels: 7
   7378            }, {
   7379                width: 32, height: 64, depth: 16, levels: 4
   7380            }, {
   7381                width: 32, height: 16, depth: 64, levels: 4
   7382            }, {
   7383                width: 57, height: 63, depth: 11, levels: 1
   7384            }, {
   7385                width: 57, height: 63, depth: 11, levels: 2
   7386            }, {
   7387                width: 57, height: 63, depth: 11, levels: 6
   7388            }
   7389        ];
   7390 
   7391        storageGroup = new tcuTestCase.DeqpTest(
   7392            'texstorage3d.size', 'glTexStorage3D() with various sizes'
   7393        );
   7394        this.addChild(storageGroup);
   7395 
   7396        for (var ndx = 0; ndx < tex2DArraySizes.length; ndx++) {
   7397            format = gl.RGBA8;
   7398            width = tex2DArraySizes[ndx].width;
   7399            height = tex2DArraySizes[ndx].height;
   7400            /** @type {number} */ var layers = tex2DArraySizes[ndx].layers;
   7401            levels = tex2DArraySizes[ndx].levels;
   7402            name = '2d_array_' + width + 'x' + height + 'x' +
   7403                layers + '_' + levels + '_levels';
   7404 
   7405            storageGroup.addChild(
   7406                new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
   7407                    name, '', format, width, height, layers, levels
   7408                )
   7409            );
   7410        }
   7411 
   7412        for (var ndx = 0; ndx < tex3DSizes.length; ndx++) {
   7413            format = gl.RGBA8;
   7414            width = tex3DSizes[ndx].width;
   7415            height = tex3DSizes[ndx].height;
   7416            var depth = tex3DSizes[ndx].depth;
   7417            levels = tex3DSizes[ndx].levels;
   7418            name = '3d_' + width + 'x' + height + 'x' +
   7419                depth + '_' + levels + '_levels';
   7420 
   7421            storageGroup.addChild(
   7422                new es3fTextureSpecificationTests.BasicTexStorage3DCase(
   7423                    name, '', format, width, height, depth, levels
   7424                )
   7425            );
   7426        }
   7427    };
   7428 
   7429    /**
   7430    * Run test
   7431    * @param {WebGL2RenderingContext} context
   7432    * @param {Array<number>=} range Test range
   7433    */
   7434    es3fTextureSpecificationTests.run = function(context, range) {
   7435        gl = context;
   7436        //Set up Test Root parameters
   7437        var state = tcuTestCase.runner;
   7438        state.setRoot(new es3fTextureSpecificationTests.TextureSpecificationTests());
   7439        if (range)
   7440            state.setRange(range);
   7441 
   7442        //Set up name and description of this test series.
   7443        setCurrentTestName(state.testCases.fullName());
   7444        description(state.testCases.getDescription());
   7445 
   7446        try {
   7447            //Run test cases
   7448            tcuTestCase.runTestCases();
   7449        }
   7450        catch (err) {
   7451            testFailedOptions('Failed to es3fTextureSpecificationTests.run tests', false);
   7452            tcuTestCase.runner.terminate();
   7453        }
   7454    };
   7455 
   7456 });