/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

'use strict';
goog.provide('functional.gles3.es3fTextureFilteringTests');
goog.require('framework.common.tcuImageCompare');
goog.require('framework.common.tcuLogImage');
goog.require('framework.common.tcuPixelFormat');
goog.require('framework.common.tcuRGBA');
goog.require('framework.common.tcuSurface');
goog.require('framework.common.tcuTestCase');
goog.require('framework.common.tcuTexLookupVerifier');
goog.require('framework.common.tcuTexture');
goog.require('framework.common.tcuTextureUtil');
goog.require('framework.delibs.debase.deMath');
goog.require('framework.delibs.debase.deRandom');
goog.require('framework.delibs.debase.deString');
goog.require('framework.opengl.gluShaderUtil');
goog.require('framework.opengl.gluTexture');
goog.require('framework.opengl.gluTextureUtil');
goog.require('functional.gles3.es3fFboTestUtil');
goog.require('modules.shared.glsTextureTestUtil');

goog.scope(function() {

    var es3fTextureFilteringTests = functional.gles3.es3fTextureFilteringTests;
    var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
    var gluShaderUtil = framework.opengl.gluShaderUtil;
    var gluTextureUtil = framework.opengl.gluTextureUtil;
    var tcuImageCompare = framework.common.tcuImageCompare;
    var tcuLogImage = framework.common.tcuLogImage;
    var tcuPixelFormat = framework.common.tcuPixelFormat;
    var tcuRGBA = framework.common.tcuRGBA;
    var tcuTestCase = framework.common.tcuTestCase;
    var tcuTexLookupVerifier = framework.common.tcuTexLookupVerifier;
    var tcuSurface = framework.common.tcuSurface;
    var tcuTexture = framework.common.tcuTexture;
    var tcuTextureUtil = framework.common.tcuTextureUtil;
    var deMath = framework.delibs.debase.deMath;
    var deString = framework.delibs.debase.deString;
    var deRandom = framework.delibs.debase.deRandom;
    var gluTexture = framework.opengl.gluTexture;
    var glsTextureTestUtil = modules.shared.glsTextureTestUtil;

    /** @type {WebGL2RenderingContext} */ var gl;

    es3fTextureFilteringTests.version =
        gluShaderUtil.getGLSLVersionString(gluShaderUtil.GLSLVersion.V300_ES);

    let canvasWH = 256;
    let viewportWH = 64;

    if (tcuTestCase.isQuickMode()) {
        canvasWH = 64;
        viewportWH = 32;
    }

    const TEX2D_VIEWPORT_WIDTH = viewportWH;
    const TEX2D_VIEWPORT_HEIGHT = viewportWH;
    const TEX2D_MIN_VIEWPORT_WIDTH = viewportWH;
    const TEX2D_MIN_VIEWPORT_HEIGHT = viewportWH;

    const TEX3D_VIEWPORT_WIDTH = viewportWH;
    const TEX3D_VIEWPORT_HEIGHT = viewportWH;
    const TEX3D_MIN_VIEWPORT_WIDTH = viewportWH;
    const TEX3D_MIN_VIEWPORT_HEIGHT = viewportWH;

    /**
     * @constructor
     * @extends {tcuTestCase.DeqpTest}
     */
    es3fTextureFilteringTests.TextureFilteringTests = function() {
        tcuTestCase.DeqpTest.call(this, 'filtering', 'Texture Filtering Tests');
    };

    es3fTextureFilteringTests.TextureFilteringTests.prototype =
        Object.create(tcuTestCase.DeqpTest.prototype);

    es3fTextureFilteringTests.TextureFilteringTests.prototype.constructor =
        es3fTextureFilteringTests.TextureFilteringTests;

    /**
     * @constructor
     * @extends {tcuTestCase.DeqpTest}
     * @param {string} name
     * @param {string} desc
     * @param {number} minFilter
     * @param {number} magFilter
     * @param {number} wrapS
     * @param {number} wrapT
     * @param {number} internalFormat
     * @param {number} width
     * @param {number} height
     */
    es3fTextureFilteringTests.Texture2DFilteringCase = function(
        name, desc, minFilter, magFilter, wrapS, wrapT,
        internalFormat, width, height
    ) {
        tcuTestCase.DeqpTest.call(this, name, desc);
        this.m_minFilter = minFilter;
        this.m_magFilter = magFilter;
        this.m_wrapS = wrapS;
        this.m_wrapT = wrapT;
        this.m_internalFormat = internalFormat;
        this.m_width = width;
        this.m_height = height;
        /** @type {glsTextureTestUtil.TextureRenderer} */
        this.m_renderer = new glsTextureTestUtil.TextureRenderer(
            es3fTextureFilteringTests.version,
            gluShaderUtil.precision.PRECISION_HIGHP
        );
        this.m_caseNdx = 0;
        /** @type {Array<gluTexture.Texture2D>} */ this.m_textures = [];
        this.m_cases = [];
    };

    es3fTextureFilteringTests.Texture2DFilteringCase.prototype =
        Object.create(tcuTestCase.DeqpTest.prototype);
    es3fTextureFilteringTests.Texture2DFilteringCase.prototype.constructor =
        es3fTextureFilteringTests.Texture2DFilteringCase;

    /**
     * @constructor
     * @param {gluTexture.Texture2D} tex_
     * @param {Array<number>} minCoord_
     * @param {Array<number>} maxCoord_
     */
    es3fTextureFilteringTests.Texture2DFilteringCase.FilterCase = function(
        tex_, minCoord_, maxCoord_
    ) {
        this.texture = tex_;
        this.minCoord = minCoord_;
        this.maxCoord = maxCoord_;
    };

    /** @typedef {{texNdx: number, lodX: number,
     * lodY: number, oX: number, oY: number}} */
    es3fTextureFilteringTests.Cases;

    /**
     * init
     */
    es3fTextureFilteringTests.Texture2DFilteringCase.prototype.init =
    function() {
        try {
            // Create 2 textures.
            for (var ndx = 0; ndx < 2; ndx++)
                this.m_textures.push(
                    gluTexture.texture2DFromInternalFormat(
                        gl, this.m_internalFormat,
                        this.m_width, this.m_height
                    )
                );

            var mipmaps = true;
            var numLevels = mipmaps ? deMath.logToFloor(
                Math.max(this.m_width, this.m_height)
            ) + 1 : 1;

            /** @type {tcuTextureUtil.TextureFormatInfo} */
            var fmtInfo = tcuTextureUtil.getTextureFormatInfo(
                this.m_textures[0].getRefTexture().getFormat()
            );
            /** @type {Array<number>} */ var cBias = fmtInfo.valueMin;
            /** @type {Array<number>} */
            var cScale = deMath.subtract(
                fmtInfo.valueMax, fmtInfo.valueMin
            );

            // Fill first gradient texture.
            for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                /** @type {Array<number>} */ var gMin = deMath.add(
                    deMath.multiply([0.0, 0.0, 0.0, 1.0], cScale), cBias
                );
                /** @type {Array<number>} */ var gMax = deMath.add(
                    deMath.multiply([1.0, 1.0, 1.0, 0.0], cScale), cBias
                );

                this.m_textures[0].getRefTexture().allocLevel(levelNdx);
                tcuTextureUtil.fillWithComponentGradients(
                    this.m_textures[0].getRefTexture().getLevel(levelNdx),
                    gMin, gMax
                );
            }

            // Fill second with grid texture.
            for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                /** @type {number} */ var step = 0x00ffffff / numLevels;
                /** @type {number} */ var rgb = step * levelNdx;
                /** @type {number} */ var colorA = deMath.binaryOp(
                    0xff000000, rgb, deMath.BinaryOp.OR
                );
                /** @type {number} */ var colorB = deMath.binaryOp(
                    0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
                );

                this.m_textures[1].getRefTexture().allocLevel(levelNdx);
                tcuTextureUtil.fillWithGrid(
                    this.m_textures[1].getRefTexture().getLevel(levelNdx),
                    4,
                    deMath.add(deMath.multiply(
                        tcuRGBA.newRGBAFromValue(colorA).toVec(), cScale),
                        cBias
                    ),
                    deMath.add(deMath.multiply(
                        tcuRGBA.newRGBAFromValue(colorB).toVec(), cScale),
                        cBias
                    )
                );
            }

            // Upload.
            for (var i = 0; i < this.m_textures.length; i++)
                this.m_textures[i].upload();

            // Compute cases.

            /** @type {Array<es3fTextureFilteringTests.Cases>} */
            var cases = [{
                    texNdx: 0, lodX: 1.6, lodY: 2.9, oX: -1.0, oY: -2.7
                }, {
                    texNdx: 0, lodX: -2.0, lodY: -1.35, oX: -0.2, oY: 0.7
                }, {
                    texNdx: 1, lodX: 0.14, lodY: 0.275, oX: -1.5, oY: -1.1
                }, {
                    texNdx: 1, lodX: -0.92, lodY: -2.64, oX: 0.4, oY: -0.1
                }
            ];

            var viewportW = Math.min(
                TEX2D_VIEWPORT_WIDTH, gl.canvas.width
            );
            var viewportH = Math.min(
                TEX2D_VIEWPORT_HEIGHT, gl.canvas.height
            );

            for (var caseNdx = 0; caseNdx < cases.length; caseNdx++) {
                /** @type {number} */ var texNdx = deMath.clamp(
                    cases[caseNdx].texNdx, 0, this.m_textures.length - 1
                );
                /** @type {number} */ var lodX = cases[caseNdx].lodX;
                /** @type {number} */ var lodY = cases[caseNdx].lodY;
                /** @type {number} */ var oX = cases[caseNdx].oX;
                /** @type {number} */ var oY = cases[caseNdx].oY;
                /** @type {number} */ var sX = Math.exp(lodX * Math.log(2)) * viewportW /
                    this.m_textures[texNdx].getRefTexture().getWidth();
                /** @type {number} */ var sY = Math.exp(lodY * Math.log(2)) * viewportH /
                    this.m_textures[texNdx].getRefTexture().getHeight();

                this.m_cases.push(
                    new
                    es3fTextureFilteringTests.Texture2DFilteringCase.FilterCase(
                        this.m_textures[texNdx], [oX, oY], [oX + sX, oY + sY]
                    )
                );
            }

            this.m_caseNdx = 0;
        }
        catch (e) {
            // Clean up to save memory.
            this.deinit();
            throw e;
        }
    };

    /**
     * deinit
     */
    es3fTextureFilteringTests.Texture2DFilteringCase.prototype.deinit =
    function() {
        while (this.m_textures.length > 0) {
            gl.deleteTexture(this.m_textures[0].getGLTexture());
            this.m_textures.splice(0, 1);
        }
    };

    /**
     * @return {tcuTestCase.IterateResult}
     */
    es3fTextureFilteringTests.Texture2DFilteringCase.prototype.iterate =
    function() {
        /** @type {glsTextureTestUtil.RandomViewport} */
        var viewport = new glsTextureTestUtil.RandomViewport(
            gl.canvas, TEX2D_VIEWPORT_WIDTH,
            TEX2D_VIEWPORT_HEIGHT, deMath.binaryOp(
                deString.deStringHash(this.fullName()),
                deMath.deMathHash(this.m_caseNdx),
                deMath.BinaryOp.XOR
            )
        );
        /** @type {tcuTexture.TextureFormat} */
        var texFmt = this.m_textures[0].getRefTexture().getFormat();

        /** @type {tcuTextureUtil.TextureFormatInfo} */
        var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
        var curCase = this.m_cases[this.m_caseNdx];
        bufferedLogToConsole('Test ' + this.m_caseNdx);
        var refParams = new glsTextureTestUtil.ReferenceParams(
            glsTextureTestUtil.textureType.TEXTURETYPE_2D
        );
        var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
        var texCoord = [0, 0];

        if (viewport.width < TEX2D_MIN_VIEWPORT_WIDTH ||
            viewport.height < TEX2D_MIN_VIEWPORT_HEIGHT)
            throw new Error('Too small render target');

        // Setup params for reference.
        refParams.sampler = gluTextureUtil.mapGLSamplerWrapST(
            this.m_wrapS, this.m_wrapT, this.m_minFilter, this.m_magFilter
        );
        refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
        refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
        refParams.colorBias = fmtInfo.lookupBias;
        refParams.colorScale = fmtInfo.lookupScale;

        // Compute texture coordinates.
        bufferedLogToConsole(
            'Texture coordinates: ' + curCase.minCoord +
            ' -> ' + curCase.maxCoord
        );
        texCoord = glsTextureTestUtil.computeQuadTexCoord2D(
            curCase.minCoord, curCase.maxCoord
        );

        gl.bindTexture(gl.TEXTURE_2D, curCase.texture.getGLTexture());
        gl.texParameteri(
            gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_minFilter
        );
        gl.texParameteri(
            gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_magFilter
        );
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.m_wrapS);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.m_wrapT);

        gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

        this.m_renderer.renderQuad(0, texCoord, refParams);
        rendered.readViewport(
            gl, [viewport.x, viewport.y, viewport.width, viewport.height]
        );

        /** @type {boolean} */ var isNearestOnly =
            this.m_minFilter == gl.NEAREST && this.m_magFilter == gl.NEAREST;
        /** @type {tcuPixelFormat.PixelFormat} */
        var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);

        //(iVec4)
        var colorBits = deMath.max(
            deMath.addScalar(
                glsTextureTestUtil.getBitsVec(pixelFormat),
                // 1 inaccurate bit if nearest only, 2 otherwise
                -1 * (isNearestOnly ? 1 : 2)
            ),
            [0, 0, 0, 0]
        );

        /** @type {tcuTexLookupVerifier.LodPrecision} */
        var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
        /** @type {tcuTexLookupVerifier.LookupPrecision} */
        var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();

        lodPrecision.derivateBits = 18;
        lodPrecision.lodBits = 6;
        lookupPrecision.colorThreshold = deMath.divide(
            tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
            refParams.colorScale
        );
        lookupPrecision.coordBits = [20, 20, 0];
        lookupPrecision.uvwBits = [7, 7, 0];
        lookupPrecision.colorMask =
            glsTextureTestUtil.getCompareMask(pixelFormat);

        var isHighQuality = glsTextureTestUtil.verifyTexture2DResult(
            rendered.getAccess(), curCase.texture.getRefTexture(),
            texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
        );

        if (!isHighQuality) {
            // Evaluate against lower precision requirements.
            lodPrecision.lodBits = 4;
            lookupPrecision.uvwBits = [4, 4, 0];

            bufferedLogToConsole('Warning: Verification against high ' +
                'precision requirements failed, trying with lower ' +
                'requirements.'
            );

            var isOk = glsTextureTestUtil.verifyTexture2DResult(
                rendered.getAccess(), curCase.texture.getRefTexture(),
                texCoord, refParams, lookupPrecision, lodPrecision,
                pixelFormat
            );

            if (!isOk) {
                bufferedLogToConsole(
                    'ERROR: Verification against low ' +
                    'precision requirements failed, failing test case.'
                );
                testFailedOptions('Image verification failed', false);
                //In JS version, one mistake and you're out
                return tcuTestCase.IterateResult.STOP;
            } else
                checkMessage(
                    false,
                    'Low-quality filtering result in iteration no. ' +
                    this.m_caseNdx
                );
        }

        this.m_caseNdx += 1;
        if (this.m_caseNdx < this.m_cases.length)
            return tcuTestCase.IterateResult.CONTINUE;

        testPassed('Verified');
        return tcuTestCase.IterateResult.STOP;
    };

    /**
     * @constructor
     * @extends {tcuTestCase.DeqpTest}
     * @param {string} name
     * @param {string} desc
     * @param {number} minFilter
     * @param {number} magFilter
     * @param {number} wrapS
     * @param {number} wrapT
     * @param {boolean} onlySampleFaceInterior
     * @param {number} internalFormat
     * @param {number} width
     * @param {number} height
     */
    es3fTextureFilteringTests.TextureCubeFilteringCase = function(
        name, desc, minFilter, magFilter, wrapS, wrapT, onlySampleFaceInterior,
        internalFormat, width, height
    ) {
        tcuTestCase.DeqpTest.call(this, name, desc);
        this.m_minFilter = minFilter;
        this.m_magFilter = magFilter;
        this.m_wrapS = wrapS;
        this.m_wrapT = wrapT;
        /** @type {boolean}*/
        this.m_onlySampleFaceInterior = onlySampleFaceInterior;
        this.m_internalFormat = internalFormat;
        this.m_width = width;
        this.m_height = height;
        /** @type {glsTextureTestUtil.TextureRenderer} */
        this.m_renderer = new glsTextureTestUtil.TextureRenderer(
            es3fTextureFilteringTests.version,
            gluShaderUtil.precision.PRECISION_HIGHP
        );
        this.m_caseNdx = 0;
        /** @type {Array<gluTexture.TextureCube>} */ this.m_textures = [];
        /** @type {Array<es3fTextureFilteringTests.
         *      TextureCubeFilteringCase.FilterCase>}
         */
        this.m_cases = [];
    };

    /**
     * @constructor
     * @param {gluTexture.TextureCube} tex_
     * @param {Array<number>} bottomLeft_
     * @param {Array<number>} topRight_
     */
    es3fTextureFilteringTests.TextureCubeFilteringCase.FilterCase = function(
        tex_, bottomLeft_, topRight_
    ) {
        this.texture = tex_;
        this.bottomLeft = bottomLeft_;
        this.topRight = topRight_;
    };

    es3fTextureFilteringTests.TextureCubeFilteringCase.prototype =
        Object.create(tcuTestCase.DeqpTest.prototype);

    es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.constructor =
        es3fTextureFilteringTests.TextureCubeFilteringCase;

    /**
     * init
     */
    es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.init =
    function() {
        try {
            assertMsgOptions(
                this.m_width == this.m_height, 'Texture has to be squared',
                false, true
            );
            for (var ndx = 0; ndx < 2; ndx++)
                this.m_textures.push(gluTexture.cubeFromInternalFormat(
                    gl, this.m_internalFormat, this.m_width
                ));

            var numLevels = deMath.logToFloor(
                Math.max(this.m_width, this.m_height)
            ) + 1;
            /** @type {tcuTextureUtil.TextureFormatInfo} */
            var fmtInfo = tcuTextureUtil.getTextureFormatInfo(
                this.m_textures[0].getRefTexture().getFormat()
            );
            /** @type {Array<number>} */
            var cBias = fmtInfo.valueMin;
            /** @type {Array<number>} */
            var cScale = deMath.subtract(
                fmtInfo.valueMax, fmtInfo.valueMin
            );

            // Fill first with gradient texture.
            /** @type {Array<Array<Array<number>>>}
             * (array of 4 component vectors)
             */
            var gradients = [
                [ // negative x
                    [0.0, 0.0, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
                ], [ // positive x
                    [0.5, 0.0, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
                ], [ // negative y
                    [0.0, 0.5, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
                ], [ // positive y
                    [0.0, 0.0, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]
                ], [ // negative z
                    [0.0, 0.0, 0.0, 0.5], [1.0, 1.0, 1.0, 1.0]
                ], [ // positive z
                    [0.5, 0.5, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]
                ]
            ];
            for (var face = 0;
                face < Object.keys(tcuTexture.CubeFace).length;
                face++) {
                for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                    this.m_textures[0].getRefTexture().allocLevel(
                        face, levelNdx
                    );
                    tcuTextureUtil.fillWithComponentGradients(
                        this.m_textures[0].getRefTexture().getLevelFace(
                            levelNdx, face
                        ),
                        deMath.add(deMath.multiply(
                            gradients[face][0], cScale
                        ), cBias),
                        deMath.add(deMath.multiply(
                            gradients[face][1], cScale
                        ), cBias)
                    );
                }
            }

            // Fill second with grid texture.
            for (var face = 0;
                face < Object.keys(tcuTexture.CubeFace).length;
                face++) {
                for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                    var step = 0x00ffffff / (
                        numLevels * Object.keys(tcuTexture.CubeFace).length
                    );
                    var rgb = step * levelNdx * face;
                    /** @type {number} */ var colorA = deMath.binaryOp(
                        0xff000000, rgb, deMath.BinaryOp.OR
                    );
                    /** @type {number} */ var colorB = deMath.binaryOp(
                        0xff000000, deMath.binaryNot(rgb),
                        deMath.BinaryOp.OR
                    );

                    this.m_textures[1].getRefTexture().allocLevel(
                        face, levelNdx
                    );
                    tcuTextureUtil.fillWithGrid(
                        this.m_textures[1].getRefTexture().getLevelFace(
                            levelNdx, face
                        ), 4, deMath.add(
                            deMath.multiply(
                                tcuRGBA.newRGBAFromValue(colorA).toVec(),
                                cScale
                            ), cBias
                        ), deMath.add(
                            deMath.multiply(
                                tcuRGBA.newRGBAFromValue(colorB).toVec(),
                                cScale
                            ), cBias
                        )
                    );
                }
            }

            // Upload.
            for (var i = 0; i < this.m_textures.length; i++)
                this.m_textures[i].upload();

            // Compute cases
            /** @type {gluTexture.TextureCube} */
            var tex0 = this.m_textures[0];
            /** @type {gluTexture.TextureCube} */
            var tex1 = this.m_textures.length > 1 ? this.m_textures[1] : tex0;

            if (this.m_onlySampleFaceInterior) {
                // minification
                this.m_cases.push(new es3fTextureFilteringTests.
                    TextureCubeFilteringCase.FilterCase(
                    tex0, [-0.8, -0.8], [0.8, 0.8]
                ));
                // magnification
                this.m_cases.push(new es3fTextureFilteringTests.
                    TextureCubeFilteringCase.FilterCase(
                    tex0, [0.5, 0.65], [0.8, 0.8]
                ));
                // minification
                this.m_cases.push(new es3fTextureFilteringTests.
                    TextureCubeFilteringCase.FilterCase(
                    tex1, [-0.8, -0.8], [0.8, 0.8]
                ));
                // magnification
                this.m_cases.push(new es3fTextureFilteringTests.
                    TextureCubeFilteringCase.FilterCase(
                    tex1, [0.2, 0.2], [0.6, 0.5]
                ));
            } else {
                // minification
                if (gl.getParameter(gl.SAMPLES) == 0)
                    this.m_cases.push(
                        new es3fTextureFilteringTests.TextureCubeFilteringCase.
                        FilterCase(
                            tex0, [-1.25, -1.2], [1.2, 1.25]
                        )
                    );
                // minification - w/ tweak to avoid hitting triangle
                // edges with face switchpoint.
                else
                    this.m_cases.push(
                        new es3fTextureFilteringTests.TextureCubeFilteringCase.
                        FilterCase(
                            tex0, [-1.19, -1.3], [1.1, 1.35]
                        )
                    );

                // magnification
                this.m_cases.push(
                    new es3fTextureFilteringTests.TextureCubeFilteringCase.
                    FilterCase(
                        tex0, [0.8, 0.8], [1.25, 1.20]
                    )
                );
                // minification
                this.m_cases.push(
                    new es3fTextureFilteringTests.TextureCubeFilteringCase.
                    FilterCase(
                        tex1, [-1.19, -1.3], [1.1, 1.35]
                    )
                );
                // magnification
                this.m_cases.push(
                    new es3fTextureFilteringTests.TextureCubeFilteringCase.
                    FilterCase(
                        tex1, [-1.2, -1.1], [-0.8, -0.8]
                    )
                );
            }

            this.m_caseNdx = 0;
        }
        catch (e) {
            // Clean up to save memory.
            this.deinit();
            throw e;
        }
    };

    /**
     * deinit
     */
    es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.deinit =
    function() {
        while (this.m_textures.length > 0) {
            gl.deleteTexture(this.m_textures[0].getGLTexture());
            this.m_textures.splice(0, 1);
        }
    };

    /**
     * @param {tcuTexture.CubeFace} face
     * @return {string}
     */
    es3fTextureFilteringTests.getFaceDesc = function(face) {
        switch (face) {
            case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: return '-X';
            case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: return '+X';
            case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: return '-Y';
            case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: return '+Y';
            case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: return '-Z';
            case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: return '+Z';
            default:
                throw new Error('Invalid cube face specified');
        }
    };

    /**
     * @return {tcuTestCase.IterateResult}
     */
    es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.iterate =
    function() {
        var viewportSize = 28;
        /** @type {glsTextureTestUtil.RandomViewport} */
        var viewport = new glsTextureTestUtil.RandomViewport(
            gl.canvas, viewportSize,
            viewportSize, deMath.binaryOp(
                deString.deStringHash(this.fullName()),
                deMath.deMathHash(this.m_caseNdx),
                deMath.BinaryOp.XOR
            )
        );
        bufferedLogToConsole('Test' + this.m_caseNdx);
        /** @type {es3fTextureFilteringTests.
         *      TextureCubeFilteringCase.FilterCase}
         */
        var curCase = this.m_cases[this.m_caseNdx];
        /** @type {tcuTexture.TextureFormat} */
        var texFmt = curCase.texture.getRefTexture().getFormat();
        /** @type {tcuTextureUtil.TextureFormatInfo} */
        var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
        /** @type {glsTextureTestUtil.ReferenceParams} */
        var sampleParams = new glsTextureTestUtil.ReferenceParams(
            glsTextureTestUtil.textureType.TEXTURETYPE_CUBE
        );

        if (viewport.width < viewportSize || viewport.height < viewportSize)
            throw new Error('Too small render target');

        // Setup texture
        gl.bindTexture(gl.TEXTURE_CUBE_MAP, curCase.texture.getGLTexture());
        gl.texParameteri(
            gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, this.m_minFilter
        );
        gl.texParameteri(
            gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, this.m_magFilter
        );
        gl.texParameteri(
            gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, this.m_wrapS
        );
        gl.texParameteri(
            gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, this.m_wrapT
        );

        // Other state
        gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

        // Params for reference computation.
        sampleParams.sampler = gluTextureUtil.mapGLSamplerWrapST(
            gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE,
            this.m_minFilter, this.m_magFilter
        );
        sampleParams.sampler.seamlessCubeMap = true;
        sampleParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
        sampleParams.colorBias = fmtInfo.lookupBias;
        sampleParams.colorScale = fmtInfo.lookupScale;
        sampleParams.lodMode = glsTextureTestUtil.lodMode.EXACT;

        bufferedLogToConsole(
            'Coordinates: ' + curCase.bottomLeft + ' -> ' + curCase.topRight
        );

        for (var faceNdx = 0;
            faceNdx < Object.keys(tcuTexture.CubeFace).length;
            faceNdx++) {
            var face = /** @type {tcuTexture.CubeFace} */ (faceNdx);
            /** @type {tcuSurface.Surface} */
            var result = new tcuSurface.Surface(
                viewport.width, viewport.height
            );
            /** @type {Array<number>} */ var texCoord;

            texCoord = glsTextureTestUtil.computeQuadTexCoordCubeFace(
                face, curCase.bottomLeft, curCase.topRight
            );

            bufferedLogToConsole(
                'Face ' + es3fTextureFilteringTests.getFaceDesc(face)
            );

            // \todo Log texture coordinates.

            this.m_renderer.renderQuad(0, texCoord, sampleParams);

            result.readViewport(
                gl, [viewport.x, viewport.y, viewport.width, viewport.height]
            );

            /** @type {boolean} */
            var isNearestOnly = this.m_minFilter == gl.NEAREST &&
                this.m_magFilter == gl.NEAREST;
            /** @type {tcuPixelFormat.PixelFormat} */
            var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);

            //(iVec4)
            var colorBits = deMath.max(
                deMath.addScalar(
                    glsTextureTestUtil.getBitsVec(pixelFormat),
                    // 1 inaccurate bit if nearest only, 2 otherwise
                    -1 * (isNearestOnly ? 1 : 2)
                ),
                [0, 0, 0, 0]
            );
            /** @type {tcuTexLookupVerifier.LodPrecision} */
            var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
            /** @type {tcuTexLookupVerifier.LookupPrecision} */
            var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();

            lodPrecision.derivateBits = 10;
            lodPrecision.lodBits = 5;
            lookupPrecision.colorThreshold = deMath.divide(
                tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
                sampleParams.colorScale
            );
            lookupPrecision.coordBits = [10, 10, 10];
            lookupPrecision.uvwBits = [6, 6, 0];
            lookupPrecision.colorMask =
                glsTextureTestUtil.getCompareMask(pixelFormat);

            var isHighQuality = glsTextureTestUtil.verifyTextureCubeResult(
                result.getAccess(), curCase.texture.getRefTexture(),
                texCoord, sampleParams, lookupPrecision, lodPrecision,
                pixelFormat
            );


            if (!isHighQuality) {
                // Evaluate against lower precision requirements.
                lodPrecision.lodBits = 2;
                lookupPrecision.uvwBits = [3, 3, 0];

                bufferedLogToConsole('Warning: Verification against high ' +
                 'precision requirements failed, trying with lower ' +
                 'requirements.');

                var isOk = glsTextureTestUtil.verifyTextureCubeResult(
                    result.getAccess(), curCase.texture.getRefTexture(),
                    texCoord, sampleParams, lookupPrecision, lodPrecision,
                    pixelFormat
                );

                if (!isOk) {
                    bufferedLogToConsole('ERROR: Verification against low' +
                        'precision requirements failed, failing test case.');
                    testFailedOptions('Image verification failed', false);
                    //In JS version, one mistake and you're out
                    return tcuTestCase.IterateResult.STOP;
                } else
                    checkMessage(
                        false,
                        'Low-quality filtering result in iteration no. ' +
                        this.m_caseNdx
                    );
            }
        }

        this.m_caseNdx += 1;
        if (this.m_caseNdx < this.m_cases.length)
            return tcuTestCase.IterateResult.CONTINUE;

        testPassed('Verified');
        return tcuTestCase.IterateResult.STOP;
    };

    // 2D array filtering

    /**
     * @constructor
     * @extends {tcuTestCase.DeqpTest}
     * @param {string} name
     * @param {string} desc
     * @param {number} minFilter
     * @param {number} magFilter
     * @param {number} wrapS
     * @param {number} wrapT
     * @param {number} internalFormat
     * @param {number} width
     * @param {number} height
     * @param {number} numLayers
     */
    es3fTextureFilteringTests.Texture2DArrayFilteringCase = function(
        name, desc, minFilter, magFilter, wrapS, wrapT,
        internalFormat, width, height, numLayers
    ) {
        tcuTestCase.DeqpTest.call(this, name, desc);
        this.m_minFilter = minFilter;
        this.m_magFilter = magFilter;
        this.m_wrapS = wrapS;
        this.m_wrapT = wrapT;
        this.m_internalFormat = internalFormat;
        this.m_width = width;
        this.m_height = height;
        this.m_numLayers = numLayers;
        this.m_gradientTex = null;
        this.m_gridTex = null;
        /** @type {glsTextureTestUtil.TextureRenderer} */
        this.m_renderer = new glsTextureTestUtil.TextureRenderer(
            es3fTextureFilteringTests.version,
            gluShaderUtil.precision.PRECISION_HIGHP
        );
        this.m_textures = [];
        this.m_caseNdx = 0;
        this.m_cases = [];
    };

    es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype =
        Object.create(tcuTestCase.DeqpTest.prototype);

    es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.
    constructor = es3fTextureFilteringTests.Texture2DArrayFilteringCase;

    /**
     * @constructor
     * @param {gluTexture.Texture2DArray} tex_
     * @param {Array<number>} lod_
     * @param {Array<number>} offset_
     * @param {Array<number>} layerRange_
     */
    es3fTextureFilteringTests.Texture2DArrayFilteringCase.FilterCase =
    function(
        tex_, lod_, offset_, layerRange_
    ) {
        this.texture = tex_;
        this.lod = lod_;
        this.offset = offset_;
        this.layerRange = layerRange_;
    };

    /*
     * init
     */
    es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.init =
    function() {
        try {
            /** @type {tcuTexture.TextureFormat} */
            var texFmt = gluTextureUtil.mapGLInternalFormat(
                this.m_internalFormat
            );
            /** @type {tcuTextureUtil.TextureFormatInfo} */
            var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
            var cScale = deMath.subtract(
                fmtInfo.valueMax, fmtInfo.valueMin
            );
            var cBias = fmtInfo.valueMin;
            var numLevels = deMath.logToFloor(
                Math.max(this.m_width, this.m_height)
            ) + 1;

            // Create textures.
            this.m_gradientTex = gluTexture.texture2DArrayFromInternalFormat(
                gl,
                this.m_internalFormat, this.m_width,
                this.m_height, this.m_numLayers
            );

            this.m_gridTex = gluTexture.texture2DArrayFromInternalFormat(
                gl,
                this.m_internalFormat, this.m_width,
                this.m_height, this.m_numLayers
            );

            var levelSwz = [
                [0, 1, 2, 3],
                [2, 1, 3, 0],
                [3, 0, 1, 2],
                [1, 3, 2, 0]
            ];

            // Fill first gradient texture
            // (gradient direction varies between layers).
            for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                this.m_gradientTex.getRefTexture().allocLevel(levelNdx);

                var levelBuf =
                    this.m_gradientTex.getRefTexture().getLevel(levelNdx);

                for (var layerNdx = 0;
                    layerNdx < this.m_numLayers;
                    layerNdx++) {
                    var swz = levelSwz[layerNdx % levelSwz.length];
                    var gMin = deMath.add(deMath.multiply(deMath.swizzle(
                        [0.0, 0.0, 0.0, 1.0], [swz[0], swz[1], swz[2], swz[3]]
                    ), cScale), cBias);
                    var gMax = deMath.add(deMath.multiply(deMath.swizzle(
                        [1.0, 1.0, 1.0, 0.0], [swz[0], swz[1], swz[2], swz[3]]
                    ), cScale), cBias);

                    tcuTextureUtil.fillWithComponentGradients2D(
                        tcuTextureUtil.getSubregion(
                            levelBuf, 0, 0, layerNdx, levelBuf.getWidth(),
                            levelBuf.getHeight(), 1
                        ), gMin, gMax
                    );
                }
            }

            // Fill second with grid texture (each layer has unique colors).
            for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                this.m_gridTex.getRefTexture().allocLevel(levelNdx);

                /** @type {tcuTexture.PixelBufferAccess} */ var levelBuf =
                    this.m_gridTex.getRefTexture().getLevel(levelNdx);

                for (
                    var layerNdx = 0;
                    layerNdx < this.m_numLayers;
                    layerNdx++) {
                    var step = 0x00ffffff / (numLevels * this.m_numLayers - 1);
                    var rgb = step * (levelNdx + layerNdx * numLevels);
                    /** @type {number} */ var colorA = deMath.binaryOp(
                        0xff000000, rgb, deMath.BinaryOp.OR
                    );
                    /** @type {number} */ var colorB = deMath.binaryOp(
                        0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
                    );

                    tcuTextureUtil.fillWithGrid(
                        tcuTextureUtil.getSubregion(
                            levelBuf, 0, 0, layerNdx, levelBuf.getWidth(),
                            levelBuf.getHeight(), 1
                        ), 4,
                        deMath.add(
                            deMath.multiply(
                                tcuRGBA.newRGBAFromValue(colorA).toVec(),
                                cScale
                            ), cBias
                        ),
                        deMath.add(
                            deMath.multiply(
                                tcuRGBA.newRGBAFromValue(colorB).toVec(),
                                cScale
                            ), cBias
                        )
                    );
                }
            }

            // Upload.
            this.m_gradientTex.upload();
            this.m_gridTex.upload();

            // Test cases
            this.m_cases.push(
                new es3fTextureFilteringTests.
                Texture2DArrayFilteringCase.FilterCase(
                    this.m_gradientTex, [1.5, 2.8], [-1.0, -2.7],
                    [-0.5, this.m_numLayers + 0.5]
                )
            );
            this.m_cases.push(
                new es3fTextureFilteringTests.
                Texture2DArrayFilteringCase.FilterCase(
                    this.m_gridTex, [0.2, 0.175], [-2.0, -3.7],
                    [-0.5, this.m_numLayers + 0.5]
                )
            );
            this.m_cases.push(
                new es3fTextureFilteringTests.
                Texture2DArrayFilteringCase.FilterCase(
                    this.m_gridTex, [-0.8, -2.3], [0.2, -0.1],
                    [this.m_numLayers + 0.5, -0.5]
                )
            );

            // Level rounding - only in single-sample configs as
            // multisample configs may produce smooth transition at the middle.
            if (gl.getParameter(gl.SAMPLES) == 0)
                this.m_cases.push(
                    new es3fTextureFilteringTests.
                    Texture2DArrayFilteringCase.FilterCase(
                        this.m_gradientTex, [-2.0, -1.5], [-0.1, 0.9],
                        [1.50001, 1.49999]
                    )
                );

            this.m_caseNdx = 0;
        }
        catch (e) {
            // Clean up to save memory.
            this.deinit();
            throw e;
        }
    };

    /**
     * deinit
     */
    es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.deinit =
    function() {
        if (this.m_gradientTex)
            gl.deleteTexture(this.m_gradientTex.getGLTexture());
        if (this.m_gridTex)
            gl.deleteTexture(this.m_gridTex.getGLTexture());

        this.m_gradientTex = null;
        this.m_gridTex = null;
    };

    /**
     * iterate
     * @return {tcuTestCase.IterateResult}
     */
    es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.iterate =
    function() {
        /** @type {glsTextureTestUtil.RandomViewport} */
        var viewport = new glsTextureTestUtil.RandomViewport(
            gl.canvas, TEX3D_VIEWPORT_WIDTH,
            TEX3D_VIEWPORT_HEIGHT, deMath.binaryOp(
                deString.deStringHash(this.fullName()),
                deMath.deMathHash(this.m_caseNdx),
                deMath.BinaryOp.XOR
            )
        );

        /** @type {es3fTextureFilteringTests.Texture2DArrayFilteringCase.
         * FilterCase} */ var curCase = this.m_cases[this.m_caseNdx];

        /** @type {tcuTexture.TextureFormat} */
        var texFmt = curCase.texture.getRefTexture().getFormat();
        /** @type {tcuTextureUtil.TextureFormatInfo} */
        var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);

        bufferedLogToConsole('Test' + this.m_caseNdx);

        /** @type {glsTextureTestUtil.ReferenceParams} */
        var refParams = new glsTextureTestUtil.ReferenceParams(
            glsTextureTestUtil.textureType.TEXTURETYPE_2D_ARRAY
        );

        /** @type {tcuSurface.Surface} */
        var rendered = new tcuSurface.Surface(viewport.width, viewport.height);

        if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH ||
            viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
            throw new Error('Too small render target');

        // Setup params for reference.
        refParams.sampler = gluTextureUtil.mapGLSampler(
            this.m_wrapS, this.m_wrapT, this.m_wrapT,
            this.m_minFilter, this.m_magFilter
        );
        refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
        refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
        refParams.colorBias = fmtInfo.lookupBias;
        refParams.colorScale = fmtInfo.lookupScale;

        // Compute texture coordinates.
        bufferedLogToConsole(
            'Approximate lod per axis = ' + curCase.lod +
            ', offset = ' + curCase.offset
        );

        /** @type {number} */ var lodX = curCase.lod[0];
        /** @type {number} */ var lodY = curCase.lod[1];
        /** @type {number} */ var oX = curCase.offset[0];
        /** @type {number} */ var oY = curCase.offset[1];
        /** @type {number} */ var sX = Math.pow(2, lodX) * viewport.width /
            this.m_gradientTex.getRefTexture().getWidth();
        /** @type {number} */ var sY = Math.pow(2, lodY) * viewport.height /
            this.m_gradientTex.getRefTexture().getHeight();
        /** @type {number} */ var l0 = curCase.layerRange[0];
        /** @type {number} */ var l1 = curCase.layerRange[1];

        /** @type {Array<number>}*/
        var texCoord = [
            oX, oY, l0,
            oX, oY + sY, l0 * 0.5 + l1 * 0.5,
            oX + sX, oY, l0 * 0.5 + l1 * 0.5,
            oX + sX, oY + sY, l1
            ];

        gl.bindTexture(gl.TEXTURE_2D_ARRAY, curCase.texture.getGLTexture());
        gl.texParameteri(
            gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, this.m_minFilter
        );
        gl.texParameteri(
            gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, this.m_magFilter
        );
        gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, this.m_wrapS);
        gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, this.m_wrapT);

        gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
        this.m_renderer.renderQuad(
            0, texCoord,
            refParams
        );
        rendered.readViewport(
            gl, [viewport.x, viewport.y, viewport.width, viewport.height]
        );

        /** @type {boolean} */
        var isNearestOnly = this.m_minFilter == gl.NEAREST &&
            this.m_magFilter == gl.NEAREST;
        /** @type {tcuPixelFormat.PixelFormat} */
        var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
        //(iVec4)
        var colorBits = deMath.max(
            deMath.addScalar(
                glsTextureTestUtil.getBitsVec(pixelFormat),
                // 1 inaccurate bit if nearest only, 2 otherwise
                -1 * (isNearestOnly ? 1 : 2)
            ),
            [0, 0, 0, 0]
        );
        /** @type {tcuTexLookupVerifier.LodPrecision} */
        var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
        /** @type {tcuTexLookupVerifier.LookupPrecision} */
        var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();

        lodPrecision.derivateBits = 18;
        lodPrecision.lodBits = 6;
        lookupPrecision.colorThreshold = deMath.divide(
            tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
            refParams.colorScale
        );
        lookupPrecision.coordBits = [20, 20, 20];
        lookupPrecision.uvwBits = [7, 7, 0];
        lookupPrecision.colorMask =
            glsTextureTestUtil.getCompareMask(pixelFormat);

        var isHighQuality = glsTextureTestUtil.verifyTexture2DArrayResult(
            rendered.getAccess(), curCase.texture.getRefTexture().getView(),
            texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat);

        if (!isHighQuality) {
            // Evaluate against lower precision requirements.
            lodPrecision.lodBits = 3;
            lookupPrecision.uvwBits = [3, 3, 0];

            bufferedLogToConsole(
                'Warning: Verification against high ' +
                'precision requirements failed, ' +
                'trying with lower requirements.'
            );

            var isOk = glsTextureTestUtil.verifyTexture2DArrayResult(
                rendered.getAccess(), curCase.texture.getRefTexture().getView(),
                texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
            );

            if (!isOk) {
                bufferedLogToConsole(
                    'ERROR: Verification against low precision requirements ' +
                    'failed, failing test case.'
                );
                testFailedOptions('Image verification failed', false);
                //In JS version, one mistake and you're out
                return tcuTestCase.IterateResult.STOP;
            } else
                checkMessage(
                    false,
                    'Low-quality filtering result in iteration no. ' +
                    this.m_caseNdx
                );
        }

        this.m_caseNdx += 1;
        if (this.m_caseNdx < this.m_cases.length)
            return tcuTestCase.IterateResult.CONTINUE;

        testPassed('Verified');
        return tcuTestCase.IterateResult.STOP;
    };

    // 3D filtering

    /**
     * @constructor
     * @extends {tcuTestCase.DeqpTest}
     * @param {string} name
     * @param {string} desc
     * @param {number} minFilter
     * @param {number} magFilter
     * @param {number} wrapS
     * @param {number} wrapT
     * @param {number} wrapR
     * @param {number} internalFormat
     * @param {number} width
     * @param {number} height
     * @param {number} depth
     */
    es3fTextureFilteringTests.Texture3DFilteringCase = function(
        name, desc, minFilter, magFilter, wrapS, wrapT, wrapR, internalFormat,
        width, height, depth
    ) {
        tcuTestCase.DeqpTest.call(this, name, desc);
        this.m_minFilter = minFilter;
        this.m_magFilter = magFilter;
        this.m_wrapS = wrapS;
        this.m_wrapT = wrapT;
        this.m_wrapR = wrapR;
        this.m_internalFormat = internalFormat;
        this.m_width = width;
        this.m_height = height;
        this.m_depth = depth;
        this.m_gradientTex = null;
        this.m_gridTex = null;
        /** @type {glsTextureTestUtil.TextureRenderer} */
        this.m_renderer = new glsTextureTestUtil.TextureRenderer(
            es3fTextureFilteringTests.version,
            gluShaderUtil.precision.PRECISION_HIGHP
        );
        this.m_caseNdx = 0;
        this.m_cases = [];
    };

    es3fTextureFilteringTests.Texture3DFilteringCase.prototype =
        Object.create(tcuTestCase.DeqpTest.prototype);

    es3fTextureFilteringTests.Texture3DFilteringCase.prototype.constructor =
        es3fTextureFilteringTests.Texture3DFilteringCase;

    /**
     * @constructor
     * @param {gluTexture.Texture3D} tex_
     * @param {Array<number>} lod_
     * @param {Array<number>} offset_
     */
    es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase = function(
        tex_, lod_, offset_
    ) {
        this.texture = tex_;
        this.lod = lod_;
        this.offset = offset_;
    };

    /**
     * init
     */
    es3fTextureFilteringTests.Texture3DFilteringCase.prototype.init = function(
    ) {
        try {
            /** @type {tcuTexture.TextureFormat} */
            var texFmt =
                gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
            /** @type {tcuTextureUtil.TextureFormatInfo} */
            var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
            var cScale = deMath.subtract(
                fmtInfo.valueMax, fmtInfo.valueMin
            );
            var cBias = fmtInfo.valueMin;
            var numLevels = deMath.logToFloor(
                Math.max(Math.max(this.m_width, this.m_height), this.m_depth)
            ) + 1;

            // Create textures.
            this.m_gradientTex = gluTexture.texture3DFromInternalFormat(
                gl, this.m_internalFormat,
                this.m_width, this.m_height, this.m_depth
            );

            this.m_gridTex = gluTexture.texture3DFromInternalFormat(
                gl, this.m_internalFormat,
                this.m_width, this.m_height, this.m_depth
            );

            // Fill first gradient texture.
            for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                var gMin = deMath.add(
                    deMath.multiply([0.0, 0.0, 0.0, 1.0], cScale), cBias
                );

                var gMax = deMath.add(
                    deMath.multiply([1.0, 1.0, 1.0, 0.0], cScale), cBias
                );

                this.m_gradientTex.getRefTexture().allocLevel(levelNdx);
                tcuTextureUtil.fillWithComponentGradients(
                    this.m_gradientTex.getRefTexture().getLevel(levelNdx),
                    gMin, gMax
                );
            }

            // Fill second with grid texture.
            for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
                /** @type {number} */ var step = 0x00ffffff / numLevels;
                /** @type {number} */ var rgb = step * levelNdx;
                /** @type {number} */ var colorA = deMath.binaryOp(
                    0xff000000, rgb, deMath.BinaryOp.OR
                );
                /** @type {number} */ var colorB = deMath.binaryOp(
                    0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
                );

                this.m_gridTex.getRefTexture().allocLevel(levelNdx);
                tcuTextureUtil.fillWithGrid(
                    this.m_gridTex.getRefTexture().getLevel(levelNdx), 4,
                    deMath.add(
                        deMath.multiply(
                            tcuRGBA.newRGBAFromValue(colorA).toVec(),
                            cScale
                        ),
                        cBias
                    ),
                    deMath.add(
                        deMath.multiply(
                            tcuRGBA.newRGBAFromValue(colorB).toVec(),
                            cScale
                        ),
                        cBias
                    )
                );
            }

            // Upload.
            this.m_gradientTex.upload();
            this.m_gridTex.upload();

            // Test cases
            this.m_cases.push(
                new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
                    this.m_gradientTex, [1.5, 2.8, 1.0], [-1.0, -2.7, -2.275]
                )
            );
            this.m_cases.push(
                new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
                    this.m_gradientTex, [-2.0, -1.5, -1.8], [-0.1, 0.9, -0.25]
                )
            );
            this.m_cases.push(
                new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
                    this.m_gridTex, [0.2, 0.175, 0.3], [-2.0, -3.7, -1.825]
                )
            );
            this.m_cases.push(
                new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
                    this.m_gridTex, [-0.8, -2.3, -2.5], [0.2, -0.1, 1.325]
                )
            );

            this.m_caseNdx = 0;
        }
        catch (e) {
            // Clean up to save memory.
            this.deinit();
            throw e;
        }
    };

    /**
     * deinit
     */
    es3fTextureFilteringTests.Texture3DFilteringCase.prototype.deinit =
    function() {
        if (this.m_gradientTex)
            gl.deleteTexture(this.m_gradientTex.getGLTexture());
        if (this.m_gridTex)
            gl.deleteTexture(this.m_gridTex.getGLTexture());

        this.m_gradientTex = null;
        this.m_gridTex = null;
    };

    /**
     * @return {tcuTestCase.IterateResult}
     */
    es3fTextureFilteringTests.Texture3DFilteringCase.prototype.iterate =
    function() {
        /** @type {glsTextureTestUtil.RandomViewport} */
        var viewport = new glsTextureTestUtil.RandomViewport(
            gl.canvas, TEX3D_VIEWPORT_WIDTH,
            TEX3D_VIEWPORT_HEIGHT, deMath.binaryOp(
                deString.deStringHash(this.fullName()),
                deMath.deMathHash(this.m_caseNdx),
                deMath.BinaryOp.XOR
            )
        );

        /** @type {es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase}
         */ var curCase = this.m_cases[this.m_caseNdx];

        /** @type {tcuTexture.TextureFormat} */
        var texFmt = curCase.texture.getRefTexture().getFormat();
        /** @type {tcuTextureUtil.TextureFormatInfo} */
        var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);

        bufferedLogToConsole('Test' + this.m_caseNdx);
        /** @type {glsTextureTestUtil.ReferenceParams} */
        var refParams = new glsTextureTestUtil.ReferenceParams(
            glsTextureTestUtil.textureType.TEXTURETYPE_3D
        );

        /** @type {tcuSurface.Surface} */
        var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
        /** @type {Array<number>}*/
        var texCoord = [];

        if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH ||
            viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
            throw new Error('Too small render target');

        // Setup params for reference.
        refParams.sampler = gluTextureUtil.mapGLSampler(
            this.m_wrapS, this.m_wrapT, this.m_wrapR,
            this.m_minFilter, this.m_magFilter
        );

        // Setup params for reference.
        refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
        refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
        refParams.colorBias = fmtInfo.lookupBias;
        refParams.colorScale = fmtInfo.lookupScale;

        // Compute texture coordinates.
        bufferedLogToConsole('Approximate lod per axis = ' + curCase.lod +
            ', offset = ' + curCase.offset);

        /** @type {number} */ var lodX = curCase.lod[0];
        /** @type {number} */ var lodY = curCase.lod[1];
        /** @type {number} */ var lodZ = curCase.lod[2];
        /** @type {number} */ var oX = curCase.offset[0];
        /** @type {number} */ var oY = curCase.offset[1];
        /** @type {number} */ var oZ = curCase.offset[2];
        /** @type {number} */ var sX = Math.pow(2, lodX) * viewport.width /
            this.m_gradientTex.getRefTexture().getWidth();
        /** @type {number} */ var sY = Math.pow(2, lodY) * viewport.height /
            this.m_gradientTex.getRefTexture().getHeight();
        /** @type {number} */ var sZ = Math.pow(2, lodZ) *
            Math.max(viewport.width, viewport.height) /
            this.m_gradientTex.getRefTexture().getDepth();

        texCoord[0] = oX; texCoord[1] = oY; texCoord[2] = oZ;
        texCoord[3] = oX; texCoord[4] = oY + sY; texCoord[5] = oZ + sZ * 0.5;
        texCoord[6] = oX + sX; texCoord[7] = oY; texCoord[8] = oZ + sZ * 0.5;
        texCoord[9] = oX + sX; texCoord[10] = oY + sY; texCoord[11] = oZ + sZ;

        gl.bindTexture(gl.TEXTURE_3D, curCase.texture.getGLTexture());
        gl.texParameteri(
            gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, this.m_minFilter
        );
        gl.texParameteri(
            gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, this.m_magFilter
        );
        gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, this.m_wrapS);
        gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, this.m_wrapT);
        gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, this.m_wrapR);

        gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
        this.m_renderer.renderQuad(0, texCoord, refParams);
        rendered.readViewport(
            gl, [viewport.x, viewport.y, viewport.width, viewport.height]
        );

        var isNearestOnly = this.m_minFilter == gl.NEAREST &&
            this.m_magFilter == gl.NEAREST;
        /** @type {tcuPixelFormat.PixelFormat} */
        var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
        //(iVec4)
        var colorBits = deMath.max(
            deMath.addScalar(
                glsTextureTestUtil.getBitsVec(pixelFormat),
                // 1 inaccurate bit if nearest only, 2 otherwise
                -1 * (isNearestOnly ? 1 : 2)
            ),
            [0, 0, 0, 0]
        );
        /** @type {tcuTexLookupVerifier.LodPrecision} */
        var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
        /** @type {tcuTexLookupVerifier.LookupPrecision} */
        var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();

        lodPrecision.derivateBits = 18;
        lodPrecision.lodBits = 6;
        lookupPrecision.colorThreshold = deMath.divide(
            tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
            refParams.colorScale
        );
        lookupPrecision.coordBits = [20, 20, 20];
        lookupPrecision.uvwBits = [7, 7, 7];
        lookupPrecision.colorMask =
            glsTextureTestUtil.getCompareMask(pixelFormat);

        var isHighQuality = glsTextureTestUtil.verifyTexture3DResult(
            rendered.getAccess(), curCase.texture.getRefTexture(),
            texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
        );

        if (!isHighQuality) {
            // Evaluate against lower precision requirements.
            lodPrecision.lodBits = 4;
            lookupPrecision.uvwBits = [4, 4, 4];

            bufferedLogToConsole(
                'Warning: Verification against high precision ' +
                'requirements failed, trying with lower requirements.'
            );

            var isOk = glsTextureTestUtil.verifyTexture3DResult(
                rendered.getAccess(), curCase.texture.getRefTexture(),
                texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
            );

            if (!isOk) {
                bufferedLogToConsole('ERROR: Verification against low ' +
                    'precision requirements failed, failing test case.'
                );
                testFailedOptions('Image verification failed', false);
                //In JS version, one mistake and you're out
                return tcuTestCase.IterateResult.STOP;
            } else
                checkMessage(
                    false,
                    'Low-quality filtering result in iteration no. ' +
                    this.m_caseNdx
                );
        }

        this.m_caseNdx += 1;
        if (this.m_caseNdx < this.m_cases.length)
            return tcuTestCase.IterateResult.CONTINUE;

        testPassed('Verified');
        return tcuTestCase.IterateResult.STOP;
    };

    /** @typedef {{name: string, mode: number}} */
    es3fTextureFilteringTests.WrapMode;

    /** @typedef {{name: string, mode: number}} */
    es3fTextureFilteringTests.MinFilterMode;

    /** @typedef {{name: string, mode: number}} */
    es3fTextureFilteringTests.MagFilterModes;

    /** @typedef {{width: number, height: number}} */
    es3fTextureFilteringTests.Sizes2D;

    /** @typedef {{width: number, height: number}} */
    es3fTextureFilteringTests.SizesCube;

    /** @typedef {{width: number, height: number, numLayers: number}} */
    es3fTextureFilteringTests.Sizes2DArray;

    /** @typedef {{width: number, height: number, depth: number}} */
    es3fTextureFilteringTests.Sizes3D;

    /** @typedef {{name: string, format: number}} */
    es3fTextureFilteringTests.FilterableFormatsByType;

    /**
     * init
     */
    es3fTextureFilteringTests.TextureFilteringTests.prototype.init =
    function() {
        /** @type {Array<es3fTextureFilteringTests.WrapMode>} */
        var wrapModes = [{
                name: 'clamp', mode: gl.CLAMP_TO_EDGE
            }, {
                name: 'repeat', mode: gl.REPEAT
            }, {
                name: 'mirror', mode: gl.MIRRORED_REPEAT
            }
        ];

        /** @type {Array<es3fTextureFilteringTests.MinFilterMode>} */
        var minFilterModes = [{
                name: 'nearest', mode: gl.NEAREST
            }, {
                name: 'linear', mode: gl.LINEAR
            }, {
                name: 'nearest_mipmap_nearest', mode: gl.NEAREST_MIPMAP_NEAREST
            }, {
                name: 'linear_mipmap_nearest', mode: gl.LINEAR_MIPMAP_NEAREST
            }, {
                name: 'nearest_mipmap_linear', mode: gl.NEAREST_MIPMAP_LINEAR
            }, {
                name: 'linear_mipmap_linear', mode: gl.LINEAR_MIPMAP_LINEAR
            }
        ];

        /** @type {Array<es3fTextureFilteringTests.MagFilterModes>} */
        var magFilterModes = [{
                   name: 'nearest', mode: gl.NEAREST
            }, {
                   name: 'linear', mode: gl.LINEAR
            }
        ];

        /** @type {Array<es3fTextureFilteringTests.Sizes2D>} */
        var sizes2D = [{
                width: 4, height: 8
            }, {
                width: 32, height: 64
            }, {
                width: 128, height: 128
            }, {
                width: 3, height: 7
            }, {
                width: 31, height: 55
            }, {
                width: 127, height: 99
            }
        ];

        /** @type {Array<es3fTextureFilteringTests.SizesCube>} */
        var sizesCube = [{
                width: 8, height: 8
            }, {
                width: 64, height: 64
            }, {
                width: 128, height: 128
            }, {
                width: 7, height: 7
            }, {
                width: 63, height: 63
            }
        ];

        /** @type {Array<es3fTextureFilteringTests.Sizes2DArray>} */
        var sizes2DArray = [{
                width: 4, height: 8, numLayers: 8
            }, {
                width: 32, height: 64, numLayers: 16
            }, {
                width: 128, height: 32, numLayers: 64
            }, {
                width: 3, height: 7, numLayers: 5
            }, {
                width: 63, height: 63, numLayers: 63
            }
        ];

        /** @type {Array<es3fTextureFilteringTests.Sizes3D>} */
        var sizes3D = [{
                width: 4, height: 8, depth: 8
            }, {
                width: 32, height: 64, depth: 16
            }, {
                width: 128, height: 32, depth: 64
            }, {
                width: 3, height: 7, depth: 5
            }, {
                width: 63, height: 63, depth: 63
            }
        ];

        /** @type {Array<es3fTextureFilteringTests.FilterableFormatsByType>} */
        var filterableFormatsByType = [{
                name: 'rgba16f', format: gl.RGBA16F
            }, {
                name: 'r11f_g11f_b10f', format: gl.R11F_G11F_B10F
            }, {
                name: 'rgb9_e5', format: gl.RGB9_E5
            }, {
                name: 'rgba8', format: gl.RGBA8
            }, {
                name: 'rgba8_snorm', format: gl.RGBA8_SNORM
            }, {
                name: 'rgb565', format: gl.RGB565
            }, {
                name: 'rgba4', format: gl.RGBA4
            }, {
                name: 'rgb5_a1', format: gl.RGB5_A1
            }, {
                name: 'srgb8_alpha8', format: gl.SRGB8_ALPHA8
            }, {
                name: 'rgb10_a2', format: gl.RGB10_A2
            }
        ];

        // 2D texture filtering.

        // Formats.
        /** @type {tcuTestCase.DeqpTest} */
        var formatsGroup;
        for (var fmtNdx = 0;
            fmtNdx < filterableFormatsByType.length;
            fmtNdx++) {
            formatsGroup = new tcuTestCase.DeqpTest(
                '2d_formats', '2D Texture Formats');
            this.addChild(formatsGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                 /** @type {number} */
                var minFilter = minFilterModes[filterNdx].mode;
                 /** @type {string} */
                var filterName = minFilterModes[filterNdx].name;
                 /** @type {number} */
                var format = filterableFormatsByType[fmtNdx].format;
                 /** @type {string} */
                var formatName = filterableFormatsByType[fmtNdx].name;
                 var isMipmap = minFilter != gl.NEAREST &&
                    minFilter != gl.LINEAR;
                 /** @type {number} */
                var magFilter = isMipmap ? gl.LINEAR : minFilter;
                 /** @type {string} */
                var name = formatName + '_' + filterName;
                 /** @type {number} */
                var wrapS = gl.REPEAT;
                 /** @type {number} */
                var wrapT = gl.REPEAT;
                 /** @type {number} */ var width = 64;
                 /** @type {number} */ var height = 64;

                 formatsGroup.addChild(
                    new es3fTextureFilteringTests.Texture2DFilteringCase(
                        name, '', minFilter, magFilter, wrapS, wrapT,
                         format, width, height
                    )
                );
            }
        }

        // Sizes.
        /** @type {tcuTestCase.DeqpTest} */
        var sizesGroup;
        for (var sizeNdx = 0; sizeNdx < sizes2D.length; sizeNdx++) {
            sizesGroup = new tcuTestCase.DeqpTest(
                '2d_sizes', '2D Texture Sizes');
            this.addChild(sizesGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                minFilter = minFilterModes[filterNdx].mode;
                filterName = minFilterModes[filterNdx].name;
                format = gl.RGBA8;
                isMipmap = minFilter != gl.NEAREST &&
                    minFilter != gl.LINEAR;
                magFilter = isMipmap ? gl.LINEAR : minFilter;
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
                width = sizes2D[sizeNdx].width;
                height = sizes2D[sizeNdx].height;
                name = '' + width + 'x' + height + '_' + filterName;

                sizesGroup.addChild(
                    new es3fTextureFilteringTests.Texture2DFilteringCase(
                        name, '', minFilter, magFilter, wrapS, wrapT,
                        format, width, height
                    )
                );
            }
        }

        // Wrap modes.
        /** @type {tcuTestCase.DeqpTest} */
        var combinationsGroup;
        for (var minFilterNdx = 0;
            minFilterNdx < minFilterModes.length;
            minFilterNdx++) {
            combinationsGroup = new tcuTestCase.DeqpTest(
                '2d_combinations', '2D Filter and wrap mode combinations');
            this.addChild(combinationsGroup);
            for (var magFilterNdx = 0;
                magFilterNdx < magFilterModes.length;
                magFilterNdx++) {
                for (var wrapSNdx = 0;
                    wrapSNdx < wrapModes.length;
                    wrapSNdx++) {
                    for (var wrapTNdx = 0;
                        wrapTNdx < wrapModes.length;
                        wrapTNdx++) {
                        minFilter = minFilterModes[minFilterNdx].mode;
                        magFilter = magFilterModes[magFilterNdx].mode;
                        format = gl.RGBA8;
                        wrapS = wrapModes[wrapSNdx].mode;
                        wrapT = wrapModes[wrapTNdx].mode;
                        width = 63;
                        height = 57;
                        name = minFilterModes[minFilterNdx].name + '_' +
                            magFilterModes[magFilterNdx].name + '_' +
                            wrapModes[wrapSNdx].name + '_' +
                            wrapModes[wrapTNdx].name;

                        combinationsGroup.addChild(
                            new
                            es3fTextureFilteringTests.Texture2DFilteringCase(
                                name, '', minFilter, magFilter, wrapS, wrapT,
                                format, width, height
                            )
                        );
                    }
                }
            }
        }

        // Cube map texture filtering.

        // Formats.
        for (var fmtNdx = 0;
            fmtNdx < filterableFormatsByType.length;
            fmtNdx++) {
            formatsGroup = new tcuTestCase.DeqpTest(
                'cube_formats', 'Cube Texture Formats');
            this.addChild(formatsGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                minFilter = minFilterModes[filterNdx].mode;
                filterName = minFilterModes[filterNdx].name;
                format = filterableFormatsByType[fmtNdx].format;
                formatName = filterableFormatsByType[fmtNdx].name;
                isMipmap = minFilter != gl.NEAREST &&
                    minFilter != gl.LINEAR;
                magFilter = isMipmap ? gl.LINEAR : minFilter;
                name = formatName + '_' + filterName;
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
                width = 64;
                height = 64;

                formatsGroup.addChild(
                    new es3fTextureFilteringTests.TextureCubeFilteringCase(
                        name, '', minFilter, magFilter, wrapS, wrapT,
                        false /* always sample exterior as well */,
                        format, width, height
                    )
                );
            }
        }

        // Sizes.
        for (var sizeNdx = 0; sizeNdx < sizesCube.length; sizeNdx++) {
            sizesGroup = new tcuTestCase.DeqpTest(
                'cube_sizes', 'Cube Texture Sizes');
            this.addChild(sizesGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                minFilter = minFilterModes[filterNdx].mode;
                filterName = minFilterModes[filterNdx].name;
                var format = gl.RGBA8;
                isMipmap = minFilter != gl.NEAREST &&
                    minFilter != gl.LINEAR;
                magFilter = isMipmap ? gl.LINEAR : minFilter;
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
                width = sizesCube[sizeNdx].width;
                height = sizesCube[sizeNdx].height;
                name = '' + width + 'x' + height + '_' + filterName;

                sizesGroup.addChild(
                    new es3fTextureFilteringTests.TextureCubeFilteringCase(
                        name, '', minFilter, magFilter, wrapS, wrapT,
                        false, format, width, height
                    )
                );
            }
        }

        // Filter/wrap mode combinations.
        for (var minFilterNdx = 0;
            minFilterNdx < minFilterModes.length;
            minFilterNdx++) {
            combinationsGroup = new tcuTestCase.DeqpTest(
                'cube_combinations', 'Cube Filter and wrap mode combinations'
            );
            this.addChild(combinationsGroup);
            for (var magFilterNdx = 0;
                magFilterNdx < magFilterModes.length;
                magFilterNdx++) {
                for (var wrapSNdx = 0;
                    wrapSNdx < wrapModes.length;
                    wrapSNdx++) {
                    for (var wrapTNdx = 0;
                        wrapTNdx < wrapModes.length;
                        wrapTNdx++) {
                        minFilter = minFilterModes[minFilterNdx].mode;
                        magFilter = magFilterModes[magFilterNdx].mode;
                        format = gl.RGBA8;
                        wrapS = wrapModes[wrapSNdx].mode;
                        wrapT = wrapModes[wrapTNdx].mode;
                        width = 63;
                        height = 63;
                        name = minFilterModes[minFilterNdx].name + '_' +
                            magFilterModes[magFilterNdx].name + '_' +
                            wrapModes[wrapSNdx].name + '_' +
                            wrapModes[wrapTNdx].name;

                        combinationsGroup.addChild(
                            new es3fTextureFilteringTests.
                            TextureCubeFilteringCase(
                                name, '', minFilter, magFilter, wrapS, wrapT,
                                false, format, width, height
                            )
                        );
                    }
                }
            }
        }

        // Cases with no visible cube edges.
        /** @type {tcuTestCase.DeqpTest} */
        var onlyFaceInteriorGroup = new tcuTestCase.DeqpTest(
            'cube_no_edges_visible', "Don't sample anywhere near a face's edges"
        );
        this.addChild(onlyFaceInteriorGroup);

        for (var isLinearI = 0; isLinearI <= 1; isLinearI++) {
            var isLinear = isLinearI != 0;
            var filter = isLinear ? gl.LINEAR : gl.NEAREST;

            onlyFaceInteriorGroup.addChild(
                new es3fTextureFilteringTests.TextureCubeFilteringCase(
                    isLinear ? 'linear' : 'nearest', '',
                    filter, filter, gl.REPEAT, gl.REPEAT,
                    true, gl.RGBA8, 63, 63
                )
            );
        }

        // Formats.
        for (var fmtNdx = 0;
            fmtNdx < filterableFormatsByType.length;
            fmtNdx++) {
            formatsGroup = new tcuTestCase.DeqpTest(
                '2d_array_formats', '2D Array Texture Formats');
            this.addChild(formatsGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                minFilter = minFilterModes[filterNdx].mode;
                filterName = minFilterModes[filterNdx].name;
                format = filterableFormatsByType[fmtNdx].format;
                var formatName = filterableFormatsByType[fmtNdx].name;
                isMipmap = minFilter != gl.NEAREST &&
                    minFilter != gl.LINEAR;
                magFilter = isMipmap ? gl.LINEAR : minFilter;
                name = formatName + '_' + filterName;
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
                width = 128;
                height = 128;
                /** @type {number} */ var numLayers = 8;

                formatsGroup.addChild(
                    new es3fTextureFilteringTests.Texture2DArrayFilteringCase(
                        name, '', minFilter, magFilter, wrapS, wrapT,
                        format, width, height, numLayers
                    )
                );
            }
        }

        // Sizes.
        for (var sizeNdx = 0; sizeNdx < sizes2DArray.length; sizeNdx++) {
            sizesGroup = new tcuTestCase.DeqpTest(
                '2d_array_sizes', '2D Array Texture Sizes');
            this.addChild(sizesGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                minFilter = minFilterModes[filterNdx].mode;
                filterName = minFilterModes[filterNdx].name;
                format = gl.RGBA8;
                isMipmap = minFilter != gl.NEAREST &&
                    minFilter != gl.LINEAR;
                magFilter = isMipmap ? gl.LINEAR : minFilter;
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
                width = sizes2DArray[sizeNdx].width;
                height = sizes2DArray[sizeNdx].height;
                numLayers = sizes2DArray[sizeNdx].numLayers;
                name = '' + width + 'x' + height + 'x' +
                    numLayers + '_' + filterName;

                sizesGroup.addChild(
                    new es3fTextureFilteringTests.Texture2DArrayFilteringCase(
                        name, '', minFilter, magFilter, wrapS, wrapT,
                        format, width, height, numLayers
                    )
                );
            }
        }

        // Wrap modes.
        for (var minFilterNdx = 0;
            minFilterNdx < minFilterModes.length;
            minFilterNdx++) {
            combinationsGroup = new tcuTestCase.DeqpTest(
                '2d_array_combinations',
                '2D Array Filter and wrap mode combinations');
            this.addChild(combinationsGroup);
            for (var magFilterNdx = 0;
                magFilterNdx < magFilterModes.length;
                magFilterNdx++) {
                for (var wrapSNdx = 0;
                    wrapSNdx < wrapModes.length;
                    wrapSNdx++) {
                    for (var wrapTNdx = 0;
                        wrapTNdx < wrapModes.length;
                        wrapTNdx++) {
                        minFilter = minFilterModes[minFilterNdx].mode;
                        magFilter = magFilterModes[magFilterNdx].mode;
                        format = gl.RGBA8;
                        wrapS = wrapModes[wrapSNdx].mode;
                        wrapT = wrapModes[wrapTNdx].mode;
                        width = 123;
                        height = 107;
                        numLayers = 7;
                        name = minFilterModes[minFilterNdx].name + '_' +
                            magFilterModes[magFilterNdx].name + '_' +
                            wrapModes[wrapSNdx].name + '_' +
                            wrapModes[wrapTNdx].name;

                        combinationsGroup.addChild(
                            new es3fTextureFilteringTests.
                            Texture2DArrayFilteringCase(
                                name, '', minFilter, magFilter,
                                wrapS, wrapT, format,
                                width, height, numLayers
                            )
                        );
                    }
                }
            }
        }

        // 3D texture filtering.

        // Formats.
        /** @type {number} */ var depth = 64;
        for (var fmtNdx = 0;
            fmtNdx < filterableFormatsByType.length;
            fmtNdx++) {
            formatsGroup = new tcuTestCase.DeqpTest(
                '3d_formats', '3D Texture Formats');
            this.addChild(formatsGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                minFilter = minFilterModes[filterNdx].mode;
                filterName = minFilterModes[filterNdx].name;
                format = filterableFormatsByType[fmtNdx].format;
                formatName = filterableFormatsByType[fmtNdx].name;
                isMipmap = minFilter != gl.NEAREST &&
                    minFilter != gl.LINEAR;
                magFilter = isMipmap ? gl.LINEAR : minFilter;
                name = formatName + '_' + filterName;
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
                /** @type {number} */ var wrapR = gl.REPEAT;
                width = 64;
                height = 64;
                depth = 64;

                formatsGroup.addChild(
                    new es3fTextureFilteringTests.Texture3DFilteringCase(
                        name, '', minFilter, magFilter,
                        wrapS, wrapT, wrapR, format,
                        width, height, depth
                    )
                );
            }
        }

        // Sizes.
        for (var sizeNdx = 0; sizeNdx < sizes3D.length; sizeNdx++) {
            sizesGroup = new tcuTestCase.DeqpTest(
                '3d_sizes', '3D Texture Sizes');
            this.addChild(sizesGroup);
            for (var filterNdx = 0;
                filterNdx < minFilterModes.length;
                filterNdx++) {
                minFilter = minFilterModes[filterNdx].mode;
                filterName = minFilterModes[filterNdx].name;
                format = gl.RGBA8;
                isMipmap =
                    minFilter != gl.NEAREST && minFilter != gl.LINEAR;
                magFilter =
                    isMipmap ? gl.LINEAR : minFilter;
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
                wrapR = gl.REPEAT;
                width = sizes3D[sizeNdx].width;
                height = sizes3D[sizeNdx].height;
                depth = sizes3D[sizeNdx].depth;
                name = '' + width + 'x' + height + 'x' + depth +
                    '_' + filterName;

                sizesGroup.addChild(
                    new es3fTextureFilteringTests.Texture3DFilteringCase(
                        name, '', minFilter, magFilter,
                        wrapS, wrapT, wrapR, format,
                        width, height, depth
                    )
                );
            }
        }

        // Wrap modes.
        for (var minFilterNdx = 0;
            minFilterNdx < minFilterModes.length;
            minFilterNdx++) {
            for (var magFilterNdx = 0;
                magFilterNdx < magFilterModes.length;
                magFilterNdx++) {
                for (var wrapSNdx = 0;
                    wrapSNdx < wrapModes.length;
                    wrapSNdx++) {
                    combinationsGroup = new tcuTestCase.DeqpTest(
                        '3d_combinations',
                        '3D Filter and wrap mode combinations');
                    this.addChild(combinationsGroup);
                    for (var wrapTNdx = 0;
                        wrapTNdx < wrapModes.length;
                        wrapTNdx++) {
                        for (var wrapRNdx = 0;
                            wrapRNdx < wrapModes.length;
                            wrapRNdx++) {
                            minFilter = minFilterModes[minFilterNdx].mode;
                            magFilter = magFilterModes[magFilterNdx].mode;
                            format = gl.RGBA8;
                            wrapS = wrapModes[wrapSNdx].mode;
                            wrapT = wrapModes[wrapTNdx].mode;
                            wrapR = wrapModes[wrapRNdx].mode;
                            width = 63;
                            height = 57;
                            depth = 67;
                            name = minFilterModes[minFilterNdx].name + '_' +
                                magFilterModes[magFilterNdx].name + '_' +
                                wrapModes[wrapSNdx].name + '_' +
                                wrapModes[wrapTNdx].name + '_' +
                                wrapModes[wrapRNdx].name;

                            combinationsGroup.addChild(
                                new
                                es3fTextureFilteringTests.
                                Texture3DFilteringCase(
                                    name, '', minFilter, magFilter,
                                    wrapS, wrapT, wrapR, format,
                                    width, height, depth
                                )
                            );
                        }
                    }
                }
            }
        }
    };

    /**
     * Create and execute the test cases
     * @param {WebGL2RenderingContext} context
     * @param {Array<number>=} range Test range
     */
    es3fTextureFilteringTests.run = function(context, range) {
        gl = context;

        const canvas = gl.canvas;
        canvas.width = canvasWH;
        canvas.height = canvasWH;

        //Set up Test Root parameters
        var state = tcuTestCase.runner;

        state.setRoot(new es3fTextureFilteringTests.TextureFilteringTests());
        if (range)
            state.setRange(range);

        //Set up name and description of this test series.
        setCurrentTestName(state.testCases.fullName());
        description(state.testCases.getDescription());

        try {
            //Run test cases
            tcuTestCase.runTestCases();
        }
        catch (err) {
            testFailedOptions('Failed to run tests', false);
            tcuTestCase.runner.terminate();
        }
    };
});
