tor-browser

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

glsAttributeLocationTests.js (70225B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL (ES) Module
      3 * -----------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the "License");
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *      http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an "AS IS" BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 *//*!
     20 * \file
     21 * \brief Attribute location tests
     22 *//*--------------------------------------------------------------------*/
     23 
     24 'use strict';
     25 goog.provide('modules.shared.glsAttributeLocationTests');
     26 goog.require('framework.common.tcuStringTemplate');
     27 goog.require('framework.common.tcuTestCase');
     28 goog.require('framework.opengl.gluShaderUtil');
     29 
     30 goog.scope(function() {
     31 
     32    var glsAttributeLocationTests = modules.shared.glsAttributeLocationTests;
     33    var tcuTestCase = framework.common.tcuTestCase;
     34    var gluShaderUtil = framework.opengl.gluShaderUtil;
     35    var tcuStringTemplate = framework.common.tcuStringTemplate;
     36 
     37      /**
     38        * @param {Array<number>} bindings
     39        * @param {string} attrib
     40        * @return {number}
     41        */
     42        glsAttributeLocationTests.getBoundLocation = function(bindings, attrib) {
     43                return (bindings[attrib] === undefined ? glsAttributeLocationTests.LocationEnum.UNDEF : bindings[attrib]);
     44        };
     45 
     46    /**
     47     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
     48     * @param {Array<number>} bindings
     49     * @return {boolean}
     50     */
     51    glsAttributeLocationTests.hasAttributeAliasing = function(attributes, bindings) {
     52        /** @type {Array<boolean>} */ var reservedSpaces = [];
     53 
     54        /** @type {number} */ var location;
     55        /** @type {number} */ var size;
     56 
     57        for (var attribNdx = 0; attribNdx < attributes.length; attribNdx++) {
     58              location = glsAttributeLocationTests.getBoundLocation(bindings, attributes[attribNdx].getName());
     59                size = attributes[attribNdx].getType().getLocationSize();
     60 
     61                if (location != glsAttributeLocationTests.LocationEnum.UNDEF) {
     62 
     63                    for (var i = 0; i < size; i++) {
     64                          if (reservedSpaces[location + i])
     65                                return true;
     66                            reservedSpaces[location + i] = true;
     67                    }
     68              }
     69        }
     70 
     71          return false;
     72    };
     73 
     74    /**
     75     * @return {number}
     76     */
     77    glsAttributeLocationTests.getMaxAttributeLocations = function() {
     78        /** @type {number} */ var maxAttribs;
     79        maxAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
     80        return maxAttribs;
     81    };
     82 
     83    /**
     84     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
     85     * @return {string}
     86     */
     87    glsAttributeLocationTests.generateAttributeDefinitions = function(attributes) {
     88        /** @type {string} */ var src = '';
     89 
     90        for (var i = 0; i < attributes.length; i++) {
     91            if (attributes[i].getLayoutLocation() != glsAttributeLocationTests.LocationEnum.UNDEF)
     92                src += ('layout(location = ' + attributes[i].getLayoutLocation() + ') ');
     93 
     94            src += '${VTX_INPUT} mediump ';
     95            src += (attributes[i].getType().getName() + ' ');
     96            src += attributes[i].getName();
     97            src += (attributes[i].getArraySize() != glsAttributeLocationTests.ArrayEnum.NOT ?
     98                '[' + attributes[i].getArraySize() + ']' : '');
     99            src += ';\n';
    100        }
    101 
    102        return src;
    103    };
    104 
    105    /**
    106     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    107     * @return {string}
    108     */
    109    glsAttributeLocationTests.generateConditionUniformDefinitions = function(attributes) {
    110        /** @type {string} */ var src = '';
    111        /** @type {Array<string>} */ var conditions = [];
    112 
    113        for (var i = 0; i < attributes.length; i++) {
    114            if (attributes[i].getCondition().notEquals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.NEVER)) &&
    115                attributes[i].getCondition().notEquals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS)))
    116                if (conditions.indexOf(attributes[i].getCondition().getName()) == -1)
    117                    conditions.push(attributes[i].getCondition().getName());
    118        }
    119 
    120        for (var i = 0; i < conditions.length; i++)
    121            src += ('uniform mediump float u_' + conditions[i] + ';\n');
    122 
    123        return src;
    124    };
    125 
    126    /**
    127     * @param {glsAttributeLocationTests.Attribute} attrib
    128     * @param {number=} id
    129     * @return {string}
    130     */
    131    glsAttributeLocationTests.generateToVec4Expression = function(attrib, id) {
    132        /** @type {string} */ var src = '';
    133        id = id === undefined ? -1 : id;
    134 
    135        /** @type {string} */
    136        var variableName = (attrib.getName() + (attrib.getArraySize() != glsAttributeLocationTests.ArrayEnum.NOT ? '[' + id + ']' : ''));
    137 
    138        switch (attrib.getType().getGLTypeEnum()) {
    139            case gl.INT_VEC2:
    140            case gl.UNSIGNED_INT_VEC2:
    141            case gl.FLOAT_VEC2:
    142                src += ('vec4(' + variableName + '.xy, ' + variableName + '.yx)');
    143                break;
    144 
    145            case gl.INT_VEC3:
    146            case gl.UNSIGNED_INT_VEC3:
    147            case gl.FLOAT_VEC3:
    148                src += ('vec4(' + variableName + '.xyz, ' + variableName + '.x)');
    149                break;
    150 
    151            default:
    152                src += ('vec4(' + variableName + ')');
    153                break;
    154        }
    155 
    156        return src;
    157    };
    158 
    159    /**
    160     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    161     * @return {string}
    162     */
    163    glsAttributeLocationTests.generateOutputCode = function(attributes) {
    164        /** @type {string} */ var src = '';
    165 
    166        for (var i = 0; i < attributes.length; i++) {
    167            if (attributes[i].getCondition().equals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.NEVER))) {
    168                src += '\tif (0 != 0)\n\t{\n';
    169 
    170                if (attributes[i].getArraySize() == glsAttributeLocationTests.ArrayEnum.NOT)
    171                    src += ('\t\tcolor += ' + glsAttributeLocationTests.generateToVec4Expression(attributes[i]) + ';\n');
    172                else {
    173                    for (var j = 0; j < attributes[i].getArraySize(); i++)
    174                        src += ('\t\tcolor += ' + glsAttributeLocationTests.generateToVec4Expression(attributes[i], j) + ';\n');
    175                }
    176 
    177                src += '\t}\n';
    178            } else if (attributes[i].getCondition().equals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS))) {
    179                if (attributes[i].getArraySize() == glsAttributeLocationTests.ArrayEnum.NOT)
    180                    src += ('\tcolor += ' + glsAttributeLocationTests.generateToVec4Expression(attributes[i]) + ';\n');
    181                else {
    182                    for (var j = 0; j < attributes[i].getArraySize(); j++)
    183                        src += ('\tcolor += ' + glsAttributeLocationTests.generateToVec4Expression(attributes[i], j) + ';\n');
    184                }
    185            } else {
    186                src += ('\tif (u_' + attributes[i].getCondition().getName() + (attributes[i].getCondition().getNegate() ? ' != ' : ' == ') + '0.0)\n');
    187                src += '\t{\n';
    188 
    189                if (attributes[i].getArraySize() == glsAttributeLocationTests.ArrayEnum.NOT)
    190                    src += ('\t\tcolor += ' + glsAttributeLocationTests.generateToVec4Expression(attributes[i]) + ';\n');
    191                else {
    192                    for (var j = 0; j < attributes[i].getArraySize(); i++)
    193                        src += ('\t\tcolor += ' + glsAttributeLocationTests.generateToVec4Expression(attributes[i], j) + ';\n');
    194                }
    195 
    196                src += '\t}\n';
    197            }
    198        }
    199 
    200        return src;
    201    };
    202 
    203    /**
    204     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    205     * @return {string}
    206     */
    207    glsAttributeLocationTests.generateVertexShaderTemplate = function(attributes) {
    208        /** @type {string} */ var src = '';
    209 
    210        src = '${VERSION}\n' +
    211        '${VTX_OUTPUT} mediump vec4 v_color;\n' +
    212        glsAttributeLocationTests.generateAttributeDefinitions(attributes) +
    213        '\n' +
    214        glsAttributeLocationTests.generateConditionUniformDefinitions(attributes) +
    215        '\n' +
    216        'void main (void)\n' +
    217        '{\n' +
    218        '\tmediump vec4 color = vec4(0.0);\n' +
    219        '\n' +
    220        glsAttributeLocationTests.generateOutputCode(attributes) +
    221        '\n' +
    222        '\tv_color = color;\n' +
    223        '\tgl_Position = color;\n' +
    224        '}\n';
    225 
    226        return src;
    227    };
    228 
    229    /**
    230     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    231     * @param {boolean} attributeAliasing
    232     * @return {string}
    233     */
    234    glsAttributeLocationTests.createVertexShaderSource = function(attributes, attributeAliasing) {
    235        // \note On GLES only GLSL #version 100 supports aliasing
    236        /** @type {gluShaderUtil.GLSLVersion} */ var glslVersion = gluShaderUtil.getGLSLVersion(gl);
    237        glslVersion = attributeAliasing ? gluShaderUtil.GLSLVersion.V100_ES : glslVersion;
    238        /** @type {boolean} */ var usesInOutQualifiers = gluShaderUtil.glslVersionUsesInOutQualifiers(glslVersion);
    239        /** @type {string} */ var vertexShaderTemplate = glsAttributeLocationTests.generateVertexShaderTemplate(attributes);
    240 
    241        /** @type {Array<string>} */ var parameters = [];
    242 
    243        parameters['VERSION'] = gluShaderUtil.getGLSLVersionDeclaration(glslVersion);
    244        parameters['VTX_OUTPUT'] = usesInOutQualifiers ? 'out' : 'varying';
    245        parameters['VTX_INPUT'] = usesInOutQualifiers ? 'in' : 'attribute';
    246        parameters['FRAG_INPUT'] = usesInOutQualifiers ? 'in' : 'varying';
    247        parameters['FRAG_OUTPUT_VAR'] = usesInOutQualifiers ? 'dEQP_FragColor' : 'gl_FragColor';
    248        parameters['FRAG_OUTPUT_DECLARATION'] = usesInOutQualifiers ? 'layout(location=0) out mediump vec4 dEQP_FragColor;' : '';
    249 
    250        return tcuStringTemplate.specialize(vertexShaderTemplate, parameters);
    251    };
    252 
    253    /**
    254     * @param {boolean} attributeAliasing
    255     * @return {string}
    256     */
    257    glsAttributeLocationTests.createFragmentShaderSource = function(attributeAliasing) {
    258        /** @type {string} */ var fragmentShaderSource = '';
    259        fragmentShaderSource = '${VERSION}\n' +
    260        '${FRAG_OUTPUT_DECLARATION}\n' +
    261        '${FRAG_INPUT} mediump vec4 v_color;\n' +
    262        'void main (void)\n' +
    263        '{\n' +
    264        '\t${FRAG_OUTPUT_VAR} = v_color;\n' +
    265        '}\n';
    266 
    267        // \note On GLES only GLSL #version 100 supports aliasing
    268        /** @type {gluShaderUtil.GLSLVersion} */ var glslVersion = gluShaderUtil.getGLSLVersion(gl);
    269        glslVersion = attributeAliasing ? gluShaderUtil.GLSLVersion.V100_ES : glslVersion;
    270        /** @type {boolean} */ var usesInOutQualifiers = gluShaderUtil.glslVersionUsesInOutQualifiers(glslVersion);
    271 
    272        /** @type {Array<string>} */ var parameters = [];
    273 
    274        parameters['VERSION'] = gluShaderUtil.getGLSLVersionDeclaration(glslVersion);
    275        parameters['VTX_OUTPUT'] = usesInOutQualifiers ? 'out' : 'varying';
    276        parameters['VTX_INPUT'] = usesInOutQualifiers ? 'in' : 'attribute';
    277        parameters['FRAG_INPUT'] = usesInOutQualifiers ? 'in' : 'varying';
    278        parameters['FRAG_OUTPUT_VAR'] = usesInOutQualifiers ? 'dEQP_FragColor' : 'gl_FragColor';
    279        parameters['FRAG_OUTPUT_DECLARATION'] = usesInOutQualifiers ? 'layout(location=0) out mediump vec4 dEQP_FragColor;' : '';
    280 
    281        return tcuStringTemplate.specialize(fragmentShaderSource, parameters);
    282    };
    283 
    284    glsAttributeLocationTests.logProgram = function(program) {
    285        var programLinkOk = /** @type {boolean} */ (gl.getProgramParameter(program, gl.LINK_STATUS));
    286        /**@type{string} */ var programInfoLog = gl.getProgramInfoLog(program);
    287        /**@type{string} */ var log = 'Program Link Info: ' + programInfoLog +
    288        'Link result: ' + (programLinkOk ? 'Ok' : 'Fail');
    289 
    290        bufferedLogToConsole(log);
    291    };
    292 
    293    glsAttributeLocationTests.logAttributes = function(attributes) {
    294        /**@type{string} */ var log;
    295        for (var i = 0; i < attributes.length; i++) {
    296 
    297            log = 'Type: ' + attributes[i].getType().getName() +
    298            ', Name: ' + attributes[i].getName() +
    299            (attributes[i].getLayoutLocation() != glsAttributeLocationTests.LocationEnum.UNDEF ? ', Layout location ' + attributes[i].getLayoutLocation() : '');
    300 
    301            bufferedLogToConsole(log);
    302        }
    303    };
    304 
    305    /**
    306     * @param {string} vertexShaderSource
    307     * @param {string} vertexShaderInfoLog
    308     * @param {boolean} vertexCompileOk
    309     * @param {string} fragmentShaderSource
    310     * @param {string} fragmentShaderInfoLog
    311     * @param {boolean} fragmentCompileOk
    312     */
    313    glsAttributeLocationTests.logShaders = function(vertexShaderSource, vertexShaderInfoLog, vertexCompileOk, fragmentShaderSource, fragmentShaderInfoLog, fragmentCompileOk) {
    314 
    315        /**@type{string} */ var log;
    316        log = '\nVertex Shader Info: ' +
    317        vertexShaderSource +
    318        '\nInfo Log: ' +
    319        vertexShaderInfoLog +
    320        '\nCompilation result: ' + (vertexCompileOk ? 'Ok' : 'Failed') +
    321 
    322        '\nFragment Shader Info: ' +
    323        fragmentShaderSource +
    324        '\nInfo Log: ' +
    325        fragmentShaderInfoLog +
    326        '\nCompilation result: ' + (fragmentCompileOk ? 'Ok' : 'Failed');
    327 
    328        bufferedLogToConsole(log);
    329    };
    330 
    331    /**
    332     * @param {WebGLProgram} program
    333     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    334     * @return {boolean}
    335     */
    336    glsAttributeLocationTests.checkActiveAttribQuery = function(program, attributes) {
    337        /** @type {number} */ var activeAttribCount = 0;
    338        /** @type {Array<string>} */ var activeAttributes = [];
    339        /** @type {boolean} */ var isOk = true;
    340        /** @type {string} */ var log;
    341 
    342        activeAttribCount = /** @type {number} */ (gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES));
    343 
    344        /** @type {glsAttributeLocationTests.Attribute} */ var attrib;
    345        /** @type {boolean} */ var isActive;
    346        /** @type {WebGLActiveInfo} */ var activeInfo;
    347 
    348        for (var activeAttribNdx = 0; activeAttribNdx < activeAttribCount; activeAttribNdx++) {
    349 
    350            activeInfo = gl.getActiveAttrib(program, activeAttribNdx);
    351 
    352            log = 'glGetActiveAttrib(program' +
    353            '\nindex= ' + activeAttribNdx +
    354            '\nsize= ' + activeInfo.size +
    355            '\ntype= ' + activeInfo.type +
    356            '\nname= ' + activeInfo.name;
    357 
    358            bufferedLogToConsole(log);
    359 
    360                /** @type {boolean} */ var found = false;
    361 
    362                for (var attribNdx = 0; attribNdx < attributes.length; attribNdx++) {
    363                    attrib = attributes[attribNdx];
    364 
    365                    if (attrib.getName() == activeInfo.name) {
    366                        if (activeInfo.type != attrib.getType().getGLTypeEnum()) {
    367 
    368                            log = 'Error: Wrong type ' + attrib.getType().getGLTypeEnum() +
    369                            ' expected= ' + activeInfo.type;
    370                            bufferedLogToConsole(log);
    371 
    372                            isOk = false;
    373                        }
    374 
    375                        if (attrib.getArraySize() == glsAttributeLocationTests.ArrayEnum.NOT) {
    376                            if (activeInfo.size != 1) {
    377 
    378                                bufferedLogToConsole('Error: Wrong size ' + activeInfo.size + ' expected 1');
    379                                isOk = false;
    380                            }
    381                        } else {
    382                            if (activeInfo.size != attrib.getArraySize()) {
    383                                bufferedLogToConsole('Error: Wrong size ' + activeInfo.size + ' expected ' + attrib.getArraySize());
    384 
    385                                isOk = false;
    386                            }
    387                        }
    388 
    389                        found = true;
    390                        break;
    391                    }
    392                }
    393 
    394                if (!found) {
    395                    log = 'Error: Unknown attribute ' + activeInfo.name + ' returned= by glGetActiveAttrib().';
    396                    bufferedLogToConsole(log);
    397 
    398                    isOk = false;
    399                }
    400 
    401            activeAttributes.push(activeInfo.name);
    402        }
    403 
    404        for (var attribNdx = 0; attribNdx < attributes.length; attribNdx++) {
    405            attrib = attributes[attribNdx];
    406            isActive = attrib.getCondition().notEquals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.NEVER));
    407 
    408            if (isActive) {
    409                if (activeAttributes.indexOf(attrib.getName()) == -1) {
    410 
    411                    bufferedLogToConsole('Error: Active attribute ' + attrib.getName() + 'wasn\'t returned by glGetActiveAttrib().');
    412                    isOk = false;
    413                }
    414            } else {
    415                if (activeAttributes[attrib.getName()] === undefined)
    416                    bufferedLogToConsole('Note: Inactive attribute ' + attrib.getName() + 'was returned by glGetActiveAttrib().');
    417            }
    418        }
    419 
    420        return isOk;
    421    };
    422 
    423    /**
    424     * @param {WebGLProgram} program
    425     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    426     * @param {Array<number>} bindings
    427     * @return {boolean}
    428     */
    429    glsAttributeLocationTests.checkAttribLocationQuery = function(program, attributes, bindings) {
    430        /** @type {boolean} */ var isOk = true;
    431        /** @type {string} */ var log;
    432 
    433        for (var attribNdx = 0; attribNdx < attributes.length; attribNdx++) {
    434            /** @type {glsAttributeLocationTests.Attribute} */ var attrib = attributes[attribNdx];
    435            /** @type {number} */ var expectedLocation = (attrib.getLayoutLocation() != glsAttributeLocationTests.LocationEnum.UNDEF ? attrib.getLayoutLocation() : glsAttributeLocationTests.getBoundLocation(bindings, attrib.getName()));
    436            var location = /** @type {number} */ (gl.getAttribLocation(program, attrib.getName()));
    437 
    438            if (attrib.getCondition().equals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.NEVER)) && location != -1)
    439                bufferedLogToConsole('Note: Inactive attribute with location.');
    440 
    441            if (attrib.getCondition().notEquals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.NEVER)) && expectedLocation != glsAttributeLocationTests.LocationEnum.UNDEF && expectedLocation != location)
    442            bufferedLogToConsole('Error: Invalid attribute location.');
    443 
    444            isOk = (attrib.getCondition().equals(glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.NEVER)) || expectedLocation == glsAttributeLocationTests.LocationEnum.UNDEF || expectedLocation == location);
    445        }
    446 
    447        return isOk;
    448    };
    449 
    450    /**
    451     * @param {WebGLProgram} program
    452     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    453     * @param {Array<number>} bindings
    454     * @return {boolean}
    455     */
    456    glsAttributeLocationTests.checkQuery = function(program, attributes, bindings) {
    457        /** @type {boolean} */ var isOk = glsAttributeLocationTests.checkActiveAttribQuery(program, attributes);
    458 
    459        if (!glsAttributeLocationTests.checkAttribLocationQuery(program, attributes, bindings))
    460            isOk = false;
    461 
    462        return isOk;
    463    };
    464 
    465    /**
    466     * @param {WebGLProgram} program
    467     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    468     * @param {boolean} attributeAliasing
    469     * @return {Object}
    470     */
    471    glsAttributeLocationTests.createAndAttachShaders = function(program, attributes, attributeAliasing) {
    472        /** @type {string} */ var vertexShaderSource = glsAttributeLocationTests.createVertexShaderSource(attributes, attributeAliasing);
    473        /** @type {string} */ var fragmentShaderSource = glsAttributeLocationTests.createFragmentShaderSource(attributeAliasing);
    474 
    475        /** @type {WebGLShader} */ var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    476        /** @type {WebGLShader} */ var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    477 
    478        gl.shaderSource(vertexShader, vertexShaderSource);
    479        gl.shaderSource(fragmentShader, fragmentShaderSource);
    480 
    481        gl.compileShader(vertexShader);
    482        gl.compileShader(fragmentShader);
    483 
    484        gl.attachShader(program, vertexShader);
    485        gl.attachShader(program, fragmentShader);
    486 
    487        var vertexShaderCompileOk = /** @type {boolean} */ (gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS));
    488        var fragmentShaderCompileOk = /** @type {boolean} */ (gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
    489 
    490        // log shaders
    491        glsAttributeLocationTests.logShaders(vertexShaderSource, gl.getShaderInfoLog(vertexShader),
    492            vertexShaderCompileOk,
    493            fragmentShaderSource, gl.getShaderInfoLog(fragmentShader),
    494            fragmentShaderCompileOk);
    495 
    496        assertMsgOptions(vertexShaderCompileOk, 'vertex Shader compile failed', false, true);
    497        assertMsgOptions(fragmentShaderCompileOk, 'fragment Shader compile failed', false, true);
    498 
    499        gl.deleteShader(vertexShader);
    500        gl.deleteShader(fragmentShader);
    501 
    502        return {first: vertexShader, second: fragmentShader};
    503 
    504    };
    505 
    506    /**
    507     * @param {WebGLProgram} program
    508     * @param {Array<glsAttributeLocationTests.Bind>} binds
    509     */
    510    glsAttributeLocationTests.bindAttributes = function(program, binds) {
    511        for (var i = 0; i < binds.length; i++) {
    512            bufferedLogToConsole('Bind attribute: ' + binds[i].getAttributeName() + ' to ' + binds[i].getLocation());
    513            gl.bindAttribLocation(program, binds[i].getLocation(), binds[i].getAttributeName());
    514        }
    515    };
    516 
    517    /**
    518     * @param {glsAttributeLocationTests.AttribType} type
    519     * @param {number=} arraySize
    520     * @return {string}
    521     */
    522    glsAttributeLocationTests.generateTestName = function(type, arraySize) {
    523        return type.getName() + (arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? '_array_' + arraySize : '');
    524    };
    525 
    526    /**
    527     * @constructor
    528     * @param {string} name
    529     * @param {number} locationSize
    530     * @param {number} typeEnum
    531     */
    532    glsAttributeLocationTests.AttribType = function(name, locationSize, typeEnum) {
    533        /** @type {string} */ this.m_name = name;
    534        /** @type {number} */ this.m_locationSize = locationSize;
    535        /** @type {number} */ this.m_glTypeEnum = typeEnum;
    536    };
    537 
    538    /**
    539     * @return {string}
    540     */
    541    glsAttributeLocationTests.AttribType.prototype.getName = function() {
    542        return this.m_name;
    543    };
    544 
    545    /**
    546     * @return {number}
    547     */
    548    glsAttributeLocationTests.AttribType.prototype.getLocationSize = function() {
    549        return this.m_locationSize;
    550    };
    551 
    552    /**
    553     * @return {number}
    554     */
    555    glsAttributeLocationTests.AttribType.prototype.getGLTypeEnum = function() {
    556        return this.m_glTypeEnum;
    557    };
    558 
    559    /**
    560     * @enum {number}
    561     */
    562    glsAttributeLocationTests.ConstCond = {
    563        ALWAYS: 0,
    564        NEVER: 1
    565    };
    566 
    567    /**
    568     * @constructor
    569     * @param {string} name
    570     * @param {boolean=} negate
    571     */
    572    glsAttributeLocationTests.Cond = function(name, negate) {
    573        /** @type {boolean} */ this.m_negate = negate === undefined ? false : negate;
    574        /** @type {string} */ this.m_name = name;
    575    };
    576 
    577    /**
    578     * @param {glsAttributeLocationTests.ConstCond} cond
    579     * @return {glsAttributeLocationTests.Cond}
    580     */
    581    glsAttributeLocationTests.NewCondWithEnum = function(cond) {
    582        var condObj = new glsAttributeLocationTests.Cond('', false);
    583        condObj.m_name = '__always__';
    584        condObj.m_negate = (cond != glsAttributeLocationTests.ConstCond.NEVER);
    585 
    586        return condObj;
    587    };
    588 
    589    /**
    590     * @param {glsAttributeLocationTests.Cond} other
    591     * @return {boolean}
    592     */
    593    glsAttributeLocationTests.Cond.prototype.equals = function(other) {
    594        return (this.m_negate == other.m_negate && this.m_name == other.m_name);
    595    };
    596 
    597    /**
    598     * @param {glsAttributeLocationTests.Cond} other
    599     * @return {boolean}
    600     */
    601    glsAttributeLocationTests.Cond.prototype.notEquals = function(other) {
    602        return (!this.equals(other));
    603    };
    604 
    605    /**
    606     * @return {string}
    607     */
    608    glsAttributeLocationTests.Cond.prototype.getName = function() {
    609        return this.m_name;
    610    };
    611 
    612    /**
    613     * @return {boolean}
    614     */
    615    glsAttributeLocationTests.Cond.prototype.getNegate = function() {
    616        return this.m_negate;
    617    };
    618 
    619    /**
    620     * @enum {number}
    621     */
    622    glsAttributeLocationTests.LocationEnum = {
    623        UNDEF: -1
    624    };
    625 
    626    /**
    627     * @enum {number}
    628     */
    629    glsAttributeLocationTests.ArrayEnum = {
    630        NOT: -1
    631    };
    632 
    633    /**
    634     * @constructor
    635     * @param {glsAttributeLocationTests.AttribType} type
    636     * @param {string} name
    637     * @param {number=} layoutLocation
    638     * @param {glsAttributeLocationTests.Cond=} cond
    639     * @param {number=} arraySize
    640     */
    641    glsAttributeLocationTests.Attribute = function(type, name, layoutLocation, cond, arraySize) {
    642        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
    643        /** @type {string} */ this.m_name = name;
    644        /** @type {number} */ this.m_layoutLocation = layoutLocation === undefined ? glsAttributeLocationTests.LocationEnum.UNDEF : layoutLocation;
    645        /** @type {glsAttributeLocationTests.Cond} */ this.m_cond = cond === undefined ?
    646                                glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS) : cond;
    647        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
    648    };
    649 
    650    /**
    651     * @return {glsAttributeLocationTests.AttribType}
    652     */
    653    glsAttributeLocationTests.Attribute.prototype.getType = function() {
    654        return this.m_type;
    655    };
    656 
    657    /**
    658     * @return {string}
    659     */
    660    glsAttributeLocationTests.Attribute.prototype.getName = function() {
    661        return this.m_name;
    662    };
    663 
    664    /**
    665     * @return {number}
    666     */
    667    glsAttributeLocationTests.Attribute.prototype.getLayoutLocation = function() {
    668        return this.m_layoutLocation;
    669    };
    670 
    671    /**
    672     * @return {glsAttributeLocationTests.Cond}
    673     */
    674    glsAttributeLocationTests.Attribute.prototype.getCondition = function() {
    675        return this.m_cond;
    676    };
    677 
    678    /**
    679     * @return {number}
    680     */
    681    glsAttributeLocationTests.Attribute.prototype.getArraySize = function() {
    682        return this.m_arraySize;
    683    };
    684 
    685    /**
    686     * @constructor
    687     * @param {string} attribute
    688     * @param {number} location
    689     */
    690    glsAttributeLocationTests.Bind = function(attribute, location) {
    691        /** @type {string} */ this.m_attribute = attribute;
    692        /** @type {number} */ this.m_location = location;
    693    };
    694 
    695    /**
    696     * @return {string}
    697     */
    698    glsAttributeLocationTests.Bind.prototype.getAttributeName = function() {
    699        return this.m_attribute;
    700    };
    701 
    702    /**
    703     * @return {number}
    704     */
    705    glsAttributeLocationTests.Bind.prototype.getLocation = function() {
    706        return this.m_location;
    707    };
    708 
    709    /**
    710     * @param {Array<glsAttributeLocationTests.Attribute>} attributes
    711     * @param {Array<glsAttributeLocationTests.Bind>} preAttachBind
    712     * @param {Array<glsAttributeLocationTests.Bind>} preLinkBind
    713     * @param {Array<glsAttributeLocationTests.Bind>} postLinkBind
    714     * @param {boolean} relink
    715     * @param {boolean=} reattach
    716     * @param {Array<glsAttributeLocationTests.Attribute>=} reattachAttributes
    717     */
    718    glsAttributeLocationTests.runTest = function(attributes, preAttachBind, preLinkBind, postLinkBind, relink, reattach, reattachAttributes) {
    719        reattach = reattach === undefined ? false : reattach;
    720        reattachAttributes = reattachAttributes === undefined ? [] : reattachAttributes;
    721 
    722        try {
    723            /** @type {boolean} */ var isOk = true;
    724            /** @type {Array<number>} */ var activeBindings = [];
    725 
    726            for (var bindNdx = 0; bindNdx < preAttachBind.length; bindNdx++)
    727                activeBindings[preAttachBind[bindNdx].getAttributeName()] = preAttachBind[bindNdx].getLocation();
    728 
    729            for (var bindNdx = 0; bindNdx < preLinkBind.length; bindNdx++)
    730                activeBindings[preLinkBind[bindNdx].getAttributeName()] = preLinkBind[bindNdx].getLocation();
    731 
    732            glsAttributeLocationTests.logAttributes(attributes);
    733 
    734            /** @type {WebGLProgram} */ var program = gl.createProgram();
    735 
    736            if (!preAttachBind.length == 0)
    737                glsAttributeLocationTests.bindAttributes(program, preAttachBind);
    738 
    739            /** @type {*} */ var shaders = glsAttributeLocationTests.createAndAttachShaders(program, attributes, glsAttributeLocationTests.hasAttributeAliasing(attributes, activeBindings));
    740 
    741            if (!preLinkBind.length == 0)
    742                glsAttributeLocationTests.bindAttributes(program, preLinkBind);
    743 
    744                gl.linkProgram(program);
    745 
    746                assertMsgOptions(gl.getProgramParameter(program, gl.LINK_STATUS) == true, 'link program failed', false, true);
    747 
    748                glsAttributeLocationTests.logProgram(program);
    749 
    750            if (!glsAttributeLocationTests.checkQuery(program, attributes, activeBindings))
    751                isOk = false;
    752 
    753            if (!postLinkBind.length == 0) {
    754                glsAttributeLocationTests.bindAttributes(program, postLinkBind);
    755 
    756                if (!glsAttributeLocationTests.checkQuery(program, attributes, activeBindings))
    757                    isOk = false;
    758            }
    759 
    760            if (relink) {
    761                gl.linkProgram(program);
    762 
    763                assertMsgOptions(gl.getProgramParameter(program, gl.LINK_STATUS) == true, 'link program failed', false, true);
    764 
    765                glsAttributeLocationTests.logProgram(program);
    766 
    767                for (var bindNdx = 0; bindNdx < postLinkBind.length; bindNdx++)
    768                    activeBindings[postLinkBind[bindNdx].getAttributeName()] = postLinkBind[bindNdx].getLocation();
    769 
    770                if (!glsAttributeLocationTests.checkQuery(program, attributes, activeBindings))
    771                    isOk = false;
    772            }
    773 
    774            if (reattach) {
    775                gl.detachShader(program, shaders.first);
    776                gl.detachShader(program, shaders.second);
    777 
    778                glsAttributeLocationTests.createAndAttachShaders(program, reattachAttributes, glsAttributeLocationTests.hasAttributeAliasing(reattachAttributes, activeBindings));
    779 
    780                gl.linkProgram(program);
    781 
    782                assertMsgOptions(gl.getProgramParameter(program, gl.LINK_STATUS) == true, 'link program failed', false, true);
    783 
    784                glsAttributeLocationTests.logProgram(program);
    785 
    786                if (!glsAttributeLocationTests.checkQuery(program, reattachAttributes, activeBindings))
    787                    isOk = false;
    788            }
    789 
    790            gl.deleteProgram(program);
    791 
    792            assertMsgOptions(isOk, '', true, true);
    793 
    794        } catch (e) {
    795            if (program)
    796                gl.deleteProgram(program);
    797 
    798            throw e;
    799        }
    800    };
    801 
    802    /**
    803     * @constructor
    804     * @extends {tcuTestCase.DeqpTest}
    805     * @param {glsAttributeLocationTests.AttribType} type
    806     * @param {number=} arraySize
    807     */
    808    glsAttributeLocationTests.BindAttributeTest = function(type, arraySize) {
    809        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
    810        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
    811        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
    812    };
    813 
    814    glsAttributeLocationTests.BindAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    815    glsAttributeLocationTests.BindAttributeTest.prototype.constructor = glsAttributeLocationTests.BindAttributeTest;
    816 
    817    glsAttributeLocationTests.BindAttributeTest.prototype.iterate = function() {
    818        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
    819 
    820        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
    821        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
    822 
    823        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_0', glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
    824        bindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
    825 
    826        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false);
    827        return tcuTestCase.IterateResult.STOP;
    828    };
    829 
    830    /**
    831     * @constructor
    832     * @extends {tcuTestCase.DeqpTest}
    833     * @param {glsAttributeLocationTests.AttribType} type
    834     * @param {number=} arraySize
    835     */
    836    glsAttributeLocationTests.BindMaxAttributesTest = function(type, arraySize) {
    837        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
    838        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
    839        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
    840    };
    841 
    842    glsAttributeLocationTests.BindMaxAttributesTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    843    glsAttributeLocationTests.BindMaxAttributesTest.prototype.constructor = glsAttributeLocationTests.BindMaxAttributesTest;
    844 
    845    glsAttributeLocationTests.BindMaxAttributesTest.prototype.iterate = function() {
    846        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
    847        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
    848        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
    849 
    850        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
    851        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
    852        /** @type {number} */ var ndx = 0;
    853 
    854        bufferedLogToConsole('MAX_VERTEX_ATTRIBS: ' + maxAttributes);
    855 
    856        for (var loc = maxAttributes - (arrayElementCount * this.m_type.getLocationSize()); loc >= 0; loc -= (arrayElementCount * this.m_type.getLocationSize())) {
    857            attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_' + ndx, glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
    858            bindings.push(new glsAttributeLocationTests.Bind('a_' + ndx, loc));
    859            ndx++;
    860        }
    861 
    862        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false);
    863        return tcuTestCase.IterateResult.STOP;
    864    };
    865 
    866    /**
    867     * @constructor
    868     * @extends {tcuTestCase.DeqpTest}
    869     * @param {glsAttributeLocationTests.AttribType} type
    870     * @param {number=} arraySize
    871     */
    872    glsAttributeLocationTests.BindHoleAttributeTest = function(type, arraySize) {
    873        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
    874        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
    875        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
    876    };
    877 
    878    glsAttributeLocationTests.BindHoleAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    879    glsAttributeLocationTests.BindHoleAttributeTest.prototype.constructor = glsAttributeLocationTests.BindHoleAttributeTest;
    880 
    881    glsAttributeLocationTests.BindHoleAttributeTest.prototype.iterate = function() {
    882        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
    883        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
    884        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
    885        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
    886 
    887        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
    888        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
    889 
    890        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0'));
    891        bindings.push(new glsAttributeLocationTests.Bind('a_0', 0));
    892 
    893        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_1', glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
    894 
    895        /** @type {number} */ var ndx = 2;
    896        for (var loc = 1 + this.m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) {
    897            attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_' + ndx));
    898            bindings.push(new glsAttributeLocationTests.Bind('a_' + ndx, loc));
    899 
    900            ndx++;
    901        }
    902 
    903        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false);
    904        return tcuTestCase.IterateResult.STOP;
    905    };
    906 
    907    /**
    908     * @constructor
    909     * @extends {tcuTestCase.DeqpTest}
    910     */
    911    glsAttributeLocationTests.PreAttachBindAttributeTest = function() {
    912        tcuTestCase.DeqpTest.call(this, 'pre_attach', 'pre_attach');
    913    };
    914 
    915    glsAttributeLocationTests.PreAttachBindAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    916    glsAttributeLocationTests.PreAttachBindAttributeTest.prototype.constructor = glsAttributeLocationTests.PreAttachBindAttributeTest;
    917 
    918    glsAttributeLocationTests.PreAttachBindAttributeTest.prototype.iterate = function() {
    919        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
    920        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
    921 
    922        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
    923        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
    924        /** @type {number} */ var ndx = 0;
    925 
    926        attributes.push(new glsAttributeLocationTests.Attribute(new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4), 'a_0'));
    927        bindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
    928 
    929        glsAttributeLocationTests.runTest(attributes, bindings, noBindings, noBindings, false);
    930        return tcuTestCase.IterateResult.STOP;
    931    };
    932 
    933    /**
    934     * @constructor
    935     * @extends {tcuTestCase.DeqpTest}
    936     */
    937    glsAttributeLocationTests.PreLinkBindAttributeTest = function() {
    938        tcuTestCase.DeqpTest.call(this, 'pre_link', 'pre_link');
    939    };
    940 
    941    glsAttributeLocationTests.PreLinkBindAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    942    glsAttributeLocationTests.PreLinkBindAttributeTest.prototype.constructor = glsAttributeLocationTests.PreLinkBindAttributeTest;
    943 
    944    glsAttributeLocationTests.PreLinkBindAttributeTest.prototype.iterate = function() {
    945        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
    946 
    947        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
    948        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
    949        /** @type {number} */ var ndx = 0;
    950 
    951        attributes.push(new glsAttributeLocationTests.Attribute(new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4), 'a_0'));
    952        bindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
    953 
    954        glsAttributeLocationTests.runTest(attributes, bindings, noBindings, noBindings, false);
    955        return tcuTestCase.IterateResult.STOP;
    956    };
    957 
    958    /**
    959     * @constructor
    960     * @extends {tcuTestCase.DeqpTest}
    961     */
    962    glsAttributeLocationTests.PostLinkBindAttributeTest = function() {
    963        tcuTestCase.DeqpTest.call(this, 'post_link', 'post_link');
    964    };
    965 
    966    glsAttributeLocationTests.PostLinkBindAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    967    glsAttributeLocationTests.PostLinkBindAttributeTest.prototype.constructor = glsAttributeLocationTests.PostLinkBindAttributeTest;
    968 
    969    glsAttributeLocationTests.PostLinkBindAttributeTest.prototype.iterate = function() {
    970        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
    971 
    972        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
    973        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
    974 
    975        attributes.push(new glsAttributeLocationTests.Attribute(new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4), 'a_0'));
    976        bindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
    977 
    978        glsAttributeLocationTests.runTest(attributes, noBindings, noBindings, bindings, false);
    979        return tcuTestCase.IterateResult.STOP;
    980    };
    981 
    982    /**
    983     * @constructor
    984     * @extends {tcuTestCase.DeqpTest}
    985     */
    986    glsAttributeLocationTests.BindReattachAttributeTest = function() {
    987        tcuTestCase.DeqpTest.call(this, 'reattach', 'reattach');
    988    };
    989 
    990    glsAttributeLocationTests.BindReattachAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    991    glsAttributeLocationTests.BindReattachAttributeTest.prototype.constructor = glsAttributeLocationTests.BindReattachAttributeTest;
    992 
    993    glsAttributeLocationTests.BindReattachAttributeTest.prototype.iterate = function() {
    994        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
    995        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
    996        /** @type {glsAttributeLocationTests.AttribType} */ var vec2 = new glsAttributeLocationTests.AttribType('vec2', 1, gl.FLOAT_VEC2);
    997 
    998        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
    999        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1000        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var reattachAttributes = [];
   1001 
   1002        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0'));
   1003        bindings.push(new glsAttributeLocationTests.Bind('a_0', 1));
   1004        bindings.push(new glsAttributeLocationTests.Bind('a_1', 1));
   1005 
   1006        reattachAttributes.push(new glsAttributeLocationTests.Attribute(vec2, 'a_1'));
   1007 
   1008        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false, true, reattachAttributes);
   1009        return tcuTestCase.IterateResult.STOP;
   1010    };
   1011 
   1012    /**
   1013     * @constructor
   1014     * @extends {tcuTestCase.DeqpTest}
   1015     * @param {glsAttributeLocationTests.AttribType} type
   1016     * @param {number=} arraySize
   1017     */
   1018    glsAttributeLocationTests.LocationAttributeTest = function(type, arraySize) {
   1019        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1020        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1021        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1022    };
   1023 
   1024    glsAttributeLocationTests.LocationAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1025    glsAttributeLocationTests.LocationAttributeTest.prototype.constructor = glsAttributeLocationTests.LocationAttributeTest;
   1026 
   1027    glsAttributeLocationTests.LocationAttributeTest.prototype.iterate = function() {
   1028        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1029        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1030 
   1031        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_0', 3, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1032 
   1033        glsAttributeLocationTests.runTest(attributes, noBindings, noBindings, noBindings, false);
   1034        return tcuTestCase.IterateResult.STOP;
   1035    };
   1036 
   1037    /**
   1038     * @constructor
   1039     * @extends {tcuTestCase.DeqpTest}
   1040     * @param {glsAttributeLocationTests.AttribType} type
   1041     * @param {number=} arraySize
   1042     */
   1043    glsAttributeLocationTests.LocationMaxAttributesTest = function(type, arraySize) {
   1044        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1045        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1046        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1047    };
   1048 
   1049    glsAttributeLocationTests.LocationMaxAttributesTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1050    glsAttributeLocationTests.LocationMaxAttributesTest.prototype.constructor = glsAttributeLocationTests.LocationMaxAttributesTest;
   1051 
   1052    glsAttributeLocationTests.LocationMaxAttributesTest.prototype.iterate = function() {
   1053        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1054        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
   1055        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
   1056 
   1057        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1058        /** @type {number} */ var ndx = 0;
   1059 
   1060        bufferedLogToConsole('MAX_VERTEX_ATTRIBS: ' + maxAttributes);
   1061 
   1062        for (var loc = maxAttributes - (arrayElementCount * this.m_type.getLocationSize()); loc >= 0; loc -= (arrayElementCount * this.m_type.getLocationSize())) {
   1063            attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_' + ndx, loc, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1064            ndx++;
   1065        }
   1066 
   1067        glsAttributeLocationTests.runTest(attributes, noBindings, noBindings, noBindings, false);
   1068        return tcuTestCase.IterateResult.STOP;
   1069    };
   1070 
   1071    /**
   1072     * @constructor
   1073     * @extends {tcuTestCase.DeqpTest}
   1074     * @param {glsAttributeLocationTests.AttribType} type
   1075     * @param {number=} arraySize
   1076     */
   1077    glsAttributeLocationTests.LocationHoleAttributeTest = function(type, arraySize) {
   1078        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1079        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1080        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1081    };
   1082 
   1083    glsAttributeLocationTests.LocationHoleAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1084    glsAttributeLocationTests.LocationHoleAttributeTest.prototype.constructor = glsAttributeLocationTests.LocationHoleAttributeTest;
   1085 
   1086    glsAttributeLocationTests.LocationHoleAttributeTest.prototype.iterate = function() {
   1087        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1088        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
   1089        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
   1090        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
   1091 
   1092        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1093 
   1094        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0', 0));
   1095 
   1096        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_1', glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1097 
   1098        /** @type {number} */ var ndx = 2;
   1099        for (var loc = 1 + this.m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) {
   1100            attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_' + ndx, loc));
   1101            ndx++;
   1102        }
   1103 
   1104        glsAttributeLocationTests.runTest(attributes, noBindings, noBindings, noBindings, false);
   1105 
   1106        return tcuTestCase.IterateResult.STOP;
   1107    };
   1108 
   1109    /**
   1110     * @constructor
   1111     * @extends {tcuTestCase.DeqpTest}
   1112     * @param {glsAttributeLocationTests.AttribType} type
   1113     * @param {number=} arraySize
   1114     */
   1115    glsAttributeLocationTests.MixedAttributeTest = function(type, arraySize) {
   1116        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1117        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1118        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1119    };
   1120 
   1121    glsAttributeLocationTests.MixedAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1122    glsAttributeLocationTests.MixedAttributeTest.prototype.constructor = glsAttributeLocationTests.MixedAttributeTest;
   1123 
   1124    glsAttributeLocationTests.MixedAttributeTest.prototype.iterate = function() {
   1125        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1126 
   1127        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
   1128        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1129 
   1130        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_0', 3, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1131        bindings.push(new glsAttributeLocationTests.Bind('a_0', 4));
   1132 
   1133        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false);
   1134        return tcuTestCase.IterateResult.STOP;
   1135    };
   1136 
   1137    /**
   1138     * @constructor
   1139     * @extends {tcuTestCase.DeqpTest}
   1140     * @param {glsAttributeLocationTests.AttribType} type
   1141     * @param {number=} arraySize
   1142     */
   1143    glsAttributeLocationTests.MixedMaxAttributesTest = function(type, arraySize) {
   1144        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1145        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1146        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1147    };
   1148 
   1149    glsAttributeLocationTests.MixedMaxAttributesTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1150    glsAttributeLocationTests.MixedMaxAttributesTest.prototype.constructor = glsAttributeLocationTests.MixedMaxAttributesTest;
   1151 
   1152    glsAttributeLocationTests.MixedMaxAttributesTest.prototype.iterate = function() {
   1153        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1154        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
   1155        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
   1156 
   1157        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
   1158        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1159        /** @type {number} */ var ndx = 0;
   1160 
   1161        bufferedLogToConsole('MAX_VERTEX_ATTRIBS: ' + maxAttributes);
   1162 
   1163        for (var loc = maxAttributes - (arrayElementCount * this.m_type.getLocationSize()); loc >= 0; loc -= (arrayElementCount * this.m_type.getLocationSize())) {
   1164            if ((ndx % 2) != 0)
   1165                attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_' + ndx, loc, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1166            else {
   1167                attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_' + ndx, glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1168                bindings.push(new glsAttributeLocationTests.Bind('a_' + ndx, loc));
   1169            }
   1170            ndx++;
   1171        }
   1172 
   1173        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false);
   1174        return tcuTestCase.IterateResult.STOP;
   1175    };
   1176 
   1177    /**
   1178     * @constructor
   1179     * @extends {tcuTestCase.DeqpTest}
   1180     * @param {glsAttributeLocationTests.AttribType} type
   1181     * @param {number=} arraySize
   1182     */
   1183    glsAttributeLocationTests.MixedHoleAttributeTest = function(type, arraySize) {
   1184        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1185        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1186        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1187    };
   1188 
   1189    glsAttributeLocationTests.MixedHoleAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1190    glsAttributeLocationTests.MixedHoleAttributeTest.prototype.constructor = glsAttributeLocationTests.MixedHoleAttributeTest;
   1191 
   1192    glsAttributeLocationTests.MixedHoleAttributeTest.prototype.iterate = function() {
   1193        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1194        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
   1195        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
   1196        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
   1197 
   1198        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
   1199        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1200 
   1201        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0'));
   1202        bindings.push(new glsAttributeLocationTests.Bind('a_0', 0));
   1203 
   1204        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_1', glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1205 
   1206        /** @type {number} */ var ndx = 2;
   1207        for (var loc = 1 + this.m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) {
   1208            if ((ndx % 2) != 0)
   1209                attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_' + ndx, loc));
   1210            else {
   1211                attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_' + ndx, loc));
   1212                bindings.push(new glsAttributeLocationTests.Bind('a_' + ndx, loc));
   1213            }
   1214            ndx++;
   1215        }
   1216 
   1217        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false);
   1218        return tcuTestCase.IterateResult.STOP;
   1219    };
   1220 
   1221    /**
   1222     * @constructor
   1223     * @extends {tcuTestCase.DeqpTest}
   1224     */
   1225    glsAttributeLocationTests.BindRelinkAttributeTest = function() {
   1226        tcuTestCase.DeqpTest.call(this, 'relink', 'relink');
   1227    };
   1228 
   1229    glsAttributeLocationTests.BindRelinkAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1230    glsAttributeLocationTests.BindRelinkAttributeTest.prototype.constructor = glsAttributeLocationTests.BindRelinkAttributeTest;
   1231 
   1232    glsAttributeLocationTests.BindRelinkAttributeTest.prototype.iterate = function() {
   1233        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1234        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
   1235 
   1236        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1237        /** @type {Array<glsAttributeLocationTests.Bind>} */ var preLinkBindings = [];
   1238        /** @type {Array<glsAttributeLocationTests.Bind>} */ var postLinkBindings = [];
   1239 
   1240        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0'));
   1241        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_1'));
   1242 
   1243        preLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
   1244        preLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 5));
   1245 
   1246        postLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 6));
   1247 
   1248        glsAttributeLocationTests.runTest(attributes, noBindings, preLinkBindings, postLinkBindings, true);
   1249        return tcuTestCase.IterateResult.STOP;
   1250    };
   1251 
   1252    /**
   1253     * @constructor
   1254     * @extends {tcuTestCase.DeqpTest}
   1255     * @param {glsAttributeLocationTests.AttribType} type
   1256     * @param {number=} arraySize
   1257     */
   1258    glsAttributeLocationTests.BindRelinkHoleAttributeTest = function(type, arraySize) {
   1259        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1260        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1261        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1262    };
   1263 
   1264    glsAttributeLocationTests.BindRelinkHoleAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1265    glsAttributeLocationTests.BindRelinkHoleAttributeTest.prototype.constructor = glsAttributeLocationTests.BindRelinkHoleAttributeTest;
   1266 
   1267    glsAttributeLocationTests.BindRelinkHoleAttributeTest.prototype.iterate = function() {
   1268        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1269        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
   1270        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
   1271        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
   1272 
   1273        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1274        /** @type {Array<glsAttributeLocationTests.Bind>} */ var preLinkBindings = [];
   1275        /** @type {Array<glsAttributeLocationTests.Bind>} */ var postLinkBindings = [];
   1276 
   1277        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0'));
   1278        preLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 0));
   1279 
   1280        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_1', glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1281 
   1282        /** @type {number} */ var ndx = 2;
   1283        for (var loc = 1 + this.m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) {
   1284            attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_' + ndx));
   1285            preLinkBindings.push(new glsAttributeLocationTests.Bind('a_' + ndx, loc));
   1286 
   1287            ndx++;
   1288        }
   1289 
   1290        postLinkBindings.push(new glsAttributeLocationTests.Bind('a_2', 1));
   1291 
   1292        glsAttributeLocationTests.runTest(attributes, noBindings, preLinkBindings, postLinkBindings, true);
   1293        return tcuTestCase.IterateResult.STOP;
   1294    };
   1295 
   1296    /**
   1297     * @constructor
   1298     * @extends {tcuTestCase.DeqpTest}
   1299     * @param {glsAttributeLocationTests.AttribType} type
   1300     * @param {number=} arraySize
   1301     */
   1302    glsAttributeLocationTests.MixedRelinkHoleAttributeTest = function(type, arraySize) {
   1303        /** @type {glsAttributeLocationTests.AttribType} */ this.m_type = type;
   1304        /** @type {number} */ this.m_arraySize = arraySize === undefined ? glsAttributeLocationTests.ArrayEnum.NOT : arraySize;
   1305        tcuTestCase.DeqpTest.call(this, glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize), glsAttributeLocationTests.generateTestName(this.m_type, this.m_arraySize));
   1306    };
   1307 
   1308    glsAttributeLocationTests.MixedRelinkHoleAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1309    glsAttributeLocationTests.MixedRelinkHoleAttributeTest.prototype.constructor = glsAttributeLocationTests.MixedRelinkHoleAttributeTest;
   1310 
   1311    glsAttributeLocationTests.MixedRelinkHoleAttributeTest.prototype.iterate = function() {
   1312        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1313        /** @type {number} */ var maxAttributes = glsAttributeLocationTests.getMaxAttributeLocations();
   1314        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
   1315        /** @type {number} */ var arrayElementCount = (this.m_arraySize != glsAttributeLocationTests.ArrayEnum.NOT ? this.m_arraySize : 1);
   1316 
   1317        /** @type {Array<glsAttributeLocationTests.Bind>} */ var preLinkBindings = [];
   1318        /** @type {Array<glsAttributeLocationTests.Bind>} */ var postLinkBindings = [];
   1319        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1320 
   1321        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0'));
   1322        preLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 0));
   1323 
   1324        attributes.push(new glsAttributeLocationTests.Attribute(this.m_type, 'a_1', glsAttributeLocationTests.LocationEnum.UNDEF, glsAttributeLocationTests.NewCondWithEnum(glsAttributeLocationTests.ConstCond.ALWAYS), this.m_arraySize));
   1325 
   1326        /** @type {number} */ var ndx = 2;
   1327        for (var loc = 1 + this.m_type.getLocationSize() * arrayElementCount; loc < maxAttributes; loc++) {
   1328            if ((ndx % 2) != 0)
   1329                attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_' + ndx, loc));
   1330            else {
   1331                attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_' + ndx));
   1332                preLinkBindings.push(new glsAttributeLocationTests.Bind('a_' + ndx, loc));
   1333 
   1334            }
   1335            ndx++;
   1336        }
   1337 
   1338        postLinkBindings.push(new glsAttributeLocationTests.Bind('a_2', 1));
   1339 
   1340        glsAttributeLocationTests.runTest(attributes, noBindings, preLinkBindings, postLinkBindings, true);
   1341        return tcuTestCase.IterateResult.STOP;
   1342    };
   1343 
   1344    /**
   1345     * @constructor
   1346     * @extends {tcuTestCase.DeqpTest}
   1347     */
   1348    glsAttributeLocationTests.PreAttachMixedAttributeTest = function() {
   1349        tcuTestCase.DeqpTest.call(this, 'pre_attach', 'pre_attach');
   1350    };
   1351 
   1352    glsAttributeLocationTests.PreAttachMixedAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1353    glsAttributeLocationTests.PreAttachMixedAttributeTest.prototype.constructor = glsAttributeLocationTests.PreAttachMixedAttributeTest;
   1354 
   1355    glsAttributeLocationTests.PreAttachMixedAttributeTest.prototype.iterate = function() {
   1356        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1357 
   1358        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1359        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
   1360 
   1361        attributes.push(new glsAttributeLocationTests.Attribute(new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4), 'a_0', 1));
   1362        bindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
   1363 
   1364        glsAttributeLocationTests.runTest(attributes, bindings, noBindings, noBindings, false);
   1365        return tcuTestCase.IterateResult.STOP;
   1366    };
   1367 
   1368    /**
   1369     * @constructor
   1370     * @extends {tcuTestCase.DeqpTest}
   1371     */
   1372    glsAttributeLocationTests.PreLinkMixedAttributeTest = function() {
   1373        tcuTestCase.DeqpTest.call(this, 'pre_link', 'pre_link');
   1374    };
   1375 
   1376    glsAttributeLocationTests.PreLinkMixedAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1377    glsAttributeLocationTests.PreLinkMixedAttributeTest.prototype.constructor = glsAttributeLocationTests.PreLinkMixedAttributeTest;
   1378 
   1379    glsAttributeLocationTests.PreLinkMixedAttributeTest.prototype.iterate = function() {
   1380        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1381 
   1382        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1383        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
   1384 
   1385        attributes.push(new glsAttributeLocationTests.Attribute(new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4), 'a_0', 1));
   1386        bindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
   1387 
   1388        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false);
   1389        return tcuTestCase.IterateResult.STOP;
   1390    };
   1391 
   1392    /**
   1393     * @constructor
   1394     * @extends {tcuTestCase.DeqpTest}
   1395     */
   1396    glsAttributeLocationTests.PostLinkMixedAttributeTest = function() {
   1397        tcuTestCase.DeqpTest.call(this, 'post_link', 'post_link');
   1398    };
   1399 
   1400    glsAttributeLocationTests.PostLinkMixedAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1401    glsAttributeLocationTests.PostLinkMixedAttributeTest.prototype.constructor = glsAttributeLocationTests.PostLinkMixedAttributeTest;
   1402 
   1403    glsAttributeLocationTests.PostLinkMixedAttributeTest.prototype.iterate = function() {
   1404        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1405 
   1406        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1407        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
   1408 
   1409        attributes.push(new glsAttributeLocationTests.Attribute(new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4), 'a_0', 1));
   1410        bindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
   1411 
   1412        glsAttributeLocationTests.runTest(attributes, noBindings, noBindings, bindings, false);
   1413        return tcuTestCase.IterateResult.STOP;
   1414    };
   1415 
   1416    /**
   1417     * @constructor
   1418     * @extends {tcuTestCase.DeqpTest}
   1419     */
   1420    glsAttributeLocationTests.MixedReattachAttributeTest = function() {
   1421        tcuTestCase.DeqpTest.call(this, 'reattach', 'reattach');
   1422    };
   1423 
   1424    glsAttributeLocationTests.MixedReattachAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1425    glsAttributeLocationTests.MixedReattachAttributeTest.prototype.constructor = glsAttributeLocationTests.MixedReattachAttributeTest;
   1426 
   1427    glsAttributeLocationTests.MixedReattachAttributeTest.prototype.iterate = function() {
   1428        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1429        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
   1430        /** @type {glsAttributeLocationTests.AttribType} */ var vec2 = new glsAttributeLocationTests.AttribType('vec2', 1, gl.FLOAT_VEC2);
   1431 
   1432        /** @type {Array<glsAttributeLocationTests.Bind>} */ var bindings = [];
   1433        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1434        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var reattachAttributes = [];
   1435 
   1436        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0', 2));
   1437        bindings.push(new glsAttributeLocationTests.Bind('a_0', 1));
   1438        bindings.push(new glsAttributeLocationTests.Bind('a_1', 1));
   1439 
   1440        reattachAttributes.push(new glsAttributeLocationTests.Attribute(vec2, 'a_1'));
   1441 
   1442        glsAttributeLocationTests.runTest(attributes, noBindings, bindings, noBindings, false, true, reattachAttributes);
   1443        return tcuTestCase.IterateResult.STOP;
   1444    };
   1445 
   1446    /**
   1447     * @constructor
   1448     * @extends {tcuTestCase.DeqpTest}
   1449     */
   1450    glsAttributeLocationTests.MixedRelinkAttributeTest = function() {
   1451        tcuTestCase.DeqpTest.call(this, 'relink', 'relink');
   1452    };
   1453 
   1454    glsAttributeLocationTests.MixedRelinkAttributeTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1455    glsAttributeLocationTests.MixedRelinkAttributeTest.prototype.constructor = glsAttributeLocationTests.MixedRelinkAttributeTest;
   1456 
   1457    glsAttributeLocationTests.MixedRelinkAttributeTest.prototype.iterate = function() {
   1458        /** @type {Array<glsAttributeLocationTests.Bind>} */ var noBindings = [];
   1459        /** @type {glsAttributeLocationTests.AttribType} */ var vec4 = new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4);
   1460 
   1461        /** @type {Array<glsAttributeLocationTests.Attribute>} */ var attributes = [];
   1462        /** @type {Array<glsAttributeLocationTests.Bind>} */ var preLinkBindings = [];
   1463        /** @type {Array<glsAttributeLocationTests.Bind>} */ var postLinkBindings = [];
   1464 
   1465        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_0', 1));
   1466        attributes.push(new glsAttributeLocationTests.Attribute(vec4, 'a_1'));
   1467 
   1468        preLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 3));
   1469        preLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 5));
   1470 
   1471        postLinkBindings.push(new glsAttributeLocationTests.Bind('a_0', 6));
   1472 
   1473        glsAttributeLocationTests.runTest(attributes, noBindings, preLinkBindings, postLinkBindings, true);
   1474        return tcuTestCase.IterateResult.STOP;
   1475    };
   1476 
   1477 });