tor-browser

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

es3fOcclusionQueryTests.js (33731B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES Utilities
      3 * ------------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2 (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
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an 'AS IS' BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 */
     20 
     21 'use strict';
     22 goog.provide('functional.gles3.es3fOcclusionQueryTests');
     23 goog.require('framework.common.tcuLogImage');
     24 goog.require('framework.common.tcuSurface');
     25 goog.require('framework.common.tcuTestCase');
     26 goog.require('framework.delibs.debase.deRandom');
     27 goog.require('framework.delibs.debase.deString');
     28 goog.require('framework.opengl.gluShaderProgram');
     29 
     30 goog.scope(function() {
     31 var es3fOcclusionQueryTests = functional.gles3.es3fOcclusionQueryTests;
     32 var tcuTestCase = framework.common.tcuTestCase;
     33 var tcuLogImage = framework.common.tcuLogImage;
     34 var tcuSurface = framework.common.tcuSurface;
     35 var deRandom = framework.delibs.debase.deRandom;
     36 var deString = framework.delibs.debase.deString;
     37 var gluShaderProgram = framework.opengl.gluShaderProgram;
     38 
     39 var setParentClass = function(child, parent) {
     40    child.prototype = Object.create(parent.prototype);
     41    child.prototype.constructor = child;
     42 };
     43 
     44 /** @const */ var DEPTH_WRITE_COLOR = [0, 0, 1, 1];
     45 /** @const */ var DEPTH_CLEAR_COLOR = [0, 0.5, 0.8, 1];
     46 /** @const */ var STENCIL_WRITE_COLOR = [0, 1, 0, 1];
     47 /** @const */ var STENCIL_CLEAR_COLOR = [0, 0.8, 0.5, 1];
     48 /** @const */ var TARGET_COLOR = [1, 0, 0, 1];
     49 /** @const */ var ELEMENTS_PER_VERTEX = 4;
     50 /** @const */ var NUM_CASE_ITERATIONS = 10;
     51 
     52 // Constants to tweak visible/invisible case probability balance.
     53 
     54 /** @const */ var DEPTH_CLEAR_OFFSET = 100;
     55 /** @const */ var STENCIL_CLEAR_OFFSET = 100;
     56 /** @const */ var SCISSOR_OFFSET = 100;
     57 /** @const */ var SCISSOR_MINSIZE = 250;
     58 
     59 /** @const */ var OCCLUDER_SCISSOR = (1 << 0);
     60 /** @const */ var OCCLUDER_DEPTH_WRITE = (1 << 1);
     61 /** @const */ var OCCLUDER_DEPTH_CLEAR = (1 << 2);
     62 /** @const */ var OCCLUDER_STENCIL_WRITE = (1 << 3);
     63 /** @const */ var OCCLUDER_STENCIL_CLEAR = (1 << 4);
     64 
     65 /**
     66 * @enum
     67 */
     68 es3fOcclusionQueryTests.State = {
     69    DRAW: 0,
     70    VERIFY: 1,
     71    FINISH: 2
     72 };
     73 
     74 /* Maximum time to wait for query result (in seconds) */
     75 /** @const */ var MAX_VERIFY_WAIT = 5;
     76 
     77 /**
     78 * @constructor
     79 * @extends {tcuTestCase.DeqpTest}
     80 */
     81 es3fOcclusionQueryTests.OcclusionQueryCase = function(name, description, numOccluderDraws, numOccludersPerDraw, occluderSize, numTargetDraws, numTargetsPerDraw, targetSize, queryMode, occluderTypes) {
     82    tcuTestCase.DeqpTest.call(this, name, description);
     83    this.m_numOccluderDraws = numOccluderDraws;
     84    this.m_numOccludersPerDraw = numOccludersPerDraw;
     85    this.m_occluderSize = occluderSize;
     86    this.m_numTargetDraws = numTargetDraws;
     87    this.m_numTargetsPerDraw = numTargetsPerDraw;
     88    this.m_targetSize = targetSize;
     89    this.m_queryMode = queryMode;
     90    this.m_occluderTypes = occluderTypes;
     91    this.m_program = null;
     92    this.m_iterNdx = 0;
     93    this.m_rnd = new deRandom.Random(deString.deStringHash(name));
     94    this.m_state = es3fOcclusionQueryTests.State.DRAW;
     95    /** @type {WebGLQuery} */ this.m_query;
     96 };
     97 
     98 setParentClass(es3fOcclusionQueryTests.OcclusionQueryCase, tcuTestCase.DeqpTest);
     99 
    100 es3fOcclusionQueryTests.OcclusionQueryCase.prototype.generateVertices = function(width, height, primitiveCount, verticesPerPrimitive, rnd, primitiveSize, minZ, maxZ) {
    101    var dst = [];
    102    var w = width / 2;
    103    var h = height / 2;
    104    var s = primitiveSize / 2;
    105 
    106    var vertexCount = verticesPerPrimitive * primitiveCount;
    107 
    108    // First loop gets a random point inside unit square
    109    for (var i = 0; i < vertexCount; i += 3) {
    110        var rndX = rnd.getFloat(-w, w);
    111        var rndY = rnd.getFloat(-h, h);
    112 
    113        // Second loop gets 3 random points within given distance s from (rndX, rndY)
    114        for (var j = 0; j < verticesPerPrimitive; j++) {
    115            var offset = (i + j) * ELEMENTS_PER_VERTEX;
    116            dst[offset] = rndX + rnd.getFloat(-s, s); // x
    117            dst[offset + 1] = rndY + rnd.getFloat(-s, s); // y
    118            dst[offset + 2] = rnd.getFloat(minZ, maxZ); // z
    119            dst[offset + 3] = 1; // w
    120        }
    121    }
    122    return dst;
    123 };
    124 
    125 es3fOcclusionQueryTests.OcclusionQueryCase.prototype.init = function() {
    126    var vertShaderSource =
    127                '#version 300 es\n' +
    128                'layout(location = 0) in mediump vec4 a_position;\n' +
    129                '\n' +
    130                'void main (void)\n' +
    131                '{\n' +
    132                ' gl_Position = a_position;\n' +
    133                '}\n';
    134 
    135    var fragShaderSource =
    136                '#version 300 es\n' +
    137                'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
    138                'uniform mediump vec4 u_color;\n' +
    139                '\n' +
    140                'void main (void)\n' +
    141                '{\n' +
    142                ' mediump float depth_gradient = gl_FragCoord.z;\n' +
    143                ' mediump float bias = 0.1;\n' +
    144                ' dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1);\n' +
    145                '}\n';
    146 
    147    this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertShaderSource, fragShaderSource));
    148 
    149    if (!this.m_program.isOk())
    150        testFailedOptions('Failed to compile program', true);
    151 
    152    this.m_buffer = gl.createBuffer();
    153    gl.bindBuffer(gl.ARRAY_BUFFER, this.m_buffer);
    154    gl.vertexAttribPointer(0, ELEMENTS_PER_VERTEX, gl.FLOAT, false, 0, 0);
    155 };
    156 
    157 es3fOcclusionQueryTests.OcclusionQueryCase.prototype.draw = function() {
    158    var colorUnif = gl.getUniformLocation(this.m_program.getProgram(), 'u_color');
    159 
    160    var targetW = gl.drawingBufferWidth;
    161    var targetH = gl.drawingBufferHeight;
    162 
    163    bufferedLogToConsole('Case iteration ' + (this.m_iterNdx + 1) + ' / ' + NUM_CASE_ITERATIONS);
    164    bufferedLogToConsole('Parameters:\n' +
    165                                 '- ' + this.m_numOccluderDraws + ' occluder draws, ' + this.m_numOccludersPerDraw + ' primitive writes per draw,\n' +
    166                                 '- ' + this.m_numTargetDraws + ' target draws, ' + this.m_numTargetsPerDraw + ' targets per draw\n');
    167 
    168    gl.clearColor(0, 0, 0, 1);
    169    gl.clearDepth(1);
    170    gl.clearStencil(0);
    171    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    172    gl.useProgram(this.m_program.getProgram());
    173    gl.enableVertexAttribArray(0);
    174 
    175    // Draw occluders
    176 
    177    var occOptions = [];
    178    if (this.m_occluderTypes & OCCLUDER_DEPTH_WRITE) occOptions.push(OCCLUDER_DEPTH_WRITE);
    179    if (this.m_occluderTypes & OCCLUDER_DEPTH_CLEAR) occOptions.push(OCCLUDER_DEPTH_CLEAR);
    180    if (this.m_occluderTypes & OCCLUDER_STENCIL_WRITE) occOptions.push(OCCLUDER_STENCIL_WRITE);
    181    if (this.m_occluderTypes & OCCLUDER_STENCIL_CLEAR) occOptions.push(OCCLUDER_STENCIL_CLEAR);
    182 
    183    for (var i = 0; i < this.m_numOccluderDraws; i++) {
    184        if (occOptions.length == 0)
    185            break;
    186 
    187        var type = occOptions[this.m_rnd.getInt(0, occOptions.length - 1)]; // Choosing a random occluder type from available options
    188 
    189        switch (type) {
    190            case OCCLUDER_DEPTH_WRITE:
    191                bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Depth write');
    192 
    193                var occluderVertices = this.generateVertices(2, 2, this.m_numOccludersPerDraw, 3, this.m_rnd, this.m_occluderSize, 0, 0.6); // Generate vertices for occluding primitives
    194 
    195                gl.enable(gl.DEPTH_TEST);
    196                gl.uniform4f(colorUnif, DEPTH_WRITE_COLOR[0], DEPTH_WRITE_COLOR[1], DEPTH_WRITE_COLOR[2], DEPTH_WRITE_COLOR[3]);
    197                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(occluderVertices), gl.STATIC_DRAW);
    198                gl.drawArrays(gl.TRIANGLES, 0, 3 * this.m_numOccludersPerDraw);
    199                gl.disable(gl.DEPTH_TEST);
    200 
    201                break;
    202 
    203            case OCCLUDER_DEPTH_CLEAR: {
    204                var scissorBoxX = this.m_rnd.getInt(-DEPTH_CLEAR_OFFSET, targetW);
    205                var scissorBoxY = this.m_rnd.getInt(-DEPTH_CLEAR_OFFSET, targetH);
    206                var scissorBoxW = this.m_rnd.getInt(DEPTH_CLEAR_OFFSET, targetW + DEPTH_CLEAR_OFFSET);
    207                var scissorBoxH = this.m_rnd.getInt(DEPTH_CLEAR_OFFSET, targetH + DEPTH_CLEAR_OFFSET);
    208 
    209                bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Depth clear');
    210                bufferedLogToConsole('Depth-clearing box drawn at ' +
    211                                                '(' + scissorBoxX + ', ' + scissorBoxY + ')' +
    212                                                ', width = ' + scissorBoxW + ', height = ' + scissorBoxH + '.');
    213 
    214                gl.enable(gl.SCISSOR_TEST);
    215                gl.scissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
    216                gl.clearDepth(0);
    217                gl.clearColor(DEPTH_CLEAR_COLOR[0], DEPTH_CLEAR_COLOR[1], DEPTH_CLEAR_COLOR[2], DEPTH_CLEAR_COLOR[3]);
    218                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    219                gl.disable(gl.SCISSOR_TEST);
    220 
    221                break;
    222            }
    223 
    224            case OCCLUDER_STENCIL_WRITE:
    225                bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Stencil write');
    226 
    227                occluderVertices = this.generateVertices(2, 2, this.m_numOccludersPerDraw, 3, this.m_rnd, this.m_occluderSize, 0, 0.6);
    228 
    229                gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
    230                gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    231 
    232                gl.enable(gl.STENCIL_TEST);
    233                gl.uniform4f(colorUnif, STENCIL_WRITE_COLOR[0], STENCIL_WRITE_COLOR[1], STENCIL_WRITE_COLOR[2], STENCIL_WRITE_COLOR[3]);
    234                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(occluderVertices), gl.STATIC_DRAW);
    235                gl.drawArrays(gl.TRIANGLES, 0, 3 * this.m_numOccludersPerDraw);
    236                gl.disable(gl.STENCIL_TEST);
    237 
    238                break;
    239 
    240            case OCCLUDER_STENCIL_CLEAR: {
    241                var scissorBoxX = this.m_rnd.getInt(-STENCIL_CLEAR_OFFSET, targetW);
    242                var scissorBoxY = this.m_rnd.getInt(-STENCIL_CLEAR_OFFSET, targetH);
    243                var scissorBoxW = this.m_rnd.getInt(STENCIL_CLEAR_OFFSET, targetW + STENCIL_CLEAR_OFFSET);
    244                var scissorBoxH = this.m_rnd.getInt(STENCIL_CLEAR_OFFSET, targetH + STENCIL_CLEAR_OFFSET);
    245 
    246                bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Stencil clear');
    247                bufferedLogToConsole('Stencil-clearing box drawn at ' +
    248                                                '(' + scissorBoxX + ', ' + scissorBoxY + ')' +
    249                                                ', width = ' + scissorBoxW + ', height = ' + scissorBoxH + '.');
    250 
    251                gl.enable(gl.SCISSOR_TEST);
    252                gl.scissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
    253                gl.clearStencil(1);
    254                gl.clearColor(STENCIL_CLEAR_COLOR[0], STENCIL_CLEAR_COLOR[1], STENCIL_CLEAR_COLOR[2], STENCIL_CLEAR_COLOR[3]);
    255                gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    256                gl.disable(gl.SCISSOR_TEST);
    257 
    258                break;
    259            }
    260 
    261            default:
    262                throw new Error('Invalid occluder type: ' + type);
    263        }
    264    }
    265 
    266    if (this.m_occluderTypes & OCCLUDER_SCISSOR) {
    267        var scissorBoxX = this.m_rnd.getInt(-SCISSOR_OFFSET, targetW - SCISSOR_OFFSET);
    268        var scissorBoxY = this.m_rnd.getInt(-SCISSOR_OFFSET, targetH - SCISSOR_OFFSET);
    269        var scissorBoxW = this.m_rnd.getInt(SCISSOR_MINSIZE, targetW + SCISSOR_OFFSET);
    270        var scissorBoxH = this.m_rnd.getInt(SCISSOR_MINSIZE, targetH + SCISSOR_OFFSET);
    271 
    272        bufferedLogToConsole('Scissor box drawn at ' +
    273                                        '(' + scissorBoxX + ', ' + scissorBoxY + ')' +
    274                                        ', width = ' + scissorBoxW + ', height = ' + scissorBoxH + '.');
    275 
    276        gl.enable(gl.SCISSOR_TEST);
    277        gl.scissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
    278    }
    279 
    280    this.m_query = gl.createQuery();
    281    gl.beginQuery(this.m_queryMode, this.m_query);
    282 
    283    // Draw target primitives
    284 
    285    gl.enable(gl.DEPTH_TEST);
    286    gl.enable(gl.STENCIL_TEST);
    287    gl.stencilFunc(gl.EQUAL, 0, 0xFF);
    288 
    289    for (var i = 0; i < this.m_numTargetDraws; i++) {
    290        var targetVertices = this.generateVertices(2, 2, this.m_numTargetsPerDraw, 3, this.m_rnd, this.m_targetSize, 0.4, 1); // Generate vertices for target primitives
    291 
    292        if (targetVertices.length > 0) {
    293            gl.uniform4f(colorUnif, TARGET_COLOR[0], TARGET_COLOR[1], TARGET_COLOR[2], TARGET_COLOR[3]);
    294            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(targetVertices), gl.STATIC_DRAW);
    295            gl.drawArrays(gl.TRIANGLES, 0, 3 * this.m_numTargetsPerDraw);
    296        }
    297    }
    298 
    299    gl.endQuery(this.m_queryMode);
    300    gl.disable(gl.SCISSOR_TEST);
    301    gl.disable(gl.STENCIL_TEST);
    302    gl.disable(gl.DEPTH_TEST);
    303    this.m_state = es3fOcclusionQueryTests.State.VERIFY;
    304 };
    305 
    306 es3fOcclusionQueryTests.OcclusionQueryCase.prototype.verify = function() {
    307    // Check that query result is available.
    308    var resultAvailable = /** @type {boolean} */ (gl.getQueryParameter(this.m_query, gl.QUERY_RESULT_AVAILABLE));
    309    if (!resultAvailable) {
    310        if (!this.m_verifyStart)
    311            this.m_verifyStart = new Date();
    312        else {
    313            var current = new Date();
    314            var elapsedTime = 0.001 * (current.getTime() - this.m_verifyStart.getTime());
    315            if (elapsedTime > MAX_VERIFY_WAIT) {
    316                testFailed('Query result not available after ' + elapsedTime + ' seconds.');
    317                this.m_state = es3fOcclusionQueryTests.State.FINISH;
    318            }
    319        }
    320        return;
    321    }
    322 
    323    // Read query result.
    324    var result = /** @type {number} */ (gl.getQueryParameter(this.m_query, gl.QUERY_RESULT));
    325    var queryResult = (result > 0);
    326 
    327    gl.deleteQuery(this.m_query);
    328 
    329    // Read pixel data
    330 
    331    var pixels = new tcuSurface.Surface();
    332    pixels.readViewport(gl);
    333    var colorReadResult = false;
    334    var width = pixels.getWidth();
    335    var height = pixels.getHeight();
    336 
    337    for (var y = 0; y < height; y++) {
    338        for (var x = 0; x < width; x++) {
    339            if (pixels.getPixel(x, y)[0] != 0) {
    340                colorReadResult = true;
    341                break;
    342            }
    343        }
    344        if (colorReadResult) break;
    345    }
    346 
    347    var message = 'Occlusion query result: Target ' + (queryResult ? 'visible' : 'invisible') + '. ' +
    348                                 'Framebuffer read result: Target ' + (colorReadResult ? 'visible' : 'invisible');
    349 
    350    var testOk = false;
    351    if (this.m_queryMode == gl.ANY_SAMPLES_PASSED_CONSERVATIVE) {
    352        if (queryResult || colorReadResult)
    353            testOk = queryResult; // Allow conservative occlusion query to return false positives.
    354        else
    355            testOk = queryResult == colorReadResult;
    356    } else
    357        testOk = (queryResult == colorReadResult);
    358 
    359    if (!testOk) {
    360        tcuLogImage.logImage('Result image', 'Result image', pixels.getAccess());
    361        testFailed(message);
    362        this.m_state = es3fOcclusionQueryTests.State.FINISH;
    363        return;
    364    }
    365 
    366    bufferedLogToConsole(message);
    367    bufferedLogToConsole('Case passed!');
    368 
    369    if (++this.m_iterNdx < NUM_CASE_ITERATIONS) {
    370        this.m_state = es3fOcclusionQueryTests.State.DRAW
    371    } else {
    372        this.m_state = es3fOcclusionQueryTests.State.FINISH;
    373        testPassed();
    374    }
    375 };
    376 
    377 
    378 es3fOcclusionQueryTests.OcclusionQueryCase.prototype.iterate = function() {
    379    switch(this.m_state) {
    380        case es3fOcclusionQueryTests.State.DRAW:
    381            this.draw();
    382            break;
    383        case es3fOcclusionQueryTests.State.VERIFY:
    384            this.verify();
    385            break;
    386        case es3fOcclusionQueryTests.State.FINISH:
    387            return tcuTestCase.IterateResult.STOP;
    388        default:
    389            throw new Error('Invalid state: ' + this.m_state);
    390    }
    391 
    392    return tcuTestCase.IterateResult.CONTINUE;
    393 };
    394 
    395 /**
    396 * @constructor
    397 * @extends {tcuTestCase.DeqpTest}
    398 */
    399 es3fOcclusionQueryTests.OcclusionQueryTests = function() {
    400    tcuTestCase.DeqpTest.call(this, 'occlusion_query', 'Occlusion Query Tests');
    401 };
    402 
    403 es3fOcclusionQueryTests.OcclusionQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    404 es3fOcclusionQueryTests.OcclusionQueryTests.prototype.constructor = es3fOcclusionQueryTests.OcclusionQueryTests;
    405 
    406 es3fOcclusionQueryTests.OcclusionQueryTests.prototype.init = function() {
    407    // Strict occlusion query cases
    408 
    409    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor', 'scissor', 1, 10, 1.6, 1, 1, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR));
    410    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write', 'depth_write', 8, 10, 1.6, 1, 7, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE));
    411    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear', 'depth_clear', 5, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR));
    412    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('stencil_write', 'stencil_write', 8, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_WRITE));
    413    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('stencil_clear', 'stencil_clear', 5, 10, 2.0, 1, 3, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_CLEAR));
    414 
    415    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write', 'scissor_depth_write', 5, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE));
    416    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear', 'scissor_depth_clear', 7, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR));
    417    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_stencil_write', 'scissor_stencil_write', 4, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE));
    418    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_stencil_clear', 'scissor_stencil_clear', 4, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_CLEAR));
    419    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear', 'depth_write_depth_clear', 7, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
    420    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_stencil_write', 'depth_write_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
    421    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_stencil_clear', 'depth_write_stencil_clear', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
    422    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear_stencil_write', 'depth_clear_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    423    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear_stencil_clear', 'depth_clear_stencil_clear', 12, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    424    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('stencil_write_stencil_clear', 'stencil_write_stencil_clear', 5, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    425 
    426    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_depth_clear', 'scissor_depth_write_depth_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
    427    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_stencil_write', 'scissor_depth_write_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
    428    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_stencil_clear', 'scissor_depth_write_stencil_clear', 6, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
    429    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear_stencil_write', 'scissor_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    430    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear_stencil_clear', 'scissor_depth_clear_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    431    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_stencil_write_stencil_clear', 'scissor_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    432    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear_stencil_write', 'depth_write_depth_clear_stencil_write', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    433    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear_stencil_clear', 'depth_write_depth_clear_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    434    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_stencil_write_stencil_clear', 'depth_write_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    435    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear_stencil_write_stencil_clear', 'depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    436 
    437    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_depth_clear_stencil_write', 'scissor_depth_write_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    438    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_depth_clear_stencil_clear', 'scissor_depth_write_depth_clear_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    439    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_stencil_write_stencil_clear', 'scissor_depth_write_stencil_write_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    440    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear_stencil_write_stencil_clear', 'scissor_depth_clear_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    441    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear_stencil_write_stencil_clear', 'depth_write_depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    442 
    443    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('all_occluders', 'all_occluders', 7, 10, 1.6, 3, 5, 0.6, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    444 
    445    // Conservative occlusion query cases
    446 
    447    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor', 'conservative_scissor', 1, 10, 1.6, 1, 1, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR));
    448    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write', 'conservative_depth_write', 8, 10, 1.6, 1, 7, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE));
    449    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear', 'conservative_depth_clear', 5, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR));
    450    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_stencil_write', 'conservative_stencil_write', 8, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_WRITE));
    451    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_stencil_clear', 'conservative_stencil_clear', 5, 10, 2.0, 1, 3, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_CLEAR));
    452 
    453    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write', 'conservative_scissor_depth_write', 5, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE));
    454    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear', 'conservative_scissor_depth_clear', 7, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR));
    455    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_stencil_write', 'conservative_scissor_stencil_write', 4, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE));
    456    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_stencil_clear', 'conservative_scissor_stencil_clear', 4, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_CLEAR));
    457    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear', 'conservative_depth_write_depth_clear', 7, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
    458    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_stencil_write', 'conservative_depth_write_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
    459    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_stencil_clear', 'conservative_depth_write_stencil_clear', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
    460    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear_stencil_write', 'conservative_depth_clear_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    461    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear_stencil_clear', 'conservative_depth_clear_stencil_clear', 12, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    462    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_stencil_write_stencil_clear', 'conservative_stencil_write_stencil_clear', 5, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    463 
    464    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_depth_clear', 'conservative_scissor_depth_write_depth_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
    465    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_stencil_write', 'conservative_scissor_depth_write_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
    466    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_stencil_clear', 'conservative_scissor_depth_write_stencil_clear', 6, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
    467    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear_stencil_write', 'conservative_scissor_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    468    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear_stencil_clear', 'conservative_scissor_depth_clear_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    469    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_stencil_write_stencil_clear', 'conservative_scissor_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    470    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear_stencil_write', 'conservative_depth_write_depth_clear_stencil_write', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    471    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear_stencil_clear', 'conservative_depth_write_depth_clear_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    472    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_stencil_write_stencil_clear', 'conservative_depth_write_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    473    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear_stencil_write_stencil_clear', 'conservative_depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    474 
    475    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_depth_clear_stencil_write', 'conservative_scissor_depth_write_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
    476    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_depth_clear_stencil_clear', 'conservative_scissor_depth_write_depth_clear_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
    477    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_stencil_write_stencil_clear', 'conservative_scissor_depth_write_stencil_write_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    478    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear_stencil_write_stencil_clear', 'conservative_scissor_depth_clear_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    479    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear_stencil_write_stencil_clear', 'conservative_depth_write_depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    480 
    481    this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_all_occluders', 'conservative_all_occluders', 7, 10, 1.6, 3, 5, 0.6, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
    482 
    483 };
    484 
    485 /**
    486 * Run test
    487 * @param {WebGL2RenderingContext} context
    488 */
    489 es3fOcclusionQueryTests.run = function(context, range) {
    490    gl = context;
    491    //Set up Test Root parameters
    492    var state = tcuTestCase.runner;
    493    state.setRoot(new es3fOcclusionQueryTests.OcclusionQueryTests());
    494 
    495    //Set up name and description of this test series.
    496    setCurrentTestName(state.testCases.fullName());
    497    description(state.testCases.getDescription());
    498 
    499    try {
    500        if (range)
    501            state.setRange(range);
    502        //Run test cases
    503        tcuTestCase.runTestCases();
    504    }
    505    catch (err) {
    506        testFailedOptions('Failed to es3fOcclusionQueryTests.run tests', false);
    507        tcuTestCase.runner.terminate();
    508    }
    509 };
    510 
    511 });