blob: 78229de447b127d230aadaa611d4352b915f04a7 [file] [log] [blame]
/*-------------------------------------------------------------------------
* drawElements Quality Program OpenGL ES Utilities
* ------------------------------------------------
*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
'use strict';
goog.provide('functional.gles3.es3fFboRenderTest');
goog.require('framework.common.tcuImageCompare');
goog.require('framework.common.tcuLogImage');
goog.require('framework.common.tcuPixelFormat');
goog.require('framework.common.tcuRGBA');
goog.require('framework.common.tcuSurface');
goog.require('framework.common.tcuTestCase');
goog.require('framework.common.tcuTexture');
goog.require('framework.common.tcuTextureUtil');
goog.require('framework.delibs.debase.deMath');
goog.require('framework.delibs.debase.deRandom');
goog.require('framework.delibs.debase.deString');
goog.require('framework.delibs.debase.deUtil');
goog.require('framework.opengl.gluShaderUtil');
goog.require('framework.opengl.gluTextureUtil');
goog.require('framework.opengl.simplereference.sglrGLContext');
goog.require('framework.opengl.simplereference.sglrReferenceContext');
goog.require('framework.referencerenderer.rrUtil');
goog.require('functional.gles3.es3fFboTestUtil');
goog.scope(function() {
var es3fFboRenderTest = functional.gles3.es3fFboRenderTest;
var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
var gluShaderUtil = framework.opengl.gluShaderUtil;
var gluTextureUtil = framework.opengl.gluTextureUtil;
var tcuImageCompare = framework.common.tcuImageCompare;
var tcuLogImage = framework.common.tcuLogImage;
var tcuPixelFormat = framework.common.tcuPixelFormat;
var tcuRGBA = framework.common.tcuRGBA;
var tcuTestCase = framework.common.tcuTestCase;
var tcuSurface = framework.common.tcuSurface;
var tcuTexture = framework.common.tcuTexture;
var tcuTextureUtil = framework.common.tcuTextureUtil;
var deMath = framework.delibs.debase.deMath;
var deRandom = framework.delibs.debase.deRandom;
var deString = framework.delibs.debase.deString;
var deUtil = framework.delibs.debase.deUtil;
var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
var sglrReferenceContext =
framework.opengl.simplereference.sglrReferenceContext;
var rrUtil = framework.referencerenderer.rrUtil;
/** @type {WebGL2RenderingContext} */ var gl;
/**
* @constructor
* @param {number=} buffers_
* @param {number=} colorType_
* @param {number=} colorFormat_
* @param {number=} depthStencilType_
* @param {number=} depthStencilFormat_
* @param {number=} width_
* @param {number=} height_
* @param {number=} samples_
*/
es3fFboRenderTest.FboConfig = function(
buffers_, colorType_, colorFormat_, depthStencilType_,
depthStencilFormat_, width_, height_, samples_
) {
// Buffer bit mask (gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|...)
this.buffers = buffers_ ? buffers_ : 0;
// gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP, gl.RENDERBUFFER
this.colorType = colorType_ ? colorType_ : gl.NONE;
// Internal format for color buffer texture or renderbuffer
this.colorFormat = colorFormat_ ? colorFormat_ : gl.NONE;
this.depthStencilType = depthStencilType_?
depthStencilType_ : gl.NONE;
this.depthStencilFormat = depthStencilFormat_ ?
depthStencilFormat_ : gl.NONE;
this.width = width_ ? width_ : 0;
this.height = height_ ? height_ : 0;
this.samples = samples_? samples_ : 0;
};
/**
* @param {number} type
* @return {string}
*/
es3fFboRenderTest.getTypeName = function(type) {
switch (type) {
case gl.TEXTURE_2D: return 'tex2d';
case gl.RENDERBUFFER: return 'rbo';
default:
testFailed('Unknown type');
}
return 'Should not get to this point';
};
/**
* @return {string}
*/
es3fFboRenderTest.FboConfig.prototype.getName = function() {
var name = '';
assertMsgOptions((this.buffers & gl.COLOR_BUFFER_BIT) != 0,
'Color buffer is not specified', false, true);
name += es3fFboRenderTest.getTypeName(this.colorType) + '_' +
es3fFboTestUtil.getFormatName(this.colorFormat);
if (this.buffers & gl.DEPTH_BUFFER_BIT)
name += '_depth';
if (this.buffers & gl.STENCIL_BUFFER_BIT)
name += '_stencil';
if (this.buffers & (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT))
name += '_' + es3fFboRenderTest.getTypeName(this.depthStencilType) +
'_' + es3fFboTestUtil.getFormatName(this.depthStencilFormat);
return name;
};
/**
* @param {number} format
* @return {Array<string>}
*/
es3fFboRenderTest.getEnablingExtensions = function(format) {
/** @type {Array<string>} */ var out = [];
switch (format) {
case gl.RGB16F:
assertMsgOptions(false, "Not part of the tested formats", false, true);
break;
case gl.RGBA16F:
case gl.RG16F:
case gl.R16F:
case gl.RGBA32F:
case gl.RGB32F:
case gl.R11F_G11F_B10F:
case gl.RG32F:
case gl.R32F:
out.push('EXT_color_buffer_float');
default:
break;
}
return out;
};
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {string} name
* @return {*}
*/
es3fFboRenderTest.isExtensionSupported = function(context, name) {
return context.getExtension(name);
};
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {Array<string>} requiredExts
* @return {boolean}
*/
es3fFboRenderTest.isAnyExtensionSupported = function(
context, requiredExts) {
if (!requiredExts || requiredExts.length == 0)
return true;
for (var extNdx = 0; extNdx < requiredExts.length; extNdx++) {
var extension = requiredExts[extNdx];
if (es3fFboRenderTest.isExtensionSupported(context, extension))
return true;
}
return false;
};
/**
* @param {Array} list
* @param {string} sep
* @return {string}
*/
es3fFboRenderTest.join = function(list, sep) {
var out = '';
for (var elemNdx = 0; elemNdx < list.length; elemNdx++) {
if (elemNdx != 0)
out += sep;
out += list[elemNdx];
}
return out;
};
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {number} sizedFormat
*/
es3fFboRenderTest.checkColorFormatSupport = function(context, sizedFormat) {
/** @type {Array<string>} */ var requiredExts =
es3fFboRenderTest.getEnablingExtensions(sizedFormat);
if (!es3fFboRenderTest.isAnyExtensionSupported(context, requiredExts)) {
var errMsg = 'Format not supported, requires ' + (
(requiredExts.length == 1) ? requiredExts[0] :
' one of the following: ' +
requiredExts.join(', ')
);
checkMessage(false, errMsg);
throw new TestFailedException(errMsg);
}
};
/**
* @constructor
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {es3fFboRenderTest.FboConfig} config
* @param {number} width
* @param {number} height
* @param {sglrReferenceContext.AnyFramebuffer=} fbo
* @param {sglrReferenceContext.AnyRenderbuffer=} colorBufferName
* @param {sglrReferenceContext.AnyRenderbuffer=} depthStencilBufferName
*/
es3fFboRenderTest.Framebuffer = function(
context, config, width, height, fbo,
colorBufferName, depthStencilBufferName) {
this.m_config = config;
this.m_context = context;
this.m_framebuffer = fbo ? fbo : null;
this.m_colorBuffer = colorBufferName ? colorBufferName : null;
this.m_depthStencilBuffer = depthStencilBufferName ?
depthStencilBufferName : null;
// Verify that color format is supported
es3fFboRenderTest.checkColorFormatSupport(context, config.colorFormat);
if (!this.m_framebuffer)
this.m_framebuffer = context.createFramebuffer();
context.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
if (this.m_config.buffers & (gl.COLOR_BUFFER_BIT)) {
switch (this.m_config.colorType) {
case gl.TEXTURE_2D:
this.m_colorBuffer = this.createTex2D(
/** @type {WebGLTexture} */ (colorBufferName),
this.m_config.colorFormat, width, height
);
context.framebufferTexture2D(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, this.m_colorBuffer, 0
);
break;
case gl.RENDERBUFFER:
this.m_colorBuffer = this.createRbo(
/** @type {WebGLRenderbuffer} */ (colorBufferName),
this.m_config.colorFormat, width, height
);
context.framebufferRenderbuffer(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.RENDERBUFFER, this.m_colorBuffer
);
break;
default:
testFailed('Unsupported type');
}
}
if (this.m_config.buffers &
(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) {
switch (this.m_config.depthStencilType) {
case gl.TEXTURE_2D:
this.m_depthStencilBuffer = this.createTex2D(
/** @type {WebGLTexture} */
(depthStencilBufferName),
this.m_config.depthStencilFormat, width, height
);
break;
case gl.RENDERBUFFER:
this.m_depthStencilBuffer = this.createRbo(
/** @type {WebGLRenderbuffer} */
(depthStencilBufferName),
this.m_config.depthStencilFormat, width, height
);
break;
default:
testFailed('Unsupported type');
}
}
for (var ndx = 0; ndx < 2; ndx++) {
var bit = ndx ? gl.STENCIL_BUFFER_BIT : gl.DEPTH_BUFFER_BIT;
var point = ndx ? gl.STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
if ((this.m_config.buffers & bit) == 0)
continue; /* Not used. */
switch (this.m_config.depthStencilType) {
case gl.TEXTURE_2D:
context.framebufferTexture2D(
gl.FRAMEBUFFER, point, gl.TEXTURE_2D,
this.m_depthStencilBuffer, 0
);
break;
case gl.RENDERBUFFER:
context.framebufferRenderbuffer(
gl.FRAMEBUFFER, point,
gl.RENDERBUFFER, this.m_depthStencilBuffer
);
break;
default:
throw new Error('Invalid depth stencil type');
}
}
context.bindFramebuffer(gl.FRAMEBUFFER, null);
};
/**
* @return {es3fFboRenderTest.FboConfig}
*/
es3fFboRenderTest.Framebuffer.prototype.getConfig = function() {
return this.m_config;
};
/**
* @return {?sglrReferenceContext.AnyFramebuffer}
*/
es3fFboRenderTest.Framebuffer.prototype.getFramebuffer = function() {
return this.m_framebuffer;
};
/**
* @return {?sglrReferenceContext.AnyRenderbuffer}
*/
es3fFboRenderTest.Framebuffer.prototype.getColorBuffer = function() {
return this.m_colorBuffer;
};
/**
* @return {?sglrReferenceContext.AnyRenderbuffer}
*/
es3fFboRenderTest.Framebuffer.prototype.getDepthStencilBuffer = function() {
return this.m_depthStencilBuffer;
};
/**
* deinit
*/
es3fFboRenderTest.Framebuffer.prototype.deinit = function() {
this.m_context.deleteFramebuffer(
/** @type {WebGLFramebuffer} */ (this.m_framebuffer)
);
this.destroyBuffer(this.m_colorBuffer, this.m_config.colorType);
this.destroyBuffer(
this.m_depthStencilBuffer, this.m_config.depthStencilType
);
};
/**
* checkCompleteness
*/
es3fFboRenderTest.Framebuffer.prototype.checkCompleteness = function() {
this.m_context.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
var status = this.m_context.checkFramebufferStatus(gl.FRAMEBUFFER);
this.m_context.bindFramebuffer(gl.FRAMEBUFFER, null);
if (status != gl.FRAMEBUFFER_COMPLETE)
throw new es3fFboTestUtil.FboIncompleteException(status);
};
/**
* @param {?WebGLTexture|sglrReferenceContext.TextureContainer} name
* @param {number} format
* @param {number} width
* @param {number} height
* @return {?WebGLTexture|sglrReferenceContext.TextureContainer}
*/
es3fFboRenderTest.Framebuffer.prototype.createTex2D = function(
name, format, width, height) {
if (!name)
name = this.m_context.createTexture();
this.m_context.bindTexture(gl.TEXTURE_2D, name);
this.m_context.texImage2DDelegate(
gl.TEXTURE_2D, 0, format, width, height
);
if (!deMath.deIsPowerOfTwo32(width) ||
!deMath.deIsPowerOfTwo32(height)) {
// Set wrap mode to clamp for NPOT FBOs
this.m_context.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE
);
this.m_context.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE
);
}
this.m_context.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
);
this.m_context.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
);
return name;
};
/**
* @param {?WebGLRenderbuffer|sglrReferenceContext.Renderbuffer} name
* @param {number} format
* @param {number} width
* @param {number} height
* @return {?WebGLRenderbuffer|sglrReferenceContext.Renderbuffer}
*/
es3fFboRenderTest.Framebuffer.prototype.createRbo = function(
name, format, width, height) {
if (!name)
name = this.m_context.createRenderbuffer();
this.m_context.bindRenderbuffer(gl.RENDERBUFFER, name);
this.m_context.renderbufferStorage(
gl.RENDERBUFFER, format, width, height
);
return name;
};
/**
* @param {?sglrReferenceContext.AnyRenderbuffer} name
* @param {number} type
*/
es3fFboRenderTest.Framebuffer.prototype.destroyBuffer = function(
name, type) {
if (type == gl.TEXTURE_2D || type == gl.TEXTURE_CUBE_MAP)
this.m_context.deleteTexture(/** @type {?WebGLTexture} */ (name));
else if (type == gl.RENDERBUFFER)
this.m_context.deleteRenderbuffer(
/** @type {?WebGLRenderbuffer} */ (name)
);
else
assertMsgOptions(
type == gl.NONE, 'Invalid buffer type', false, true
);
};
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {WebGLTexture|sglrReferenceContext.TextureContainer} name
* @param {number} format
* @param {number} dataType
* @param {number} width
* @param {number} height
*/
es3fFboRenderTest.createMetaballsTex2D = function(
context, name, format, dataType, width, height) {
/** @type {tcuTexture.TextureFormat} */ var texFormat =
gluTextureUtil.mapGLTransferFormat(format, dataType);
/** @type {tcuTexture.TextureLevel} */ var level =
new tcuTexture.TextureLevel(texFormat, width, height);
tcuTextureUtil.fillWithMetaballs(
level.getAccess(), 5, /*name ^*/ width ^ height
);
context.bindTexture(gl.TEXTURE_2D, name);
context.texImage2D(
gl.TEXTURE_2D, 0, format, width, height, 0, format,
dataType, level.getAccess().getDataPtr()
);
context.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
};
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {WebGLTexture|sglrReferenceContext.TextureContainer} name
* @param {number} format
* @param {number} dataType
* @param {number} width
* @param {number} height
*/
es3fFboRenderTest.createQuadsTex2D = function(
context, name, format, dataType, width, height) {
/** @type {tcuTexture.TextureFormat} */
var texFormat = gluTextureUtil.mapGLTransferFormat(format, dataType);
/** @type {tcuTexture.TextureLevel} */
var level = new tcuTexture.TextureLevel(texFormat, width, height);
tcuTextureUtil.fillWithRGBAQuads(level.getAccess());
context.bindTexture(gl.TEXTURE_2D, name);
context.texImage2D(
gl.TEXTURE_2D, 0, format, width, height, 0,
format, dataType, level.getAccess().getDataPtr()
);
context.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
};
/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
* @param {string} name
* @param {string} description
* @param {es3fFboRenderTest.FboConfig} config
*/
es3fFboRenderTest.FboRenderCase = function(name, description, config) {
tcuTestCase.DeqpTest.call(this, name, description);
this.m_config = config;
};
es3fFboRenderTest.FboRenderCase.prototype =
Object.create(tcuTestCase.DeqpTest.prototype);
es3fFboRenderTest.FboRenderCase.prototype.constructor =
es3fFboRenderTest.FboRenderCase;
/**
* Must be overridden
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* fboContext
* @param {tcuSurface.Surface} dst
*/
es3fFboRenderTest.FboRenderCase.prototype.render = function(
fboContext, dst) {
throw new Error('Must override');
};
/**
* @return {tcuTestCase.IterateResult}
*/
es3fFboRenderTest.FboRenderCase.prototype.iterate = function() {
var clearColor = [0.125, 0.25, 0.5, 1.0];
/** @type {?string} */ var failReason = "";
// Position & size for context
var rnd = new deRandom.deRandom();
deRandom.deRandom_init(rnd, deString.deStringHash(this.fullName()));
var width = Math.min(gl.canvas.width, 128);
var height = Math.min(gl.canvas.height, 128);
var xMax = gl.canvas.width - width + 1;
var yMax = gl.canvas.height - height + 1;
var x = Math.abs(deRandom.deRandom_getInt(rnd)) % xMax;
var y = Math.abs(deRandom.deRandom_getInt(rnd)) % yMax;
/** @type {tcuSurface.Surface} */
var gles3Frame = new tcuSurface.Surface(width, height);
/** @type {tcuSurface.Surface} */
var refFrame = new tcuSurface.Surface(width, height);
/** @type {number} */ var gles3Error = 0;
/** @type {number} */ var refError = 0;
// Render using GLES3
/**
* @type {sglrGLContext.GLContext|
* sglrReferenceContext.ReferenceContext}
*/
var context;
try {
context = new sglrGLContext.GLContext(gl, [x, y, width, height]);
context.clearColor(
clearColor[0], clearColor[1], clearColor[2], clearColor[3]
);
context.clear(
gl.COLOR_BUFFER_BIT |
gl.DEPTH_BUFFER_BIT |
gl.STENCIL_BUFFER_BIT
);
this.render(context, gles3Frame); // Call actual render func
gles3Error = context.getError();
}
catch (e) {
if (e instanceof es3fFboTestUtil.FboIncompleteException) {
e.message = WebGLTestUtils.glEnumToString(gl, e.getReason());
if(e.getReason() == gl.FRAMEBUFFER_UNSUPPORTED) {
// Mark test case as unsupported
bufferedLogToConsole(e + ': ' + e.message);
testFailed('Not supported');
return tcuTestCase.IterateResult.STOP;
}
}
// Propagate error
throw e;
}
// Render reference image
/** @type {sglrReferenceContext.ReferenceContextBuffers} */
var buffers = new sglrReferenceContext.ReferenceContextBuffers(
new tcuPixelFormat.PixelFormat(
8, 8, 8,
gl.getParameter(gl.ALPHA_BITS) ? 8 : 0
),
/** @type {number} */ (gl.getParameter(gl.DEPTH_BITS)),
/** @type {number} */ (gl.getParameter(gl.STENCIL_BITS)),
width,
height
);
context = new sglrReferenceContext.ReferenceContext(
new sglrReferenceContext.ReferenceContextLimits(gl),
buffers.getColorbuffer(),
buffers.getDepthbuffer(),
buffers.getStencilbuffer()
);
context.clearColor(
clearColor[0], clearColor[1], clearColor[2], clearColor[3]
);
context.clear(
gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
);
this.render(context, refFrame);
refError = context.getError();
// Compare error codes
var errorCodesOk = (gles3Error == refError);
if (!errorCodesOk) {
bufferedLogToConsole (
'Error code mismatch: got ' +
WebGLTestUtils.glEnumToString(gl, gles3Error) + ', expected ' +
WebGLTestUtils.glEnumToString(gl, refError)
);
failReason = 'Got unexpected error';
}
// Compare images
var imagesOk = this.compare(refFrame, gles3Frame);
if (!imagesOk && !failReason)
failReason = 'Image comparison failed';
// Store test result
var isOk = errorCodesOk && imagesOk;
assertMsgOptions(isOk, failReason, true, true);
return tcuTestCase.IterateResult.STOP;
};
/**
* @param {tcuSurface.Surface} reference
* @param {tcuSurface.Surface} result
* @return {boolean}
*/
es3fFboRenderTest.FboRenderCase.prototype.compare = function(
reference, result) {
var threshold = new tcuRGBA.RGBA(
/* TODO: tcu::max(getFormatThreshold(this.m_config.colorFormat),*/
[12, 12, 12, 12]
);
return tcuImageCompare.bilinearCompare(
'ComparisonResult', 'Image comparison result',
reference.getAccess(), result.getAccess(),
threshold, tcuImageCompare.CompareLogMode.RESULT
);
};
/**
* deinit
*/
es3fFboRenderTest.FboRenderCase.prototype.deinit = function() {
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clearDepth(1.0);
gl.clearStencil(0);
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
};
// FboCases
/**
* @constructor
* @extends {es3fFboRenderTest.FboRenderCase}
* @param {es3fFboRenderTest.FboConfig} config
*/
es3fFboRenderTest.StencilClearsTest = function(config) {
es3fFboRenderTest.FboRenderCase.call(
this, config.getName(), 'Stencil clears', config
);
};
es3fFboRenderTest.StencilClearsTest.prototype =
Object.create(es3fFboRenderTest.FboRenderCase.prototype);
es3fFboRenderTest.StencilClearsTest.prototype.constructor =
es3fFboRenderTest.StencilClearsTest;
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {tcuSurface.Surface} dst
*/
es3fFboRenderTest.StencilClearsTest.prototype.render = function(
context, dst) {
/** @type {tcuTexture.TextureFormat} */
var colorFormat = gluTextureUtil.mapGLInternalFormat(
this.m_config.colorFormat
);
/** @type {gluShaderUtil.DataType} */
var fboSamplerType = /** @type {gluShaderUtil.DataType} */ (
gluTextureUtil.getSampler2DType(colorFormat)
);
/** @type {gluShaderUtil.DataType} */
var fboOutputType = es3fFboTestUtil.getFragmentOutputType(colorFormat);
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fboRangeInfo = tcuTextureUtil.getTextureFormatInfo(colorFormat);
var fboOutScale = deMath.subtract(
fboRangeInfo.valueMax, fboRangeInfo.valueMin
);
var fboOutBias = fboRangeInfo.valueMin;
/** @type {es3fFboTestUtil.Texture2DShader} */
var texToFboShader = new es3fFboTestUtil.Texture2DShader(
[gluShaderUtil.DataType.SAMPLER_2D], fboOutputType
);
/** @type {es3fFboTestUtil.Texture2DShader} */
var texFromFboShader = new es3fFboTestUtil.Texture2DShader(
[fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4);
/** @type {number} */ var texToFboShaderID =
context.createProgram(texToFboShader);
/** @type {number} */ var texFromFboShaderID =
context.createProgram(texFromFboShader);
/** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
var metaballsTex = context.createTexture();
/** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
var quadsTex = context.createTexture();
/** @type {number} */ var width = 128;
/** @type {number} */ var height = 128;
texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
texFromFboShader.setTexScaleBias(
0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
);
es3fFboRenderTest.createQuadsTex2D(
context, quadsTex, gl.RGBA, gl.UNSIGNED_BYTE, width, height
);
es3fFboRenderTest.createMetaballsTex2D(
context, metaballsTex, gl.RGBA, gl.UNSIGNED_BYTE, width, height
);
/** @type {es3fFboRenderTest.Framebuffer} */
var fbo = new es3fFboRenderTest.Framebuffer(
context, this.m_config, width, height
);
fbo.checkCompleteness();
// Bind framebuffer and clear
context.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
context.viewport(0, 0, width, height);
context.clearColor(0.0, 0.0, 0.0, 1.0);
context.clear(
gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
);
// Do stencil clears
context.enable(gl.SCISSOR_TEST);
context.scissor(10, 16, 32, 120);
context.clearStencil(1);
context.clear(gl.STENCIL_BUFFER_BIT);
context.scissor(16, 32, 100, 64);
context.clearStencil(2);
context.clear(gl.STENCIL_BUFFER_BIT);
context.disable(gl.SCISSOR_TEST);
// Draw 2 textures with stecil tests
context.enable(gl.STENCIL_TEST);
context.bindTexture(gl.TEXTURE_2D, quadsTex);
context.stencilFunc(gl.EQUAL, 1, 0xff);
texToFboShader.setUniforms(context, texToFboShaderID);
rrUtil.drawQuad(
context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
context.bindTexture(gl.TEXTURE_2D, metaballsTex);
context.stencilFunc(gl.EQUAL, 2, 0xff);
texToFboShader.setUniforms(context, texToFboShaderID);
rrUtil.drawQuad(
context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
context.disable(gl.STENCIL_TEST);
if (fbo.getConfig().colorType == gl.TEXTURE_2D) {
context.bindFramebuffer(gl.FRAMEBUFFER, null);
context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
context.viewport(0, 0, context.getWidth(), context.getHeight());
texFromFboShader.setUniforms(context, texFromFboShaderID);
rrUtil.drawQuad(
context, texFromFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
dst.readViewport(
context, [0, 0, context.getWidth(), context.getHeight()]
);
} else
es3fFboTestUtil.readPixels(
context, dst, 0, 0, width, height, colorFormat,
fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
);
};
/**
* @constructor
* @extends {es3fFboRenderTest.FboRenderCase}
* @param {es3fFboRenderTest.FboConfig} config
*/
es3fFboRenderTest.SharedColorbufferTest = function(config) {
es3fFboRenderTest.FboRenderCase.call(
this, config.getName(), 'Shared colorbuffer', config
);
};
es3fFboRenderTest.SharedColorbufferTest.prototype =
Object.create(es3fFboRenderTest.FboRenderCase.prototype);
es3fFboRenderTest.SharedColorbufferTest.prototype.constructor =
es3fFboRenderTest.SharedColorbufferTest;
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {tcuSurface.Surface} dst
*/
es3fFboRenderTest.SharedColorbufferTest.prototype.render = function(
context, dst) {
/** @type {es3fFboTestUtil.Texture2DShader} */
var texShader = new es3fFboTestUtil.Texture2DShader(
[gluShaderUtil.DataType.SAMPLER_2D],
gluShaderUtil.DataType.FLOAT_VEC4
);
/** @type {es3fFboTestUtil.FlatColorShader} */
var flatShader = new es3fFboTestUtil.FlatColorShader(
gluShaderUtil.DataType.FLOAT_VEC4
);
/** @type {number} */
var texShaderID = context.createProgram(texShader);
/** @type {number} */
var flatShaderID = context.createProgram(flatShader);
/** @type {number} */ var width = 128;
/** @type {number} */ var height = 128;
/** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
var quadsTex = context.createTexture();
/** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
var metaballsTex = context.createTexture();
/** @type {boolean} */ var stencil =
(this.m_config.buffers & gl.STENCIL_BUFFER_BIT) != 0;
context.disable(gl.DITHER);
// Textures
es3fFboRenderTest.createQuadsTex2D(
context, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
);
es3fFboRenderTest.createMetaballsTex2D(
context, metaballsTex, gl.RGBA, gl.UNSIGNED_BYTE, 64, 64
);
context.viewport(0, 0, width, height);
// Fbo A
/** @type {es3fFboRenderTest.Framebuffer} */
var fboA = new es3fFboRenderTest.Framebuffer(
context, this.m_config, width, height
);
fboA.checkCompleteness();
// Fbo B - don't create colorbuffer
/** @type {es3fFboRenderTest.FboConfig} */
var cfg = /** @type {es3fFboRenderTest.FboConfig} */
(deUtil.clone(this.m_config));
cfg.buffers = deMath.binaryOp(
cfg.buffers,
deMath.binaryNot(gl.COLOR_BUFFER_BIT),
deMath.BinaryOp.AND
);
cfg.colorType = gl.NONE;
cfg.colorFormat = gl.NONE;
/** @type {es3fFboRenderTest.Framebuffer} */
var fboB = new es3fFboRenderTest.Framebuffer(
context, cfg, width, height
);
// Attach color buffer from fbo A
context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
switch (this.m_config.colorType) {
case gl.TEXTURE_2D:
context.framebufferTexture2D(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, fboA.getColorBuffer(), 0
);
break;
case gl.RENDERBUFFER:
context.framebufferRenderbuffer(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.RENDERBUFFER, fboA.getColorBuffer()
);
break;
default:
throw new Error('Invalid color type');
}
// Clear depth and stencil in fbo B
context.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
// Render quads to fbo 1, with depth 0.0
context.bindFramebuffer(gl.FRAMEBUFFER, fboA.getFramebuffer());
context.bindTexture(gl.TEXTURE_2D, quadsTex);
context.clearColor(0.0, 0.0, 0.0, 1.0);
context.clear(
gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
);
if (stencil) {
// Stencil to 1 in fbo A
context.clearStencil(1);
context.clear(gl.STENCIL_BUFFER_BIT);
}
texShader.setUniforms(context, texShaderID);
context.enable(gl.DEPTH_TEST);
rrUtil.drawQuad(
context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
context.disable(gl.DEPTH_TEST);
// Blend metaballs to fbo 2
context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
context.bindTexture(gl.TEXTURE_2D, metaballsTex);
context.enable(gl.BLEND);
context.blendFuncSeparate(
gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE
);
rrUtil.drawQuad(
context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
// Render small quad that is only visible if depth buffer
// is not shared with fbo A - or there is no depth bits
context.bindTexture(gl.TEXTURE_2D, quadsTex);
context.enable(gl.DEPTH_TEST);
rrUtil.drawQuad(context, texShaderID, [0.5, 0.5, 0.5], [1.0, 1.0, 0.5]);
context.disable(gl.DEPTH_TEST);
if (stencil) {
flatShader.setColor(context, flatShaderID, [0.0, 1.0, 0.0, 1.0]);
// Clear subset of stencil buffer to 1
context.enable(gl.SCISSOR_TEST);
context.scissor(10, 10, 12, 25);
context.clearStencil(1);
context.clear(gl.STENCIL_BUFFER_BIT);
context.disable(gl.SCISSOR_TEST);
// Render quad with stencil mask == 1
context.enable(gl.STENCIL_TEST);
context.stencilFunc(gl.EQUAL, 1, 0xff);
rrUtil.drawQuad(
context, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
context.disable(gl.STENCIL_TEST);
}
// Get results
if (fboA.getConfig().colorType == gl.TEXTURE_2D) {
texShader.setUniforms(context, texShaderID);
context.bindFramebuffer(gl.FRAMEBUFFER, null);
context.bindTexture(gl.TEXTURE_2D, fboA.getColorBuffer());
context.viewport(0, 0, context.getWidth(), context.getHeight());
rrUtil.drawQuad(
context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
dst.readViewport(
context, [0, 0, context.getWidth(), context.getHeight()]
);
} else
es3fFboTestUtil.readPixels(
context, dst, 0, 0, width, height,
gluTextureUtil.mapGLInternalFormat(
fboA.getConfig().colorFormat
), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]
);
};
/**
* @constructor
* @extends {es3fFboRenderTest.FboRenderCase}
* @param {es3fFboRenderTest.FboConfig} config
*/
es3fFboRenderTest.SharedColorbufferClearsTest = function(config) {
es3fFboRenderTest.FboRenderCase.call(
this, config.getName(), 'Shared colorbuffer clears', config
);
};
es3fFboRenderTest.SharedColorbufferClearsTest.prototype =
Object.create(es3fFboRenderTest.FboRenderCase.prototype);
es3fFboRenderTest.SharedColorbufferClearsTest.prototype.constructor =
es3fFboRenderTest.SharedColorbufferClearsTest;
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {tcuSurface.Surface} dst
*/
es3fFboRenderTest.SharedColorbufferClearsTest.prototype.render = function(
context, dst) {
/** @type {tcuTexture.TextureFormat} */
var colorFormat = gluTextureUtil.mapGLInternalFormat(
this.m_config.colorFormat
);
/** @type {gluShaderUtil.DataType} */
var fboSamplerType = gluTextureUtil.getSampler2DType(colorFormat);
var width = 128;
var height = 128;
var colorbuffer = this.m_config.colorType == gl.TEXTURE_2D?
context.createTexture() :
context.createRenderbuffer();
// Check for format support.
es3fFboRenderTest.checkColorFormatSupport(
context, this.m_config.colorFormat
);
// Single colorbuffer
if (this.m_config.colorType == gl.TEXTURE_2D) {
context.bindTexture(gl.TEXTURE_2D, colorbuffer);
context.texImage2DDelegate(
gl.TEXTURE_2D, 0, this.m_config.colorFormat, width, height
);
context.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
);
context.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
);
} else {
assertMsgOptions(
this.m_config.colorType == gl.RENDERBUFFER,
'Not a render buffer type', false, true
);
context.bindRenderbuffer(gl.RENDERBUFFER, colorbuffer);
context.renderbufferStorage(
gl.RENDERBUFFER, this.m_config.colorFormat, width, height
);
}
// Multiple framebuffers sharing the colorbuffer
var fbo = [
context.createFramebuffer(),
context.createFramebuffer(),
context.createFramebuffer()
];
for (var fboi = 0; fboi < fbo.length; fboi++) {
context.bindFramebuffer(gl.FRAMEBUFFER, fbo[fboi]);
if (this.m_config.colorType == gl.TEXTURE_2D)
context.framebufferTexture2D(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, colorbuffer, 0
);
else
context.framebufferRenderbuffer(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.RENDERBUFFER, colorbuffer
);
}
context.bindFramebuffer(gl.FRAMEBUFFER, fbo[0]);
// Check completeness
var status = context.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE)
throw new es3fFboTestUtil.FboIncompleteException(status);
// Render to them
context.viewport(0, 0, width, height);
context.clearColor(0.0, 0.0, 1.0, 1.0);
context.clear(gl.COLOR_BUFFER_BIT);
context.enable(gl.SCISSOR_TEST);
context.bindFramebuffer(gl.FRAMEBUFFER, fbo[1]);
context.clearColor(0.6, 0.0, 0.0, 1.0);
context.scissor(10, 10, 64, 64);
context.clear(gl.COLOR_BUFFER_BIT);
context.clearColor(0.0, 0.6, 0.0, 1.0);
context.scissor(60, 60, 40, 20);
context.clear(gl.COLOR_BUFFER_BIT);
context.bindFramebuffer(gl.FRAMEBUFFER, fbo[2]);
context.clearColor(0.0, 0.0, 0.6, 1.0);
context.scissor(20, 20, 100, 10);
context.clear(gl.COLOR_BUFFER_BIT);
context.bindFramebuffer(gl.FRAMEBUFFER, fbo[0]);
context.clearColor(0.6, 0.0, 0.6, 1.0);
context.scissor(20, 20, 5, 100);
context.clear(gl.COLOR_BUFFER_BIT);
context.disable(gl.SCISSOR_TEST);
if (this.m_config.colorType == gl.TEXTURE_2D) {
/** @type {es3fFboTestUtil.Texture2DShader} */
var shader = new es3fFboTestUtil.Texture2DShader(
[fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4
);
var shaderID = context.createProgram(shader);
shader.setUniforms(context, shaderID);
context.bindFramebuffer(gl.FRAMEBUFFER, null);
context.viewport(0, 0, context.getWidth(), context.getHeight());
rrUtil.drawQuad(
context, shaderID, [-0.9, -0.9, 0.0], [0.9, 0.9, 0.0]
);
dst.readViewport(
context, [0, 0, context.getWidth(), context.getHeight()]
);
} else
es3fFboTestUtil.readPixels(
context, dst, 0, 0, width, height, colorFormat,
[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]
);
//delete FBOs
for (fboi = 0; fboi < fbo.length; fboi++)
context.deleteFramebuffer(fbo[fboi]);
//delete Texture/Renderbuffer
if (this.m_config.colorType == gl.TEXTURE_2D)
context.deleteTexture(colorbuffer);
else
context.deleteRenderbuffer(colorbuffer);
};
/**
* @constructor
* @extends {es3fFboRenderTest.FboRenderCase}
* @param {es3fFboRenderTest.FboConfig} config
*/
es3fFboRenderTest.SharedDepthStencilTest = function(config) {
es3fFboRenderTest.FboRenderCase.call(
this, config.getName(), 'Shared depth/stencilbuffer', config
);
};
es3fFboRenderTest.SharedDepthStencilTest.prototype =
Object.create(es3fFboRenderTest.FboRenderCase.prototype);
es3fFboRenderTest.SharedDepthStencilTest.prototype.constructor =
es3fFboRenderTest.SharedDepthStencilTest;
/**
* @param {es3fFboRenderTest.FboConfig} config
* @return {boolean}
*/
es3fFboRenderTest.SharedDepthStencilTest.prototype.isConfigSupported =
function(config) {
return deMath.binaryOp(
config.buffers,
deMath.binaryOp(
gl.DEPTH_BUFFER_BIT, gl.STENCIL_BUFFER_BIT, deMath.BinaryOp.OR
), deMath.BinaryOp.AND
) != 0;
};
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {tcuSurface.Surface} dst
*/
es3fFboRenderTest.SharedDepthStencilTest.prototype.render = function(
context, dst) {
/** @type {es3fFboTestUtil.Texture2DShader} */
var texShader = new es3fFboTestUtil.Texture2DShader(
[gluShaderUtil.DataType.SAMPLER_2D],
gluShaderUtil.DataType.FLOAT_VEC4
);
/** @type {es3fFboTestUtil.FlatColorShader} */
var flatShader = new es3fFboTestUtil.FlatColorShader(
gluShaderUtil.DataType.FLOAT_VEC4
);
var texShaderID = context.createProgram(texShader);
var flatShaderID = context.createProgram(flatShader);
var width = 128;
var height = 128;
// bool depth = (this.m_config.buffers & gl.DEPTH_BUFFER_BIT) != 0;
/**@type {boolean} */ var stencil =
(this.m_config.buffers & gl.STENCIL_BUFFER_BIT) != 0;
// Textures
var metaballsTex = context.createTexture();
var quadsTex = context.createTexture();
es3fFboRenderTest.createMetaballsTex2D(
context, metaballsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
);
es3fFboRenderTest.createQuadsTex2D(
context, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
);
context.viewport(0, 0, width, height);
// Fbo A
/** @type {es3fFboRenderTest.Framebuffer} */
var fboA = new es3fFboRenderTest.Framebuffer(
context, this.m_config, width, height
);
fboA.checkCompleteness();
// Fbo B
/** @type {es3fFboRenderTest.FboConfig} */
var cfg = /** @type {es3fFboRenderTest.FboConfig} */
(deUtil.clone(this.m_config));
cfg.buffers = deMath.binaryOp(
cfg.buffers,
deMath.binaryNot(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT),
deMath.BinaryOp.AND
);
cfg.depthStencilType = gl.NONE;
cfg.depthStencilFormat = gl.NONE;
/** @type {es3fFboRenderTest.Framebuffer} */
var fboB = new es3fFboRenderTest.Framebuffer(
context, cfg, width, height
);
// Bind depth/stencil buffers from fbo A to fbo B
context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
for (var ndx = 0; ndx < 2; ndx++) {
var bit = ndx ? gl.STENCIL_BUFFER_BIT : gl.DEPTH_BUFFER_BIT;
var point = ndx ? gl.STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
if (
deMath.binaryOp(
this.m_config.buffers, bit, deMath.BinaryOp.AND
) == 0
)
continue;
switch (this.m_config.depthStencilType) {
case gl.TEXTURE_2D:
context.framebufferTexture2D(
gl.FRAMEBUFFER, point, gl.TEXTURE_2D,
fboA.getDepthStencilBuffer(), 0
);
break;
case gl.RENDERBUFFER:
context.framebufferRenderbuffer(
gl.FRAMEBUFFER, point, gl.RENDERBUFFER,
fboA.getDepthStencilBuffer()
);
break;
default:
testFailed('Not implemented');
}
}
// Setup uniforms
texShader.setUniforms(context, texShaderID);
// Clear color to red and stencil to 1 in fbo B.
context.clearColor(1.0, 0.0, 0.0, 1.0);
context.clearStencil(1);
context.clear(
gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
);
context.enable(gl.DEPTH_TEST);
// Render quad to fbo A
context.bindFramebuffer(gl.FRAMEBUFFER, fboA.getFramebuffer());
context.bindTexture(gl.TEXTURE_2D, quadsTex);
rrUtil.drawQuad(
context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
if (stencil) {
// Clear subset of stencil buffer to 0 in fbo A
context.enable(gl.SCISSOR_TEST);
context.scissor(10, 10, 12, 25);
context.clearStencil(0);
context.clear(gl.STENCIL_BUFFER_BIT);
context.disable(gl.SCISSOR_TEST);
}
// Render metaballs to fbo B
context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
context.bindTexture(gl.TEXTURE_2D, metaballsTex);
rrUtil.drawQuad(
context, texShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]
);
context.disable(gl.DEPTH_TEST);
if (stencil) {
// Render quad with stencil mask == 0
context.enable(gl.STENCIL_TEST);
context.stencilFunc(gl.EQUAL, 0, 0xff);
context.useProgram(flatShaderID);
flatShader.setColor(context, flatShaderID, [0.0, 1.0, 0.0, 1.0]);
rrUtil.drawQuad(
context, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
context.disable(gl.STENCIL_TEST);
}
if (this.m_config.colorType == gl.TEXTURE_2D) {
// Render both to screen
context.bindFramebuffer(gl.FRAMEBUFFER, null);
context.viewport(0, 0, context.getWidth(), context.getHeight());
context.bindTexture(gl.TEXTURE_2D, fboA.getColorBuffer());
rrUtil.drawQuad(
context, texShaderID, [-1.0, -1.0, 0.0], [0.0, 1.0, 0.0]
);
context.bindTexture(gl.TEXTURE_2D, fboB.getColorBuffer());
rrUtil.drawQuad(
context, texShaderID, [0.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
dst.readViewport(
context, [0, 0, context.getWidth(), context.getHeight()]
);
} else {
// Read results from fbo B
es3fFboTestUtil.readPixels(
context, dst, 0, 0, width, height,
gluTextureUtil.mapGLInternalFormat(this.m_config.colorFormat),
[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]
);
}
};
/**
* @constructor
* @extends {es3fFboRenderTest.FboRenderCase}
* @param {es3fFboRenderTest.FboConfig} config
*/
es3fFboRenderTest.ResizeTest = function(config) {
es3fFboRenderTest.FboRenderCase.call(
this, config.getName(), 'Resize framebuffer', config
);
};
es3fFboRenderTest.ResizeTest.prototype =
Object.create(es3fFboRenderTest.FboRenderCase.prototype);
es3fFboRenderTest.ResizeTest.prototype.constructor =
es3fFboRenderTest.ResizeTest;
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* context
* @param {tcuSurface.Surface} dst
*/
es3fFboRenderTest.ResizeTest.prototype.render = function(context, dst) {
/** @type {tcuTexture.TextureFormat} */
var colorFormat = gluTextureUtil.mapGLInternalFormat(
this.m_config.colorFormat
);
/** @type {gluShaderUtil.DataType} */
var fboSamplerType = gluTextureUtil.getSampler2DType(colorFormat);
/** @type {gluShaderUtil.DataType} */
var fboOutputType = es3fFboTestUtil.getFragmentOutputType(colorFormat);
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fboRangeInfo = tcuTextureUtil.getTextureFormatInfo(colorFormat);
var fboOutScale = deMath.subtract(
fboRangeInfo.valueMax, fboRangeInfo.valueMin
);
var fboOutBias = fboRangeInfo.valueMin;
/** @type {es3fFboTestUtil.Texture2DShader} */
var texToFboShader = new es3fFboTestUtil.Texture2DShader(
[gluShaderUtil.DataType.SAMPLER_2D], fboOutputType
);
/** @type {es3fFboTestUtil.Texture2DShader} */
var texFromFboShader = new es3fFboTestUtil.Texture2DShader(
[fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4
);
/** @type {es3fFboTestUtil.FlatColorShader} */
var flatShader = new es3fFboTestUtil.FlatColorShader(fboOutputType);
/** @type {WebGLProgram} */
var texToFboShaderID = context.createProgram(texToFboShader);
/** @type {WebGLProgram} */
var texFromFboShaderID = context.createProgram(texFromFboShader);
/** @type {WebGLProgram} */
var flatShaderID = context.createProgram(flatShader);
var quadsTex = context.createTexture();
var metaballsTex = context.createTexture();
var depth = deMath.binaryOp(
this.m_config.buffers, gl.DEPTH_BUFFER_BIT, deMath.BinaryOp.AND
) != 0;
var stencil = deMath.binaryOp(
this.m_config.buffers, gl.STENCIL_BUFFER_BIT, deMath.BinaryOp.AND
) != 0;
var initialWidth = 128;
var initialHeight = 128;
var newWidth = 64;
var newHeight = 32;
texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
texFromFboShader.setTexScaleBias(
0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
);
es3fFboRenderTest.createQuadsTex2D(
context, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
);
es3fFboRenderTest.createMetaballsTex2D(
context, metaballsTex, gl.RGB, gl.UNSIGNED_BYTE, 32, 32
);
/** @type {es3fFboRenderTest.Framebuffer} */
var fbo = new es3fFboRenderTest.Framebuffer(
context, this.m_config, initialWidth, initialHeight
);
fbo.checkCompleteness();
// Setup shaders
texToFboShader.setUniforms(context, texToFboShaderID);
texFromFboShader.setUniforms(context, texFromFboShaderID);
flatShader.setColor(
context, flatShaderID, deMath.add(
deMath.multiply([0.0, 1.0, 0.0, 1.0], fboOutScale), fboOutBias
)
);
// Render quads
context.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
context.viewport(0, 0, initialWidth, initialHeight);
es3fFboTestUtil.clearColorBuffer(
context, colorFormat, [0.0, 0.0, 0.0, 1.0]
);
context.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
context.bindTexture(gl.TEXTURE_2D, quadsTex);
rrUtil.drawQuad(
context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
if (fbo.getConfig().colorType == gl.TEXTURE_2D) {
// Render fbo to screen
context.bindFramebuffer(gl.FRAMEBUFFER, null);
context.viewport(0, 0, context.getWidth(), context.getHeight());
context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
rrUtil.drawQuad(
context, texFromFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
// Restore binding
context.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
}
// Resize buffers
switch (fbo.getConfig().colorType) {
case gl.TEXTURE_2D:
context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
context.texImage2DDelegate(
gl.TEXTURE_2D, 0, fbo.getConfig().colorFormat,
newWidth, newHeight
);
break;
case gl.RENDERBUFFER:
context.bindRenderbuffer(gl.RENDERBUFFER, fbo.getColorBuffer());
context.renderbufferStorage(
gl.RENDERBUFFER, fbo.getConfig().colorFormat,
newWidth, newHeight
);
break;
default:
throw new Error('Color type unsupported');
}
if (depth || stencil) {
switch (fbo.getConfig().depthStencilType) {
case gl.TEXTURE_2D:
context.bindTexture(
gl.TEXTURE_2D, fbo.getDepthStencilBuffer()
);
context.texImage2DDelegate(
gl.TEXTURE_2D, 0, fbo.getConfig().depthStencilFormat,
newWidth, newHeight
);
break;
case gl.RENDERBUFFER:
context.bindRenderbuffer(
gl.RENDERBUFFER, fbo.getDepthStencilBuffer()
);
context.renderbufferStorage(
gl.RENDERBUFFER, fbo.getConfig().depthStencilFormat,
newWidth, newHeight
);
break;
default:
throw new Error('Depth / stencil type unsupported');
}
}
// Render to resized fbo
context.viewport(0, 0, newWidth, newHeight);
es3fFboTestUtil.clearColorBuffer(
context, colorFormat, [1.0, 0.0, 0.0, 1.0]
);
context.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
context.enable(gl.DEPTH_TEST);
context.bindTexture(gl.TEXTURE_2D, metaballsTex);
rrUtil.drawQuad(
context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
context.bindTexture(gl.TEXTURE_2D, quadsTex);
rrUtil.drawQuad(
context, texToFboShaderID, [0.0, 0.0, -1.0], [1.0, 1.0, 1.0]
);
context.disable(gl.DEPTH_TEST);
if (stencil) {
context.enable(gl.SCISSOR_TEST);
context.clearStencil(1);
context.scissor(10, 10, 5, 15);
context.clear(gl.STENCIL_BUFFER_BIT);
context.disable(gl.SCISSOR_TEST);
context.enable(gl.STENCIL_TEST);
context.stencilFunc(gl.EQUAL, 1, 0xff);
rrUtil.drawQuad(
context, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
context.disable(gl.STENCIL_TEST);
}
if (this.m_config.colorType == gl.TEXTURE_2D) {
context.bindFramebuffer(gl.FRAMEBUFFER, null);
context.viewport(0, 0, context.getWidth(), context.getHeight());
context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
rrUtil.drawQuad(
context, texFromFboShaderID, [-0.5, -0.5, 0.0], [0.5, 0.5, 0.0]
);
dst.readViewport(
context, [0, 0, context.getWidth(), context.getHeight()]
);
} else
es3fFboTestUtil.readPixels(
context, dst, 0, 0, newWidth, newHeight, colorFormat,
fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
);
};
/**
* @constructor
* @extends {es3fFboRenderTest.FboRenderCase}
* @param {es3fFboRenderTest.FboConfig} config
* @param {number} buffers
* @param {boolean} rebind
*/
es3fFboRenderTest.RecreateBuffersTest = function(config, buffers, rebind) {
es3fFboRenderTest.FboRenderCase.call(
this, config.getName() +
(rebind ? '' : '_no_rebind'),
'Recreate buffers', config
);
this.m_buffers = buffers;
this.m_rebind = rebind;
};
es3fFboRenderTest.RecreateBuffersTest.prototype =
Object.create(es3fFboRenderTest.FboRenderCase.prototype);
es3fFboRenderTest.RecreateBuffersTest.prototype.construtor =
es3fFboRenderTest.RecreateBuffersTest;
/**
* @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
* ctx
* @param {tcuSurface.Surface} dst
*/
es3fFboRenderTest.RecreateBuffersTest.prototype.render = function(
ctx, dst) {
/** @type {tcuTexture.TextureFormat} */
var colorFormat = gluTextureUtil.mapGLInternalFormat(
this.m_config.colorFormat
);
/** @type {gluShaderUtil.DataType} */
var fboSamplerType = gluTextureUtil.getSampler2DType(colorFormat);
/** @type {gluShaderUtil.DataType} */
var fboOutputType = es3fFboTestUtil.getFragmentOutputType(colorFormat);
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fboRangeInfo = tcuTextureUtil.getTextureFormatInfo(colorFormat);
var fboOutScale = deMath.subtract(
fboRangeInfo.valueMax, fboRangeInfo.valueMin
);
var fboOutBias = fboRangeInfo.valueMin;
/** @type {es3fFboTestUtil.Texture2DShader} */
var texToFboShader = new es3fFboTestUtil.Texture2DShader(
[gluShaderUtil.DataType.SAMPLER_2D], fboOutputType
);
/** @type {es3fFboTestUtil.Texture2DShader} */
var texFromFboShader = new es3fFboTestUtil.Texture2DShader(
[fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4
);
/** @type {es3fFboTestUtil.FlatColorShader} */
var flatShader = new es3fFboTestUtil.FlatColorShader(fboOutputType);
/** @type {number} */
var texToFboShaderID = ctx.createProgram(texToFboShader);
/** @type {number} */
var texFromFboShaderID = ctx.createProgram(texFromFboShader);
/** @type {number} */
var flatShaderID = ctx.createProgram(flatShader);
var width = 128;
var height = 128;
var metaballsTex = ctx.createTexture();
var quadsTex = ctx.createTexture();
var stencil = deMath.binaryOp(
this.m_config.buffers, gl.STENCIL_BUFFER_BIT, deMath.BinaryOp.AND
) != 0;
es3fFboRenderTest.createQuadsTex2D(
ctx, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
);
es3fFboRenderTest.createMetaballsTex2D(
ctx, metaballsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
);
/** @type {es3fFboRenderTest.Framebuffer} */
var fbo = new es3fFboRenderTest.Framebuffer(
ctx, this.m_config, width, height
);
fbo.checkCompleteness();
// Setup shaders
texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
texFromFboShader.setTexScaleBias(
0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
);
texToFboShader.setUniforms(ctx, texToFboShaderID);
texFromFboShader.setUniforms(ctx, texFromFboShaderID);
flatShader.setColor(
ctx, flatShaderID, deMath.add(
deMath.multiply([0.0, 0.0, 1.0, 1.0], fboOutScale
), fboOutBias)
);
// Draw scene
ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
ctx.viewport(0, 0, width, height);
es3fFboTestUtil.clearColorBuffer(
ctx, colorFormat, [1.0, 0.0, 0.0, 1.0]
);
ctx.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
ctx.enable(gl.DEPTH_TEST);
ctx.bindTexture(gl.TEXTURE_2D, quadsTex);
rrUtil.drawQuad(
ctx, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
ctx.disable(gl.DEPTH_TEST);
if (stencil) {
ctx.enable(gl.SCISSOR_TEST);
ctx.scissor(
Math.floor(width / 4), Math.floor(height / 4),
Math.floor(width / 2), Math.floor(height / 2)
);
ctx.clearStencil(1);
ctx.clear(gl.STENCIL_BUFFER_BIT);
ctx.disable(gl.SCISSOR_TEST);
}
// Recreate buffers
if (!this.m_rebind)
ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
assertMsgOptions(
deMath.binaryOp(
this.m_buffers, deMath.binaryOp(
gl.DEPTH_BUFFER_BIT,
gl.STENCIL_BUFFER_BIT,
deMath.BinaryOp.OR
), deMath.BinaryOp.AND
) == 0 || deMath.binaryOp(
this.m_buffers, deMath.binaryOp(
gl.DEPTH_BUFFER_BIT,
gl.STENCIL_BUFFER_BIT,
deMath.BinaryOp.OR
), deMath.BinaryOp.AND
) == deMath.binaryOp(
this.m_config.buffers, deMath.binaryOp(
gl.DEPTH_BUFFER_BIT,
gl.STENCIL_BUFFER_BIT,
deMath.BinaryOp.OR
), deMath.BinaryOp.AND
), 'Depth/stencil buffers are not disabled or not ' +
'equal to the config\'s depth/stencil buffer state',
false, true
);
// Recreate.
for (var ndx = 0; ndx < 2; ndx++) {
var bit = ndx == 0 ? gl.COLOR_BUFFER_BIT :
(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
var type = ndx == 0 ? fbo.getConfig().colorType :
fbo.getConfig().depthStencilType;
var format = ndx == 0 ? fbo.getConfig().colorFormat :
fbo.getConfig().depthStencilFormat;
var buf = ndx == 0 ? fbo.getColorBuffer() :
fbo.getDepthStencilBuffer();
if (deMath.binaryOp(this.m_buffers, bit, deMath.BinaryOp.AND) == 0)
continue;
switch (type) {
case gl.TEXTURE_2D:
ctx.deleteTexture(/** @type {WebGLTexture} */ (buf));
buf = ctx.createTexture();
ctx.bindTexture(gl.TEXTURE_2D, buf);
ctx.texImage2DDelegate(
gl.TEXTURE_2D, 0, format, width, height
);
ctx.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
);
ctx.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
);
break;
case gl.RENDERBUFFER:
ctx.deleteRenderbuffer(
/** @type {WebGLRenderbuffer} */ (buf)
);
buf = ctx.createRenderbuffer();
ctx.bindRenderbuffer(gl.RENDERBUFFER, buf);
ctx.renderbufferStorage(
gl.RENDERBUFFER, format, width, height
);
break;
default:
throw new Error('Unsupported buffer type');
}
if (ndx == 0) {
fbo.m_colorBuffer = buf;
} else {
fbo.m_depthStencilBuffer = buf;
}
}
// Rebind.
if (this.m_rebind) {
for (var ndx = 0; ndx < 3; ndx++) {
var bit = ndx == 0 ? gl.COLOR_BUFFER_BIT :
ndx == 1 ? gl.DEPTH_BUFFER_BIT :
ndx == 2 ? gl.STENCIL_BUFFER_BIT : 0;
var point = ndx == 0 ? gl.COLOR_ATTACHMENT0 :
ndx == 1 ? gl.DEPTH_ATTACHMENT :
ndx == 2 ? gl.STENCIL_ATTACHMENT : 0;
var type = ndx == 0 ? fbo.getConfig().colorType :
fbo.getConfig().depthStencilType;
var buf = ndx == 0 ? fbo.getColorBuffer() :
fbo.getDepthStencilBuffer();
if (deMath.binaryOp(
this.m_buffers, bit, deMath.BinaryOp.AND) == 0)
continue;
switch (type) {
case gl.TEXTURE_2D:
ctx.framebufferTexture2D(
gl.FRAMEBUFFER, point, gl.TEXTURE_2D, buf, 0
);
break;
case gl.RENDERBUFFER:
ctx.framebufferRenderbuffer(
gl.FRAMEBUFFER, point, gl.RENDERBUFFER, buf
);
break;
default:
throw new Error('Invalid buffer type');
}
}
}
if (!this.m_rebind)
ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
ctx.clearStencil(0);
// \note Clear only buffers that were re-created
ctx.clear(
deMath.binaryOp(
this.m_buffers,
deMath.binaryOp(
gl.DEPTH_BUFFER_BIT,
gl.STENCIL_BUFFER_BIT,
deMath.BinaryOp.OR
), deMath.BinaryOp.AND
)
);
if (deMath.binaryOp(
this.m_buffers, gl.COLOR_BUFFER_BIT, deMath.BinaryOp.AND)) {
// Clearing of integer buffers is undefined
// so do clearing by rendering flat color.
rrUtil.drawQuad(
ctx, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
}
ctx.enable(gl.DEPTH_TEST);
if (stencil) {
// \note Stencil test enabled only if we have stencil buffer
ctx.enable(gl.STENCIL_TEST);
ctx.stencilFunc(gl.EQUAL, 0, 0xff);
}
ctx.bindTexture(gl.TEXTURE_2D, metaballsTex);
rrUtil.drawQuad(
ctx, texToFboShaderID, [-1.0, -1.0, 1.0], [1.0, 1.0, -1.0]
);
if (stencil)
ctx.disable(gl.STENCIL_TEST);
ctx.disable(gl.DEPTH_TEST);
if (fbo.getConfig().colorType == gl.TEXTURE_2D) {
// Unbind fbo
ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
// Draw to screen
ctx.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
rrUtil.drawQuad(
ctx, texFromFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
);
// Read from screen
dst.readViewport(ctx, [0, 0, ctx.getWidth(), ctx.getHeight()]);
} else {
// Read from fbo
es3fFboTestUtil.readPixels(
ctx, dst, 0, 0, width, height, colorFormat,
fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
);
}
};
// FboGroups
/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
*/
es3fFboRenderTest.FboRenderTestGroup = function() {
tcuTestCase.DeqpTest.call(this, 'render', 'Rendering Tests');
};
es3fFboRenderTest.FboRenderTestGroup.prototype =
Object.create(tcuTestCase.DeqpTest.prototype);
es3fFboRenderTest.FboRenderTestGroup.prototype.constructor =
es3fFboRenderTest.FboRenderTestGroup;
/**
* @enum {number}
*/
var FormatType = {
FLOAT: 0,
INT: 1,
UINT: 2
};
// Required by specification.
/**
* @typedef {{format: number, type: FormatType}}
*/
var ColorFormatStruct;
/**
* @typedef {{format: number, depth: boolean, stencil: boolean}}
*/
var DepthStencilFormatStruct;
/**
* init
*/
es3fFboRenderTest.FboRenderTestGroup.prototype.init = function() {
var objectTypes = [
gl.TEXTURE_2D,
gl.RENDERBUFFER
];
/** @type {Array<ColorFormatStruct>} */ var colorFormats = [{
format: gl.RGBA32F, type: FormatType.FLOAT
},{
format: gl.RGBA32I, type: FormatType.INT
},{
format: gl.RGBA32UI, type: FormatType.UINT
},{
format: gl.RGBA16F, type: FormatType.FLOAT
},{
format: gl.RGBA16I, type: FormatType.INT
},{
format: gl.RGBA16UI, type: FormatType.UINT
},/*{
// RGB16F isn't made color-renderable through WebGL's EXT_color_buffer_float
format: gl.RGB16F, type: FormatType.FLOAT
},*/{
format: gl.RGBA8I, type: FormatType.INT
},{
format: gl.RGBA8UI, type: FormatType.UINT
},{
format: gl.RGB10_A2UI, type: FormatType.UINT
},{
format: gl.R11F_G11F_B10F, type: FormatType.FLOAT
},{
format: gl.RG32F, type: FormatType.FLOAT
},{
format: gl.RG32I, type: FormatType.INT
},{
format: gl.RG32UI, type: FormatType.UINT
},{
format: gl.RG16F, type: FormatType.FLOAT
},{
format: gl.RG16I, type: FormatType.INT
},{
format: gl.RG16UI, type: FormatType.UINT
},{
format: gl.RG8, type: FormatType.FLOAT
},{
format: gl.RG8I, type: FormatType.INT
},{
format: gl.RG8UI, type: FormatType.UINT
},{
format: gl.R32F, type: FormatType.FLOAT
},{
format: gl.R32I, type: FormatType.INT
},{
format: gl.R32UI, type: FormatType.UINT
},{
format: gl.R16F, type: FormatType.FLOAT
},{
format: gl.R16I, type: FormatType.INT
},{
format: gl.R16UI, type: FormatType.UINT
},{
format: gl.R8, type: FormatType.FLOAT
},{
format: gl.R8I, type: FormatType.INT
},{
format: gl.R8UI, type: FormatType.UINT
}];
/** @type {Array<DepthStencilFormatStruct>} */
var depthStencilFormats = [{
format: gl.DEPTH_COMPONENT32F, depth: true, stencil: false
},{
format: gl.DEPTH_COMPONENT24, depth: true, stencil: false
},{
format: gl.DEPTH_COMPONENT16, depth: true, stencil: false
},{
format: gl.DEPTH32F_STENCIL8, depth: true, stencil: true
},{
format: gl.DEPTH24_STENCIL8, depth: true, stencil: true
},{
format: gl.STENCIL_INDEX8, depth: false, stencil: true
}];
/** @type {es3fFboRenderTest.FboConfig} */ var config;
var colorType;
var stencilType;
var colorFmt;
var depth;
var stencil;
var depthStencilType;
var depthStencilFormat;
// .stencil_clear
/** @type {tcuTestCase.DeqpTest} */
var stencilClearGroup = new tcuTestCase.DeqpTest(
'stencil_clear', 'Stencil buffer clears'
);
this.addChild(stencilClearGroup);
for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
colorType = gl.TEXTURE_2D;
stencilType = gl.RENDERBUFFER;
colorFmt = gl.RGBA8;
if (!depthStencilFormats[fmtNdx].stencil)
continue;
config = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT,
colorType, colorFmt, stencilType,
depthStencilFormats[fmtNdx].format
);
stencilClearGroup.addChild(
new es3fFboRenderTest.StencilClearsTest(config)
);
}
// .shared_colorbuffer_clear
/** @type {tcuTestCase.DeqpTest} */
var sharedColorbufferClearGroup = new tcuTestCase.DeqpTest(
'shared_colorbuffer_clear', 'Shader colorbuffer clears'
);
this.addChild(sharedColorbufferClearGroup);
for (var colorFmtNdx = 0;
colorFmtNdx < colorFormats.length;
colorFmtNdx++) {
// Clearing of integer buffers is undefined.
if (colorFormats[colorFmtNdx].type == FormatType.INT ||
colorFormats[colorFmtNdx].type == FormatType.UINT)
continue;
for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
config = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT, objectTypes[typeNdx],
colorFormats[colorFmtNdx].format, gl.NONE, gl.NONE
);
sharedColorbufferClearGroup.addChild(
new es3fFboRenderTest.SharedColorbufferClearsTest(config)
);
}
}
// .shared_colorbuffer
/** @type {Array<tcuTestCase.DeqpTest>} */ var sharedColorbufferGroup = [];
var numSharedColorbufferGroups = 3;
for (var ii = 0; ii < numSharedColorbufferGroups; ++ii) {
sharedColorbufferGroup[ii] = new tcuTestCase.DeqpTest(
'shared_colorbuffer', 'Shared colorbuffer tests'
);
this.addChild(sharedColorbufferGroup[ii]);
}
for (var colorFmtNdx = 0; colorFmtNdx < colorFormats.length; colorFmtNdx++) {
depthStencilType = gl.RENDERBUFFER;
depthStencilFormat = gl.DEPTH24_STENCIL8;
// Blending with integer buffers and fp32 targets is not supported.
if (colorFormats[colorFmtNdx].type == FormatType.INT ||
colorFormats[colorFmtNdx].type == FormatType.UINT ||
colorFormats[colorFmtNdx].format == gl.RGBA32F ||
colorFormats[colorFmtNdx].format == gl.RGB32F ||
colorFormats[colorFmtNdx].format == gl.RG32F ||
colorFormats[colorFmtNdx].format == gl.R32F)
continue;
for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
/** @type {es3fFboRenderTest.FboConfig} */
var colorOnlyConfig = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT, objectTypes[typeNdx],
colorFormats[colorFmtNdx].format, gl.NONE, gl.NONE
);
/** @type {es3fFboRenderTest.FboConfig} */
var colorDepthConfig = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT,
objectTypes[typeNdx], colorFormats[colorFmtNdx].format,
depthStencilType, depthStencilFormat
);
/** @type {es3fFboRenderTest.FboConfig} */
var colorDepthStencilConfig =
new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT |
gl.DEPTH_BUFFER_BIT |
gl.STENCIL_BUFFER_BIT,
objectTypes[typeNdx], colorFormats[colorFmtNdx].format,
depthStencilType, depthStencilFormat
);
sharedColorbufferGroup[0].addChild(
new es3fFboRenderTest.SharedColorbufferTest(colorOnlyConfig)
);
sharedColorbufferGroup[1].addChild(
new es3fFboRenderTest.SharedColorbufferTest(
colorDepthConfig
)
);
sharedColorbufferGroup[2].addChild(
new es3fFboRenderTest.SharedColorbufferTest(
colorDepthStencilConfig
)
);
}
}
// .shared_depth_stencil
/** @type {tcuTestCase.DeqpTest} */
var sharedDepthStencilGroup = new tcuTestCase.DeqpTest(
'shared_depth_stencil', 'Shared depth and stencil buffers'
);
this.addChild(sharedDepthStencilGroup);
for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
colorType = gl.TEXTURE_2D;
colorFmt = gl.RGBA8;
depth = depthStencilFormats[fmtNdx].depth;
stencil = depthStencilFormats[fmtNdx].stencil;
if (!depth)
continue; // Not verified.
// Depth and stencil: both rbo and textures
for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
config = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT |
(depth ? gl.DEPTH_BUFFER_BIT : 0) |
(stencil ? gl.STENCIL_BUFFER_BIT : 0),
colorType, colorFmt, objectTypes[typeNdx],
depthStencilFormats[fmtNdx].format
);
sharedDepthStencilGroup.addChild(
new es3fFboRenderTest.SharedDepthStencilTest(config)
);
}
}
// .resize
/** @type {Array<tcuTestCase.DeqpTest>} */ var resizeGroup = [];
var numResizeGroups = 4;
for (var ii = 0; ii < numResizeGroups; ++ii) {
resizeGroup[ii] = new tcuTestCase.DeqpTest('resize', 'FBO resize tests');
this.addChild(resizeGroup[ii]);
}
for (var colorFmtNdx = 0; colorFmtNdx < colorFormats.length; colorFmtNdx++) {
var colorFormat = colorFormats[colorFmtNdx].format;
// Color-only.
for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
config = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT, objectTypes[typeNdx],
colorFormat, gl.NONE, gl.NONE
);
resizeGroup[colorFmtNdx % numResizeGroups].addChild(new es3fFboRenderTest.ResizeTest(config));
}
// For selected color formats tests depth & stencil variants.
if (colorFormat == gl.RGBA8 || colorFormat == gl.RGBA16F) {
for (var depthStencilFmtNdx = 0; depthStencilFmtNdx < depthStencilFormats.length; depthStencilFmtNdx++) {
colorType = gl.TEXTURE_2D;
depth = depthStencilFormats[depthStencilFmtNdx].depth;
stencil = depthStencilFormats[depthStencilFmtNdx].stencil;
// Depth and stencil: both rbo and textures
for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
if (!depth && objectTypes[typeNdx] != gl.RENDERBUFFER)
continue; // Not supported.
config = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT |
(depth ? gl.DEPTH_BUFFER_BIT : 0) |
(stencil ? gl.STENCIL_BUFFER_BIT : 0),
colorType, colorFormat, objectTypes[typeNdx],
depthStencilFormats[depthStencilFmtNdx].format
);
resizeGroup[colorFmtNdx % numResizeGroups].addChild(
new es3fFboRenderTest.ResizeTest(config)
);
}
}
}
}
// .recreate_color
/** @type {Array<tcuTestCase.DeqpTest>} */ var recreateColorGroup = [];
var numRecreateColorGroups = 7;
for (var ii = 0; ii < numRecreateColorGroups; ++ii) {
recreateColorGroup[ii] = new tcuTestCase.DeqpTest('recreate_color', 'Recreate colorbuffer tests');
this.addChild(recreateColorGroup[ii]);
}
for (var colorFmtNdx = 0; colorFmtNdx < colorFormats.length; colorFmtNdx++) {
colorFormat = colorFormats[colorFmtNdx].format;
depthStencilFormat = gl.DEPTH24_STENCIL8;
depthStencilType = gl.RENDERBUFFER;
// Color-only.
for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
config = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT |
gl.DEPTH_BUFFER_BIT |
gl.STENCIL_BUFFER_BIT,
objectTypes[typeNdx], colorFormat,
depthStencilType, depthStencilFormat
);
recreateColorGroup[colorFmtNdx % numRecreateColorGroups].addChild(
new es3fFboRenderTest.RecreateBuffersTest(
config, gl.COLOR_BUFFER_BIT, true /* rebind */
)
);
}
}
// .recreate_depth_stencil
/** @type {tcuTestCase.DeqpTest} */
var recreateDepthStencilGroup = new tcuTestCase.DeqpTest(
'recreate_depth_stencil', 'Recreate depth and stencil buffers'
);
this.addChild(recreateDepthStencilGroup);
for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
colorType = gl.TEXTURE_2D;
colorFmt = gl.RGBA8;
depth = depthStencilFormats[fmtNdx].depth;
stencil = depthStencilFormats[fmtNdx].stencil;
// Depth and stencil: both rbo and textures
for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
if (!depth && objectTypes[typeNdx] != gl.RENDERBUFFER)
continue;
config = new es3fFboRenderTest.FboConfig(
gl.COLOR_BUFFER_BIT |
(depth ? gl.DEPTH_BUFFER_BIT : 0) |
(stencil ? gl.STENCIL_BUFFER_BIT : 0),
colorType, colorFmt, objectTypes[typeNdx],
depthStencilFormats[fmtNdx].format
);
recreateDepthStencilGroup.addChild(
new es3fFboRenderTest.RecreateBuffersTest(
config,
(depth ? gl.DEPTH_BUFFER_BIT : 0) |
(stencil ? gl.STENCIL_BUFFER_BIT : 0),
true /* rebind */
)
);
}
}
};
/**
* Create and execute the test cases
* @param {WebGL2RenderingContext} context
*/
es3fFboRenderTest.run = function(context, range) {
gl = context;
//Set up Test Root parameters
var state = tcuTestCase.runner;
state.setRoot(new es3fFboRenderTest.FboRenderTestGroup());
//Set up name and description of this test series.
setCurrentTestName(state.testCases.fullName());
description(state.testCases.getDescription());
try {
if (range)
state.setRange(range);
//Run test cases
tcuTestCase.runTestCases();
}
catch (err) {
testFailedOptions('Failed to run tests', false);
tcuTestCase.runner.terminate();
}
};
});