| 'use strict'; |
| goog.provide('modules.shared.glsFboCompletenessTests'); |
| goog.require('framework.common.tcuTestCase'); |
| goog.require('framework.opengl.gluObjectWrapper'); |
| goog.require('framework.opengl.gluStrUtil'); |
| goog.require('modules.shared.glsFboUtil'); |
| |
| goog.scope(function() { |
| |
| var glsFboCompletenessTests = modules.shared.glsFboCompletenessTests; |
| var glsFboUtil = modules.shared.glsFboUtil; |
| var gluObjectWrapper = framework.opengl.gluObjectWrapper; |
| var gluStrUtil = framework.opengl.gluStrUtil; |
| var tcuTestCase = framework.common.tcuTestCase; |
| |
| /** |
| * @param {WebGL2RenderingContext} gl |
| */ |
| glsFboCompletenessTests.initGlDependents = function(gl) { |
| if (!(gl = gl || window.gl)) throw new Error('Invalid gl object'); |
| |
| // The following extensions are applicable both to ES2 and ES3. |
| /** |
| * OES_depth_texture |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesDepthTextureFormats = [ |
| glsFboUtil.formatkey(gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT), |
| glsFboUtil.formatkey(gl.DEPTH_COMPONENT, gl.UNSIGNED_INT) |
| ]; |
| |
| /** |
| * OES_packed_depth_stencil |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesPackedDepthStencilSizedFormats = [ |
| gl.DEPTH24_STENCIL8 |
| ]; |
| |
| /** |
| * s_oesPackedDepthStencilTexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesPackedDepthStencilTexFormats = [ |
| glsFboUtil.formatkey(gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8) |
| ]; |
| |
| /** |
| * OES_required_internalformat |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesRequiredInternalFormatColorFormats = [ |
| // Same as ES2 RBO formats, plus RGBA8 (even without OES_rgb8_rgba8) |
| gl.RGB5_A1, gl.RGBA8, gl.RGBA4, gl.RGB565 |
| ]; |
| |
| /** |
| * s_oesRequiredInternalFormatDepthFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesRequiredInternalFormatDepthFormats = [ |
| gl.DEPTH_COMPONENT16 |
| ]; |
| |
| /** |
| * EXT_color_buffer_half_float |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extColorBufferHalfFloatFormats = [ |
| gl.RGBA16F, gl.RGB16F, gl.RG16F, gl.R16F |
| ]; |
| |
| /** |
| * s_oesDepth24SizedFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesDepth24SizedFormats = [ |
| gl.DEPTH_COMPONENT24 |
| ]; |
| |
| /** |
| * s_oesDepth32SizedFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesDepth32SizedFormats = [ |
| gl['DEPTH_COMPONENT32'] |
| ]; |
| |
| /** |
| * s_oesRgb8Rgba8RboFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesRgb8Rgba8RboFormats = [ |
| gl.RGB8, gl.RGBA8 |
| ]; |
| |
| /** |
| * s_oesRequiredInternalFormatRgb8ColorFormat |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesRequiredInternalFormatRgb8ColorFormat = [ |
| gl.RGB8 |
| ]; |
| |
| /** |
| * s_extTextureType2101010RevFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extTextureType2101010RevFormats = [ |
| glsFboUtil.formatkey(gl.RGBA, gl.UNSIGNED_INT_2_10_10_10_REV), |
| glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_INT_2_10_10_10_REV) |
| ]; |
| |
| /** |
| * s_oesRequiredInternalFormat10bitColorFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesRequiredInternalFormat10bitColorFormats = [ |
| gl.RGB10_A2, gl['RGB10'] |
| ]; |
| |
| /** |
| * s_extTextureRgRboFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extTextureRgRboFormats = [ |
| gl.R8, gl.RG8 |
| ]; |
| |
| /** |
| * s_extTextureRgTexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extTextureRgTexFormats = [ |
| glsFboUtil.formatkey(gl.RED, gl.UNSIGNED_BYTE), |
| glsFboUtil.formatkey(gl.RG, gl.UNSIGNED_BYTE) |
| ]; |
| |
| /** |
| * s_extTextureRgFloatTexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extTextureRgFloatTexFormats = [ |
| glsFboUtil.formatkey(gl.RED, gl.FLOAT), |
| glsFboUtil.formatkey(gl.RG, gl.FLOAT) |
| ]; |
| |
| /** |
| * s_extTextureRgHalfFloatTexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extTextureRgHalfFloatTexFormats = [ |
| glsFboUtil.formatkey(gl.RED, gl['HALF_FLOAT_OES']), |
| glsFboUtil.formatkey(gl.RG, gl['HALF_FLOAT_OES']) |
| ]; |
| |
| /** |
| * s_nvPackedFloatRboFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_nvPackedFloatRboFormats = [ |
| gl.R11F_G11F_B10F |
| ]; |
| |
| /** |
| * s_nvPackedFloatTexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_nvPackedFloatTexFormats = [ |
| glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_INT_10F_11F_11F_REV) |
| ]; |
| |
| /** |
| * s_extSrgbRboFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extSrgbRboFormats = [ |
| gl.SRGB8_ALPHA8 |
| ]; |
| |
| /** |
| * s_extSrgbRenderableTexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extSrgbRenderableTexFormats = [ |
| glsFboUtil.formatkey(gl['SRGB_ALPHA'], gl.UNSIGNED_BYTE) |
| ]; |
| |
| /** |
| * s_extSrgbNonRenderableTexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_extSrgbNonRenderableTexFormats = [ |
| glsFboUtil.formatkey(gl.SRGB, gl.UNSIGNED_BYTE), |
| gl.SRGB8 |
| ]; |
| |
| /** |
| * s_nvSrgbFormatsRboFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_nvSrgbFormatsRboFormats = [ |
| gl.SRGB8 |
| ]; |
| |
| /** |
| * s_nvSrgbFormatsTextureFormats |
| * The extension does not actually require any unsized format |
| * to be renderable. However, the renderablility of unsized |
| * SRGB,UBYTE internalformat-type pair is implied. |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_nvSrgbFormatsTextureFormats = [ |
| gl.SRGB8, |
| glsFboUtil.formatkey(gl.SRGB, gl.UNSIGNED_BYTE) |
| ]; |
| |
| /** |
| * s_oesRgb8Rgba8TexFormats |
| * @type {Array<number>} |
| */ |
| glsFboCompletenessTests.s_oesRgb8Rgba8TexFormats = [ |
| glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_BYTE), |
| glsFboUtil.formatkey(gl.RGBA, gl.UNSIGNED_BYTE) |
| ]; |
| |
| var fmt = glsFboUtil.FormatFlags; |
| |
| /** |
| * s_esExtFormats |
| * @type {Array<glsFboUtil.FormatExtEntry>} |
| */ |
| glsFboCompletenessTests.s_esExtFormats = [ |
| new glsFboUtil.FormatExtEntry( |
| 'OES_depth_texture', |
| fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepthTextureFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'OES_packed_depth_stencil', |
| fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.STENCIL_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesPackedDepthStencilSizedFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'OES_packed_depth_stencil OES_required_internalformat', |
| fmt.DEPTH_RENDERABLE | fmt.STENCIL_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesPackedDepthStencilTexFormats) |
| ), |
| |
| // \todo [2013-12-10 lauri] Find out if OES_texture_half_float is really a |
| // requirement on ES3 also. Or is color_buffer_half_float applicatble at |
| // all on ES3, since there's also EXT_color_buffer_float? |
| new glsFboUtil.FormatExtEntry( |
| 'OES_texture_half_float EXT_color_buffer_half_float', |
| fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extColorBufferHalfFloatFormats) |
| ), |
| |
| // OES_required_internalformat doesn't actually specify that these are renderable, |
| // since it was written against ES 1.1. |
| new glsFboUtil.FormatExtEntry( |
| 'OES_required_internalformat', |
| // Allow but don't require RGBA8 to be color-renderable if |
| // OES_rgb8_rgba8 is not present. |
| fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormatColorFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'OES_required_internalformat', |
| fmt.DEPTH_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormatDepthFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_texture_rg', |
| fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgRboFormats) |
| ), |
| |
| // These are not specified to be color-renderable, but the wording is |
| // exactly as ambiguous as the wording in the ES2 spec. |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_texture_rg', |
| fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgTexFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_texture_rg OES_texture_float', |
| fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgFloatTexFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_texture_rg OES_texture_half_float', |
| fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgHalfFloatTexFormats) |
| ), |
| |
| // Some Tegra drivers report gl.EXT_packed_float even for ES. Treat it as |
| // a synonym for the NV_ version. |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_packed_float', |
| fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvPackedFloatTexFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_packed_float EXT_color_buffer_half_float', |
| fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvPackedFloatRboFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_sRGB', |
| fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extSrgbRenderableTexFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_sRGB', |
| fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extSrgbNonRenderableTexFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_sRGB', |
| fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extSrgbRboFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'NV_sRGB_formats', |
| fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvSrgbFormatsRboFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'NV_sRGB_formats', |
| fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvSrgbFormatsTextureFormats) |
| ), |
| |
| // In Khronos bug 7333 discussion, the consensus is that these texture |
| // formats, at least, should be color-renderable. Still, that cannot be |
| // found in any extension specs, so only allow it, not require it. |
| new glsFboUtil.FormatExtEntry( |
| 'OES_rgb8_rgba8', |
| fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRgb8Rgba8TexFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'OES_rgb8_rgba8', |
| fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRgb8Rgba8RboFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'OES_rgb8_rgba8 OES_required_internalformat', |
| fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormatRgb8ColorFormat) |
| ), |
| |
| // The depth-renderability of the depth RBO formats is not explicitly |
| // spelled out, but all renderbuffer formats are meant to be renderable. |
| new glsFboUtil.FormatExtEntry( |
| 'OES_depth24', |
| fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth24SizedFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'OES_depth24 OES_required_internalformat OES_depth_texture', |
| fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth24SizedFormats) |
| ), |
| |
| new glsFboUtil.FormatExtEntry( |
| 'OES_depth32', |
| fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.RENDERBUFFER_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth32SizedFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'OES_depth32 OES_required_internalformat OES_depth_texture', |
| fmt.TEXTURE_VALID, |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth32SizedFormats) |
| ), |
| |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_texture_type_2_10_10_10_REV', |
| fmt.TEXTURE_VALID, // explicitly unrenderable |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureType2101010RevFormats) |
| ), |
| new glsFboUtil.FormatExtEntry( |
| 'EXT_texture_type_2_10_10_10_REV OES_required_internalformat', |
| fmt.TEXTURE_VALID, // explicitly unrenderable |
| glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormat10bitColorFormats) |
| ) |
| ]; |
| |
| }; // initGlDependents ---------------------------------------- |
| |
| /** |
| * @constructor |
| * @param {null} testCtx |
| * @param {WebGLRenderingContextBase} renderCtx |
| * @param {glsFboUtil.CheckerFactory} factory |
| */ |
| glsFboCompletenessTests.Context = function(testCtx, renderCtx, factory) { |
| |
| this.m_testCtx = testCtx; |
| this.m_renderCtx = renderCtx; |
| this.m_ctxFormats = new glsFboUtil.FormatDB(); |
| this.m_minFormats = new glsFboUtil.FormatDB(); |
| this.m_maxFormats = new glsFboUtil.FormatDB(); |
| this.m_verifier = new glsFboUtil.FboVerifier(this.m_ctxFormats, factory); |
| this.m_haveMultiColorAtts = false; |
| |
| // FormatExtEntries |
| var extRange = glsFboUtil.rangeArray(glsFboCompletenessTests.s_esExtFormats); |
| this.addExtFormats(extRange); |
| |
| }; |
| |
| // RenderContext& |
| glsFboCompletenessTests.Context.prototype.getRenderContext = function() { |
| return this.m_renderCtx; |
| }; |
| |
| // TestContext& |
| glsFboCompletenessTests.Context.prototype.getTestContext = function() { |
| return this.m_testCtx; |
| }; |
| |
| // const FboVerifier& |
| glsFboCompletenessTests.Context.prototype.getVerifier = function() { |
| return this.m_verifier; |
| }; |
| |
| // const FormatDB& |
| glsFboCompletenessTests.Context.prototype.getMinFormats = function() { |
| return this.m_minFormats; |
| }; |
| |
| // const FormatDB& |
| glsFboCompletenessTests.Context.prototype.getCtxFormats = function() { |
| return this.m_ctxFormats; |
| }; |
| |
| // bool |
| glsFboCompletenessTests.Context.prototype.haveMultiColorAtts = function() { |
| return this.m_haveMultiColorAtts; |
| }; |
| |
| glsFboCompletenessTests.Context.prototype.setHaveMulticolorAtts = function(have) { |
| this.m_haveMultiColorAtts = (have == true); |
| }; |
| |
| glsFboCompletenessTests.Context.prototype.addFormats = function(fmtRange) { |
| glsFboUtil.addFormats(this.m_minFormats, fmtRange); |
| glsFboUtil.addFormats(this.m_ctxFormats, fmtRange); |
| glsFboUtil.addFormats(this.m_maxFormats, fmtRange); |
| }; |
| glsFboCompletenessTests.Context.prototype.addExtFormats = function(extRange) { |
| glsFboUtil.addExtFormats(this.m_ctxFormats, extRange, this.m_renderCtx); |
| glsFboUtil.addExtFormats(this.m_maxFormats, extRange, this.m_renderCtx); |
| }; |
| |
| glsFboCompletenessTests.Context.prototype.createRenderableTests = function(gl) { |
| |
| /** @type {tcuTestCase.DeqpTest} */ |
| var renderableTests = tcuTestCase.newTest('renderable', 'Tests for support of renderable image formats'); |
| /** @type {tcuTestCase.DeqpTest} */ |
| var rbRenderableTests = tcuTestCase.newTest('renderbuffer', 'Tests for renderbuffer formats'); |
| /** @type {tcuTestCase.DeqpTest} */ |
| var texRenderableTests = tcuTestCase.newTest('texture', 'Tests for texture formats'); |
| |
| var attPoints = [ |
| [gl.DEPTH_ATTACHMENT, 'depth', 'Tests for depth attachments'], |
| [gl.STENCIL_ATTACHMENT, 'stencil', 'Tests for stencil attachments'], |
| [gl.COLOR_ATTACHMENT0, 'color0', 'Tests for color attachments'] |
| ]; |
| |
| // At each attachment point, iterate through all the possible formats to |
| // detect both false positives and false negatives. |
| var rboFmts = this.m_maxFormats.getFormats(glsFboUtil.FormatFlags.ANY_FORMAT); |
| var texFmts = this.m_maxFormats.getFormats(glsFboUtil.FormatFlags.ANY_FORMAT); |
| |
| for (var i = 0, l_attPoints = attPoints.length; i < l_attPoints; ++i) { |
| var rbAttTests = tcuTestCase.newTest(attPoints[i][1], attPoints[i][2]); |
| var texAttTests = tcuTestCase.newTest(attPoints[i][1], attPoints[i][2]); |
| |
| for (var j = 0, l_rboFmts = rboFmts.length; j < l_rboFmts; ++j) { |
| var params = glsFboCompletenessTests.renderableParams( |
| attPoints[i][0], gl.RENDERBUFFER, rboFmts[j] |
| ); |
| rbAttTests.addChild( |
| new glsFboCompletenessTests.RenderableTest( |
| glsFboCompletenessTests.renderableParams.getName(params), |
| glsFboCompletenessTests.renderableParams.getDescription(params), |
| this, params |
| ) |
| ); |
| } |
| rbRenderableTests.addChild(rbAttTests); |
| |
| for (var j = 0, l_texFmts = texFmts.length; j < l_texFmts; ++j) { |
| var params = glsFboCompletenessTests.renderableParams( |
| attPoints[i][0], gl.TEXTURE, texFmts[j] |
| ); |
| texAttTests.addChild( |
| new glsFboCompletenessTests.RenderableTest( |
| glsFboCompletenessTests.renderableParams.getName(params), |
| glsFboCompletenessTests.renderableParams.getDescription(params), |
| this, params |
| ) |
| ); |
| } |
| texRenderableTests.addChild(texAttTests); |
| |
| } |
| renderableTests.addChild(rbRenderableTests); |
| renderableTests.addChild(texRenderableTests); |
| |
| return renderableTests; |
| }; |
| |
| glsFboCompletenessTests.Context.prototype.createAttachmentTests = function(gl) { |
| |
| var attCombTests = tcuTestCase.newTest('attachment_combinations', 'Tests for attachment combinations'); |
| |
| var s_bufTypes = [gl.NONE, gl.RENDERBUFFER, gl.TEXTURE]; |
| var ls_bufTypes = s_bufTypes.length; |
| |
| for (var col0 = 0; col0 < ls_bufTypes; ++col0) |
| for (var coln = 0; coln < ls_bufTypes; ++coln) |
| for (var dep = 0; dep < ls_bufTypes; ++dep) |
| for (var stc = 0; stc < ls_bufTypes; ++stc) { |
| var params = glsFboCompletenessTests.attachmentParams( |
| s_bufTypes[col0], s_bufTypes[coln], s_bufTypes[dep], s_bufTypes[stc] |
| ); |
| attCombTests.addChild(new glsFboCompletenessTests.AttachmentTest( |
| glsFboCompletenessTests.attachmentParams.getName(params), |
| glsFboCompletenessTests.attachmentParams.getDescription(params), |
| this, params |
| )); |
| } |
| return attCombTests; |
| }; |
| |
| glsFboCompletenessTests.Context.prototype.createSizeTests = function(gl) { |
| |
| var sizeTests = tcuTestCase.newTest('size', 'Tests for attachment sizes'); |
| |
| sizeTests.addChild(new glsFboCompletenessTests.EmptyImageTest( |
| 'zero', 'Test for zero-sized image attachment', this |
| )); |
| |
| return sizeTests; |
| |
| }; |
| |
| /** |
| * @constructor |
| * @extends {tcuTestCase.DeqpTest} |
| * @param {string} name |
| * @param {string} desc |
| * @param {Object} params |
| */ |
| glsFboCompletenessTests.TestBase = function(name, desc, params) { |
| tcuTestCase.DeqpTest.call(this, name, desc); |
| this.m_params = params; |
| }; |
| glsFboCompletenessTests.TestBase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); |
| glsFboCompletenessTests.TestBase.prototype.constructor = glsFboCompletenessTests.TestBase; |
| |
| glsFboCompletenessTests.TestBase.prototype.getContext = function() { |
| return tcuTestCase.runner; |
| }; |
| |
| // GLenum attPoint, GLenum bufType |
| /** |
| * @param {number} attPoint |
| * @param {number} bufType |
| * @param {WebGLRenderingContextBase=} gl |
| */ |
| glsFboCompletenessTests.TestBase.prototype.getDefaultFormat = function(attPoint, bufType, gl) { |
| gl = gl || window.gl; |
| |
| if (bufType == gl.NONE) { |
| return glsFboUtil.ImageFormat.none(); |
| } |
| |
| // Prefer a standard format, if there is one, but if not, use a format |
| // provided by an extension. |
| var formats = this.m_ctx.getMinFormats().getFormats( |
| glsFboUtil.formatFlag(attPoint, gl) | glsFboUtil.formatFlag(bufType, gl) |
| ); |
| |
| if (!formats.length) { |
| formats = this.m_ctx.getCtxFormats().getFormats( |
| glsFboUtil.formatFlag(attPoint, gl) | glsFboUtil.formatFlag(bufType, gl) |
| ); |
| } |
| if (!formats.length) { |
| throw new Error('Unsupported attachment kind for attachment point'); |
| } |
| |
| return formats[0]; |
| |
| }; |
| |
| /** |
| * @param {number} bufType |
| * @param {glsFboUtil.ImageFormat} format |
| * @param {number} width |
| * @param {number} height |
| * @param {glsFboUtil.FboBuilder} builder |
| * @param {WebGLRenderingContextBase=} gl |
| * @return {glsFboUtil.Image} |
| */ |
| glsFboCompletenessTests.makeImage = function(bufType, format, width, height, builder, gl) { |
| gl = gl || window.gl; |
| var image = 0; |
| switch (bufType) { |
| case gl.NONE: |
| return null; |
| break; |
| case gl.RENDERBUFFER: |
| image = /** @type {glsFboUtil.Renderbuffer}*/(builder.makeConfig(glsFboUtil.Renderbuffer)); |
| break; |
| case gl.TEXTURE: |
| image = /** @type {glsFboUtil.Texture2D}*/(builder.makeConfig(glsFboUtil.Texture2D)); |
| break; |
| default: |
| throw new Error('Impossible case'); |
| } |
| image.internalFormat = format; |
| image.width = width; |
| image.height = height; |
| return image; |
| }; |
| |
| /** |
| * @param {number} bufType |
| * @param {glsFboUtil.ImageFormat} format |
| * @param {number} width |
| * @param {number} height |
| * @param {glsFboUtil.FboBuilder} builder |
| * @param {WebGLRenderingContextBase=} gl |
| * @return {glsFboUtil.Attachment} |
| */ |
| glsFboCompletenessTests.makeAttachment = function(bufType, format, width, height, builder, gl) { |
| gl = gl || window.gl; |
| var cfg = glsFboCompletenessTests.makeImage(bufType, format, width, height, builder, gl); |
| if (cfg == null) return null; |
| |
| /** @type {glsFboUtil.Attachment} */ var att = null; |
| var img = 0; |
| |
| var mask = glsFboUtil.Config.s_types.RENDERBUFFER | glsFboUtil.Config.s_types.TEXTURE_2D; |
| |
| switch (cfg.type & mask) { |
| case glsFboUtil.Config.s_types.RENDERBUFFER: |
| img = builder.glCreateRbo(/** @type {glsFboUtil.Renderbuffer} */(cfg)); |
| att = /** @type {glsFboUtil.RenderbufferAttachment} */ (builder.makeConfig(glsFboUtil.RenderbufferAttachment)); |
| break; |
| case glsFboUtil.Config.s_types.TEXTURE_2D: |
| img = builder.glCreateTexture(/** @type {glsFboUtil.Texture2D} */(cfg)); |
| att = /** @type {glsFboUtil.TextureFlatAttachment} */ (builder.makeConfig(glsFboUtil.TextureFlatAttachment)); |
| att.texTarget = gl.TEXTURE_2D; |
| break; |
| default: |
| throw new Error('Unsupported config.'); |
| } |
| att.imageName = img; |
| return att; |
| }; |
| |
| //GLenum target, GLenum bufType, ImageFormat format, GLsizei width, GLsizei height, FboBuilder& builder, webglctx |
| /** |
| * @param {number} target |
| * @param {number} bufType |
| * @param {glsFboUtil.ImageFormat} format |
| * @param {number} width |
| * @param {number} height |
| * @param {glsFboUtil.FboBuilder} builder |
| * @param {WebGL2RenderingContext} gl |
| */ |
| glsFboCompletenessTests.TestBase.prototype.attachTargetToNew = function( |
| target, bufType, format, width, height, builder, gl |
| ) { |
| var imgFmt = format; |
| if (imgFmt.format == gl.NONE) |
| imgFmt = this.getDefaultFormat(target, bufType, gl); |
| var att = glsFboCompletenessTests.makeAttachment(bufType, imgFmt, width, height, builder, gl); |
| builder.glAttach(target, att); |
| }; |
| |
| /** |
| * @param {number} status |
| * @param {WebGLRenderingContextBase=} gl |
| * @return {string} |
| */ |
| glsFboCompletenessTests.statusName = function(status, gl) { |
| gl = gl || window.gl; |
| |
| var errorName = gluStrUtil.getErrorName(status); |
| if (status != gl.NO_ERROR && errorName != '') |
| return errorName + ' (during FBO initialization)'; |
| |
| var fbStatusName = gluStrUtil.getFramebufferStatusName(status); |
| if (fbStatusName != '') |
| return fbStatusName; |
| |
| return 'unknown value (' + status + ')'; |
| }; |
| |
| glsFboCompletenessTests.TestBase.prototype.iterate = function() { |
| var gl = window.gl; |
| |
| var fbo = new gluObjectWrapper.Framebuffer(gl); |
| var builder = new glsFboUtil.FboBuilder(fbo.get(), gl.FRAMEBUFFER, gl); |
| var ret = this.build(builder, gl); |
| var statuses = this.m_ctx.getVerifier().validStatusCodes(builder, gl); |
| |
| var errorCode = builder.getError(); |
| if (errorCode != gl.NO_ERROR) { |
| bufferedLogToConsole('Received ' + gluStrUtil.getErrorName(errorCode) + ' (during FBO initialization).'); |
| if (statuses.isErrorCodeValid(errorCode)) |
| testPassed(); |
| else if (statuses.isErrorCodeRequired(gl.NO_ERROR)) |
| testFailedOptions('Excepted no error but got ' + gluStrUtil.getErrorName(errorCode), true); |
| else |
| testFailedOptions('Got wrong error code', true); |
| } else { |
| var fboStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER); |
| var validStatus = statuses.isFBOStatusValid(fboStatus); |
| bufferedLogToConsole('Received ' + gluStrUtil.getFramebufferStatusName(fboStatus)); |
| if (!validStatus) { |
| if (fboStatus == gl.FRAMEBUFFER_COMPLETE) { |
| testFailedOptions('Framebuffer checked as complete, expected incomplete', true); |
| } else if (statuses.isFBOStatusRequired(gl.FRAMEBUFFER_COMPLETE)) { |
| testFailedOptions('Framebuffer checked as incomplete, expected complete', true); |
| } else { |
| // An incomplete status is allowed, but not _this_ incomplete status. |
| testFailedOptions('Framebuffer checked as incomplete, but with wrong status', true); |
| } |
| } else if (fboStatus != gl.FRAMEBUFFER_COMPLETE && statuses.isFBOStatusValid(gl.FRAMEBUFFER_COMPLETE)) { |
| testPassedOptions('Warning: framebuffer object could have checked as complete but did not.', true); |
| } else { |
| // pass |
| testPassed(); |
| } |
| } |
| builder.deinit(); |
| |
| return tcuTestCase.IterateResult.STOP; |
| }; |
| |
| glsFboCompletenessTests.formatName = function(format, gl) { |
| if (!(gl = gl || window.gl)) throw new Error('Invalid GL object'); |
| |
| var s = gluStrUtil.getPixelFormatName(format.format).substr(3).toLowerCase(); |
| |
| if (format.unsizedType != gl.NONE) |
| s += '_' + gluStrUtil.getTypeName(format.unsizedType).substr(3).toLowerCase(); |
| |
| return s; |
| }; |
| glsFboCompletenessTests.formatDesc = function(format, gl) { |
| if (!(gl = gl || window.gl)) throw new Error('Invalid GL object'); |
| |
| var s = gluStrUtil.getPixelFormatName(format.format); |
| |
| if (format.unsizedType != gl.NONE) |
| s += ' with type ' + gluStrUtil.getTypeName(format.unsizedType); |
| |
| return s; |
| }; |
| |
| /** |
| * @typedef {{attPoint: number, bufType: number, format: glsFboUtil.ImageFormat}} |
| */ |
| glsFboCompletenessTests.renderableParamsT; |
| |
| /** |
| * @param {number} attPoint |
| * @param {number} bufType |
| * @param {glsFboUtil.ImageFormat} format |
| * @return {glsFboCompletenessTests.renderableParamsT} |
| */ |
| glsFboCompletenessTests.renderableParams = function(attPoint, bufType, format) { |
| var ret = { |
| attPoint: attPoint, |
| bufType: bufType, |
| format: format |
| }; |
| return ret; |
| }; |
| /** |
| * @param {glsFboCompletenessTests.renderableParamsT} params |
| * @param {WebGLRenderingContextBase=} gl |
| * @return {string} |
| */ |
| glsFboCompletenessTests.renderableParams.getName = function(params, gl) { |
| return glsFboCompletenessTests.formatName(params.format, gl); |
| }; |
| /** |
| * @param {glsFboCompletenessTests.renderableParamsT} params |
| * @param {WebGLRenderingContextBase=} gl |
| * @return {string} |
| */ |
| glsFboCompletenessTests.renderableParams.getDescription = function(params, gl) { |
| return glsFboCompletenessTests.formatDesc(params.format, gl); |
| }; |
| |
| /** |
| * @constructor |
| * @extends {glsFboCompletenessTests.TestBase} |
| * @param {string} name |
| * @param {string} desc |
| * @param {glsFboCompletenessTests.Context} ctx |
| * @param {glsFboCompletenessTests.renderableParamsT} params |
| */ |
| glsFboCompletenessTests.RenderableTest = function(name, desc, ctx, params) { |
| glsFboCompletenessTests.TestBase.call(this, name, desc, params); |
| this.m_ctx = ctx; |
| }; |
| glsFboCompletenessTests.RenderableTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype); |
| glsFboCompletenessTests.RenderableTest.prototype.constructor = glsFboCompletenessTests.RenderableTest; |
| |
| glsFboCompletenessTests.RenderableTest.prototype.build = function(builder, gl) { |
| this.attachTargetToNew(this.m_params.attPoint, this.m_params.bufType, this.m_params.format, 64, 64, builder, gl); |
| return true; |
| }; |
| |
| glsFboCompletenessTests.attTypeName = function(bufType, gl) { |
| if (!(gl = gl || window.gl)) throw new Error('Invalid GL object'); |
| switch (bufType) { |
| case gl.NONE: return 'none'; |
| case gl.RENDERBUFFER: return 'rbo'; |
| case gl.TEXTURE: return 'tex'; |
| default: break; |
| } |
| throw new Error('Impossible case'); |
| }; |
| |
| /** |
| * @typedef {{color0Kind: number, colornKind: number, depthKind: number, stencilKind: number}} |
| */ |
| glsFboCompletenessTests.attachmentParamsT; |
| |
| /** |
| * @param {number} color0Kind |
| * @param {number} colornKind |
| * @param {number} depthKind |
| * @param {number} stencilKind |
| * @return {glsFboCompletenessTests.attachmentParamsT} |
| */ |
| glsFboCompletenessTests.attachmentParams = function(color0Kind, colornKind, depthKind, stencilKind) { |
| var ret = { |
| color0Kind: color0Kind, |
| colornKind: colornKind, |
| depthKind: depthKind, |
| stencilKind: stencilKind |
| }; |
| return ret; |
| }; |
| /** |
| * @param {glsFboCompletenessTests.attachmentParamsT} params |
| * @param {WebGLRenderingContextBase=} gl |
| * @return {string} |
| */ |
| glsFboCompletenessTests.attachmentParams.getName = function(params, gl) { |
| return (glsFboCompletenessTests.attTypeName(params.color0Kind, gl) + '_' + |
| glsFboCompletenessTests.attTypeName(params.colornKind, gl) + '_' + |
| glsFboCompletenessTests.attTypeName(params.depthKind, gl) + '_' + |
| glsFboCompletenessTests.attTypeName(params.stencilKind, gl)); |
| }; |
| /** |
| * @param {glsFboCompletenessTests.attachmentParamsT} params |
| * @return {string} |
| */ |
| glsFboCompletenessTests.attachmentParams.getDescription = glsFboCompletenessTests.attachmentParams.getName; |
| |
| /** |
| * @constructor |
| * @extends {glsFboCompletenessTests.TestBase} |
| * @param {string} name |
| * @param {string} desc |
| * @param {glsFboCompletenessTests.Context} ctx |
| * @param {glsFboCompletenessTests.attachmentParamsT} params |
| */ |
| glsFboCompletenessTests.AttachmentTest = function(name, desc, ctx, params) { |
| glsFboCompletenessTests.TestBase.call(this, name, desc, params); |
| this.m_ctx = ctx; |
| }; |
| glsFboCompletenessTests.AttachmentTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype); |
| glsFboCompletenessTests.AttachmentTest.prototype.constructor = glsFboCompletenessTests.AttachmentTest; |
| |
| glsFboCompletenessTests.AttachmentTest.prototype.makeDepthAndStencil = function(builder, gl) { |
| |
| /** @type {glsFboUtil.Attachment} */ |
| var att = null; |
| |
| if (this.m_params.stencilKind == this.m_params.depthKind) { |
| // If there is a common stencil+depth -format, try to use a common |
| // image for both attachments. |
| var flags = glsFboUtil.FormatFlags.DEPTH_RENDERABLE | |
| glsFboUtil.FormatFlags.STENCIL_RENDERABLE | |
| glsFboUtil.formatFlag(this.m_params.stencilKind, gl); |
| |
| var formats = this.m_ctx.getMinFormats().getFormats(flags); |
| if (formats.length) { |
| var format = formats[0]; |
| att = glsFboCompletenessTests.makeAttachment(this.m_params.depthKind, format, 64, 64, builder, gl); |
| builder.glAttach(gl.DEPTH_ATTACHMENT, att); |
| builder.glAttach(gl.STENCIL_ATTACHMENT, att); |
| return; |
| } |
| } |
| // Either the kinds were separate, or a suitable format was not found. |
| // Create separate images. |
| this.attachTargetToNew(gl.STENCIL_ATTACHMENT, this.m_params.stencilKind, |
| glsFboUtil.ImageFormat.none(), 64, 64, builder, gl); |
| this.attachTargetToNew(gl.DEPTH_ATTACHMENT, this.m_params.depthKind, |
| glsFboUtil.ImageFormat.none(), 64, 64, builder, gl); |
| }; |
| |
| glsFboCompletenessTests.AttachmentTest.prototype.build = function(builder, gl) { |
| |
| this.attachTargetToNew(gl.COLOR_ATTACHMENT0, this.m_params.color0Kind, |
| glsFboUtil.ImageFormat.none(), 64, 64, builder, gl); |
| |
| if (this.m_params.colornKind != gl.NONE) { |
| if (this.m_ctx.haveMultiColorAtts()) |
| throw new Error('Multiple attachments not supported'); |
| var maxAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS); |
| |
| for (var i = 1; i < maxAttachments; ++i) { |
| this.attachTargetToNew(gl.COLOR_ATTACHMENT0 + i, this.m_params.colornKind, |
| glsFboUtil.ImageFormat.none(), 64, 64, builder, gl); |
| } |
| } |
| |
| this.makeDepthAndStencil(builder, gl); |
| |
| return true; |
| }; |
| |
| /** |
| * @constructor |
| * @extends {glsFboCompletenessTests.TestBase} |
| * @param {string} name |
| * @param {string} desc |
| * @param {glsFboCompletenessTests.Context} ctx |
| */ |
| glsFboCompletenessTests.EmptyImageTest = function(name, desc, ctx) { |
| glsFboCompletenessTests.TestBase.call(this, name, desc, null); |
| this.m_ctx = ctx; |
| }; |
| glsFboCompletenessTests.EmptyImageTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype); |
| glsFboCompletenessTests.EmptyImageTest.prototype.constructor = glsFboCompletenessTests.EmptyImageTest; |
| |
| glsFboCompletenessTests.EmptyImageTest.prototype.build = function(builder, gl) { |
| this.attachTargetToNew(gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, |
| glsFboUtil.ImageFormat.none(), 0, 0, builder, gl); |
| return true; |
| }; |
| |
| }); |