Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fFboMultisampleTests.js
blob261da0073412a7084e60dd652ee5a1c6b17f59a0
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.es3fFboMultisampleTests');
23 goog.require('framework.common.tcuImageCompare');
24 goog.require('framework.common.tcuRGBA');
25 goog.require('framework.common.tcuSurface');
26 goog.require('framework.common.tcuTestCase');
27 goog.require('framework.common.tcuTexture');
28 goog.require('framework.common.tcuTextureUtil');
29 goog.require('framework.delibs.debase.deMath');
30 goog.require('framework.delibs.debase.deRandom');
31 goog.require('framework.opengl.gluTextureUtil');
32 goog.require('framework.referencerenderer.rrUtil');
33 goog.require('functional.gles3.es3fFboTestCase');
34 goog.require('functional.gles3.es3fFboTestUtil');
36 goog.scope(function() {
38 var es3fFboMultisampleTests = functional.gles3.es3fFboMultisampleTests;
39 var es3fFboTestCase = functional.gles3.es3fFboTestCase;
40 var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
41 var tcuTestCase = framework.common.tcuTestCase;
42 var tcuSurface = framework.common.tcuSurface;
43 var tcuRGBA = framework.common.tcuRGBA;
44 var tcuImageCompare = framework.common.tcuImageCompare;
45 var tcuTexture = framework.common.tcuTexture;
46 var tcuTextureUtil = framework.common.tcuTextureUtil;
47 var deRandom = framework.delibs.debase.deRandom;
48 var deMath = framework.delibs.debase.deMath;
49 var gluTextureUtil = framework.opengl.gluTextureUtil;
50 var rrUtil = framework.referencerenderer.rrUtil;
52 /** @type {WebGL2RenderingContext} */ var gl;
54 var DE_ASSERT = function(x) {
55     if (!x)
56         throw new Error('Assert failed');
59     /**
60      * @constructor
61      * @extends {es3fFboTestCase.FboTestCase}
62      * @param {string} name
63      * @param {string} desc
64      * @param {number} colorFormat
65      * @param {number} depthStencilFormat
66      * @param {Array<number>} size
67      * @param {number} numSamples
68      */
69     es3fFboMultisampleTests.BasicFboMultisampleCase = function(name, desc, colorFormat, depthStencilFormat, size, numSamples) {
70         es3fFboTestCase.FboTestCase.call(this, name, desc);
71         /** @type {number} */ this.m_colorFormat = colorFormat;
72         /** @type {number} */ this.m_depthStencilFormat = depthStencilFormat;
73         /** @type {Array<number>} */ this.m_size = size;
74         /** @type {number} */ this.m_numSamples = numSamples;
75     };
77     es3fFboMultisampleTests.BasicFboMultisampleCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
78     es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.constructor = es3fFboMultisampleTests.BasicFboMultisampleCase;
80     es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.preCheck = function() {
81         this.checkFormatSupport(this.m_colorFormat);
82         if (!this.checkSampleCount(this.m_colorFormat, this.m_numSamples))
83             return false;
85         if (this.m_depthStencilFormat != gl.NONE) {
86             this.checkFormatSupport(this.m_depthStencilFormat);
87             if (!this.checkSampleCount(this.m_depthStencilFormat, this.m_numSamples))
88                 return false;
89         }
90         return true; // No exception thrown
91     };
93     /**
94      * @param {tcuSurface.Surface} dst
95      */
96     es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.render = function(dst) {
97         var ctx = this.getCurrentContext();
98         /** @type {tcuTexture.TextureFormat} */ var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFormat);
99         /** @type {tcuTexture.TextureFormat} */ var depthStencilFmt = this.m_depthStencilFormat != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFormat) : new tcuTexture.TextureFormat(null, null);
100         /** @type {tcuTextureUtil.TextureFormatInfo} */ var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
101         /** @type {boolean} */ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
102         /** @type {boolean} */ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
103         /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(es3fFboTestUtil.getFragmentOutputType(colorFmt));
104         /** @type {es3fFboTestUtil.FlatColorShader} */ var flatShader = new es3fFboTestUtil.FlatColorShader(es3fFboTestUtil.getFragmentOutputType(colorFmt));
105         var gradShaderID = this.getCurrentContext().createProgram(gradShader);
106         var flatShaderID = this.getCurrentContext().createProgram(flatShader);
107         var msaaFbo = null;
108         var resolveFbo = null;
109         var msaaColorRbo = null;
110         var resolveColorRbo = null;
111         var msaaDepthStencilRbo = null;
112         var resolveDepthStencilRbo = null;
114         // Create framebuffers.
115         msaaColorRbo = ctx.createRenderbuffer();
116         ctx.bindRenderbuffer(gl.RENDERBUFFER, msaaColorRbo);
117         ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFormat, this.m_size[0], this.m_size[1]);
119         if (depth || stencil) {
120             msaaDepthStencilRbo = ctx.createRenderbuffer();
121             ctx.bindRenderbuffer(gl.RENDERBUFFER, msaaDepthStencilRbo);
122             ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFormat, this.m_size[0], this.m_size[1]);
123         }
125         msaaFbo = ctx.createFramebuffer();
126         ctx.bindFramebuffer(gl.FRAMEBUFFER, msaaFbo);
127         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaColorRbo);
128         if (depth)
129             ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, msaaDepthStencilRbo);
130         if (stencil)
131             ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, msaaDepthStencilRbo);
133         this.checkError();
134         this.checkFramebufferStatus(gl.FRAMEBUFFER);
136         resolveColorRbo = ctx.createRenderbuffer();
137         ctx.bindRenderbuffer(gl.RENDERBUFFER, resolveColorRbo);
138         ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, 0, this.m_colorFormat, this.m_size[0], this.m_size[1]);
140         if (depth || stencil) {
141             resolveDepthStencilRbo = ctx.createRenderbuffer();
142             ctx.bindRenderbuffer(gl.RENDERBUFFER, resolveDepthStencilRbo);
143             ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, 0, this.m_depthStencilFormat, this.m_size[0], this.m_size[1]);
144         }
146         resolveFbo = ctx.createFramebuffer();
147         ctx.bindFramebuffer(gl.FRAMEBUFFER, resolveFbo);
148         ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, resolveColorRbo);
149         if (depth)
150             ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, resolveDepthStencilRbo);
151         if (stencil)
152             ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, resolveDepthStencilRbo);
154         this.checkError();
155         this.checkFramebufferStatus(gl.FRAMEBUFFER);
157         ctx.bindFramebuffer(gl.FRAMEBUFFER, msaaFbo);
158         ctx.viewport(0, 0, this.m_size[0], this.m_size[1]);
160         // Clear depth and stencil buffers.
161         ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
163         // Fill MSAA fbo with gradient, depth = [-1..1]
164         ctx.enable(gl.DEPTH_TEST);
165         gradShader.setGradient(this.getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
167         rrUtil.drawQuad(this.getCurrentContext(), gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
169         // Render random-colored quads.
170         /** @const {number} */ var numQuads = 8;
172         // The choice of random seed affects the correctness of the tests,
173         // because there are some boundary conditions which aren't handled
174         // correctly even in the C++ dEQP tests.
175         /** @type {deRandom.Random} */ var rnd = new deRandom.Random(7);
177         ctx.depthFunc(gl.ALWAYS);
178         ctx.enable(gl.STENCIL_TEST);
179         ctx.stencilFunc(gl.ALWAYS, 0, 0xff);
180         ctx.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
182         for (var ndx = 0; ndx < numQuads; ndx++) {
183             /** @type {number} */ var r = rnd.getFloat();
184             /** @type {number} */ var g = rnd.getFloat();
185             /** @type {number} */ var b = rnd.getFloat();
186             /** @type {number} */ var a = rnd.getFloat();
187             /** @type {number} */ var x0 = rnd.getFloat(-1.0, 1.0);
188             /** @type {number} */ var y0 = rnd.getFloat(-1.0, 1.0);
189             /** @type {number} */ var z0 = rnd.getFloat(-1.0, 1.0);
190             /** @type {number} */ var x1 = rnd.getFloat(-1.0, 1.0);
191             /** @type {number} */ var y1 = rnd.getFloat(-1.0, 1.0);
192             /** @type {number} */ var z1 = rnd.getFloat(-1.0, 1.0);
194             flatShader.setColor(this.getCurrentContext(), flatShaderID, deMath.add(deMath.multiply([r, g, b, a], deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin)), colorFmtInfo.valueMin));
195             rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [x0, y0, z0], [x1, y1, z1]);
196         }
198         ctx.disable(gl.DEPTH_TEST);
199         ctx.disable(gl.STENCIL_TEST);
200         this.checkError();
202         // Resolve using glBlitFramebuffer().
203         ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFbo);
204         ctx.blitFramebuffer(0, 0, this.m_size[0], this.m_size[1], 0, 0, this.m_size[0], this.m_size[1], gl.COLOR_BUFFER_BIT | (depth ? gl.DEPTH_BUFFER_BIT : 0) | (stencil ? gl.STENCIL_BUFFER_BIT : 0), gl.NEAREST);
206         ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, resolveFbo);
208         /** @type {number} */ var numSteps;
209         /** @type {number} */ var step;
210         /** @type {number} */ var d;
211         /** @type {number} */ var c;
212         /** @type {number} */ var s;
213         if (depth) {
214             // Visualize depth.
215             numSteps = 8;
216             step = 2.0 / numSteps;
217             ctx.enable(gl.DEPTH_TEST);
218             ctx.depthFunc(gl.LESS);
219             ctx.depthMask(false);
220             ctx.colorMask(false, false, true, false);
222             for (var ndx = 0; ndx < numSteps; ndx++) {
223                 d = -1.0 + step * ndx;
224                 c = ndx / (numSteps - 1);
226                 flatShader.setColor(this.getCurrentContext(), flatShaderID, deMath.add(deMath.multiply([0.0, 0.0, c, 1.0], deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin)), colorFmtInfo.valueMin));
227                 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, d], [1.0, 1.0, d]);
228             }
230             ctx.disable(gl.DEPTH_TEST);
231         }
233         if (stencil) {
234             // Visualize stencil.
235             numSteps = 4;
236             step = 1;
238             ctx.enable(gl.STENCIL_TEST);
239             ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
240             ctx.colorMask(false, true, false, false);
242             for (var ndx = 0; ndx < numSteps; ndx++) {
243                 s = step * ndx;
244                 c = ndx / (numSteps - 1);
246                 ctx.stencilFunc(gl.EQUAL, s, 0xff);
248                 flatShader.setColor(this.getCurrentContext(), flatShaderID, deMath.add(deMath.multiply([0.0, c, 0.0, 1.0], deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin)), colorFmtInfo.valueMin));
249                 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
250             }
252             ctx.disable(gl.STENCIL_TEST);
253         }
255         this.readPixelsUsingFormat(dst, 0, 0, this.m_size[0], this.m_size[1], colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
256     };
258     /**
259      * @param {tcuSurface.Surface} reference
260      * @param {tcuSurface.Surface} result
261      * @return {boolean}
262      */
263     es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.colorCompare = function(reference, result) {
264         /** @const {tcuRGBA.RGBA} */ var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_colorFormat), tcuRGBA.newRGBAComponents(12, 12, 12, 12));
265         return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold, tcuImageCompare.CompareLogMode.RESULT);
266     };
268     /**
269      * @param {tcuSurface.Surface} reference
270      * @param {tcuSurface.Surface} result
271      * @return {boolean}
272      */
273     es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.compare = function(reference, result) {
274         if (this.m_depthStencilFormat != gl.NONE)
275             return es3fFboTestCase.FboTestCase.prototype.compare(reference, result); // FboTestCase.compare
276         else
277             return this.colorCompare(reference, result);
278     };
280     /**
281      * @constructor
282      * @extends {tcuTestCase.DeqpTest}
283      */
284     es3fFboMultisampleTests.FboMultisampleTests = function() {
285         tcuTestCase.DeqpTest.call(this, 'msaa', 'Multisample FBO tests');
286     };
288     es3fFboMultisampleTests.FboMultisampleTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
289     es3fFboMultisampleTests.FboMultisampleTests.prototype.constructor = es3fFboMultisampleTests.FboMultisampleTests;
291     es3fFboMultisampleTests.FboMultisampleTests.prototype.init = function() {
292         /** @const {Array<number>} */ var colorFormats = [
293             // RGBA formats
294             gl.RGBA8,
295             gl.SRGB8_ALPHA8,
296             gl.RGB10_A2,
297             gl.RGBA4,
298             gl.RGB5_A1,
300             // RGB formats
301             gl.RGB8,
302             gl.RGB565,
304             // RG formats
305             gl.RG8,
307             // R formats
308             gl.R8,
310             // gl.EXT_color_buffer_float
311             // Multi-sample floating-point color buffers can be optional supported, see https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/
312             gl.RGBA32F,
313             gl.RGBA16F,
314             gl.R11F_G11F_B10F,
315             gl.RG32F,
316             gl.RG16F,
317             gl.R32F,
318             gl.R16F
319         ];
321         /** @const {Array<number>} */ var depthStencilFormats = [
322             gl.DEPTH_COMPONENT32F,
323             gl.DEPTH_COMPONENT24,
324             gl.DEPTH_COMPONENT16,
325             gl.DEPTH32F_STENCIL8,
326             gl.DEPTH24_STENCIL8,
327             gl.STENCIL_INDEX8
328         ];
330         /** @const {Array<number>} */ var sampleCounts = [2, 4, 8];
332         for (var sampleCntNdx in sampleCounts) {
333             /** @type {number} */ var samples = sampleCounts[sampleCntNdx];
334             /** @type {tcuTestCase.DeqpTest} */
335             var sampleCountGroup = tcuTestCase.newTest(samples + '_samples', '');
336             this.addChild(sampleCountGroup);
338             // Color formats.
339             for (var fmtNdx in colorFormats)
340                 sampleCountGroup.addChild(new es3fFboMultisampleTests.BasicFboMultisampleCase(es3fFboTestUtil.getFormatName(colorFormats[fmtNdx]), '', colorFormats[fmtNdx], gl.NONE, [119, 131], samples));
342             // Depth/stencil formats.
343             for (var fmtNdx in depthStencilFormats)
344                 sampleCountGroup.addChild(new es3fFboMultisampleTests.BasicFboMultisampleCase(es3fFboTestUtil.getFormatName(depthStencilFormats[fmtNdx]), '', gl.RGBA8, depthStencilFormats[fmtNdx], [119, 131], samples));
345         }
346     };
348     es3fFboMultisampleTests.run = function(context, range) {
349         gl = context;
350         //Set up root Test
351         var state = tcuTestCase.runner;
353         var test = new es3fFboMultisampleTests.FboMultisampleTests();
354         var testName = test.fullName();
355         var testDescription = test.getDescription();
357         state.testName = testName;
358         state.setRoot(test);
359         //Set up name and description of this test series.
360         setCurrentTestName(testName);
361         description(testDescription);
363         try {
364             //Create test cases
365             test.init();
366             if (range)
367                 state.setRange(range);
368             //Run test cases
369             tcuTestCase.runTestCases();
370         }
371         catch (err) {
372             testFailedOptions('Failed to es3fFboMultisampleTests.run tests', false);
373             tcuTestCase.runner.terminate();
374         }
375     };