/*-------------------------------------------------------------------------
 * 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('modules.shared.glsBufferTestUtil');
goog.require('framework.common.tcuImageCompare');
goog.require('framework.common.tcuRGBA');
goog.require('framework.common.tcuSurface');
goog.require('framework.common.tcuTestCase');
goog.require('framework.common.tcuTexture');
goog.require('framework.delibs.debase.deMath');
goog.require('framework.delibs.debase.deRandom');
goog.require('framework.delibs.debase.deString');
goog.require('framework.delibs.debase.deUtil');
goog.require('framework.opengl.gluDrawUtil');
goog.require('framework.opengl.gluShaderProgram');
goog.require('framework.opengl.gluShaderUtil');

goog.scope(function() {

    var glsBufferTestUtil = modules.shared.glsBufferTestUtil;
    var tcuImageCompare = framework.common.tcuImageCompare;
    var tcuRGBA = framework.common.tcuRGBA;
    var tcuSurface = framework.common.tcuSurface;
    var tcuTestCase = framework.common.tcuTestCase;
    var tcuTexture = framework.common.tcuTexture;
    var gluShaderProgram = framework.opengl.gluShaderProgram;
    var gluShaderUtil = framework.opengl.gluShaderUtil;
    var gluDrawUtil = framework.opengl.gluDrawUtil;
    var deUtil = framework.delibs.debase.deUtil;
    var deMath = framework.delibs.debase.deMath;
    var deRandom = framework.delibs.debase.deRandom;
    var deString = framework.delibs.debase.deString;

    glsBufferTestUtil.VERIFY_QUAD_SIZE = 8; //!< Quad size in VertexArrayVerifier
    glsBufferTestUtil.MAX_LINES_PER_INDEX_ARRAY_DRAW = 128; //!< Maximum number of lines per one draw in IndexArrayVerifier
    glsBufferTestUtil.INDEX_ARRAY_DRAW_VIEWPORT_WIDTH = 128;
    glsBufferTestUtil.INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT = 128;

    // Helper functions.

    /**
     * @param {Uint8Array} ptr
     * @param {number} numBytes
     * @param {number} seed
     */
    glsBufferTestUtil.fillWithRandomBytes = function(ptr, numBytes, seed) {
        var rnd = new deRandom.Random(seed);
        for (var left = numBytes; left > 0; left--)
            ptr[left - 1] = rnd.getInt();
    };

    /**
     * @param {Uint8Array} resPtr
     * @param {Uint8Array} refPtr
     * @param {number} numBytes
     * @return {boolean}
     */
    glsBufferTestUtil.compareByteArrays = function(resPtr, refPtr, numBytes) {
        var isOk = true;
        var maxSpanLen = 8;
        var maxDiffSpans = 4;
        var numDiffSpans = 0;
        var diffSpanStart = -1;
        var ndx = 0;

        var log = 'Verification result: ';

        for (; ndx < numBytes; ndx++) {
            if (resPtr[ndx] != refPtr[ndx]) {
                if (diffSpanStart < 0)
                    diffSpanStart = ndx;

                isOk = false;
            } else if (diffSpanStart >= 0) {
                if (numDiffSpans < maxDiffSpans) {
                    var len = ndx - diffSpanStart;
                    var printLen = Math.min(len, maxSpanLen);

                    log += len + ' byte difference at offset ' + diffSpanStart + '\n' +
                        ' expected ' + refPtr.subarray(diffSpanStart, diffSpanStart + printLen) +
                        ' got ' + resPtr.subarray(diffSpanStart, diffSpanStart + printLen);
                } else
                    log += '(output too long, truncated)';

                numDiffSpans += 1;
                diffSpanStart = -1;
            }
        }

        if (diffSpanStart >= 0) {
            if (numDiffSpans < maxDiffSpans) {
                var len = ndx - diffSpanStart;
                var printLen = Math.min(len, maxSpanLen);

                log += len + ' byte difference at offset ' + diffSpanStart + '\n' +
                    ' expected ' + refPtr.subarray(diffSpanStart, diffSpanStart + printLen) +
                    ' got ' + resPtr.subarray(diffSpanStart, diffSpanStart + printLen);
            } else
                log += '(output too long, truncated)';
        }

        log += (isOk ? 'Verification passed.' : 'Verification FAILED!');

        bufferedLogToConsole(log);

        return isOk;
    };

    /**
     * @param {number} target
     * @return {string}
     */
    glsBufferTestUtil.getBufferTargetName = function(target) {
        switch (target) {
            case gl.ARRAY_BUFFER: return 'array';
            case gl.COPY_READ_BUFFER: return 'copy_read';
            case gl.COPY_WRITE_BUFFER: return 'copy_write';
            case gl.ELEMENT_ARRAY_BUFFER: return 'element_array';
            case gl.PIXEL_PACK_BUFFER: return 'pixel_pack';
            case gl.PIXEL_UNPACK_BUFFER: return 'pixel_unpack';
            //case gl.TEXTURE_BUFFER: return "texture"; //TODO: Unimplemented in WebGL 2. Remove?
            case gl.TRANSFORM_FEEDBACK_BUFFER: return 'transform_feedback';
            case gl.UNIFORM_BUFFER: return 'uniform';
            default:
                throw new Error('Invalid buffer target');
        }
    };

    /**
     * @param {number} hint
     * @return {string}
     */
    glsBufferTestUtil.getUsageHintName = function(hint) {
        switch (hint) {
            case gl.STREAM_DRAW: return 'stream_draw';
            case gl.STREAM_READ: return 'stream_read';
            case gl.STREAM_COPY: return 'stream_copy';
            case gl.STATIC_DRAW: return 'static_draw';
            case gl.STATIC_READ: return 'static_read';
            case gl.STATIC_COPY: return 'static_copy';
            case gl.DYNAMIC_DRAW: return 'dynamic_draw';
            case gl.DYNAMIC_READ: return 'dynamic_read';
            case gl.DYNAMIC_COPY: return 'dynamic_copy';
            default:
            throw new Error('Invalid buffer usage hint');
        }
    };

    // Base class for buffer cases.
    // BufferCase

    /**
     * @constructor
     * @extends {tcuTestCase.DeqpTest}
     * @param {string} name
     * @param {string} description
     */
    glsBufferTestUtil.BufferCase = function(name, description) {
        tcuTestCase.DeqpTest.call(this, name, description);
        /** @type {Array<WebGLBuffer>} */ this.m_allocatedBuffers = [];
    };

    glsBufferTestUtil.BufferCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    glsBufferTestUtil.BufferCase.prototype.constructor = glsBufferTestUtil.BufferCase;

    /**
     * init
     */
    glsBufferTestUtil.BufferCase.prototype.init = function() {};

    /**
     * deinit
     */
    glsBufferTestUtil.BufferCase.prototype.deinit = function() {
        for (var ndx = 0; ndx < this.m_allocatedBuffers.length; ndx++)
            this.deleteBuffer(this.m_allocatedBuffers[ndx]);
    };

    /**
     * @return {WebGLBuffer}
     */
    glsBufferTestUtil.BufferCase.prototype.genBuffer = function() {
        var buf = 0;
        buf = gl.createBuffer();
        if (buf != 0) {
            try {
                deUtil.dePushUniqueToArray(this.m_allocatedBuffers, buf);
            }
            catch (err) {
                gl.deleteBuffer(buf);
                throw err;
            }
        }
        return buf;
    };

    /**
     * @param {WebGLBuffer} buffer
     */
    glsBufferTestUtil.BufferCase.prototype.deleteBuffer = function(buffer) {
        gl.deleteBuffer(buffer);
        this.m_allocatedBuffers.splice(this.m_allocatedBuffers.indexOf(buffer), 1);
    };

    glsBufferTestUtil.BufferCase.prototype.checkError = function() {
        /** @type {number} */ var err = gl.getError();
        if (err != gl.NO_ERROR)
            throw new TestFailedException('Got ' + WebGLTestUtils.glEnumToString(gl, err));
    };

    // Reference buffer.

    /**
     * @constructor
     */
    glsBufferTestUtil.ReferenceBuffer = function() {
        /** @type {ArrayBuffer} */ this.m_data;
    };

    /**
     * @param {number=} offset
     * @return {Uint8Array}
     */
    glsBufferTestUtil.ReferenceBuffer.prototype.getPtr = function(offset) {
        offset = offset ? offset : 0; return new Uint8Array(this.m_data, offset);
    };

    /**
     * @param {number} numBytes
     */
    glsBufferTestUtil.ReferenceBuffer.prototype.setSize = function(numBytes) {
        this.m_data = new ArrayBuffer(numBytes);
    };

    /**
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     */
    glsBufferTestUtil.ReferenceBuffer.prototype.setData = function(numBytes, bytes) {
        this.setSize(numBytes);
        var dst = new Uint8Array(this.m_data);
        dst.set(bytes.subarray(numBytes));
    };

    /**
     * @param {number} offset
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     */
    glsBufferTestUtil.ReferenceBuffer.prototype.setSubData = function(offset, numBytes, bytes) {
        assertMsgOptions(deMath.deInBounds32(offset, 0, this.m_data.byteLength) && deMath.deInRange32(offset + numBytes, offset, this.m_data.byteLength),
            'Parameters not in buffer bounds or range', false, true);
        var dst = new Uint8Array(this.m_data, offset);
        dst.set(bytes.subarray(offset, offset + numBytes));
    };

    // Buffer writer system.

    /**
     * @enum {number}
     */
    glsBufferTestUtil.WriteType = {
        BUFFER_SUB_DATA: 0,
        BUFFER_WRITE_MAP: 1,
        TRANSFORM_FEEDBACK: 2,
        PIXEL_PACK: 3
    };

    /**
     * @param {glsBufferTestUtil.WriteType} write
     * @return {string}
     */
    glsBufferTestUtil.getWriteTypeDescription = function(write) {
        /** @type {Array<string>} */ var s_desc = [
            'gl.bufferSubData()',
            'gl.mapBufferRange()',
            'transform feedback',
            'gl.readPixels() into PBO binding'
        ];
        return /** @type {string} */ (deUtil.getArrayElement(s_desc, write));
    };

    // BufferWriterBase

    /**
     * @constructor
     */
    glsBufferTestUtil.BufferWriterBase = function() {};

    /**
     * //Meant to be overriden
     * @return {number}
     */
    glsBufferTestUtil.BufferWriterBase.prototype.getMinSize = function() { throw new Error('Must be overriden'); };

    /**
     * //Meant to be overriden
     * @return {number}
     */
    glsBufferTestUtil.BufferWriterBase.prototype.getAlignment = function() { throw new Error('Must be overriden'); };

    /**
     * //Meant to be overriden
     * @param {WebGLBuffer} buffer
     * @param {number} offset
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     */
    glsBufferTestUtil.BufferWriterBase.prototype.writeNoTarget = function(buffer, offset, numBytes, bytes) { throw new Error('Must be overriden'); };

    /**
     * @param {WebGLBuffer} buffer
     * @param {number} offset
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     * @param {number} targetHint
     */
    glsBufferTestUtil.BufferWriterBase.prototype.write = function(buffer, offset, numBytes, bytes, targetHint) {
        this.writeNoTarget(buffer, offset, numBytes, bytes);
    };

    // BufferWriter

    /**
     * @constructor
     * @param {glsBufferTestUtil.WriteType} writeType
     */
    glsBufferTestUtil.BufferWriter = function(writeType) {
        /** @type {glsBufferTestUtil.BufferWriterBase} */ this.m_writer = null;
        switch (writeType) {
            case glsBufferTestUtil.WriteType.BUFFER_SUB_DATA: this.m_writer = new glsBufferTestUtil.BufferSubDataWriter(); break;
            default:
                testFailed('Unsupported writer');
        }
    };

    /**
     * @return {number}
     */
    glsBufferTestUtil.BufferWriter.prototype.getMinSize = function() {return this.m_writer.getMinSize();};

    /**
     * @return {number}
     */
    glsBufferTestUtil.BufferWriter.prototype.getAlignment = function() {return this.m_writer.getAlignment();};

    /**
     * @param {WebGLBuffer} buffer
     * @param {number} offset
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     */
    glsBufferTestUtil.BufferWriter.prototype.writeNoTarget = function(buffer, offset, numBytes, bytes) {
        assertMsgOptions(numBytes >= this.getMinSize(), 'Number of bytes to write is smaller than the minimum size.', false, true);
        assertMsgOptions(offset % this.getAlignment() == 0, 'Offset is not aligned.', false, true);
        assertMsgOptions((offset + numBytes) % this.getAlignment() == 0, 'Buffer segment is not aligned', false, true);
        return this.m_writer.writeNoTarget(buffer, offset, numBytes, bytes);
    };

    /**
     * @param {WebGLBuffer} buffer
     * @param {number} offset
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     * @param {number} targetHint
     */
    glsBufferTestUtil.BufferWriter.prototype.write = function(buffer, offset, numBytes, bytes, targetHint) {
        assertMsgOptions(numBytes >= this.getMinSize(), 'Number of bytes to write is smaller than the minimum size.', false, true);
        assertMsgOptions(offset % this.getAlignment() == 0, 'Offset is not aligned.', false, true);
        assertMsgOptions((offset + numBytes) % this.getAlignment() == 0, 'Buffer segment is not aligned', false, true);
        return this.m_writer.write(buffer, offset, numBytes, bytes, targetHint);
    };

    // BufferSubDataWriter

    /**
     * @constructor
     * @extends {glsBufferTestUtil.BufferWriterBase}
     */
    glsBufferTestUtil.BufferSubDataWriter = function() {
        glsBufferTestUtil.BufferWriterBase.call(this);
    };

    glsBufferTestUtil.BufferSubDataWriter.prototype = Object.create(glsBufferTestUtil.BufferWriterBase.prototype);
    glsBufferTestUtil.BufferSubDataWriter.prototype.constructor = glsBufferTestUtil.BufferSubDataWriter;

    /**
     * @return {number}
     */
    glsBufferTestUtil.BufferSubDataWriter.prototype.getMinSize = function() { return 1; };

    /**
     * @return {number}
     */
    glsBufferTestUtil.BufferSubDataWriter.prototype.getAlignment = function() { return 1; };

    /**
     * @param {WebGLBuffer} buffer
     * @param {number} offset
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     */
    glsBufferTestUtil.BufferSubDataWriter.prototype.writeNoTarget = function(buffer, offset, numBytes, bytes) {
        this.write(buffer, offset, numBytes, bytes, gl.ARRAY_BUFFER);
    };

    /**
     * @param {WebGLBuffer} buffer
     * @param {number} offset
     * @param {number} numBytes
     * @param {Uint8Array} bytes
     * @param {number} target
     */
    glsBufferTestUtil.BufferSubDataWriter.prototype.write = function(buffer, offset, numBytes, bytes, target) {
        gl.bindBuffer(target, buffer);
        gl.bufferSubData(target, offset, bytes);
        gl.bindBuffer(target, null);
    };

    // Buffer verifier system.

    /**
     * @enum {number}
     */
    glsBufferTestUtil.VerifyType = {
        AS_VERTEX_ARRAY: 0,
        AS_INDEX_ARRAY: 1,
        AS_UNIFORM_BUFFER: 2,
        AS_PIXEL_UNPACK_BUFFER: 3,
        BUFFER_READ_MAP: 4
    };

    /**
     * @param {glsBufferTestUtil.VerifyType} verify
     * @return {string}
     */
    glsBufferTestUtil.getVerifyTypeDescription = function(verify) {
        /** @type {Array<string>} */ var s_desc =
        [
            'rendering as vertex data',
            'rendering as index data',
            'reading in shader as uniform buffer data',
            'using as PBO and uploading to texture',
            'reading back using glMapBufferRange()'
        ];

        return /** @type {string} */ (deUtil.getArrayElement(s_desc, verify));
    };

    /**
     * @constructor
     */
    glsBufferTestUtil.BufferVerifierBase = function() {};

    /**
     * //Meant to be overriden
     * @return {number}
     */
    glsBufferTestUtil.BufferVerifierBase.prototype.getMinSize = function() { throw new Error('Must be overriden'); };

    /**
     * //Meant to be overriden
     * @return {number}
     */
    glsBufferTestUtil.BufferVerifierBase.prototype.getAlignment = function() { throw new Error('Must be overriden'); };

    /**
     * @param {WebGLBuffer} buffer
     * @param {Uint8Array} reference
     * @param {number} offset
     * @param {number} numBytes
     * @return {boolean}
     */
    glsBufferTestUtil.BufferVerifierBase.prototype.verifyNoTarget = function(buffer, reference, offset, numBytes) {
        throw new Error('Must be overriden');
    };

    /**
     * //Meant to be overriden
     * @param {WebGLBuffer} buffer
     * @param {Uint8Array} reference
     * @param {number} offset
     * @param {number} numBytes
     * @param {number} targetHint
     * @return {boolean}
     */
    glsBufferTestUtil.BufferVerifierBase.prototype.verify = function(buffer, reference, offset, numBytes, targetHint) {
        //In WebGL 2, ELEMENT_ARRAY_BUFFER and TRANSFORM_FEEDBACK_BUFFER cannot be rebound to a different
        //type of buffer, so, let's copy their data to an ARRAY BUFFER and pass that one instead to be verified.
        var wasReadBufferCreated = false;
        try {
            if (targetHint == gl.ELEMENT_ARRAY_BUFFER || targetHint == gl.TRANSFORM_FEEDBACK_BUFFER) {
                var readBuffer = new Uint8Array(offset + numBytes);
                gl.getBufferSubData(targetHint, 0, readBuffer);
                buffer = gl.createBuffer();

                wasReadBufferCreated = true;

                gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
                gl.bufferData(gl.ARRAY_BUFFER, readBuffer, gl.STATIC_DRAW);
            }

            var result = this.verifyNoTarget(buffer, reference, offset, numBytes);

            if (wasReadBufferCreated)
                gl.deleteBuffer(buffer);

            return result;
        } catch (err) {
            if (wasReadBufferCreated)
                gl.deleteBuffer(buffer);
            throw err;
        }
    };

    // BufferVerifier

    /**
     * @constructor
     * @param {glsBufferTestUtil.VerifyType} verifyType
     */
    glsBufferTestUtil.BufferVerifier = function(verifyType) {
        /** @type {glsBufferTestUtil.BufferVerifierBase} */ this.m_verifier = null;
        switch (verifyType) {
            case glsBufferTestUtil.VerifyType.AS_VERTEX_ARRAY: this.m_verifier = new glsBufferTestUtil.VertexArrayVerifier(); break;
            case glsBufferTestUtil.VerifyType.AS_INDEX_ARRAY: this.m_verifier = new glsBufferTestUtil.IndexArrayVerifier(); break;
            default:
                testFailed('Unsupported verifier type');
        }
    };

    /**
     * @return {number}
     */
    glsBufferTestUtil.BufferVerifier.prototype.getMinSize = function() { return this.m_verifier.getMinSize(); };

    /**
     * @return {number}
     */
    glsBufferTestUtil.BufferVerifier.prototype.getAlignment = function() { return this.m_verifier.getAlignment(); };

    /**
     * @param {WebGLBuffer} buffer
     * @param {Uint8Array} reference
     * @param {number} numBytes
     * @return {boolean}
     */
    glsBufferTestUtil.BufferVerifier.prototype.verifyNoTarget = function(buffer, reference, offset, numBytes) {
        assertMsgOptions(numBytes >= this.getMinSize(), 'Number of bytes to write is smaller than the minimum size.', false, true);
        assertMsgOptions(offset % this.getAlignment() == 0, 'Offset is not aligned.', false, true);
        assertMsgOptions((offset + numBytes) % this.getAlignment() == 0, 'Buffer segment is not aligned', false, true);
        return this.m_verifier.verifyNoTarget(buffer, reference, offset, numBytes);
    };

    /**
     * @param {WebGLBuffer} buffer
     * @param {Uint8Array} reference
     * @param {number} offset
     * @param {number} numBytes
     * @param {number} targetHint
     * @return {boolean}
     */
    glsBufferTestUtil.BufferVerifier.prototype.verify = function(buffer, reference, offset, numBytes, targetHint) {
        assertMsgOptions(numBytes >= this.getMinSize(), 'Number of bytes to write is smaller than the minimum size.', false, true);
        assertMsgOptions(offset % this.getAlignment() == 0, 'Offset is not aligned.', false, true);
        assertMsgOptions((offset + numBytes) % this.getAlignment() == 0, 'Buffer segment is not aligned', false, true);
        return this.m_verifier.verify(buffer, reference, offset, numBytes, targetHint);
    };

    // VertexArrayVerifier

    /**
     * @constructor
     * @extends {glsBufferTestUtil.BufferVerifierBase}
     */
    glsBufferTestUtil.VertexArrayVerifier = function() {
        glsBufferTestUtil.BufferVerifierBase.call(this);
        /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
        this.m_posLoc = 0;
        this.m_byteVecLoc = 0;
        /** @type {WebGLVertexArrayObject} */ this.m_vao = null;

        /** @type {gluShaderUtil.GLSLVersion} */ var glslVersion = gluShaderUtil.getGLSLVersion(gl);

        assertMsgOptions(gluShaderUtil.isGLSLVersionSupported(gl, glslVersion), 'Unsupported GLSL version', false, true);

        this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(
            gluShaderUtil.getGLSLVersionDeclaration(glslVersion) + '\n' +
            'in highp vec2 a_position;\n' +
            'in mediump vec3 a_byteVec;\n' +
            'out mediump vec3 v_byteVec;\n' +
            'void main (void)\n' +
            '{\n' +
            ' gl_Position = vec4(a_position, 0.0, 1.0);\n' +
            ' v_byteVec = a_byteVec;\n' +
            '}\n',

            gluShaderUtil.getGLSLVersionDeclaration(glslVersion) + '\n' +
            'in mediump vec3 v_byteVec;\n' +
            'layout(location = 0) out mediump vec4 o_color;\n' +
            'void main (void)\n' +
            '{\n' +
            ' o_color = vec4(v_byteVec, 1.0);\n' +
            '}\n'
        ));

        if (!this.m_program.isOk()) {
            testFailed('Compile failed');
        }

        this.m_posLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
        this.m_byteVecLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_byteVec');

        this.m_vao = gl.createVertexArray();
        this.m_positionBuf = gl.createBuffer();
        this.m_indexBuf = gl.createBuffer();
    };

    glsBufferTestUtil.VertexArrayVerifier.prototype = Object.create(glsBufferTestUtil.BufferVerifierBase.prototype);
    glsBufferTestUtil.VertexArrayVerifier.prototype.constructor = glsBufferTestUtil.VertexArrayVerifier;

    /**
     * @return {number}
     */
    glsBufferTestUtil.VertexArrayVerifier.prototype.getMinSize = function() { return 3 * 4; };

    /**
     * @return {number}
     */
    glsBufferTestUtil.VertexArrayVerifier.prototype.getAlignment = function() { return 1; };

    /**
     * deinit
     */
    glsBufferTestUtil.VertexArrayVerifier.prototype.deinit = function() {
        if (this.m_vao) gl.deleteVertexArray(this.m_vao);
        if (this.m_positionBuf) gl.deleteBuffer(this.m_positionBuf);
        if (this.m_indexBuf) gl.deleteBuffer(this.m_indexBuf);
    };

    /**
     * @param {number} gridSizeX
     * @param {number} gridSizeY
     * @return {Array<number>}
     */
    glsBufferTestUtil.computePositions = function(gridSizeX, gridSizeY) {
        var positions = [];

        for (var y = 0; y < gridSizeY; y++)
        for (var x = 0; x < gridSizeX; x++) {
            /** @type {number} */ var sx0 = (x + 0) / gridSizeX;
            /** @type {number} */ var sy0 = (y + 0) / gridSizeY;
            /** @type {number} */ var sx1 = (x + 1) / gridSizeX;
            /** @type {number} */ var sy1 = (y + 1) / gridSizeY;
            /** @type {number} */ var fx0 = 2.0 * sx0 - 1.0;
            /** @type {number} */ var fy0 = 2.0 * sy0 - 1.0;
            /** @type {number} */ var fx1 = 2.0 * sx1 - 1.0;
            /** @type {number} */ var fy1 = 2.0 * sy1 - 1.0;
            /** @type {number} */ var baseNdx = (y * gridSizeX + x) * 8;

            positions[baseNdx + 0] = fx0; positions[baseNdx + 1] = fy0;
            positions[baseNdx + 2] = fx0; positions[baseNdx + 3] = fy1;
            positions[baseNdx + 4] = fx1; positions[baseNdx + 5] = fy0;
            positions[baseNdx + 6] = fx1; positions[baseNdx + 7] = fy1;
        }

        return positions;
    };

    /**
     * @param {number} gridSizeX
     * @param {number} gridSizeY
     * @return {Uint16Array}
     */
    glsBufferTestUtil.computeIndices = function(gridSizeX, gridSizeY) {
        var indices = new Uint16Array(3 * 2 * gridSizeX * gridSizeY);

        for (var quadNdx = 0; quadNdx < gridSizeX * gridSizeY; quadNdx++) {
            /** @type {number} */ var v00 = quadNdx * 4 + 0;
            /** @type {number} */ var v01 = quadNdx * 4 + 1;
            /** @type {number} */ var v10 = quadNdx * 4 + 2;
            /** @type {number} */ var v11 = quadNdx * 4 + 3;

            assertMsgOptions(v11 < (1 << 16), 'Vertex index value won\'t fit into a 16-bit number', false, true);

            indices[quadNdx * 6 + 0] = v10;
            indices[quadNdx * 6 + 1] = v00;
            indices[quadNdx * 6 + 2] = v01;

            indices[quadNdx * 6 + 3] = v10;
            indices[quadNdx * 6 + 4] = v01;
            indices[quadNdx * 6 + 5] = v11;
        }

        return indices;
    };

    /**
     * @param {Uint8Array} ptr
     * @param {number} vtxNdx
     * @return {Array<number>}
     */
    glsBufferTestUtil.fetchVtxColor = function(ptr, vtxNdx) {
        return new tcuRGBA.RGBA([
            ptr[vtxNdx * 3 + 0],
            ptr[vtxNdx * 3 + 1],
            ptr[vtxNdx * 3 + 2],
            255]).toVec();
    };

    /**
     * @param {tcuSurface.Surface} dst
     * @param {number} numQuads
     * @param {number} rowLength
     * @param {Uint8Array} inPtr
     */
    glsBufferTestUtil.renderQuadGridReference = function(dst, numQuads, rowLength, inPtr) {
        dst.setSize(rowLength * glsBufferTestUtil.VERIFY_QUAD_SIZE, (Math.floor(numQuads / rowLength) + (numQuads % rowLength != 0 ? 1 : 0)) * glsBufferTestUtil.VERIFY_QUAD_SIZE);

        /** @type {tcuTexture.PixelBufferAccess} */ var dstAccess = dst.getAccess();
        dstAccess.clear([0, 0, 0, 1.0]);

        for (var quadNdx = 0; quadNdx < numQuads; quadNdx++) {
            /** @type {number} */ var x0 = (quadNdx % rowLength) * glsBufferTestUtil.VERIFY_QUAD_SIZE;
            /** @type {number} */ var y0 = Math.floor(quadNdx / rowLength) * glsBufferTestUtil.VERIFY_QUAD_SIZE;
            /** @type {Array<number>} */ var v00 = glsBufferTestUtil.fetchVtxColor(inPtr, quadNdx * 4 + 0);
            /** @type {Array<number>} */ var v10 = glsBufferTestUtil.fetchVtxColor(inPtr, quadNdx * 4 + 1);
            /** @type {Array<number>} */ var v01 = glsBufferTestUtil.fetchVtxColor(inPtr, quadNdx * 4 + 2);
            /** @type {Array<number>} */ var v11 = glsBufferTestUtil.fetchVtxColor(inPtr, quadNdx * 4 + 3);

            for (var y = 0; y < glsBufferTestUtil.VERIFY_QUAD_SIZE; y++)
            for (var x = 0; x < glsBufferTestUtil.VERIFY_QUAD_SIZE; x++) {
                /** @type {number} */ var fx = (x + 0.5) / glsBufferTestUtil.VERIFY_QUAD_SIZE;
                /** @type {number} */ var fy = (y + 0.5) / glsBufferTestUtil.VERIFY_QUAD_SIZE;

                /** @type {boolean} */ var tri = fx + fy <= 1.0;
                /** @type {number} */ var tx = tri ? fx : (1.0 - fx);
                /** @type {number} */ var ty = tri ? fy : (1.0 - fy);
                /** @type {Array<number>} */ var t0 = tri ? v00 : v11;
                /** @type {Array<number>} */ var t1 = tri ? v01 : v10;
                /** @type {Array<number>} */ var t2 = tri ? v10 : v01;
                /** @type {Array<number>} */ var color = deMath.add(
                    deMath.add(t0, deMath.scale(deMath.subtract(t1, t0), tx)),
                    deMath.scale(deMath.subtract(t2, t0), ty)
                );

                dstAccess.setPixel(color, x0 + x, y0 + y);
            }
        }
    };

    /**
     * @param {WebGLBuffer} buffer
     * @param {Uint8Array} refPtr
     * @param {number} offset
     * @param {number} numBytes
     * @return {boolean}
     */
    glsBufferTestUtil.VertexArrayVerifier.prototype.verifyNoTarget = function(buffer, refPtr, offset, numBytes) {
        var numBytesInVtx = 3;
        var numBytesInQuad = numBytesInVtx * 4;
        var maxQuadsX = Math.min(128, Math.floor(gl.drawingBufferWidth / glsBufferTestUtil.VERIFY_QUAD_SIZE));
        var maxQuadsY = Math.min(128, Math.floor(gl.drawingBufferHeight / glsBufferTestUtil.VERIFY_QUAD_SIZE));
        var maxQuadsPerBatch = maxQuadsX * maxQuadsY;
        var numVerified = 0;
        var program = this.m_program.getProgram();
        /** @type {tcuRGBA.RGBA} */ var threshold = /*TODO: renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(3,3,3,3);*/ new tcuRGBA.RGBA([3, 3, 3, 3]);
        var isOk = true;

        /** @type {Array<number>} */ var positions = [];
        /** @type {Uint16Array} */var indices;

        /** @type {tcuSurface.Surface} */ var rendered = new tcuSurface.Surface();
        /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface();

        // Can't render full quad with smaller buffers.
        assertMsgOptions(numBytes >= numBytesInQuad, 'Number of bytes must be bigger than number of bytes per quad', false, true);

        positions = glsBufferTestUtil.computePositions(maxQuadsX, maxQuadsY);
        indices = glsBufferTestUtil.computeIndices(maxQuadsX, maxQuadsY);

        // Reset buffer bindings.
        gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);

        // Setup rendering state.
        gl.viewport(0, 0, maxQuadsX * glsBufferTestUtil.VERIFY_QUAD_SIZE, maxQuadsY * glsBufferTestUtil.VERIFY_QUAD_SIZE);
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.useProgram(program);
        gl.bindVertexArray(this.m_vao);

        // Upload positions
        gl.bindBuffer(gl.ARRAY_BUFFER, this.m_positionBuf);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
        gl.enableVertexAttribArray(this.m_posLoc);
        gl.vertexAttribPointer(this.m_posLoc, 2, gl.FLOAT, false, 0, 0);

        // Upload indices
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.m_indexBuf);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

        gl.enableVertexAttribArray(this.m_byteVecLoc);

        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

        while (numVerified < numBytes) {
            /** @type {number} */ var numRemaining = numBytes - numVerified;
            var isLeftoverBatch = numRemaining < numBytesInQuad;
            /** @type {number} */ var numBytesToVerify = isLeftoverBatch ? numBytesInQuad : Math.min(maxQuadsPerBatch * numBytesInQuad, numRemaining - numRemaining % numBytesInQuad);
            /** @type {number} */ var curOffset = isLeftoverBatch ? (numBytes - numBytesInQuad) : numVerified;
            /** @type {number} */ var numQuads = Math.floor(numBytesToVerify / numBytesInQuad);
            /** @type {number} */ var numCols = Math.min(maxQuadsX, numQuads);
            /** @type {number} */ var numRows = Math.floor(numQuads / maxQuadsX) + (numQuads % maxQuadsX != 0 ? 1 : 0);
            /** @type {string} */ var imageSetDesc = 'Bytes ' + (offset + curOffset) + ' to ' + (offset + curOffset + numBytesToVerify - 1);

            assertMsgOptions(numBytesToVerify > 0 && numBytesToVerify % numBytesInQuad == 0, 'Bytes to verify must be greater than zero and must be a multiple of the bytes per quad', false, true);
            assertMsgOptions(deMath.deInBounds32(curOffset, 0, numBytes), 'Offset out of bounds', false, true);
            assertMsgOptions(deMath.deInRange32(curOffset + numBytesToVerify, curOffset, numBytes), 'Range of bytes to verify outside of bounds', false, true);

            // Render batch.
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.vertexAttribPointer(this.m_byteVecLoc, 3, gl.UNSIGNED_BYTE, true, 0, offset + curOffset);
            gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_SHORT, 0);

            glsBufferTestUtil.renderQuadGridReference(reference, numQuads, numCols, refPtr.subarray(offset + curOffset));

            rendered.setSize(numCols * glsBufferTestUtil.VERIFY_QUAD_SIZE, numRows * glsBufferTestUtil.VERIFY_QUAD_SIZE);
            rendered.readViewport(gl, [0, 0, numCols * glsBufferTestUtil.VERIFY_QUAD_SIZE, numRows * glsBufferTestUtil.VERIFY_QUAD_SIZE]);

            if (!tcuImageCompare.pixelThresholdCompare('RenderResult', imageSetDesc, reference, rendered, threshold.toIVec(), tcuImageCompare.CompareLogMode.RESULT)) {
                isOk = false;
                break;
            }

            numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
        }

        gl.bindVertexArray(null);

        return isOk;
    };

    // IndexArrayVerifier

    /**
     * @constructor
     * @extends {glsBufferTestUtil.BufferVerifierBase}
     */
    glsBufferTestUtil.IndexArrayVerifier = function() {
        glsBufferTestUtil.BufferVerifierBase.call(this);

        this.m_program = null;
        this.m_posLoc = 0;
        this.m_colorLoc = 0;

        /** @type {gluShaderUtil.GLSLVersion} */ var glslVersion = gluShaderUtil.GLSLVersion.V300_ES;

        assertMsgOptions(gluShaderUtil.isGLSLVersionSupported(gl, glslVersion), 'GLSL version not supported', false, true);

        this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(
            gluShaderUtil.getGLSLVersionDeclaration(glslVersion) + '\n' +
            'in highp vec2 a_position;\n' +
            'in mediump vec3 a_color;\n' +
            'out mediump vec3 v_color;\n' +
            'void main (void)\n' +
            '{\n' +
            ' gl_Position = vec4(a_position, 0.0, 1.0);\n' +
            ' v_color = a_color;\n' +
            '}\n',

            gluShaderUtil.getGLSLVersionDeclaration(glslVersion) + '\n' +
            'in mediump vec3 v_color;\n' +
            'layout(location = 0) out mediump vec4 o_color;\n' +
            'void main (void)\n' +
            '{\n' +
            ' o_color = vec4(v_color, 1.0);\n' +
            '}\n'));

        if (!this.m_program.isOk()) {
            testFailed('Compile failed');
        }

        this.m_posLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
        this.m_colorLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_color');

        this.m_vao = gl.createVertexArray();
        this.m_positionBuf = gl.createBuffer();
        this.m_colorBuf = gl.createBuffer();
    };

    glsBufferTestUtil.IndexArrayVerifier.prototype = Object.create(glsBufferTestUtil.BufferVerifierBase.prototype);
    glsBufferTestUtil.IndexArrayVerifier.prototype.constructor = glsBufferTestUtil.IndexArrayVerifier;

    /**
     * deinit
     */
    glsBufferTestUtil.IndexArrayVerifier.prototype.deinit = function() {
        if (this.m_vao) gl.deleteVertexArray(this.m_vao);
        if (this.m_positionBuf) gl.deleteBuffer(this.m_positionBuf);
        if (this.m_colorBuf) gl.deleteBuffer(this.m_colorBuf);
    };

    /**
     * @return {Array<number>}
     */
    glsBufferTestUtil.computeIndexVerifierPositions = function() {
        var numPosX = 16;
        var numPosY = 16;

        var dst = [];

        for (var y = 0; y < numPosY; y++) {
            for (var x = 0; x < numPosX; x++) {
                var xf = x / (numPosX - 1);
                var yf = y / (numPosY - 1);

                var offset = 2 * (y * numPosX + x);
                dst[offset] = 2.0 * xf - 1.0;
                dst[offset + 1] = 2.0 * yf - 1.0;
            }
        }

        return dst;
    };

    /**
     * @return {Array<number>}
     */
    glsBufferTestUtil.computeIndexVerifierColors = function() {
        /** @type {number} */ var numColors = 256;
        /** @type {number} */ var minVal = 0.1;
        /** @type {number} */ var maxVal = 0.5;
        var rnd = new deRandom.Random(0xabc231);

        var dst = [];

        for (var i = 0; i < numColors; ++i) {
            dst[3 * i] = rnd.getFloat(minVal, maxVal);
            dst[3 * i + 1] = rnd.getFloat(minVal, maxVal);
            dst[3 * i + 2] = rnd.getFloat(minVal, maxVal);
        }

        return dst;
    };

    /**
     * @param {Array<number>} dst
     * @param {Array<number>} src
     * @param {Uint8Array} indices
     * @param {number} numIndices
     */
    glsBufferTestUtil.execVertexFetch = function(dst, src, indices, numIndices) {
        for (var i = 0; i < numIndices; ++i)
            dst[i] = src[indices[i]];
    };

    /**
     * @param {WebGLBuffer} buffer
     * @param {Uint8Array} refPtr
     * @param {number} offset
     * @param {number} numBytes
     * @return {boolean}
     */
    glsBufferTestUtil.IndexArrayVerifier.prototype.verify = function(buffer, refPtr, offset, numBytes) {
        var viewportW = Math.min(glsBufferTestUtil.INDEX_ARRAY_DRAW_VIEWPORT_WIDTH, gl.drawingBufferWidth);
        var viewportH = Math.min(glsBufferTestUtil.INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT, gl.drawingBufferHeight);
        var minBytesPerBatch = 2;
        /** @type {tcuRGBA.RGBA} */ var threshold = new tcuRGBA.RGBA([0, 0, 0, 0]);

        var positions = [];
        var colors = [];

        var fetchedPos = [];
        var fetchedColor = [];

        /** @type {tcuSurface.Surface} */ var indexBufferImg = new tcuSurface.Surface(viewportW, viewportH);
        /** @type {tcuSurface.Surface} */ var referenceImg = new tcuSurface.Surface(viewportW, viewportH);

        var numVerified = 0;
        var isOk = true;

        positions = glsBufferTestUtil.computeIndexVerifierPositions();
        colors = glsBufferTestUtil.computeIndexVerifierColors();

        // Reset buffer bindings.
        gl.bindVertexArray(this.m_vao);
        gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);

        // Setup rendering state.
        gl.viewport(0, 0, viewportW, viewportH);
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.useProgram(this.m_program.getProgram());
        gl.enableVertexAttribArray(this.m_posLoc);
        gl.enableVertexAttribArray(this.m_colorLoc);
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.ONE, gl.ONE);
        gl.blendEquation(gl.FUNC_ADD);

        while (numVerified < numBytes) {
            var numRemaining = numBytes - numVerified;
            var isLeftoverBatch = numRemaining < minBytesPerBatch;
            var numBytesToVerify = isLeftoverBatch ? minBytesPerBatch : Math.min(glsBufferTestUtil.MAX_LINES_PER_INDEX_ARRAY_DRAW + 1, numRemaining);
            var curOffset = isLeftoverBatch ? (numBytes - minBytesPerBatch) : numVerified;
            /** @type {string} */ var imageSetDesc = 'Bytes ' + (offset + curOffset) + ' to ' + (offset + curOffset + numBytesToVerify - 1);

            // Step 1: Render using index buffer.
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.bindBuffer(gl.ARRAY_BUFFER, this.m_positionBuf);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STREAM_DRAW);
            gl.vertexAttribPointer(this.m_posLoc, 2, gl.FLOAT, false, 0, 0);

            gl.bindBuffer(gl.ARRAY_BUFFER, this.m_colorBuf);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STREAM_DRAW);
            gl.vertexAttribPointer(this.m_colorLoc, 3, gl.FLOAT, false, 0, 0);

            gl.drawElements(gl.LINE_STRIP, numBytesToVerify, gl.UNSIGNED_BYTE, offset + curOffset);
            indexBufferImg.readViewport(gl);

            // Step 2: Do manual fetch and render without index buffer.
            glsBufferTestUtil.execVertexFetch(fetchedPos, positions, refPtr.subarray(offset + curOffset), numBytesToVerify);
            glsBufferTestUtil.execVertexFetch(fetchedColor, colors, refPtr.subarray(offset + curOffset), numBytesToVerify);

            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.bindBuffer(gl.ARRAY_BUFFER, this.m_positionBuf);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(fetchedPos), gl.STREAM_DRAW);
            gl.vertexAttribPointer(this.m_posLoc, 2, gl.FLOAT, false, 0, 0);

            gl.bindBuffer(gl.ARRAY_BUFFER, this.m_colorBuf);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(fetchedColor), gl.STREAM_DRAW);
            gl.vertexAttribPointer(this.m_colorLoc, 3, gl.FLOAT, false, 0, 0);

            gl.drawArrays(gl.LINE_STRIP, 0, numBytesToVerify);
            referenceImg.readViewport(gl, [0, 0, viewportW, viewportH]);

            if (!tcuImageCompare.pixelThresholdCompare('RenderResult', imageSetDesc, referenceImg, indexBufferImg, threshold.toIVec(), tcuImageCompare.CompareLogMode.RESULT)) {
                isOk = false;
                break;
            }

            numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
        }

        gl.bindVertexArray(null);

        return isOk;
    };

});
