Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fFboInvalidateTests.js
blob3a90cceccd4d1831630aeb340336308cc2b592c5
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  */
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');
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;
49 /** @type {WebGL2RenderingContext} */ var gl;
51 var setParentClass = function(child, parent) {
52     child.prototype = Object.create(parent.prototype);
53     child.prototype.constructor = child;
56 var getDefaultFBDiscardAttachments = function(discardBufferBits) {
57     var attachments = [];
59     if (discardBufferBits & gl.COLOR_BUFFER_BIT)
60         attachments.push(gl.COLOR);
62     if (discardBufferBits & gl.DEPTH_BUFFER_BIT)
63         attachments.push(gl.DEPTH);
65     if (discardBufferBits & gl.STENCIL_BUFFER_BIT)
66         attachments.push(gl.STENCIL);
68     return attachments;
71 var getFBODiscardAttachments = function(discardBufferBits) {
72     var attachments = [];
74     if (discardBufferBits & gl.COLOR_BUFFER_BIT)
75         attachments.push(gl.COLOR_ATTACHMENT0);
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);
85     return attachments;
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     }
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;
107     if (!hasDepth || !hasStencil || (stencilBits != 8))
108         return gl.NONE;
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;
118 var hasAttachment = function(attachments, attachment) {
119     return attachments.indexOf(attachment) >= 0;
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;
136 setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase, es3fFboTestCase.FboTestCase);
138 es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase.prototype.render = function(dst) {
139     var ctx = this.getCurrentContext();
140     var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
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);
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);
153     rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
154     ctx.invalidateFramebuffer(this.m_fboTarget, attachments);
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);
161         shader.setColor(ctx, program, [0, 1, 0, 1]);
162         rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
164         ctx.enable(gl.DEPTH_TEST);
165         ctx.enable(gl.STENCIL_TEST);
166     }
168     if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
169         // Depth was not preserved.
170         ctx.depthFunc(gl.ALWAYS);
171     }
173     if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
174         // Stencil was preserved.
175         ctx.stencilFunc(gl.EQUAL, 1, 0xff);
176     }
178     ctx.enable(gl.BLEND);
179     ctx.blendFunc(gl.ONE, gl.ONE);
180     ctx.blendEquation(gl.FUNC_ADD);
182     shader.setColor(ctx, program, [0, 0, 1, 1]);
183     rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
184     dst.readViewport(ctx);
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;
199 setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase, es3fFboTestCase.FboTestCase);
201 es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase.prototype.render = function(dst) {
202     var ctx = this.getCurrentContext();
203     var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
205     var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
206     var program = ctx.createProgram(shader);
208     /** @type {es3fFboTestUtil.Texture2DShader} */
209     var texShader = new es3fFboTestUtil.Texture2DShader(
210         [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
212     /** @type {es3fFboTestUtil.GradientShader} */
213     var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
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);
230     ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
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);
237     shader.setColor(ctx, program, [1, 0, 0, 1]);
238     rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
240     ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
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);
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);
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     }
258     if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
259         // Depth was not preserved.
260         ctx.depthFunc(gl.ALWAYS);
261     }
263     if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
264         // Stencil was preserved.
265         ctx.stencilFunc(gl.EQUAL, 1, 0xff);
266     }
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);
275     texShader.setUniforms(ctx, texShaderID);
276     rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
278     dst.readViewport(ctx);
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;
295 setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase, es3fFboTestCase.FboTestCase);
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);
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);
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);
316     rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
317     ctx.invalidateSubFramebuffer(this.m_fboTarget, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
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);
327     ctx.enable(gl.BLEND);
328     ctx.blendFunc(gl.ONE, gl.ONE);
329     ctx.blendEquation(gl.FUNC_ADD);
331     shader.setColor(ctx, program, [0, 0, 1, 1]);
332     rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
333     dst.readViewport(ctx);
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;
348 setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase, es3fFboTestCase.FboTestCase);
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;
358     var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
359     var program = ctx.createProgram(shader);
361     /** @type {es3fFboTestUtil.Texture2DShader} */
362     var texShader = new es3fFboTestUtil.Texture2DShader(
363         [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
365     /** @type {es3fFboTestUtil.GradientShader} */
366     var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
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);
383     ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
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);
390     shader.setColor(ctx, program, [1, 0, 0, 1]);
391     rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
393     ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
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);
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);
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     }
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);
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);
426     texShader.setUniforms(ctx, texShaderID);
427     rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
429     dst.readViewport(ctx);
430     ctx.disable(gl.DEPTH_TEST);
431     ctx.disable(gl.STENCIL_TEST);
432     ctx.disable(gl.BLEND);
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;
451 setParentClass(es3fFboInvalidateTests.InvalidateFboRenderCase, es3fFboTestCase.FboTestCase);
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
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);
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());
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     }
483     var fbo = ctx.createFramebuffer();
484     ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
485     ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
487     if (depth)
488         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
490     if (stencil)
491         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
493     this.checkFramebufferStatus(gl.FRAMEBUFFER);
495     ctx.clearColor(0, 0, 0, 1);
496     ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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);
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]);
506     ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
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);
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]);
516         ctx.enable(gl.DEPTH_TEST);
517         ctx.enable(gl.STENCIL_TEST);
518     }
520     if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
521         // Depth was not preserved.
522         ctx.depthFunc(gl.ALWAYS);
523     }
525     if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
526         // Stencil was preserved.
527         ctx.stencilFunc(gl.EQUAL, 1, 0xff);
528     }
530     ctx.enable(gl.BLEND);
531     ctx.blendFunc(gl.ONE, gl.ONE);
532     ctx.blendEquation(gl.FUNC_ADD);
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]);
537     es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
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;
556 setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindReadCase, es3fFboTestCase.FboTestCase);
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
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);
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);
582     if (this.m_depthStencilFmt != gl.NONE) {
583         transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);
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     }
592     var fbo = ctx.createFramebuffer();
593     ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
594     ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
596     if (depth)
597         ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
599     if (stencil)
600         ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
602     this.checkFramebufferStatus(gl.FRAMEBUFFER);
604     ctx.clearColor(0, 0, 0, 1);
605     ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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);
612     gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
613     rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
615     ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
617     ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
618     ctx.disable(gl.DEPTH_TEST);
619     ctx.disable(gl.STENCIL_TEST);
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);
628         texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
629         texShader.setUniforms(ctx, texShaderID);
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);
639         texShader.setUniforms(ctx, texShaderID);
641         ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
642         rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
643     }
645     dst.readViewport(ctx);
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;
667 setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindBlitCase, es3fFboTestCase.FboTestCase);
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
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);
689     ctx.clearColor(0, 0, 0, 1);
690     ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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]);
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     }
703     var fbo = ctx.createFramebuffer();
704     ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
705     ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
707     if (depth)
708         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
710     if (stencil)
711         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
713     this.checkFramebufferStatus(gl.FRAMEBUFFER);
715     ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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);
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]);
727     ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
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);
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);
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]);
746         ctx.enable(gl.DEPTH_TEST);
747         ctx.enable(gl.STENCIL_TEST);
748     }
750     if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
751         // Depth was not preserved.
752         ctx.depthFunc(gl.ALWAYS);
753     }
755     if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
756         // Stencil was preserved.
757         ctx.stencilFunc(gl.EQUAL, 1, 0xff);
758     }
760     ctx.enable(gl.BLEND);
761     ctx.blendFunc(gl.ONE, gl.ONE);
762     ctx.blendEquation(gl.FUNC_ADD);
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]);
769     dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
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;
788 setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase, es3fFboTestCase.FboTestCase);
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
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);
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();
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);
828     if (this.m_depthStencilFmt != gl.NONE) {
829         transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);
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     }
838     var fbo = ctx.createFramebuffer();
839     ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
840     ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
842     if (depth)
843         ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
845     if (stencil)
846         ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
848     this.checkFramebufferStatus(gl.FRAMEBUFFER);
850     this.clearColorBuffer(colorFmt, [0.0, 0.0, 0.0, 1.0]);
851     ctx.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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);
858     gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
859     rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
861     ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
863     ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
864     ctx.disable(gl.DEPTH_TEST);
865     ctx.disable(gl.STENCIL_TEST);
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);
870     // Limit read area using scissor.
871     ctx.scissor(readX, readY, readW, readH);
872     ctx.enable(gl.SCISSOR_TEST);
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);
881         texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
882         texShader.setUniforms(ctx, texShaderID);
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);
892         texShader.setUniforms(ctx, texShaderID);
894         ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
895         rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
896     }
898     dst.readViewport(ctx);
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;
917 setParentClass(es3fFboInvalidateTests.InvalidateSubFboRenderCase, es3fFboTestCase.FboTestCase);
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
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;
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());
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     }
953     var fbo = ctx.createFramebuffer();
954     ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
955     ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
957     if (depth)
958         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
960     if (stencil)
961         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
963     this.checkFramebufferStatus(gl.FRAMEBUFFER);
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);
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);
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]);
976     ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
978     // Clear invalidated buffers.
979     ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
980     ctx.enable(gl.SCISSOR_TEST);
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));
985     ctx.clear(this.m_invalidateBuffers & ~gl.COLOR_BUFFER_BIT);
986     ctx.disable(gl.SCISSOR_TEST);
988     ctx.enable(gl.BLEND);
989     ctx.blendFunc(gl.ONE, gl.ONE);
990     ctx.blendEquation(gl.FUNC_ADD);
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]);
995     es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
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;
1017 setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase, es3fFboTestCase.FboTestCase);
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
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];
1047     ctx.clearColor(0, 0, 0, 1);
1048     ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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]);
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     }
1061     var fbo = ctx.createFramebuffer();
1062     ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
1063     ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
1065     if (depth)
1066         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
1068     if (stencil)
1069         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
1071     this.checkFramebufferStatus(gl.FRAMEBUFFER);
1073     ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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);
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]);
1085     ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
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);
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);
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]);
1103         ctx.enable(gl.DEPTH_TEST);
1104         ctx.enable(gl.STENCIL_TEST);
1105     }
1107     if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
1108         // Depth was not preserved.
1109         ctx.depthFunc(gl.ALWAYS);
1110     }
1112     if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
1113         // Stencil was preserved.
1114         ctx.stencilFunc(gl.EQUAL, 1, 0xff);
1115     }
1117     ctx.enable(gl.BLEND);
1118     ctx.blendFunc(gl.ONE, gl.ONE);
1119     ctx.blendEquation(gl.FUNC_ADD);
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]);
1126     dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
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;
1145 setParentClass(es3fFboInvalidateTests.InvalidateFboTargetCase, es3fFboTestCase.FboTestCase);
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));
1162     var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
1163     var flatShaderID = ctx.createProgram(flatShader);
1165     // Create fbo.
1166     var colorRbo = ctx.createRenderbuffer();
1167     ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
1168     ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.getWidth(), this.getHeight());
1170     var depthStencilRbo = ctx.createRenderbuffer();
1171     ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
1172     ctx.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, this.getWidth(), this.getHeight());
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);
1180     this.checkFramebufferStatus(gl.FRAMEBUFFER);
1182     ctx.clearColor(0, 0, 0, 1);
1183     ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
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);
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]);
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;
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);
1206         ctx.bindFramebuffer(this.m_boundTarget, fbo);
1207     }
1209     ctx.invalidateFramebuffer(this.m_invalidateTarget, this.m_invalidateAttachments);
1211     if (this.m_boundTarget != gl.FRAMEBUFFER)
1212         ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
1214     if (isColorDiscarded) {
1215         // Color was not preserved - fill with green.
1216         ctx.disable(gl.DEPTH_TEST);
1217         ctx.disable(gl.STENCIL_TEST);
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]);
1222         ctx.enable(gl.DEPTH_TEST);
1223         ctx.enable(gl.STENCIL_TEST);
1224     }
1226     if (isDepthDiscarded) {
1227         // Depth was not preserved.
1228         ctx.depthFunc(gl.ALWAYS);
1229     }
1231     if (!isStencilDiscarded) {
1232         // Stencil was preserved.
1233         ctx.stencilFunc(gl.EQUAL, 1, 0xff);
1234     }
1236     ctx.enable(gl.BLEND);
1237     ctx.blendFunc(gl.ONE, gl.ONE);
1238     ctx.blendEquation(gl.FUNC_ADD);
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]);
1243     es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
1247 * @constructor
1248 * @extends {tcuTestCase.DeqpTest}
1250 es3fFboInvalidateTests.FboInvalidateTests = function() {
1251     tcuTestCase.DeqpTest.call(this, 'invalidate', 'Framebuffer invalidate tests');
1254 es3fFboInvalidateTests.FboInvalidateTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
1255 es3fFboInvalidateTests.FboInvalidateTests.prototype.constructor = es3fFboInvalidateTests.FboInvalidateTests;
1257 es3fFboInvalidateTests.FboInvalidateTests.prototype.init = function() {
1258     var defaultFbGroup = new tcuTestCase.DeqpTest('default', 'Default framebuffer invalidate tests');
1259     this.addChild(defaultFbGroup);
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));
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));
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));
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     }
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));
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));
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,
1363         // RGB formats
1364         gl.RGB8,
1365         gl.RGB565,
1367         // RG formats
1368         gl.RG32I,
1369         gl.RG32UI,
1370         gl.RG16I,
1371         gl.RG16UI,
1372         gl.RG8,
1373         gl.RG8I,
1374         gl.RG8UI,
1376         // R formats
1377         gl.R32I,
1378         gl.R32UI,
1379         gl.R16I,
1380         gl.R16UI,
1381         gl.R8,
1382         gl.R8I,
1383         gl.R8UI,
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     ];
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     ];
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));
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));
1413     // invalidate.target
1414     var targetGroup = new tcuTestCase.DeqpTest('target', 'Invalidate target');
1415     this.addChild(targetGroup);
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     ];
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];
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];
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     }
1446 * Run test
1447 * @param {WebGL2RenderingContext} context
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());
1455     //Set up name and description of this test series.
1456     setCurrentTestName(state.testCases.fullName());
1457     description(state.testCases.getDescription());
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     }