Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fFboTestCase.js
blobcdaa7d352f895121d8621170d19efda457f07f26
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.es3fFboTestCase');
23 goog.require('framework.common.tcuImageCompare');
24 goog.require('framework.common.tcuPixelFormat');
25 goog.require('framework.common.tcuSurface');
26 goog.require('framework.common.tcuTestCase');
27 goog.require('framework.common.tcuTexture');
28 goog.require('framework.delibs.debase.deMath');
29 goog.require('framework.delibs.debase.deRandom');
30 goog.require('framework.delibs.debase.deString');
31 goog.require('framework.opengl.simplereference.sglrGLContext');
32 goog.require('framework.opengl.simplereference.sglrReferenceContext');
33 goog.require('framework.referencerenderer.rrRenderer');
34 goog.require('functional.gles3.es3fFboTestUtil');
36 goog.scope(function() {
38 var es3fFboTestCase = functional.gles3.es3fFboTestCase;
39 var tcuTestCase = framework.common.tcuTestCase;
40 var deMath = framework.delibs.debase.deMath;
41 var tcuSurface = framework.common.tcuSurface;
42 var tcuTexture = framework.common.tcuTexture;
43 var rrRenderer = framework.referencerenderer.rrRenderer;
44 var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
45 var tcuPixelFormat = framework.common.tcuPixelFormat;
46 var tcuImageCompare = framework.common.tcuImageCompare;
47 var deString = framework.delibs.debase.deString;
48 var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
49 var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
50 var deRandom = framework.delibs.debase.deRandom;
52 /** @typedef {(sglrGLContext.GLContext | WebGL2RenderingContext | sglrReferenceContext.ReferenceContext)} */
53 es3fFboTestCase.Context;
55 var DE_ASSERT = function(x) {
56     if (!x)
57         throw new Error('Assert failed');
60     /**
61     * es3fFboTestCase.FboTestCase class, inherits from TestCase and sglrContextWrapper
62     * @constructor
63     * @extends {tcuTestCase.DeqpTest}
64     * @param {string} name
65     * @param {string} description
66     * @param {boolean=} useScreenSizedViewport
67     */
68     es3fFboTestCase.FboTestCase = function(name, description, useScreenSizedViewport /*= false */) {
69         tcuTestCase.DeqpTest.call(this, name, description);
70         /** @type {number} */ this.m_viewportWidth = useScreenSizedViewport === undefined ? gl.drawingBufferWidth : 128;
71         /** @type {number} */ this.m_viewportHeight = useScreenSizedViewport === undefined ? gl.drawingBufferHeight : 128;
72         /** @type {es3fFboTestCase.Context} */ this.m_curCtx = null;
73     };
75     es3fFboTestCase.FboTestCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
76     es3fFboTestCase.FboTestCase.prototype.constructor = es3fFboTestCase.FboTestCase;
78     es3fFboTestCase.FboTestCase.prototype.getWidth = function() {
79         return Math.min(gl.drawingBufferWidth, this.m_viewportWidth);
80     };
82     es3fFboTestCase.FboTestCase.prototype.getHeight = function() {
83         return Math.min(gl.drawingBufferHeight, this.m_viewportHeight);
84     };
86     /**
87      * Sets the current context (inherited from sglrContextWrapper)
88      * @param {es3fFboTestCase.Context} context
89      */
90     es3fFboTestCase.FboTestCase.prototype.setContext = function(context) {
91         this.m_curCtx = context;
92     };
94     /**
95      * Gets the current context (inherited from sglrContextWrapper)
96      * @return {es3fFboTestCase.Context}
97      */
98     es3fFboTestCase.FboTestCase.prototype.getCurrentContext = function() {
99         return this.m_curCtx;
100     };
102     /**
103      * @param {tcuSurface.Surface} reference
104      * @param {tcuSurface.Surface} result
105      */
106     es3fFboTestCase.FboTestCase.prototype.compare = function(reference, result) {
107         return tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), 0.05, tcuImageCompare.CompareLogMode.RESULT);
108     };
110     /**
111      * @param {number} sizedFormat
112      */
113     es3fFboTestCase.FboTestCase.prototype.checkFormatSupport = function(sizedFormat) {
114         /** @const @type {boolean} */ var isCoreFormat = es3fFboTestCase.isRequiredFormat(sizedFormat);
115         /** @const @type {Array<string>} */ var requiredExts = (!isCoreFormat) ? es3fFboTestCase.getEnablingExtensions(sizedFormat) : [];
117         // Check that we don't try to use invalid formats.
118         DE_ASSERT(isCoreFormat || requiredExts);
119         if (requiredExts.length > 0 && !es3fFboTestCase.isAnyExtensionSupported(gl, requiredExts)) {
120             var msg = 'SKIP: Format ' + WebGLTestUtils.glEnumToString(gl, sizedFormat) + ' not supported';
121             debug(msg);
122             throw new TestFailedException(msg);
123         }
124     };
126     /**
127     * @param {number} sizedFormat deUint32
128     * @param {number} numSamples
129     */
130     es3fFboTestCase.FboTestCase.prototype.checkSampleCount = function(sizedFormat, numSamples) {
131         /** @const @type {number} */ var minSampleCount = es3fFboTestCase.getMinimumSampleCount(sizedFormat);
133         if (numSamples > minSampleCount) {
134             // Exceeds spec-mandated minimum - need to check.
135             /** @const @type {goog.NumberArray} */ var supportedSampleCounts = es3fFboTestCase.querySampleCounts(sizedFormat);
136             var supported = Array.prototype.slice.call(supportedSampleCounts);
137             if (supported.indexOf(numSamples) == -1) {
138                 if (minSampleCount == 0 || numSamples > gl.getParameter(gl.MAX_SAMPLES)) {
139                     checkMessage(false, "Sample count not supported, but it is allowed.");
140                     return false;
141                 } else {
142                     throw new Error('Sample count not supported');
143                 }
144             }
145             return true;
146         }
147         return true;
148     };
150     /**
151     * @param {tcuSurface.Surface} dst
152     * @param {number} x
153     * @param {number} y
154     * @param {number} width
155     * @param {number} height
156     * @param {tcuTexture.TextureFormat} format
157     * @param {Array<number>} scale Vec4
158     * @param {Array<number>} bias Vec4
159     */
160     es3fFboTestCase.FboTestCase.prototype.readPixelsUsingFormat = function(dst, x, y, width, height, format, scale, bias) {
161         dst.setSize(width, height);
162         es3fFboTestUtil.readPixels(this.getCurrentContext(), dst, x, y, width, height, format, scale, bias);
163     };
165     /**
166     * @param {tcuSurface.Surface} dst
167     * @param {number} x
168     * @param {number} y
169     * @param {number} width
170     * @param {number} height
171     */
172     es3fFboTestCase.FboTestCase.prototype.readPixels = function(dst, x, y, width, height) {
173         dst.readViewport(this.getCurrentContext(), [x, y, width, height]);
174     };
176     /**
177     * @param {number} target
178     */
179     es3fFboTestCase.FboTestCase.prototype.checkFramebufferStatus = function(target) {
180         /** @type {number} */ var status = this.getCurrentContext().checkFramebufferStatus(target);
181         if (status != gl.FRAMEBUFFER_COMPLETE)
182             throw new Error('Framebuffer Status: ' + WebGLTestUtils.glEnumToString(gl, status));
183     };
185     es3fFboTestCase.FboTestCase.prototype.checkError = function() {
186         /** @type {number} */ var err = this.getCurrentContext().getError();
187             if (err != gl.NO_ERROR)
188                 throw new Error('glError: ' + WebGLTestUtils.glEnumToString(gl, err));
189     };
191     /**
192     * @param {tcuTexture.TextureFormat} format
193     * @param {Array<number>=} value Vec4
194     */
195     es3fFboTestCase.FboTestCase.prototype.clearColorBuffer = function(format, value) {
196         if (value === undefined) value = [0.0, 0.0, 0.0, 0.0];
197         es3fFboTestUtil.clearColorBuffer(this.getCurrentContext(), format, value);
198     };
200     es3fFboTestCase.FboTestCase.prototype.iterate = function() {
201         // Viewport.
202         /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
203         /** @type {number} */ var width = Math.min(gl.drawingBufferWidth, this.m_viewportWidth);
204         /** @type {number} */ var height = Math.min(gl.drawingBufferHeight, this.m_viewportHeight);
205         /** @type {number} */ var x = rnd.getInt(0, gl.drawingBufferWidth - width);
206         /** @type {number} */ var y = rnd.getInt(0, gl.drawingBufferHeight - height);
208         // Surface format and storage is choosen by render().
209         /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(width, height);
210         /** @type {tcuSurface.Surface} */ var result = new tcuSurface.Surface(width, height);
212         // Call preCheck() that can throw exception if some requirement is not met.
213         if (this.preCheck && !this.preCheck())
214             return tcuTestCase.IterateResult.STOP;
216         // Render using GLES3.
217         try {
218             /** @type {sglrGLContext.GLContext} */ var context = new sglrGLContext.GLContext(
219                                                              gl,
220                                                              [x, y, width, height]);
222              this.setContext(context);
223              this.render(result);
225              // Check error.
226              /** @type {number} */ var err = context.getError();
227              if (err != gl.NO_ERROR)
228                  throw new Error('glError: ' + context);
230              this.setContext(null);
231          } catch (e) {
232              if (e instanceof es3fFboTestUtil.FboIncompleteException)
233                  if (e.getReason() == gl.FRAMEBUFFER_UNSUPPORTED) {
234                      // log << e;
235                      // m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, 'Not supported');
236                      assertMsgOptions(false, 'Not supported', true, false);
237                      return tcuTestCase.IterateResult.STOP;
238                  }
239              throw e;
240          }
242         // Render reference.
243         var alphaBits = /** @type {number} */ (gl.getParameter(gl.ALPHA_BITS));
244         /** @type {sglrReferenceContext.ReferenceContextBuffers} */
245         var buffers = new sglrReferenceContext.ReferenceContextBuffers(new tcuPixelFormat.PixelFormat(
246                                                                             8,
247                                                                             8,
248                                                                             8,
249                                                                             alphaBits > 0 ? 8 : 0),
250                                                                        /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS)),
251                                                                        /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS)),
252                                                                        width,
253                                                                        height);
254         /** @type {sglrReferenceContext.ReferenceContext} */
255         var refContext = new sglrReferenceContext.ReferenceContext(new sglrReferenceContext.ReferenceContextLimits(gl),
256                                                                 buffers.getColorbuffer(),
257                                                                 buffers.getDepthbuffer(),
258                                                                 buffers.getStencilbuffer());
259         refContext.getError();
260         this.setContext(refContext);
261         this.render(reference);
262         this.setContext(null);
264         /** @type {boolean} */ var isOk = this.compare(reference, result);
266         assertMsgOptions(isOk, '', true, false);
268         return tcuTestCase.IterateResult.STOP;
269     };
271     /**
272     * Deinit. Clear some GL state variables
273     */
274     es3fFboTestCase.FboTestCase.prototype.deinit = function () {
275         // Pixel operations
276         {
277             gl.disable(gl.SCISSOR_TEST);
279             gl.disable(gl.STENCIL_TEST);
280             gl.stencilFunc(gl.ALWAYS, 0, 0xffff);
281             gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
283             gl.disable(gl.DEPTH_TEST);
284             gl.depthFunc(gl.LESS);
286             gl.disable(gl.BLEND);
287             gl.blendFunc(gl.ONE, gl.ZERO);
288             gl.blendEquation(gl.FUNC_ADD);
289             gl.blendColor(0.0, 0.0, 0.0, 0.0);
291             gl.enable(gl.DITHER);
292         }
294         // Framebuffer control
295         {
296             gl.colorMask(true, true, true, true);
297             gl.depthMask(true);
298             gl.stencilMask(0xffff);
300             gl.clearColor(0.0, 0.0, 0.0, 0.0);
301             gl.clearDepth(1.0);
302             gl.clearStencil(0.0);
303             // Do not call clear() here because it might generate an INVALID_OPERATION if
304             // some color buffers are of integer formats due to WebGL2 specific constraint.
305             // The tests do not rely on clear() here.
306         }
307     };
309     /**
310     * @param {number} format
311     * @return {boolean}
312     */
313     es3fFboTestCase.isRequiredFormat = function(format) {
314         switch (format) {
315             // Color-renderable formats
316             case gl.RGBA32I:
317             case gl.RGBA32UI:
318             case gl.RGBA16I:
319             case gl.RGBA16UI:
320             case gl.RGBA8:
321             case gl.RGBA8I:
322             case gl.RGBA8UI:
323             case gl.SRGB8_ALPHA8:
324             case gl.RGB10_A2:
325             case gl.RGB10_A2UI:
326             case gl.RGBA4:
327             case gl.RGB5_A1:
328             case gl.RGB8:
329             case gl.RGB565:
330             case gl.RG32I:
331             case gl.RG32UI:
332             case gl.RG16I:
333             case gl.RG16UI:
334             case gl.RG8:
335             case gl.RG8I:
336             case gl.RG8UI:
337             case gl.R32I:
338             case gl.R32UI:
339             case gl.R16I:
340             case gl.R16UI:
341             case gl.R8:
342             case gl.R8I:
343             case gl.R8UI:
344                 return true;
346             // Depth formats
347             case gl.DEPTH_COMPONENT32F:
348             case gl.DEPTH_COMPONENT24:
349             case gl.DEPTH_COMPONENT16:
350                 return true;
352             // Depth+stencil formats
353             case gl.DEPTH32F_STENCIL8:
354             case gl.DEPTH24_STENCIL8:
355                 return true;
357             // Stencil formats
358             case gl.STENCIL_INDEX8:
359                 return true;
361             default:
362                 return false;
363         }
364     };
366     /**
367     * @param {number} format deUint32
368     * @return {Array<string>}
369     */
370     es3fFboTestCase.getEnablingExtensions = function(format) {
371         /** @return {Array<string>} */ var out = [];
373         DE_ASSERT(!es3fFboTestCase.isRequiredFormat(format));
375         switch (format) {
376             case gl.RGBA16F:
377             case gl.RG16F:
378             case gl.R16F:
379             case gl.RGBA32F:
380             case gl.RGB32F:
381             case gl.R11F_G11F_B10F:
382             case gl.RG32F:
383             case gl.R32F:
384                 out.push('EXT_color_buffer_float');
385                 break;
386             case gl.RGB16F:
387                 // EXT_color_buffer_half_float is not exposed in WebGL 2.0.
388                 break;
389             default:
390                 break;
391         }
393         return out;
394     };
396     /**
397     * @param {es3fFboTestCase.Context} context
398     * @param {Array<string>} requiredExts
399     * @return {boolean}
400     */
401     es3fFboTestCase.isAnyExtensionSupported = function(context, requiredExts) {
402         for (var iter in requiredExts) {
403             /** @const @type {string} */ var extension = requiredExts[iter];
405             if (sglrGLContext.isExtensionSupported(gl, extension)) {
406                 // enable the extension
407                 gl.getExtension(extension);
408                 return true;
409             }
410         }
412         return false;
413     };
416  * @param {number} format GL format
417  * @return {number}
418  */
419 es3fFboTestCase.getMinimumSampleCount = function(format) {
420     switch (format) {
421         // Core formats
422         case gl.RGBA32I:
423         case gl.RGBA32UI:
424         case gl.RGBA16I:
425         case gl.RGBA16UI:
426         case gl.RGBA8:
427         case gl.RGBA8I:
428         case gl.RGBA8UI:
429         case gl.SRGB8_ALPHA8:
430         case gl.RGB10_A2:
431         case gl.RGB10_A2UI:
432         case gl.RGBA4:
433         case gl.RGB5_A1:
434         case gl.RGB8:
435         case gl.RGB565:
436         case gl.RG32I:
437         case gl.RG32UI:
438         case gl.RG16I:
439         case gl.RG16UI:
440         case gl.RG8:
441         case gl.RG8I:
442         case gl.RG8UI:
443         case gl.R32I:
444         case gl.R32UI:
445         case gl.R16I:
446         case gl.R16UI:
447         case gl.R8:
448         case gl.R8I:
449         case gl.R8UI:
450         case gl.DEPTH_COMPONENT32F:
451         case gl.DEPTH_COMPONENT24:
452         case gl.DEPTH_COMPONENT16:
453         case gl.DEPTH32F_STENCIL8:
454         case gl.DEPTH24_STENCIL8:
455         case gl.STENCIL_INDEX8:
456             return 4;
458         // gl.EXT_color_buffer_float
459         case gl.R11F_G11F_B10F:
460         case gl.RG16F:
461         case gl.R16F:
462             return 4;
464         case gl.RGBA32F:
465         case gl.RGBA16F:
466         case gl.RG32F:
467         case gl.R32F:
468             return 0;
470         // gl.EXT_color_buffer_half_float
471         case gl.RGB16F:
472             return 0;
474         default:
475             throw new Error('Unknown format:' + format);
476     }
479 es3fFboTestCase.querySampleCounts = function(format) {
480     return gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);