1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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) {
57 throw new Error('Assert failed');
61 * es3fFboTestCase.FboTestCase class, inherits from TestCase and sglrContextWrapper
63 * @extends {tcuTestCase.DeqpTest}
64 * @param {string} name
65 * @param {string} description
66 * @param {boolean=} useScreenSizedViewport
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;
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);
82 es3fFboTestCase.FboTestCase.prototype.getHeight = function() {
83 return Math.min(gl.drawingBufferHeight, this.m_viewportHeight);
87 * Sets the current context (inherited from sglrContextWrapper)
88 * @param {es3fFboTestCase.Context} context
90 es3fFboTestCase.FboTestCase.prototype.setContext = function(context) {
91 this.m_curCtx = context;
95 * Gets the current context (inherited from sglrContextWrapper)
96 * @return {es3fFboTestCase.Context}
98 es3fFboTestCase.FboTestCase.prototype.getCurrentContext = function() {
103 * @param {tcuSurface.Surface} reference
104 * @param {tcuSurface.Surface} result
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);
111 * @param {number} sizedFormat
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';
122 throw new TestFailedException(msg);
127 * @param {number} sizedFormat deUint32
128 * @param {number} numSamples
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.");
142 throw new Error('Sample count not supported');
151 * @param {tcuSurface.Surface} dst
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
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);
166 * @param {tcuSurface.Surface} dst
169 * @param {number} width
170 * @param {number} height
172 es3fFboTestCase.FboTestCase.prototype.readPixels = function(dst, x, y, width, height) {
173 dst.readViewport(this.getCurrentContext(), [x, y, width, height]);
177 * @param {number} target
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));
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));
192 * @param {tcuTexture.TextureFormat} format
193 * @param {Array<number>=} value Vec4
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);
200 es3fFboTestCase.FboTestCase.prototype.iterate = function() {
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.
218 /** @type {sglrGLContext.GLContext} */ var context = new sglrGLContext.GLContext(
220 [x, y, width, height]);
222 this.setContext(context);
226 /** @type {number} */ var err = context.getError();
227 if (err != gl.NO_ERROR)
228 throw new Error('glError: ' + context);
230 this.setContext(null);
232 if (e instanceof es3fFboTestUtil.FboIncompleteException)
233 if (e.getReason() == gl.FRAMEBUFFER_UNSUPPORTED) {
235 // m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, 'Not supported');
236 assertMsgOptions(false, 'Not supported', true, false);
237 return tcuTestCase.IterateResult.STOP;
243 var alphaBits = /** @type {number} */ (gl.getParameter(gl.ALPHA_BITS));
244 /** @type {sglrReferenceContext.ReferenceContextBuffers} */
245 var buffers = new sglrReferenceContext.ReferenceContextBuffers(new tcuPixelFormat.PixelFormat(
249 alphaBits > 0 ? 8 : 0),
250 /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS)),
251 /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS)),
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;
272 * Deinit. Clear some GL state variables
274 es3fFboTestCase.FboTestCase.prototype.deinit = function () {
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);
294 // Framebuffer control
296 gl.colorMask(true, true, true, true);
298 gl.stencilMask(0xffff);
300 gl.clearColor(0.0, 0.0, 0.0, 0.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.
310 * @param {number} format
313 es3fFboTestCase.isRequiredFormat = function(format) {
315 // Color-renderable formats
323 case gl.SRGB8_ALPHA8:
347 case gl.DEPTH_COMPONENT32F:
348 case gl.DEPTH_COMPONENT24:
349 case gl.DEPTH_COMPONENT16:
352 // Depth+stencil formats
353 case gl.DEPTH32F_STENCIL8:
354 case gl.DEPTH24_STENCIL8:
358 case gl.STENCIL_INDEX8:
367 * @param {number} format deUint32
368 * @return {Array<string>}
370 es3fFboTestCase.getEnablingExtensions = function(format) {
371 /** @return {Array<string>} */ var out = [];
373 DE_ASSERT(!es3fFboTestCase.isRequiredFormat(format));
381 case gl.R11F_G11F_B10F:
384 out.push('EXT_color_buffer_float');
387 // EXT_color_buffer_half_float is not exposed in WebGL 2.0.
397 * @param {es3fFboTestCase.Context} context
398 * @param {Array<string>} requiredExts
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);
416 * @param {number} format GL format
419 es3fFboTestCase.getMinimumSampleCount = function(format) {
429 case gl.SRGB8_ALPHA8:
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:
458 // gl.EXT_color_buffer_float
459 case gl.R11F_G11F_B10F:
470 // gl.EXT_color_buffer_half_float
475 throw new Error('Unknown format:' + format);
479 es3fFboTestCase.querySampleCounts = function(format) {
480 return gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);