tor-browser

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

es3fFboInvalidateTests.js (69869B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES Utilities
      3 * ------------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the 'License');
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *      http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an 'AS IS' BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 */
     20 
     21 'use strict';
     22 goog.provide('functional.gles3.es3fFboInvalidateTests');
     23 goog.require('framework.common.tcuImageCompare');
     24 goog.require('framework.common.tcuRGBA');
     25 goog.require('framework.common.tcuTestCase');
     26 goog.require('framework.common.tcuTexture');
     27 goog.require('framework.common.tcuTextureUtil');
     28 goog.require('framework.delibs.debase.deMath');
     29 goog.require('framework.opengl.gluShaderUtil');
     30 goog.require('framework.opengl.gluTextureUtil');
     31 goog.require('framework.referencerenderer.rrUtil');
     32 goog.require('functional.gles3.es3fFboTestCase');
     33 goog.require('functional.gles3.es3fFboTestUtil');
     34 
     35 goog.scope(function() {
     36 var es3fFboInvalidateTests = functional.gles3.es3fFboInvalidateTests;
     37 var tcuTestCase = framework.common.tcuTestCase;
     38 var es3fFboTestCase = functional.gles3.es3fFboTestCase;
     39 var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
     40 var rrUtil = framework.referencerenderer.rrUtil;
     41 var gluShaderUtil = framework.opengl.gluShaderUtil;
     42 var gluTextureUtil = framework.opengl.gluTextureUtil;
     43 var tcuTexture = framework.common.tcuTexture;
     44 var tcuTextureUtil = framework.common.tcuTextureUtil;
     45 var deMath = framework.delibs.debase.deMath;
     46 var tcuRGBA = framework.common.tcuRGBA;
     47 var tcuImageCompare = framework.common.tcuImageCompare;
     48 
     49 /** @type {WebGL2RenderingContext} */ var gl;
     50 
     51 var setParentClass = function(child, parent) {
     52    child.prototype = Object.create(parent.prototype);
     53    child.prototype.constructor = child;
     54 };
     55 
     56 var getDefaultFBDiscardAttachments = function(discardBufferBits) {
     57    var attachments = [];
     58 
     59    if (discardBufferBits & gl.COLOR_BUFFER_BIT)
     60        attachments.push(gl.COLOR);
     61 
     62    if (discardBufferBits & gl.DEPTH_BUFFER_BIT)
     63        attachments.push(gl.DEPTH);
     64 
     65    if (discardBufferBits & gl.STENCIL_BUFFER_BIT)
     66        attachments.push(gl.STENCIL);
     67 
     68    return attachments;
     69 };
     70 
     71 var getFBODiscardAttachments = function(discardBufferBits) {
     72    var attachments = [];
     73 
     74    if (discardBufferBits & gl.COLOR_BUFFER_BIT)
     75        attachments.push(gl.COLOR_ATTACHMENT0);
     76 
     77    // \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB
     78    if ((discardBufferBits & (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) == (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT))
     79        attachments.push(gl.DEPTH_STENCIL_ATTACHMENT);
     80    else if (discardBufferBits & gl.DEPTH_BUFFER_BIT)
     81        attachments.push(gl.DEPTH_ATTACHMENT);
     82    else if (discardBufferBits & gl.STENCIL_BUFFER_BIT)
     83        attachments.push(gl.STENCIL_ATTACHMENT);
     84 
     85    return attachments;
     86 };
     87 
     88 var getCompatibleColorFormat = function() {
     89    var redBits = gl.getParameter(gl.RED_BITS);
     90    var greenBits = gl.getParameter(gl.GREEN_BITS);
     91    var blueBits = gl.getParameter(gl.BLUE_BITS);
     92    var alphaBits = gl.getParameter(gl.ALPHA_BITS);
     93    switch ('' + redBits + greenBits + blueBits + alphaBits) {
     94        case '8888' : return gl.RGBA8;
     95        case '8880' : return gl.RGB8;
     96        default:
     97            throw new Error('Unexpected bit depth');
     98    }
     99 };
    100 
    101 var getCompatibleDepthStencilFormat = function() {
    102    var depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
    103    var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
    104    var hasDepth = depthBits > 0;
    105    var hasStencil = stencilBits > 0;
    106 
    107    if (!hasDepth || !hasStencil || (stencilBits != 8))
    108        return gl.NONE;
    109 
    110    if (depthBits == 32)
    111        return gl.DEPTH32F_STENCIL8;
    112    else if (depthBits == 24)
    113        return gl.DEPTH24_STENCIL8;
    114    else
    115        return gl.NONE;
    116 };
    117 
    118 var hasAttachment = function(attachments, attachment) {
    119    return attachments.indexOf(attachment) >= 0;
    120 };
    121 
    122 /**
    123 * @constructor
    124 * @extends {es3fFboTestCase.FboTestCase}
    125 * @param {string} name
    126 * @param {string} desc
    127 * @param {number} buffers
    128 * @param {number=} target
    129 */
    130 es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase = function(name, desc, buffers, target) {
    131    es3fFboTestCase.FboTestCase.call(this, name, desc);
    132    this.m_buffers = buffers;
    133    this.m_fboTarget = target || gl.FRAMEBUFFER;
    134 };
    135 
    136 setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase, es3fFboTestCase.FboTestCase);
    137 
    138 es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase.prototype.render = function(dst) {
    139    var ctx = this.getCurrentContext();
    140    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
    141 
    142    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    143    var program = ctx.createProgram(shader);
    144    shader.setColor(ctx, program, [1, 0, 0, 1]);
    145    ctx.clearColor(0, 0, 0, 1);
    146    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    147 
    148    ctx.enable(gl.DEPTH_TEST);
    149    ctx.enable(gl.STENCIL_TEST);
    150    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    151    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    152 
    153    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
    154    ctx.invalidateFramebuffer(this.m_fboTarget, attachments);
    155 
    156    if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
    157        // Color was not preserved - fill with green.
    158        ctx.disable(gl.DEPTH_TEST);
    159        ctx.disable(gl.STENCIL_TEST);
    160 
    161        shader.setColor(ctx, program, [0, 1, 0, 1]);
    162        rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    163 
    164        ctx.enable(gl.DEPTH_TEST);
    165        ctx.enable(gl.STENCIL_TEST);
    166    }
    167 
    168    if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
    169        // Depth was not preserved.
    170        ctx.depthFunc(gl.ALWAYS);
    171    }
    172 
    173    if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
    174        // Stencil was preserved.
    175        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    176    }
    177 
    178    ctx.enable(gl.BLEND);
    179    ctx.blendFunc(gl.ONE, gl.ONE);
    180    ctx.blendEquation(gl.FUNC_ADD);
    181 
    182    shader.setColor(ctx, program, [0, 0, 1, 1]);
    183    rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    184    dst.readViewport(ctx);
    185 };
    186 
    187 /**
    188 * @constructor
    189 * @extends {es3fFboTestCase.FboTestCase}
    190 * @param {string} name
    191 * @param {string} desc
    192 * @param {number} buffers
    193 */
    194 es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase = function(name, desc, buffers) {
    195    es3fFboTestCase.FboTestCase.call(this, name, desc);
    196    this.m_buffers = buffers;
    197 };
    198 
    199 setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase, es3fFboTestCase.FboTestCase);
    200 
    201 es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase.prototype.render = function(dst) {
    202    var ctx = this.getCurrentContext();
    203    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
    204 
    205    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    206    var program = ctx.createProgram(shader);
    207 
    208    /** @type {es3fFboTestUtil.Texture2DShader} */
    209    var texShader = new es3fFboTestUtil.Texture2DShader(
    210        [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
    211 
    212    /** @type {es3fFboTestUtil.GradientShader} */
    213    var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
    214 
    215    var texShaderID = ctx.createProgram(texShader);
    216    var gradShaderID = ctx.createProgram(gradShader);
    217    ctx.clearColor(0, 0, 0, 1);
    218    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    219    // Create fbo.
    220    var fbo = ctx.createFramebuffer();
    221    var tex = ctx.createTexture();
    222    ctx.bindTexture(gl.TEXTURE_2D, tex);
    223    ctx.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, this.getWidth(), this.getHeight(), 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    224    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    225    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    226    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
    227    ctx.bindTexture(gl.TEXTURE_2D, null);
    228    this.checkFramebufferStatus(gl.FRAMEBUFFER);
    229 
    230    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    231 
    232    ctx.enable(gl.DEPTH_TEST);
    233    ctx.enable(gl.STENCIL_TEST);
    234    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    235    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    236 
    237    shader.setColor(ctx, program, [1, 0, 0, 1]);
    238    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
    239 
    240    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
    241 
    242    // Switch to fbo and render gradient into it.
    243    ctx.disable(gl.DEPTH_TEST);
    244    ctx.disable(gl.STENCIL_TEST);
    245    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    246 
    247    gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
    248    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
    249    // Restore default fbo.
    250    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    251 
    252    if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
    253        // Color was not preserved - fill with green.
    254        shader.setColor(ctx, program, [0, 1, 0, 1]);
    255        rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    256    }
    257 
    258    if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
    259        // Depth was not preserved.
    260        ctx.depthFunc(gl.ALWAYS);
    261    }
    262 
    263    if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
    264        // Stencil was preserved.
    265        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    266    }
    267 
    268    ctx.enable(gl.DEPTH_TEST);
    269    ctx.enable(gl.STENCIL_TEST);
    270    ctx.enable(gl.BLEND);
    271    ctx.blendFunc(gl.ONE, gl.ONE);
    272    ctx.blendEquation(gl.FUNC_ADD);
    273    ctx.bindTexture(gl.TEXTURE_2D, tex);
    274 
    275    texShader.setUniforms(ctx, texShaderID);
    276    rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    277 
    278    dst.readViewport(ctx);
    279 };
    280 
    281 /**
    282 * @constructor
    283 * @extends {es3fFboTestCase.FboTestCase}
    284 * @param {string} name
    285 * @param {string} desc
    286 * @param {number} buffers
    287 * @param {number=} target
    288 */
    289 es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase = function(name, desc, buffers, target) {
    290    es3fFboTestCase.FboTestCase.call(this, name, desc);
    291    this.m_buffers = buffers;
    292    this.m_fboTarget = target || gl.FRAMEBUFFER;
    293 };
    294 
    295 setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase, es3fFboTestCase.FboTestCase);
    296 
    297 es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase.prototype.render = function(dst) {
    298    var ctx = this.getCurrentContext();
    299    var invalidateX = this.getWidth() / 4;
    300    var invalidateY = this.getHeight() / 4;
    301    var invalidateW = this.getWidth() / 2;
    302    var invalidateH = this.getHeight() / 2;
    303    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
    304 
    305    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    306    var program = ctx.createProgram(shader);
    307    shader.setColor(ctx, program, [1, 0, 0, 1]);
    308    ctx.clearColor(0, 0, 0, 1);
    309    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    310 
    311    ctx.enable(gl.DEPTH_TEST);
    312    ctx.enable(gl.STENCIL_TEST);
    313    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    314    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    315 
    316    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
    317    ctx.invalidateSubFramebuffer(this.m_fboTarget, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
    318 
    319    // Clear invalidated buffers.
    320    ctx.clearColor(0, 1, 0, 1);
    321    ctx.clearStencil(1);
    322    ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
    323    ctx.enable(gl.SCISSOR_TEST);
    324    ctx.clear(this.m_buffers);
    325    ctx.disable(gl.SCISSOR_TEST);
    326 
    327    ctx.enable(gl.BLEND);
    328    ctx.blendFunc(gl.ONE, gl.ONE);
    329    ctx.blendEquation(gl.FUNC_ADD);
    330 
    331    shader.setColor(ctx, program, [0, 0, 1, 1]);
    332    rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    333    dst.readViewport(ctx);
    334 };
    335 
    336 /**
    337 * @constructor
    338 * @extends {es3fFboTestCase.FboTestCase}
    339 * @param {string} name
    340 * @param {string} desc
    341 * @param {number} buffers
    342 */
    343 es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase = function(name, desc, buffers) {
    344    es3fFboTestCase.FboTestCase.call(this, name, desc);
    345    this.m_buffers = buffers;
    346 };
    347 
    348 setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase, es3fFboTestCase.FboTestCase);
    349 
    350 es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase.prototype.render = function(dst) {
    351    var ctx = this.getCurrentContext();
    352    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
    353    var invalidateX = this.getWidth() / 4;
    354    var invalidateY = this.getHeight() / 4;
    355    var invalidateW = this.getWidth() / 2;
    356    var invalidateH = this.getHeight() / 2;
    357 
    358    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    359    var program = ctx.createProgram(shader);
    360 
    361    /** @type {es3fFboTestUtil.Texture2DShader} */
    362    var texShader = new es3fFboTestUtil.Texture2DShader(
    363        [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
    364 
    365    /** @type {es3fFboTestUtil.GradientShader} */
    366    var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
    367 
    368    var texShaderID = ctx.createProgram(texShader);
    369    var gradShaderID = ctx.createProgram(gradShader);
    370    ctx.clearColor(0, 0, 0, 1);
    371    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    372    // Create fbo.
    373    var fbo = ctx.createFramebuffer();
    374    var tex = ctx.createTexture();
    375    ctx.bindTexture(gl.TEXTURE_2D, tex);
    376    ctx.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, this.getWidth(), this.getHeight(), 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    377    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    378    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    379    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
    380    ctx.bindTexture(gl.TEXTURE_2D, null);
    381    this.checkFramebufferStatus(gl.FRAMEBUFFER);
    382 
    383    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    384 
    385    ctx.enable(gl.DEPTH_TEST);
    386    ctx.enable(gl.STENCIL_TEST);
    387    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    388    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    389 
    390    shader.setColor(ctx, program, [1, 0, 0, 1]);
    391    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
    392 
    393    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
    394 
    395    // Switch to fbo and render gradient into it.
    396    ctx.disable(gl.DEPTH_TEST);
    397    ctx.disable(gl.STENCIL_TEST);
    398    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    399 
    400    gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
    401    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
    402    // Restore default fbo.
    403    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    404 
    405    if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
    406        // Color was not preserved - fill with green.
    407        shader.setColor(ctx, program, [0, 1, 0, 1]);
    408        rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    409    }
    410 
    411    // Clear invalidated buffers.
    412    ctx.clearColor(0, 1, 0, 1);
    413    ctx.clearStencil(1);
    414    ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
    415    ctx.enable(gl.SCISSOR_TEST);
    416    ctx.clear(this.m_buffers);
    417    ctx.disable(gl.SCISSOR_TEST);
    418 
    419    ctx.enable(gl.DEPTH_TEST);
    420    ctx.enable(gl.STENCIL_TEST);
    421    ctx.enable(gl.BLEND);
    422    ctx.blendFunc(gl.ONE, gl.ONE);
    423    ctx.blendEquation(gl.FUNC_ADD);
    424    ctx.bindTexture(gl.TEXTURE_2D, tex);
    425 
    426    texShader.setUniforms(ctx, texShaderID);
    427    rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    428 
    429    dst.readViewport(ctx);
    430    ctx.disable(gl.DEPTH_TEST);
    431    ctx.disable(gl.STENCIL_TEST);
    432    ctx.disable(gl.BLEND);
    433 };
    434 
    435 /**
    436 * @constructor
    437 * @extends {es3fFboTestCase.FboTestCase}
    438 * @param {string} name
    439 * @param {string} desc
    440 * @param {number} colorFmt
    441 * @param {number} depthStencilFmt
    442 * @param {number} invalidateBuffers
    443 */
    444 es3fFboInvalidateTests.InvalidateFboRenderCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    445    es3fFboTestCase.FboTestCase.call(this, name, desc);
    446    this.m_colorFmt = colorFmt;
    447    this.m_depthStencilFmt = depthStencilFmt;
    448    this.m_invalidateBuffers = invalidateBuffers;
    449 };
    450 
    451 setParentClass(es3fFboInvalidateTests.InvalidateFboRenderCase, es3fFboTestCase.FboTestCase);
    452 
    453 es3fFboInvalidateTests.InvalidateFboRenderCase.prototype.preCheck = function() {
    454    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    455    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    456    return true; // No exception thrown
    457 };
    458 
    459 es3fFboInvalidateTests.InvalidateFboRenderCase.prototype.render = function(dst) {
    460    var ctx = this.getCurrentContext();
    461    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    462    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    463    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    464    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    465    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    466    var cBias = colorFmtInfo.valueMin;
    467    var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
    468    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    469    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    470    var flatShaderID = ctx.createProgram(flatShader);
    471 
    472    // Create fbo.
    473    var colorRbo = ctx.createRenderbuffer();
    474    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    475    ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_colorFmt, this.getWidth(), this.getHeight());
    476 
    477    if (this.m_depthStencilFmt != gl.NONE) {
    478        var depthStencilRbo = ctx.createRenderbuffer();
    479        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
    480        ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_depthStencilFmt, this.getWidth(), this.getHeight());
    481    }
    482 
    483    var fbo = ctx.createFramebuffer();
    484    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    485    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
    486 
    487    if (depth)
    488        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
    489 
    490    if (stencil)
    491        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
    492 
    493    this.checkFramebufferStatus(gl.FRAMEBUFFER);
    494 
    495    ctx.clearColor(0, 0, 0, 1);
    496    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    497 
    498    ctx.enable(gl.DEPTH_TEST);
    499    ctx.enable(gl.STENCIL_TEST);
    500    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    501    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    502 
    503    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
    504    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);
    505 
    506    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
    507 
    508    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
    509        // Color was not preserved - fill with green.
    510        ctx.disable(gl.DEPTH_TEST);
    511        ctx.disable(gl.STENCIL_TEST);
    512 
    513        flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
    514        rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
    515 
    516        ctx.enable(gl.DEPTH_TEST);
    517        ctx.enable(gl.STENCIL_TEST);
    518    }
    519 
    520    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
    521        // Depth was not preserved.
    522        ctx.depthFunc(gl.ALWAYS);
    523    }
    524 
    525    if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
    526        // Stencil was preserved.
    527        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    528    }
    529 
    530    ctx.enable(gl.BLEND);
    531    ctx.blendFunc(gl.ONE, gl.ONE);
    532    ctx.blendEquation(gl.FUNC_ADD);
    533 
    534    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
    535    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
    536 
    537    es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
    538 };
    539 
    540 /**
    541 * @constructor
    542 * @extends {es3fFboTestCase.FboTestCase}
    543 * @param {string} name
    544 * @param {string} desc
    545 * @param {number} colorFmt
    546 * @param {number} depthStencilFmt
    547 * @param {number} invalidateBuffers
    548 */
    549 es3fFboInvalidateTests.InvalidateFboUnbindReadCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    550    es3fFboTestCase.FboTestCase.call(this, name, desc);
    551    this.m_colorFmt = colorFmt;
    552    this.m_depthStencilFmt = depthStencilFmt;
    553    this.m_invalidateBuffers = invalidateBuffers;
    554 };
    555 
    556 setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindReadCase, es3fFboTestCase.FboTestCase);
    557 
    558 es3fFboInvalidateTests.InvalidateFboUnbindReadCase.prototype.preCheck = function() {
    559    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    560    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    561    return true; // No exception thrown
    562 };
    563 
    564 es3fFboInvalidateTests.InvalidateFboUnbindReadCase.prototype.render = function(dst) {
    565    var ctx = this.getCurrentContext();
    566    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    567    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    568    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    569    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    570    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    571    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    572    // Create fbo.
    573    var transferFmt = gluTextureUtil.getTransferFormat(colorFmt);
    574    var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
    575    var gradShaderID = ctx.createProgram(gradShader);
    576 
    577    var colorTex = ctx.createTexture();
    578    ctx.bindTexture(gl.TEXTURE_2D, colorTex);
    579    ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_colorFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
    580    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    581 
    582    if (this.m_depthStencilFmt != gl.NONE) {
    583        transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);
    584 
    585        var depthStencilTex = ctx.createTexture();
    586        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
    587        ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_depthStencilFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
    588        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    589        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    590    }
    591 
    592    var fbo = ctx.createFramebuffer();
    593    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    594    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
    595 
    596    if (depth)
    597        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
    598 
    599    if (stencil)
    600        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
    601 
    602    this.checkFramebufferStatus(gl.FRAMEBUFFER);
    603 
    604    ctx.clearColor(0, 0, 0, 1);
    605    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    606 
    607    ctx.enable(gl.DEPTH_TEST);
    608    ctx.enable(gl.STENCIL_TEST);
    609    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    610    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    611 
    612    gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
    613    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
    614 
    615    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
    616 
    617    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    618    ctx.disable(gl.DEPTH_TEST);
    619    ctx.disable(gl.STENCIL_TEST);
    620 
    621    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
    622        // Render color.
    623        /** @type {es3fFboTestUtil.Texture2DShader} */
    624        var texShader = new es3fFboTestUtil.Texture2DShader(
    625            [gluTextureUtil.getSampler2DType(colorFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
    626        var texShaderID = ctx.createProgram(texShader);
    627 
    628        texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
    629        texShader.setUniforms(ctx, texShaderID);
    630 
    631        ctx.bindTexture(gl.TEXTURE_2D, colorTex);
    632        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    633    } else {
    634        // Render depth.
    635        texShader = new es3fFboTestUtil.Texture2DShader(
    636            [gluTextureUtil.getSampler2DType(depthStencilFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
    637        texShaderID = ctx.createProgram(texShader);
    638 
    639        texShader.setUniforms(ctx, texShaderID);
    640 
    641        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
    642        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    643    }
    644 
    645    dst.readViewport(ctx);
    646 };
    647 
    648 /**
    649 * @constructor
    650 * @extends {es3fFboTestCase.FboTestCase}
    651 * @param {string} name
    652 * @param {string} desc
    653 * @param {number} numSamples
    654 * @param {number} invalidateBuffers
    655 */
    656 es3fFboInvalidateTests.InvalidateFboUnbindBlitCase = function(name, desc, numSamples, invalidateBuffers) {
    657 // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
    658 //       behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
    659 //       source and destination rectangles must match when multisampling.
    660    es3fFboTestCase.FboTestCase.call(this, name, desc, numSamples > 0);
    661    this.m_numSamples = numSamples;
    662    this.m_colorFmt = getCompatibleColorFormat();
    663    this.m_depthStencilFmt = getCompatibleDepthStencilFormat();
    664    this.m_invalidateBuffers = invalidateBuffers;
    665 };
    666 
    667 setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindBlitCase, es3fFboTestCase.FboTestCase);
    668 
    669 es3fFboInvalidateTests.InvalidateFboUnbindBlitCase.prototype.preCheck = function() {
    670    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    671    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    672    return true; // No exception thrown
    673 };
    674 
    675 es3fFboInvalidateTests.InvalidateFboUnbindBlitCase.prototype.render = function(dst) {
    676    var ctx = this.getCurrentContext();
    677    var quadSizePixels = [this.m_numSamples == 0 ? this.getWidth() : Math.min(128, this.getWidth()),
    678                                                     this.m_numSamples == 0 ? this.getHeight() : Math.min(128, this.getHeight())];
    679    var quadNDCLeftBottomXY = [-1, -1];
    680    var quadNDCSize = [2 * quadSizePixels[0] / this.getWidth(), 2 * quadSizePixels[1] / this.getHeight()];
    681    var quadNDCRightTopXY = deMath.add(quadNDCLeftBottomXY, quadNDCSize);
    682    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    683    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    684    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    685    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    686    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    687    var flatShaderID = ctx.createProgram(flatShader);
    688 
    689    ctx.clearColor(0, 0, 0, 1);
    690    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    691 
    692    // Create fbo.
    693    var colorRbo = ctx.createRenderbuffer();
    694    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    695    ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFmt, quadSizePixels[0], quadSizePixels[1]);
    696 
    697    if (this.m_depthStencilFmt != gl.NONE) {
    698        var depthStencilRbo = ctx.createRenderbuffer();
    699        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
    700        ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFmt, quadSizePixels[0], quadSizePixels[1]);
    701    }
    702 
    703    var fbo = ctx.createFramebuffer();
    704    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    705    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
    706 
    707    if (depth)
    708        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
    709 
    710    if (stencil)
    711        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
    712 
    713    this.checkFramebufferStatus(gl.FRAMEBUFFER);
    714 
    715    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    716 
    717    ctx.enable(gl.DEPTH_TEST);
    718    ctx.enable(gl.STENCIL_TEST);
    719    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    720    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    721 
    722    flatShader.setColor(ctx, flatShaderID, [1, 0, 0, 1]);
    723    rrUtil.drawQuad(ctx, flatShaderID,
    724        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], -1],
    725        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 1]);
    726 
    727    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
    728 
    729    // Set default framebuffer as draw framebuffer and blit preserved buffers.
    730    ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    731    ctx.blitFramebuffer(0, 0, quadSizePixels[0], quadSizePixels[1],
    732                         0, 0, quadSizePixels[0], quadSizePixels[1],
    733                         (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) & ~this.m_invalidateBuffers, gl.NEAREST);
    734    ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
    735 
    736    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
    737        // Color was not preserved - fill with green.
    738        ctx.disable(gl.DEPTH_TEST);
    739        ctx.disable(gl.STENCIL_TEST);
    740 
    741        flatShader.setColor(ctx, flatShaderID, [0, 1, 0, 1]);
    742        rrUtil.drawQuad(ctx, flatShaderID,
    743            [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
    744            [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
    745 
    746        ctx.enable(gl.DEPTH_TEST);
    747        ctx.enable(gl.STENCIL_TEST);
    748    }
    749 
    750    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
    751        // Depth was not preserved.
    752        ctx.depthFunc(gl.ALWAYS);
    753    }
    754 
    755    if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
    756        // Stencil was preserved.
    757        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    758    }
    759 
    760    ctx.enable(gl.BLEND);
    761    ctx.blendFunc(gl.ONE, gl.ONE);
    762    ctx.blendEquation(gl.FUNC_ADD);
    763 
    764    flatShader.setColor(ctx, flatShaderID, [0, 0, 1, 1]);
    765    rrUtil.drawQuad(ctx, flatShaderID,
    766        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
    767        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
    768 
    769    dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
    770 };
    771 
    772 /**
    773 * @constructor
    774 * @extends {es3fFboTestCase.FboTestCase}
    775 * @param {string} name
    776 * @param {string} desc
    777 * @param {number} colorFmt
    778 * @param {number} depthStencilFmt
    779 * @param {number} invalidateBuffers
    780 */
    781 es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    782    es3fFboTestCase.FboTestCase.call(this, name, desc);
    783    this.m_colorFmt = colorFmt;
    784    this.m_depthStencilFmt = depthStencilFmt;
    785    this.m_invalidateBuffers = invalidateBuffers;
    786 };
    787 
    788 setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase, es3fFboTestCase.FboTestCase);
    789 
    790 es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.preCheck = function() {
    791    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    792    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    793    return true; // No exception thrown
    794 };
    795 
    796 es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.compare = function(reference, result) {
    797    var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_colorFmt), new tcuRGBA.RGBA([12, 12, 12, 12]));
    798    return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold);
    799 };
    800 
    801 es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.render = function(dst) {
    802    var ctx = this.getCurrentContext();
    803    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    804    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    805    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    806    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    807    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    808    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    809    // Create fbo.
    810    var transferFmt = gluTextureUtil.getTransferFormat(colorFmt);
    811    var gradShader = new es3fFboTestUtil.GradientShader(es3fFboTestUtil.getFragmentOutputType(colorFmt));
    812    var gradShaderID = ctx.createProgram(gradShader);
    813    var invalidateX = 0;
    814    var invalidateY = 0;
    815    var invalidateW = this.getWidth() / 2;
    816    var invalidateH = this.getHeight();
    817    var readX = invalidateW;
    818    var readY = 0;
    819    var readW = this.getWidth() / 2;
    820    var readH = this.getHeight();
    821 
    822    var colorTex = ctx.createTexture();
    823    ctx.bindTexture(gl.TEXTURE_2D, colorTex);
    824    ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_colorFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
    825    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    826    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    827 
    828    if (this.m_depthStencilFmt != gl.NONE) {
    829        transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);
    830 
    831        var depthStencilTex = ctx.createTexture();
    832        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
    833        ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_depthStencilFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
    834        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    835        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    836    }
    837 
    838    var fbo = ctx.createFramebuffer();
    839    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    840    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
    841 
    842    if (depth)
    843        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
    844 
    845    if (stencil)
    846        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
    847 
    848    this.checkFramebufferStatus(gl.FRAMEBUFFER);
    849 
    850    this.clearColorBuffer(colorFmt, [0.0, 0.0, 0.0, 1.0]);
    851    ctx.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    852 
    853    ctx.enable(gl.DEPTH_TEST);
    854    ctx.enable(gl.STENCIL_TEST);
    855    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    856    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    857 
    858    gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
    859    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
    860 
    861    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
    862 
    863    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    864    ctx.disable(gl.DEPTH_TEST);
    865    ctx.disable(gl.STENCIL_TEST);
    866 
    867    ctx.clearColor(0.25, 0.5, 0.75, 1);
    868    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    869 
    870    // Limit read area using scissor.
    871    ctx.scissor(readX, readY, readW, readH);
    872    ctx.enable(gl.SCISSOR_TEST);
    873 
    874    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
    875        // Render color.
    876        /** @type {es3fFboTestUtil.Texture2DShader} */
    877        var texShader = new es3fFboTestUtil.Texture2DShader(
    878            [gluTextureUtil.getSampler2DType(colorFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
    879        var texShaderID = ctx.createProgram(texShader);
    880 
    881        texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
    882        texShader.setUniforms(ctx, texShaderID);
    883 
    884        ctx.bindTexture(gl.TEXTURE_2D, colorTex);
    885        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    886    } else {
    887        // Render depth.
    888        texShader = new es3fFboTestUtil.Texture2DShader(
    889            [gluTextureUtil.getSampler2DType(depthStencilFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
    890        texShaderID = ctx.createProgram(texShader);
    891 
    892        texShader.setUniforms(ctx, texShaderID);
    893 
    894        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
    895        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    896    }
    897 
    898    dst.readViewport(ctx);
    899 };
    900 
    901 /**
    902 * @constructor
    903 * @extends {es3fFboTestCase.FboTestCase}
    904 * @param {string} name
    905 * @param {string} desc
    906 * @param {number} colorFmt
    907 * @param {number} depthStencilFmt
    908 * @param {number} invalidateBuffers
    909 */
    910 es3fFboInvalidateTests.InvalidateSubFboRenderCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    911    es3fFboTestCase.FboTestCase.call(this, name, desc);
    912    this.m_colorFmt = colorFmt;
    913    this.m_depthStencilFmt = depthStencilFmt;
    914    this.m_invalidateBuffers = invalidateBuffers;
    915 };
    916 
    917 setParentClass(es3fFboInvalidateTests.InvalidateSubFboRenderCase, es3fFboTestCase.FboTestCase);
    918 
    919 es3fFboInvalidateTests.InvalidateSubFboRenderCase.prototype.preCheck = function() {
    920    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    921    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    922    return true; // No exception thrown
    923 };
    924 
    925 es3fFboInvalidateTests.InvalidateSubFboRenderCase.prototype.render = function(dst) {
    926    var ctx = this.getCurrentContext();
    927    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    928    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    929    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    930    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    931    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    932    var cBias = colorFmtInfo.valueMin;
    933    var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
    934    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    935    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    936    var flatShaderID = ctx.createProgram(flatShader);
    937    var invalidateX = this.getWidth() / 4;
    938    var invalidateY = this.getHeight() / 4;
    939    var invalidateW = this.getWidth() / 2;
    940    var invalidateH = this.getHeight() / 2;
    941 
    942    // Create fbo.
    943    var colorRbo = ctx.createRenderbuffer();
    944    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    945    ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_colorFmt, this.getWidth(), this.getHeight());
    946 
    947    if (this.m_depthStencilFmt != gl.NONE) {
    948        var depthStencilRbo = ctx.createRenderbuffer();
    949        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
    950        ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_depthStencilFmt, this.getWidth(), this.getHeight());
    951    }
    952 
    953    var fbo = ctx.createFramebuffer();
    954    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    955    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
    956 
    957    if (depth)
    958        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
    959 
    960    if (stencil)
    961        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
    962 
    963    this.checkFramebufferStatus(gl.FRAMEBUFFER);
    964 
    965    ctx.clearBufferfv(gl.COLOR, 0, deMath.add(deMath.multiply([0, 0, 0, 1], cScale), cBias));
    966    ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0);
    967 
    968    ctx.enable(gl.DEPTH_TEST);
    969    ctx.enable(gl.STENCIL_TEST);
    970    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    971    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
    972 
    973    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
    974    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);
    975 
    976    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
    977 
    978    // Clear invalidated buffers.
    979    ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
    980    ctx.enable(gl.SCISSOR_TEST);
    981 
    982    if (this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT)
    983        ctx.clearBufferfv(gl.COLOR, 0, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
    984 
    985    ctx.clear(this.m_invalidateBuffers & ~gl.COLOR_BUFFER_BIT);
    986    ctx.disable(gl.SCISSOR_TEST);
    987 
    988    ctx.enable(gl.BLEND);
    989    ctx.blendFunc(gl.ONE, gl.ONE);
    990    ctx.blendEquation(gl.FUNC_ADD);
    991 
    992    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
    993    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
    994 
    995    es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
    996 };
    997 
    998 /**
    999 * @constructor
   1000 * @extends {es3fFboTestCase.FboTestCase}
   1001 * @param {string} name
   1002 * @param {string} desc
   1003 * @param {number} numSamples
   1004 * @param {number} invalidateBuffers
   1005 */
   1006 es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase = function(name, desc, numSamples, invalidateBuffers) {
   1007 // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
   1008 //       behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
   1009 //       source and destination rectangles must match when multisampling.
   1010    es3fFboTestCase.FboTestCase.call(this, name, desc, numSamples > 0);
   1011    this.m_numSamples = numSamples;
   1012    this.m_colorFmt = getCompatibleColorFormat();
   1013    this.m_depthStencilFmt = getCompatibleDepthStencilFormat();
   1014    this.m_invalidateBuffers = invalidateBuffers;
   1015 };
   1016 
   1017 setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase, es3fFboTestCase.FboTestCase);
   1018 
   1019 es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase.prototype.preCheck = function() {
   1020    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
   1021    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
   1022    return true; // No exception thrown
   1023 };
   1024 
   1025 es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase.prototype.render = function(dst) {
   1026    var ctx = this.getCurrentContext();
   1027    var quadSizePixels = [this.m_numSamples == 0 ? this.getWidth() : Math.min(128, this.getWidth()),
   1028                                                     this.m_numSamples == 0 ? this.getHeight() : Math.min(128, this.getHeight())];
   1029    var quadNDCLeftBottomXY = [-1, -1];
   1030    var quadNDCSize = [2 * quadSizePixels[0] / this.getWidth(), 2 * quadSizePixels[1] / this.getHeight()];
   1031    var quadNDCRightTopXY = deMath.add(quadNDCLeftBottomXY, quadNDCSize);
   1032    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
   1033    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
   1034    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
   1035    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
   1036    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
   1037    var flatShaderID = ctx.createProgram(flatShader);
   1038    var invalidateX = 0;
   1039    var invalidateY = 0;
   1040    var invalidateW = quadSizePixels[0] / 2;
   1041    var invalidateH = quadSizePixels[1];
   1042    var blitX0 = invalidateW;
   1043    var blitY0 = 0;
   1044    var blitX1 = blitX0 + quadSizePixels[0] / 2;
   1045    var blitY1 = blitY0 + quadSizePixels[1];
   1046 
   1047    ctx.clearColor(0, 0, 0, 1);
   1048    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
   1049 
   1050    // Create fbo.
   1051    var colorRbo = ctx.createRenderbuffer();
   1052    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
   1053    ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFmt, quadSizePixels[0], quadSizePixels[1]);
   1054 
   1055    if (this.m_depthStencilFmt != gl.NONE) {
   1056        var depthStencilRbo = ctx.createRenderbuffer();
   1057        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
   1058        ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFmt, quadSizePixels[0], quadSizePixels[1]);
   1059    }
   1060 
   1061    var fbo = ctx.createFramebuffer();
   1062    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
   1063    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
   1064 
   1065    if (depth)
   1066        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
   1067 
   1068    if (stencil)
   1069        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
   1070 
   1071    this.checkFramebufferStatus(gl.FRAMEBUFFER);
   1072 
   1073    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
   1074 
   1075    ctx.enable(gl.DEPTH_TEST);
   1076    ctx.enable(gl.STENCIL_TEST);
   1077    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
   1078    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
   1079 
   1080    flatShader.setColor(ctx, flatShaderID, [1, 0, 0, 1]);
   1081    rrUtil.drawQuad(ctx, flatShaderID,
   1082        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], -1],
   1083        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 1]);
   1084 
   1085    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
   1086 
   1087    // Set default framebuffer as draw framebuffer and blit preserved buffers.
   1088    ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
   1089    ctx.blitFramebuffer(blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1,
   1090                         (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) & ~this.m_invalidateBuffers, gl.NEAREST);
   1091    ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
   1092 
   1093    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
   1094        // Color was not preserved - fill with green.
   1095        ctx.disable(gl.DEPTH_TEST);
   1096        ctx.disable(gl.STENCIL_TEST);
   1097 
   1098        flatShader.setColor(ctx, flatShaderID, [0, 1, 0, 1]);
   1099        rrUtil.drawQuad(ctx, flatShaderID,
   1100            [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
   1101            [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
   1102 
   1103        ctx.enable(gl.DEPTH_TEST);
   1104        ctx.enable(gl.STENCIL_TEST);
   1105    }
   1106 
   1107    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
   1108        // Depth was not preserved.
   1109        ctx.depthFunc(gl.ALWAYS);
   1110    }
   1111 
   1112    if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
   1113        // Stencil was preserved.
   1114        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
   1115    }
   1116 
   1117    ctx.enable(gl.BLEND);
   1118    ctx.blendFunc(gl.ONE, gl.ONE);
   1119    ctx.blendEquation(gl.FUNC_ADD);
   1120 
   1121    flatShader.setColor(ctx, flatShaderID, [0, 0, 1, 1]);
   1122    rrUtil.drawQuad(ctx, flatShaderID,
   1123        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
   1124        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
   1125 
   1126    dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
   1127 };
   1128 
   1129 /**
   1130 * @constructor
   1131 * @extends {es3fFboTestCase.FboTestCase}
   1132 * @param {string} name
   1133 * @param {string} desc
   1134 * @param {number} boundTarget
   1135 * @param {number} invalidateTarget
   1136 * @param {Array<number>} invalidateAttachments
   1137 */
   1138 es3fFboInvalidateTests.InvalidateFboTargetCase = function(name, desc, boundTarget, invalidateTarget, invalidateAttachments) {
   1139    es3fFboTestCase.FboTestCase.call(this, name, desc);
   1140    this.m_boundTarget = boundTarget;
   1141    this.m_invalidateTarget = invalidateTarget;
   1142    this.m_invalidateAttachments = invalidateAttachments;
   1143 };
   1144 
   1145 setParentClass(es3fFboInvalidateTests.InvalidateFboTargetCase, es3fFboTestCase.FboTestCase);
   1146 
   1147 es3fFboInvalidateTests.InvalidateFboTargetCase.prototype.render = function(dst) {
   1148    var ctx = this.getCurrentContext();
   1149    var colorFormat = gl.RGBA8;
   1150    var depthStencilFormat = gl.DEPTH24_STENCIL8;
   1151    var colorFmt = gluTextureUtil.mapGLInternalFormat(colorFormat);
   1152    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
   1153    var cBias = colorFmtInfo.valueMin;
   1154    var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
   1155    var isDiscarded = (this.m_boundTarget == gl.FRAMEBUFFER) ||
   1156                                    (this.m_invalidateTarget == gl.FRAMEBUFFER && this.m_boundTarget == gl.DRAW_FRAMEBUFFER) ||
   1157                                    (this.m_invalidateTarget == this.m_boundTarget);
   1158    var isColorDiscarded = isDiscarded && hasAttachment(this.m_invalidateAttachments, gl.COLOR_ATTACHMENT0);
   1159    var isDepthDiscarded = isDiscarded && (hasAttachment(this.m_invalidateAttachments, gl.DEPTH_ATTACHMENT) || hasAttachment(this.m_invalidateAttachments, gl.DEPTH_STENCIL_ATTACHMENT));
   1160    var isStencilDiscarded = isDiscarded && (hasAttachment(this.m_invalidateAttachments, gl.STENCIL_ATTACHMENT) || hasAttachment(this.m_invalidateAttachments, gl.DEPTH_STENCIL_ATTACHMENT));
   1161 
   1162    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
   1163    var flatShaderID = ctx.createProgram(flatShader);
   1164 
   1165    // Create fbo.
   1166    var colorRbo = ctx.createRenderbuffer();
   1167    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
   1168    ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.getWidth(), this.getHeight());
   1169 
   1170    var depthStencilRbo = ctx.createRenderbuffer();
   1171    ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
   1172    ctx.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, this.getWidth(), this.getHeight());
   1173 
   1174    var fbo = ctx.createFramebuffer();
   1175    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
   1176    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
   1177    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
   1178    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
   1179 
   1180    this.checkFramebufferStatus(gl.FRAMEBUFFER);
   1181 
   1182    ctx.clearColor(0, 0, 0, 1);
   1183    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
   1184 
   1185    ctx.enable(gl.DEPTH_TEST);
   1186    ctx.enable(gl.STENCIL_TEST);
   1187    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
   1188    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
   1189 
   1190    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
   1191    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);
   1192 
   1193    // Bound FBO to test target and default to other
   1194    if (this.m_boundTarget != gl.FRAMEBUFFER) {
   1195        // Dummy fbo is used as complemeting target (read when discarding draw for example).
   1196        // \note Framework takes care of deleting objects at the end of test case.
   1197        var dummyTarget = this.m_boundTarget == gl.DRAW_FRAMEBUFFER ? gl.READ_FRAMEBUFFER : gl.DRAW_FRAMEBUFFER;
   1198 
   1199        var dummyColorRbo = ctx.createRenderbuffer();
   1200        ctx.bindRenderbuffer(gl.RENDERBUFFER, dummyColorRbo);
   1201        ctx.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 64, 64);
   1202        var dummyFbo = ctx.createFramebuffer();
   1203        ctx.bindFramebuffer(dummyTarget, dummyFbo);
   1204        ctx.framebufferRenderbuffer(dummyTarget, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dummyColorRbo);
   1205 
   1206        ctx.bindFramebuffer(this.m_boundTarget, fbo);
   1207    }
   1208 
   1209    ctx.invalidateFramebuffer(this.m_invalidateTarget, this.m_invalidateAttachments);
   1210 
   1211    if (this.m_boundTarget != gl.FRAMEBUFFER)
   1212        ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
   1213 
   1214    if (isColorDiscarded) {
   1215        // Color was not preserved - fill with green.
   1216        ctx.disable(gl.DEPTH_TEST);
   1217        ctx.disable(gl.STENCIL_TEST);
   1218 
   1219        flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
   1220        rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
   1221 
   1222        ctx.enable(gl.DEPTH_TEST);
   1223        ctx.enable(gl.STENCIL_TEST);
   1224    }
   1225 
   1226    if (isDepthDiscarded) {
   1227        // Depth was not preserved.
   1228        ctx.depthFunc(gl.ALWAYS);
   1229    }
   1230 
   1231    if (!isStencilDiscarded) {
   1232        // Stencil was preserved.
   1233        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
   1234    }
   1235 
   1236    ctx.enable(gl.BLEND);
   1237    ctx.blendFunc(gl.ONE, gl.ONE);
   1238    ctx.blendEquation(gl.FUNC_ADD);
   1239 
   1240    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
   1241    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
   1242 
   1243    es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
   1244 };
   1245 
   1246 /**
   1247 * @constructor
   1248 * @extends {tcuTestCase.DeqpTest}
   1249 */
   1250 es3fFboInvalidateTests.FboInvalidateTests = function() {
   1251    tcuTestCase.DeqpTest.call(this, 'invalidate', 'Framebuffer invalidate tests');
   1252 };
   1253 
   1254 es3fFboInvalidateTests.FboInvalidateTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
   1255 es3fFboInvalidateTests.FboInvalidateTests.prototype.constructor = es3fFboInvalidateTests.FboInvalidateTests;
   1256 
   1257 es3fFboInvalidateTests.FboInvalidateTests.prototype.init = function() {
   1258    var defaultFbGroup = new tcuTestCase.DeqpTest('default', 'Default framebuffer invalidate tests');
   1259    this.addChild(defaultFbGroup);
   1260 
   1261    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_none', 'Invalidating no framebuffers (ref)', 0));
   1262    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_color', 'Rendering after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
   1263    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_depth', 'Rendering after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
   1264    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_stencil', 'Rendering after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
   1265    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_depth_stencil', 'Rendering after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1266    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_all', 'Rendering after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1267    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_color', 'Binding fbo after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
   1268    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_depth', 'Binding fbo after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
   1269    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_stencil', 'Binding fbo after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
   1270    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_depth_stencil', 'Binding fbo after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1271    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_all', 'Binding fbo after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1272    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_color', 'Rendering after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
   1273    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_depth', 'Rendering after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
   1274    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_stencil', 'Rendering after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
   1275    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_depth_stencil', 'Rendering after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1276    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_all', 'Rendering after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1277    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_color', 'Binding fbo after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
   1278    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_depth', 'Binding fbo after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
   1279    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_stencil', 'Binding fbo after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
   1280    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_depth_stencil', 'Binding fbo after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1281    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_all', 'Binding fbo after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1282    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('draw_framebuffer_color', 'Invalidating gl.COLOR in gl.DRAW_FRAMEBUFFER', gl.COLOR_BUFFER_BIT, gl.DRAW_FRAMEBUFFER));
   1283    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('draw_framebuffer_all', 'Invalidating all in gl.DRAW_FRAMEBUFFER', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.DRAW_FRAMEBUFFER));
   1284    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('read_framebuffer_color', 'Invalidating gl.COLOR in gl.READ_FRAMEBUFFER', gl.COLOR_BUFFER_BIT, gl.READ_FRAMEBUFFER));
   1285    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('read_framebuffer_all', 'Invalidating all in gl.READ_FRAMEBUFFER', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.READ_FRAMEBUFFER));
   1286 
   1287    // invalidate.whole.
   1288    var wholeFboGroup = new tcuTestCase.DeqpTest('whole', 'Invalidating whole framebuffer object');
   1289    this.addChild(wholeFboGroup);
   1290    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_none', '', gl.RGBA8, gl.DEPTH24_STENCIL8, 0));
   1291    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
   1292    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
   1293    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
   1294    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1295    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_all', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1296 
   1297    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
   1298    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
   1299    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
   1300    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1301    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_color_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1302 
   1303    if (getCompatibleDepthStencilFormat() !== gl.NONE) {
   1304        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_color', '', 0, gl.COLOR_BUFFER_BIT));
   1305        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_depth', '', 0, gl.DEPTH_BUFFER_BIT));
   1306        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_stencil', '', 0, gl.STENCIL_BUFFER_BIT));
   1307        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_depth_stencil', '', 0, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1308        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_color', '', 4, gl.COLOR_BUFFER_BIT));
   1309        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_depth', '', 4, gl.DEPTH_BUFFER_BIT));
   1310        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_stencil', '', 4, gl.STENCIL_BUFFER_BIT));
   1311        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_depth_stencil', '', 4, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1312    }
   1313 
   1314    // invalidate.sub.
   1315    var subFboGroup = new tcuTestCase.DeqpTest('sub', 'Invalidating subsection of framebuffer object');
   1316    this.addChild(subFboGroup);
   1317    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_none', '', gl.RGBA8, gl.DEPTH24_STENCIL8, 0));
   1318    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
   1319    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
   1320    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
   1321    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1322    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_all', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1323 
   1324    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
   1325    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
   1326    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
   1327    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1328    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_color_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1329 
   1330    if (getCompatibleDepthStencilFormat() !== gl.NONE) {
   1331        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_color', '', 0, gl.COLOR_BUFFER_BIT));
   1332        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_depth', '', 0, gl.DEPTH_BUFFER_BIT));
   1333        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_stencil', '', 0, gl.STENCIL_BUFFER_BIT));
   1334        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_depth_stencil', '', 0, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1335        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_color', '', 4, gl.COLOR_BUFFER_BIT));
   1336        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_depth', '', 4, gl.DEPTH_BUFFER_BIT));
   1337        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_stencil', '', 4, gl.STENCIL_BUFFER_BIT));
   1338        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_depth_stencil', '', 4, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1339    }
   1340    // invalidate.format.
   1341    var numFormatSubGroups = 3;
   1342    var formatGroup = [];
   1343    for (var ii = 0; ii < numFormatSubGroups; ++ii) {
   1344        formatGroup[ii] = new tcuTestCase.DeqpTest('format', 'Invalidating framebuffers with selected formats');
   1345        this.addChild(formatGroup[ii]);
   1346    }
   1347    // Color buffer formats.
   1348    var colorFormats = [
   1349        // RGBA formats
   1350        gl.RGBA32I,
   1351        gl.RGBA32UI,
   1352        gl.RGBA16I,
   1353        gl.RGBA16UI,
   1354        gl.RGBA8,
   1355        gl.RGBA8I,
   1356        gl.RGBA8UI,
   1357        gl.SRGB8_ALPHA8,
   1358        gl.RGB10_A2,
   1359        gl.RGB10_A2UI,
   1360        gl.RGBA4,
   1361        gl.RGB5_A1,
   1362 
   1363        // RGB formats
   1364        gl.RGB8,
   1365        gl.RGB565,
   1366 
   1367        // RG formats
   1368        gl.RG32I,
   1369        gl.RG32UI,
   1370        gl.RG16I,
   1371        gl.RG16UI,
   1372        gl.RG8,
   1373        gl.RG8I,
   1374        gl.RG8UI,
   1375 
   1376        // R formats
   1377        gl.R32I,
   1378        gl.R32UI,
   1379        gl.R16I,
   1380        gl.R16UI,
   1381        gl.R8,
   1382        gl.R8I,
   1383        gl.R8UI,
   1384 
   1385        // gl.EXT_color_buffer_float
   1386        gl.RGBA32F,
   1387        gl.RGBA16F,
   1388        gl.R11F_G11F_B10F,
   1389        gl.RG32F,
   1390        gl.RG16F,
   1391        gl.R32F,
   1392        gl.R16F
   1393    ];
   1394 
   1395    // Depth/stencilbuffer formats.
   1396    var depthStencilFormats = [
   1397        gl.DEPTH_COMPONENT32F,
   1398        gl.DEPTH_COMPONENT24,
   1399        gl.DEPTH_COMPONENT16,
   1400        gl.DEPTH32F_STENCIL8,
   1401        gl.DEPTH24_STENCIL8,
   1402        gl.STENCIL_INDEX8
   1403    ];
   1404 
   1405    // Colorbuffer tests use invalidate, unbind, read test.
   1406    for (var ndx = 0; ndx < colorFormats.length; ndx++)
   1407        formatGroup[ndx % numFormatSubGroups].addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase(es3fFboTestUtil.getFormatName(colorFormats[ndx]), '', colorFormats[ndx], gl.NONE, gl.COLOR_BUFFER_BIT));
   1408 
   1409    // Depth/stencilbuffer tests use invalidate, render test.
   1410    for (var ndx = 0; ndx < depthStencilFormats.length; ndx++)
   1411        formatGroup[ndx % numFormatSubGroups].addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase(es3fFboTestUtil.getFormatName(depthStencilFormats[ndx]), '', gl.RGBA8, depthStencilFormats[ndx], gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
   1412 
   1413    // invalidate.target
   1414    var targetGroup = new tcuTestCase.DeqpTest('target', 'Invalidate target');
   1415    this.addChild(targetGroup);
   1416 
   1417    var s_targetCases = [
   1418        ['framebuffer_framebuffer', gl.FRAMEBUFFER, gl.FRAMEBUFFER],
   1419        ['framebuffer_read_framebuffer', gl.FRAMEBUFFER, gl.READ_FRAMEBUFFER],
   1420        ['framebuffer_draw_framebuffer', gl.FRAMEBUFFER, gl.DRAW_FRAMEBUFFER],
   1421        ['read_framebuffer_framebuffer', gl.READ_FRAMEBUFFER, gl.FRAMEBUFFER],
   1422        ['read_framebuffer_read_framebuffer', gl.READ_FRAMEBUFFER, gl.READ_FRAMEBUFFER],
   1423        ['read_framebuffer_draw_framebuffer', gl.READ_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER],
   1424        ['draw_framebuffer_framebuffer', gl.DRAW_FRAMEBUFFER, gl.FRAMEBUFFER],
   1425        ['draw_framebuffer_read_framebuffer', gl.DRAW_FRAMEBUFFER, gl.READ_FRAMEBUFFER],
   1426        ['draw_framebuffer_draw_framebuffer', gl.DRAW_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER]
   1427    ];
   1428 
   1429    var colorAttachment = [gl.COLOR_ATTACHMENT0];
   1430    var depthStencilAttachment = [gl.DEPTH_STENCIL_ATTACHMENT];
   1431    var allAttachments = [gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT];
   1432 
   1433    for (var caseNdx = 0; caseNdx < s_targetCases.length; caseNdx++) {
   1434        var baseName = s_targetCases[caseNdx][0];
   1435        var invalidateT = s_targetCases[caseNdx][1];
   1436        var boundT = s_targetCases[caseNdx][1];
   1437 
   1438        targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_color', '', boundT, invalidateT, colorAttachment));
   1439        targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_depth_stencil', '', boundT, invalidateT, depthStencilAttachment));
   1440        targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_all', '', boundT, invalidateT, allAttachments));
   1441    }
   1442 
   1443 };
   1444 
   1445 /**
   1446 * Run test
   1447 * @param {WebGL2RenderingContext} context
   1448 */
   1449 es3fFboInvalidateTests.run = function(context, range) {
   1450    gl = context;
   1451    //Set up Test Root parameters
   1452    var state = tcuTestCase.runner;
   1453    state.setRoot(new es3fFboInvalidateTests.FboInvalidateTests());
   1454 
   1455    //Set up name and description of this test series.
   1456    setCurrentTestName(state.testCases.fullName());
   1457    description(state.testCases.getDescription());
   1458 
   1459    try {
   1460        if (range)
   1461            state.setRange(range);
   1462        //Run test cases
   1463        tcuTestCase.runTestCases();
   1464    }
   1465    catch (err) {
   1466        testFailedOptions('Failed to es3fFboInvalidateTests.run tests', false);
   1467        tcuTestCase.runner.terminate();
   1468    }
   1469 };
   1470 
   1471 });