tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

glsFboCompletenessTests.js (38228B)


      1 'use strict';
      2 goog.provide('modules.shared.glsFboCompletenessTests');
      3 goog.require('framework.common.tcuTestCase');
      4 goog.require('framework.opengl.gluObjectWrapper');
      5 goog.require('framework.opengl.gluStrUtil');
      6 goog.require('modules.shared.glsFboUtil');
      7 
      8 goog.scope(function() {
      9 
     10    var glsFboCompletenessTests = modules.shared.glsFboCompletenessTests;
     11    var glsFboUtil = modules.shared.glsFboUtil;
     12    var gluObjectWrapper = framework.opengl.gluObjectWrapper;
     13    var gluStrUtil = framework.opengl.gluStrUtil;
     14    var tcuTestCase = framework.common.tcuTestCase;
     15 
     16    /**
     17     * @param {WebGL2RenderingContext} gl
     18     */
     19    glsFboCompletenessTests.initGlDependents = function(gl) {
     20        if (!(gl = gl || window.gl)) throw new Error('Invalid gl object');
     21 
     22        // The following extensions are applicable both to ES2 and ES3.
     23        /**
     24         * OES_depth_texture
     25         * @type {Array<number>}
     26         */
     27        glsFboCompletenessTests.s_oesDepthTextureFormats = [
     28            glsFboUtil.formatkey(gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT),
     29            glsFboUtil.formatkey(gl.DEPTH_COMPONENT, gl.UNSIGNED_INT)
     30        ];
     31 
     32        /**
     33         * OES_packed_depth_stencil
     34         * @type {Array<number>}
     35         */
     36        glsFboCompletenessTests.s_oesPackedDepthStencilSizedFormats = [
     37            gl.DEPTH24_STENCIL8
     38        ];
     39 
     40        /**
     41         * s_oesPackedDepthStencilTexFormats
     42         * @type {Array<number>}
     43         */
     44        glsFboCompletenessTests.s_oesPackedDepthStencilTexFormats = [
     45            glsFboUtil.formatkey(gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8)
     46        ];
     47 
     48        /**
     49         * OES_required_internalformat
     50         * @type {Array<number>}
     51         */
     52        glsFboCompletenessTests.s_oesRequiredInternalFormatColorFormats = [
     53            // Same as ES2 RBO formats, plus RGBA8 (even without OES_rgb8_rgba8)
     54            gl.RGB5_A1, gl.RGBA8, gl.RGBA4, gl.RGB565
     55        ];
     56 
     57        /**
     58         * s_oesRequiredInternalFormatDepthFormats
     59         * @type {Array<number>}
     60         */
     61        glsFboCompletenessTests.s_oesRequiredInternalFormatDepthFormats = [
     62            gl.DEPTH_COMPONENT16
     63        ];
     64 
     65        /**
     66         * EXT_color_buffer_half_float
     67         * @type {Array<number>}
     68         */
     69        glsFboCompletenessTests.s_extColorBufferHalfFloatFormats = [
     70            gl.RGBA16F, gl.RGB16F, gl.RG16F, gl.R16F
     71        ];
     72 
     73        /**
     74         * s_oesDepth24SizedFormats
     75         * @type {Array<number>}
     76         */
     77        glsFboCompletenessTests.s_oesDepth24SizedFormats = [
     78            gl.DEPTH_COMPONENT24
     79        ];
     80 
     81        /**
     82         * s_oesDepth32SizedFormats
     83         * @type {Array<number>}
     84         */
     85        glsFboCompletenessTests.s_oesDepth32SizedFormats = [
     86            gl['DEPTH_COMPONENT32']
     87        ];
     88 
     89        /**
     90         * s_oesRgb8Rgba8RboFormats
     91         * @type {Array<number>}
     92         */
     93        glsFboCompletenessTests.s_oesRgb8Rgba8RboFormats = [
     94            gl.RGB8, gl.RGBA8
     95        ];
     96 
     97        /**
     98         * s_oesRequiredInternalFormatRgb8ColorFormat
     99         * @type {Array<number>}
    100         */
    101        glsFboCompletenessTests.s_oesRequiredInternalFormatRgb8ColorFormat = [
    102            gl.RGB8
    103        ];
    104 
    105        /**
    106         * s_extTextureType2101010RevFormats
    107         * @type {Array<number>}
    108         */
    109        glsFboCompletenessTests.s_extTextureType2101010RevFormats = [
    110            glsFboUtil.formatkey(gl.RGBA, gl.UNSIGNED_INT_2_10_10_10_REV),
    111            glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_INT_2_10_10_10_REV)
    112        ];
    113 
    114        /**
    115         * s_oesRequiredInternalFormat10bitColorFormats
    116         * @type {Array<number>}
    117         */
    118        glsFboCompletenessTests.s_oesRequiredInternalFormat10bitColorFormats = [
    119            gl.RGB10_A2, gl['RGB10']
    120        ];
    121 
    122        /**
    123         * s_extTextureRgRboFormats
    124         * @type {Array<number>}
    125         */
    126        glsFboCompletenessTests.s_extTextureRgRboFormats = [
    127            gl.R8, gl.RG8
    128        ];
    129 
    130        /**
    131         * s_extTextureRgTexFormats
    132         * @type {Array<number>}
    133         */
    134        glsFboCompletenessTests.s_extTextureRgTexFormats = [
    135            glsFboUtil.formatkey(gl.RED, gl.UNSIGNED_BYTE),
    136            glsFboUtil.formatkey(gl.RG, gl.UNSIGNED_BYTE)
    137        ];
    138 
    139        /**
    140         * s_extTextureRgFloatTexFormats
    141         * @type {Array<number>}
    142         */
    143        glsFboCompletenessTests.s_extTextureRgFloatTexFormats = [
    144            glsFboUtil.formatkey(gl.RED, gl.FLOAT),
    145            glsFboUtil.formatkey(gl.RG, gl.FLOAT)
    146        ];
    147 
    148        /**
    149         * s_extTextureRgHalfFloatTexFormats
    150         * @type {Array<number>}
    151         */
    152        glsFboCompletenessTests.s_extTextureRgHalfFloatTexFormats = [
    153            glsFboUtil.formatkey(gl.RED, gl['HALF_FLOAT_OES']),
    154            glsFboUtil.formatkey(gl.RG, gl['HALF_FLOAT_OES'])
    155        ];
    156 
    157        /**
    158         * s_nvPackedFloatRboFormats
    159         * @type {Array<number>}
    160         */
    161        glsFboCompletenessTests.s_nvPackedFloatRboFormats = [
    162            gl.R11F_G11F_B10F
    163        ];
    164 
    165        /**
    166         * s_nvPackedFloatTexFormats
    167         * @type {Array<number>}
    168         */
    169        glsFboCompletenessTests.s_nvPackedFloatTexFormats = [
    170            glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_INT_10F_11F_11F_REV)
    171        ];
    172 
    173        /**
    174         * s_extSrgbRboFormats
    175         * @type {Array<number>}
    176         */
    177        glsFboCompletenessTests.s_extSrgbRboFormats = [
    178            gl.SRGB8_ALPHA8
    179        ];
    180 
    181        /**
    182         * s_extSrgbRenderableTexFormats
    183         * @type {Array<number>}
    184         */
    185        glsFboCompletenessTests.s_extSrgbRenderableTexFormats = [
    186            glsFboUtil.formatkey(gl['SRGB_ALPHA'], gl.UNSIGNED_BYTE)
    187        ];
    188 
    189        /**
    190         * s_extSrgbNonRenderableTexFormats
    191         * @type {Array<number>}
    192         */
    193        glsFboCompletenessTests.s_extSrgbNonRenderableTexFormats = [
    194            glsFboUtil.formatkey(gl.SRGB, gl.UNSIGNED_BYTE),
    195            gl.SRGB8
    196        ];
    197 
    198        /**
    199         * s_nvSrgbFormatsRboFormats
    200         * @type {Array<number>}
    201         */
    202        glsFboCompletenessTests.s_nvSrgbFormatsRboFormats = [
    203            gl.SRGB8
    204        ];
    205 
    206        /**
    207         * s_nvSrgbFormatsTextureFormats
    208         * The extension does not actually require any unsized format
    209         * to be renderable. However, the renderablility of unsized
    210         * SRGB,UBYTE internalformat-type pair is implied.
    211         * @type {Array<number>}
    212         */
    213        glsFboCompletenessTests.s_nvSrgbFormatsTextureFormats = [
    214            gl.SRGB8,
    215            glsFboUtil.formatkey(gl.SRGB, gl.UNSIGNED_BYTE)
    216        ];
    217 
    218        /**
    219         * s_oesRgb8Rgba8TexFormats
    220         * @type {Array<number>}
    221         */
    222        glsFboCompletenessTests.s_oesRgb8Rgba8TexFormats = [
    223            glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_BYTE),
    224            glsFboUtil.formatkey(gl.RGBA, gl.UNSIGNED_BYTE)
    225        ];
    226 
    227        var fmt = glsFboUtil.FormatFlags;
    228 
    229        /**
    230         * s_esExtFormats
    231         * @type {Array<glsFboUtil.FormatExtEntry>}
    232         */
    233        glsFboCompletenessTests.s_esExtFormats = [
    234            new glsFboUtil.FormatExtEntry(
    235                'OES_depth_texture',
    236                fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.TEXTURE_VALID,
    237                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepthTextureFormats)
    238            ),
    239            new glsFboUtil.FormatExtEntry(
    240                'OES_packed_depth_stencil',
    241                fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.STENCIL_RENDERABLE | fmt.RENDERBUFFER_VALID,
    242                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesPackedDepthStencilSizedFormats)
    243            ),
    244            new glsFboUtil.FormatExtEntry(
    245                'OES_packed_depth_stencil OES_required_internalformat',
    246                fmt.DEPTH_RENDERABLE | fmt.STENCIL_RENDERABLE | fmt.TEXTURE_VALID,
    247                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesPackedDepthStencilTexFormats)
    248            ),
    249 
    250            // \todo [2013-12-10 lauri] Find out if OES_texture_half_float is really a
    251            // requirement on ES3 also. Or is color_buffer_half_float applicatble at
    252            // all on ES3, since there's also EXT_color_buffer_float?
    253            new glsFboUtil.FormatExtEntry(
    254                'OES_texture_half_float EXT_color_buffer_half_float',
    255                fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID,
    256                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extColorBufferHalfFloatFormats)
    257            ),
    258 
    259            // OES_required_internalformat doesn't actually specify that these are renderable,
    260            // since it was written against ES 1.1.
    261            new glsFboUtil.FormatExtEntry(
    262                'OES_required_internalformat',
    263                // Allow but don't require RGBA8 to be color-renderable if
    264                // OES_rgb8_rgba8 is not present.
    265                fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID,
    266                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormatColorFormats)
    267            ),
    268            new glsFboUtil.FormatExtEntry(
    269                'OES_required_internalformat',
    270                fmt.DEPTH_RENDERABLE | fmt.TEXTURE_VALID,
    271                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormatDepthFormats)
    272            ),
    273            new glsFboUtil.FormatExtEntry(
    274                'EXT_texture_rg',
    275                fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID,
    276                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgRboFormats)
    277            ),
    278 
    279            // These are not specified to be color-renderable, but the wording is
    280            // exactly as ambiguous as the wording in the ES2 spec.
    281            new glsFboUtil.FormatExtEntry(
    282                'EXT_texture_rg',
    283                fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID,
    284                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgTexFormats)
    285            ),
    286            new glsFboUtil.FormatExtEntry(
    287                'EXT_texture_rg OES_texture_float',
    288                fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID,
    289                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgFloatTexFormats)
    290            ),
    291            new glsFboUtil.FormatExtEntry(
    292                'EXT_texture_rg OES_texture_half_float',
    293                fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID,
    294                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureRgHalfFloatTexFormats)
    295            ),
    296 
    297            // Some Tegra drivers report gl.EXT_packed_float even for ES. Treat it as
    298            // a synonym for the NV_ version.
    299            new glsFboUtil.FormatExtEntry(
    300                'EXT_packed_float',
    301                fmt.REQUIRED_RENDERABLE | fmt.TEXTURE_VALID,
    302                glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvPackedFloatTexFormats)
    303            ),
    304            new glsFboUtil.FormatExtEntry(
    305                'EXT_packed_float EXT_color_buffer_half_float',
    306                fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID,
    307                glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvPackedFloatRboFormats)
    308            ),
    309            new glsFboUtil.FormatExtEntry(
    310                'EXT_sRGB',
    311                fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID,
    312                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extSrgbRenderableTexFormats)
    313            ),
    314            new glsFboUtil.FormatExtEntry(
    315                'EXT_sRGB',
    316                fmt.TEXTURE_VALID,
    317                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extSrgbNonRenderableTexFormats)
    318            ),
    319            new glsFboUtil.FormatExtEntry(
    320                'EXT_sRGB',
    321                fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID,
    322                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extSrgbRboFormats)
    323            ),
    324            new glsFboUtil.FormatExtEntry(
    325                'NV_sRGB_formats',
    326                fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID,
    327                glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvSrgbFormatsRboFormats)
    328            ),
    329            new glsFboUtil.FormatExtEntry(
    330                'NV_sRGB_formats',
    331                fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID,
    332                glsFboUtil.rangeArray(glsFboCompletenessTests.s_nvSrgbFormatsTextureFormats)
    333            ),
    334 
    335            // In Khronos bug 7333 discussion, the consensus is that these texture
    336            // formats, at least, should be color-renderable. Still, that cannot be
    337            // found in any extension specs, so only allow it, not require it.
    338            new glsFboUtil.FormatExtEntry(
    339                'OES_rgb8_rgba8',
    340                fmt.COLOR_RENDERABLE | fmt.TEXTURE_VALID,
    341                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRgb8Rgba8TexFormats)
    342            ),
    343            new glsFboUtil.FormatExtEntry(
    344                'OES_rgb8_rgba8',
    345                fmt.REQUIRED_RENDERABLE | fmt.COLOR_RENDERABLE | fmt.RENDERBUFFER_VALID,
    346                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRgb8Rgba8RboFormats)
    347            ),
    348            new glsFboUtil.FormatExtEntry(
    349                'OES_rgb8_rgba8 OES_required_internalformat',
    350                fmt.TEXTURE_VALID,
    351                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormatRgb8ColorFormat)
    352            ),
    353 
    354            // The depth-renderability of the depth RBO formats is not explicitly
    355            // spelled out, but all renderbuffer formats are meant to be renderable.
    356            new glsFboUtil.FormatExtEntry(
    357                'OES_depth24',
    358                fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.RENDERBUFFER_VALID,
    359                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth24SizedFormats)
    360            ),
    361            new glsFboUtil.FormatExtEntry(
    362                'OES_depth24 OES_required_internalformat OES_depth_texture',
    363                fmt.TEXTURE_VALID,
    364                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth24SizedFormats)
    365            ),
    366 
    367            new glsFboUtil.FormatExtEntry(
    368                'OES_depth32',
    369                fmt.REQUIRED_RENDERABLE | fmt.DEPTH_RENDERABLE | fmt.RENDERBUFFER_VALID,
    370                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth32SizedFormats)
    371            ),
    372            new glsFboUtil.FormatExtEntry(
    373                'OES_depth32 OES_required_internalformat OES_depth_texture',
    374                fmt.TEXTURE_VALID,
    375                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesDepth32SizedFormats)
    376            ),
    377 
    378            new glsFboUtil.FormatExtEntry(
    379                'EXT_texture_type_2_10_10_10_REV',
    380                fmt.TEXTURE_VALID, // explicitly unrenderable
    381                glsFboUtil.rangeArray(glsFboCompletenessTests.s_extTextureType2101010RevFormats)
    382            ),
    383            new glsFboUtil.FormatExtEntry(
    384                'EXT_texture_type_2_10_10_10_REV OES_required_internalformat',
    385                fmt.TEXTURE_VALID, // explicitly unrenderable
    386                glsFboUtil.rangeArray(glsFboCompletenessTests.s_oesRequiredInternalFormat10bitColorFormats)
    387            )
    388        ];
    389 
    390    }; // initGlDependents ----------------------------------------
    391 
    392    /**
    393    * @constructor
    394    * @param {null} testCtx
    395    * @param {WebGLRenderingContextBase} renderCtx
    396    * @param {glsFboUtil.CheckerFactory} factory
    397    */
    398    glsFboCompletenessTests.Context = function(testCtx, renderCtx, factory) {
    399 
    400        this.m_testCtx = testCtx;
    401        this.m_renderCtx = renderCtx;
    402        this.m_ctxFormats = new glsFboUtil.FormatDB();
    403        this.m_minFormats = new glsFboUtil.FormatDB();
    404        this.m_maxFormats = new glsFboUtil.FormatDB();
    405        this.m_verifier = new glsFboUtil.FboVerifier(this.m_ctxFormats, factory);
    406        this.m_haveMultiColorAtts = false;
    407 
    408        // FormatExtEntries
    409        var extRange = glsFboUtil.rangeArray(glsFboCompletenessTests.s_esExtFormats);
    410        this.addExtFormats(extRange);
    411 
    412    };
    413 
    414    // RenderContext&
    415    glsFboCompletenessTests.Context.prototype.getRenderContext = function() {
    416        return this.m_renderCtx;
    417    };
    418 
    419    // TestContext&
    420    glsFboCompletenessTests.Context.prototype.getTestContext = function() {
    421        return this.m_testCtx;
    422    };
    423 
    424    // const FboVerifier&
    425    glsFboCompletenessTests.Context.prototype.getVerifier = function() {
    426        return this.m_verifier;
    427    };
    428 
    429    // const FormatDB&
    430    glsFboCompletenessTests.Context.prototype.getMinFormats = function() {
    431        return this.m_minFormats;
    432    };
    433 
    434    // const FormatDB&
    435    glsFboCompletenessTests.Context.prototype.getCtxFormats = function() {
    436        return this.m_ctxFormats;
    437    };
    438 
    439    // bool
    440    glsFboCompletenessTests.Context.prototype.haveMultiColorAtts = function() {
    441        return this.m_haveMultiColorAtts;
    442    };
    443 
    444    glsFboCompletenessTests.Context.prototype.setHaveMulticolorAtts = function(have) {
    445        this.m_haveMultiColorAtts = (have == true);
    446    };
    447 
    448    glsFboCompletenessTests.Context.prototype.addFormats = function(fmtRange) {
    449        glsFboUtil.addFormats(this.m_minFormats, fmtRange);
    450        glsFboUtil.addFormats(this.m_ctxFormats, fmtRange);
    451        glsFboUtil.addFormats(this.m_maxFormats, fmtRange);
    452    };
    453    glsFboCompletenessTests.Context.prototype.addExtFormats = function(extRange) {
    454        glsFboUtil.addExtFormats(this.m_ctxFormats, extRange, this.m_renderCtx);
    455        glsFboUtil.addExtFormats(this.m_maxFormats, extRange, this.m_renderCtx);
    456    };
    457 
    458    glsFboCompletenessTests.Context.prototype.createRenderableTests = function(gl) {
    459 
    460        /** @type {tcuTestCase.DeqpTest} */
    461        var renderableTests = tcuTestCase.newTest('renderable', 'Tests for support of renderable image formats');
    462        /** @type {tcuTestCase.DeqpTest} */
    463        var rbRenderableTests = tcuTestCase.newTest('renderbuffer', 'Tests for renderbuffer formats');
    464        /** @type {tcuTestCase.DeqpTest} */
    465        var texRenderableTests = tcuTestCase.newTest('texture', 'Tests for texture formats');
    466 
    467        var attPoints = [
    468            [gl.DEPTH_ATTACHMENT, 'depth', 'Tests for depth attachments'],
    469            [gl.STENCIL_ATTACHMENT, 'stencil', 'Tests for stencil attachments'],
    470            [gl.COLOR_ATTACHMENT0, 'color0', 'Tests for color attachments']
    471        ];
    472 
    473        // At each attachment point, iterate through all the possible formats to
    474        // detect both false positives and false negatives.
    475        var rboFmts = this.m_maxFormats.getFormats(glsFboUtil.FormatFlags.ANY_FORMAT);
    476        var texFmts = this.m_maxFormats.getFormats(glsFboUtil.FormatFlags.ANY_FORMAT);
    477 
    478        for (var i = 0, l_attPoints = attPoints.length; i < l_attPoints; ++i) {
    479            var rbAttTests = tcuTestCase.newTest(attPoints[i][1], attPoints[i][2]);
    480            var texAttTests = tcuTestCase.newTest(attPoints[i][1], attPoints[i][2]);
    481 
    482            for (var j = 0, l_rboFmts = rboFmts.length; j < l_rboFmts; ++j) {
    483                var params = glsFboCompletenessTests.renderableParams(
    484                    attPoints[i][0], gl.RENDERBUFFER, rboFmts[j]
    485                );
    486                rbAttTests.addChild(
    487                    new glsFboCompletenessTests.RenderableTest(
    488                        glsFboCompletenessTests.renderableParams.getName(params),
    489                        glsFboCompletenessTests.renderableParams.getDescription(params),
    490                        this, params
    491                    )
    492                );
    493            }
    494            rbRenderableTests.addChild(rbAttTests);
    495 
    496            for (var j = 0, l_texFmts = texFmts.length; j < l_texFmts; ++j) {
    497                var params = glsFboCompletenessTests.renderableParams(
    498                    attPoints[i][0], gl.TEXTURE, texFmts[j]
    499                );
    500                texAttTests.addChild(
    501                    new glsFboCompletenessTests.RenderableTest(
    502                        glsFboCompletenessTests.renderableParams.getName(params),
    503                        glsFboCompletenessTests.renderableParams.getDescription(params),
    504                        this, params
    505                    )
    506                );
    507            }
    508            texRenderableTests.addChild(texAttTests);
    509 
    510        }
    511        renderableTests.addChild(rbRenderableTests);
    512        renderableTests.addChild(texRenderableTests);
    513 
    514        return renderableTests;
    515    };
    516 
    517    glsFboCompletenessTests.Context.prototype.createAttachmentTests = function(gl) {
    518 
    519        var attCombTests = tcuTestCase.newTest('attachment_combinations', 'Tests for attachment combinations');
    520 
    521        var s_bufTypes = [gl.NONE, gl.RENDERBUFFER, gl.TEXTURE];
    522        var ls_bufTypes = s_bufTypes.length;
    523 
    524        for (var col0 = 0; col0 < ls_bufTypes; ++col0)
    525            for (var coln = 0; coln < ls_bufTypes; ++coln)
    526                for (var dep = 0; dep < ls_bufTypes; ++dep)
    527                    for (var stc = 0; stc < ls_bufTypes; ++stc) {
    528                        var params = glsFboCompletenessTests.attachmentParams(
    529                            s_bufTypes[col0], s_bufTypes[coln], s_bufTypes[dep], s_bufTypes[stc]
    530                        );
    531                        attCombTests.addChild(new glsFboCompletenessTests.AttachmentTest(
    532                            glsFboCompletenessTests.attachmentParams.getName(params),
    533                            glsFboCompletenessTests.attachmentParams.getDescription(params),
    534                            this, params
    535                        ));
    536                    }
    537        return attCombTests;
    538    };
    539 
    540    glsFboCompletenessTests.Context.prototype.createSizeTests = function(gl) {
    541 
    542        var sizeTests = tcuTestCase.newTest('size', 'Tests for attachment sizes');
    543 
    544        sizeTests.addChild(new glsFboCompletenessTests.EmptyImageTest(
    545            'zero', 'Test for zero-sized image attachment', this
    546        ));
    547 
    548        return sizeTests;
    549 
    550    };
    551 
    552    /**
    553    * @constructor
    554    * @extends {tcuTestCase.DeqpTest}
    555    * @param {string} name
    556    * @param {string} desc
    557    * @param {Object} params
    558    */
    559    glsFboCompletenessTests.TestBase = function(name, desc, params) {
    560        tcuTestCase.DeqpTest.call(this, name, desc);
    561        this.m_params = params;
    562    };
    563    glsFboCompletenessTests.TestBase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    564    glsFboCompletenessTests.TestBase.prototype.constructor = glsFboCompletenessTests.TestBase;
    565 
    566    glsFboCompletenessTests.TestBase.prototype.getContext = function() {
    567        return tcuTestCase.runner;
    568    };
    569 
    570    // GLenum attPoint, GLenum bufType
    571    /**
    572    * @param {number} attPoint
    573    * @param {number} bufType
    574    * @param {WebGLRenderingContextBase=} gl
    575    */
    576    glsFboCompletenessTests.TestBase.prototype.getDefaultFormat = function(attPoint, bufType, gl) {
    577        gl = gl || window.gl;
    578 
    579        if (bufType == gl.NONE) {
    580            return glsFboUtil.ImageFormat.none();
    581        }
    582 
    583        // Prefer a standard format, if there is one, but if not, use a format
    584        // provided by an extension.
    585        var formats = this.m_ctx.getMinFormats().getFormats(
    586            glsFboUtil.formatFlag(attPoint, gl) | glsFboUtil.formatFlag(bufType, gl)
    587        );
    588 
    589        if (!formats.length) {
    590            formats = this.m_ctx.getCtxFormats().getFormats(
    591                glsFboUtil.formatFlag(attPoint, gl) | glsFboUtil.formatFlag(bufType, gl)
    592            );
    593        }
    594        if (!formats.length) {
    595            throw new Error('Unsupported attachment kind for attachment point');
    596        }
    597 
    598        return formats[0];
    599 
    600    };
    601 
    602    /**
    603    * @param {number} bufType
    604    * @param {glsFboUtil.ImageFormat} format
    605    * @param {number} width
    606    * @param {number} height
    607    * @param {glsFboUtil.FboBuilder} builder
    608    * @param {WebGLRenderingContextBase=} gl
    609    * @return {glsFboUtil.Image}
    610    */
    611    glsFboCompletenessTests.makeImage = function(bufType, format, width, height, builder, gl) {
    612        gl = gl || window.gl;
    613        var image = 0;
    614        switch (bufType) {
    615            case gl.NONE:
    616                return null;
    617                break;
    618            case gl.RENDERBUFFER:
    619                image = /** @type {glsFboUtil.Renderbuffer}*/(builder.makeConfig(glsFboUtil.Renderbuffer));
    620                break;
    621            case gl.TEXTURE:
    622                image = /** @type {glsFboUtil.Texture2D}*/(builder.makeConfig(glsFboUtil.Texture2D));
    623                break;
    624            default:
    625                throw new Error('Impossible case');
    626        }
    627        image.internalFormat = format;
    628        image.width = width;
    629        image.height = height;
    630        return image;
    631    };
    632 
    633    /**
    634    * @param {number} bufType
    635    * @param {glsFboUtil.ImageFormat} format
    636    * @param {number} width
    637    * @param {number} height
    638    * @param {glsFboUtil.FboBuilder} builder
    639    * @param {WebGLRenderingContextBase=} gl
    640    * @return {glsFboUtil.Attachment}
    641    */
    642    glsFboCompletenessTests.makeAttachment = function(bufType, format, width, height, builder, gl) {
    643        gl = gl || window.gl;
    644        var cfg = glsFboCompletenessTests.makeImage(bufType, format, width, height, builder, gl);
    645        if (cfg == null) return null;
    646 
    647        /** @type {glsFboUtil.Attachment} */ var att = null;
    648        var img = 0;
    649 
    650        var mask = glsFboUtil.Config.s_types.RENDERBUFFER | glsFboUtil.Config.s_types.TEXTURE_2D;
    651 
    652        switch (cfg.type & mask) {
    653            case glsFboUtil.Config.s_types.RENDERBUFFER:
    654                img = builder.glCreateRbo(/** @type {glsFboUtil.Renderbuffer} */(cfg));
    655                att = /** @type {glsFboUtil.RenderbufferAttachment} */ (builder.makeConfig(glsFboUtil.RenderbufferAttachment));
    656                break;
    657            case glsFboUtil.Config.s_types.TEXTURE_2D:
    658                img = builder.glCreateTexture(/** @type {glsFboUtil.Texture2D} */(cfg));
    659                att = /** @type {glsFboUtil.TextureFlatAttachment} */ (builder.makeConfig(glsFboUtil.TextureFlatAttachment));
    660                att.texTarget = gl.TEXTURE_2D;
    661                break;
    662            default:
    663                throw new Error('Unsupported config.');
    664        }
    665        att.imageName = img;
    666        return att;
    667    };
    668 
    669    //GLenum target, GLenum bufType, ImageFormat format, GLsizei width, GLsizei height, FboBuilder& builder, webglctx
    670    /**
    671     * @param {number} target
    672     * @param {number} bufType
    673     * @param {glsFboUtil.ImageFormat} format
    674     * @param {number} width
    675     * @param {number} height
    676     * @param {glsFboUtil.FboBuilder} builder
    677     * @param {WebGL2RenderingContext} gl
    678     */
    679    glsFboCompletenessTests.TestBase.prototype.attachTargetToNew = function(
    680        target, bufType, format, width, height, builder, gl
    681    ) {
    682        var imgFmt = format;
    683        if (imgFmt.format == gl.NONE)
    684            imgFmt = this.getDefaultFormat(target, bufType, gl);
    685        var att = glsFboCompletenessTests.makeAttachment(bufType, imgFmt, width, height, builder, gl);
    686        builder.glAttach(target, att);
    687    };
    688 
    689    /**
    690    * @param {number} status
    691    * @param {WebGLRenderingContextBase=} gl
    692    * @return {string}
    693    */
    694    glsFboCompletenessTests.statusName = function(status, gl) {
    695        gl = gl || window.gl;
    696 
    697        var errorName = gluStrUtil.getErrorName(status);
    698        if (status != gl.NO_ERROR && errorName != '')
    699            return errorName + ' (during FBO initialization)';
    700 
    701        var fbStatusName = gluStrUtil.getFramebufferStatusName(status);
    702        if (fbStatusName != '')
    703            return fbStatusName;
    704 
    705        return 'unknown value (' + status + ')';
    706    };
    707 
    708    glsFboCompletenessTests.TestBase.prototype.iterate = function() {
    709        var gl = window.gl;
    710 
    711        var fbo = new gluObjectWrapper.Framebuffer(gl);
    712        var builder = new glsFboUtil.FboBuilder(fbo.get(), gl.FRAMEBUFFER, gl);
    713        var ret = this.build(builder, gl);
    714        var statuses = this.m_ctx.getVerifier().validStatusCodes(builder, gl);
    715 
    716        var errorCode = builder.getError();
    717        if (errorCode != gl.NO_ERROR) {
    718            bufferedLogToConsole('Received ' + gluStrUtil.getErrorName(errorCode) + ' (during FBO initialization).');
    719            if (statuses.isErrorCodeValid(errorCode))
    720                testPassed();
    721            else if (statuses.isErrorCodeRequired(gl.NO_ERROR))
    722                testFailedOptions('Excepted no error but got ' + gluStrUtil.getErrorName(errorCode), true);
    723            else
    724                testFailedOptions('Got wrong error code', true);
    725        } else {
    726            var fboStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    727            var validStatus = statuses.isFBOStatusValid(fboStatus);
    728            bufferedLogToConsole('Received ' + gluStrUtil.getFramebufferStatusName(fboStatus));
    729            if (!validStatus) {
    730                if (fboStatus == gl.FRAMEBUFFER_COMPLETE) {
    731                    testFailedOptions('Framebuffer checked as complete, expected incomplete', true);
    732                } else if (statuses.isFBOStatusRequired(gl.FRAMEBUFFER_COMPLETE)) {
    733                    testFailedOptions('Framebuffer checked as incomplete, expected complete', true);
    734                } else {
    735                    // An incomplete status is allowed, but not _this_ incomplete status.
    736                    testFailedOptions('Framebuffer checked as incomplete, but with wrong status', true);
    737                }
    738            } else if (fboStatus != gl.FRAMEBUFFER_COMPLETE && statuses.isFBOStatusValid(gl.FRAMEBUFFER_COMPLETE)) {
    739                testPassedOptions('Warning: framebuffer object could have checked as complete but did not.', true);
    740            } else {
    741                // pass
    742                testPassed();
    743            }
    744        }
    745        builder.deinit();
    746 
    747        return tcuTestCase.IterateResult.STOP;
    748    };
    749 
    750    glsFboCompletenessTests.formatName = function(format, gl) {
    751        if (!(gl = gl || window.gl)) throw new Error('Invalid GL object');
    752 
    753        var s = gluStrUtil.getPixelFormatName(format.format).substr(3).toLowerCase();
    754 
    755        if (format.unsizedType != gl.NONE)
    756            s += '_' + gluStrUtil.getTypeName(format.unsizedType).substr(3).toLowerCase();
    757 
    758        return s;
    759    };
    760    glsFboCompletenessTests.formatDesc = function(format, gl) {
    761        if (!(gl = gl || window.gl)) throw new Error('Invalid GL object');
    762 
    763        var s = gluStrUtil.getPixelFormatName(format.format);
    764 
    765        if (format.unsizedType != gl.NONE)
    766            s += ' with type ' + gluStrUtil.getTypeName(format.unsizedType);
    767 
    768        return s;
    769    };
    770 
    771    /**
    772    * @typedef {{attPoint: number, bufType: number, format: glsFboUtil.ImageFormat}}
    773    */
    774    glsFboCompletenessTests.renderableParamsT;
    775 
    776    /**
    777    * @param {number} attPoint
    778    * @param {number} bufType
    779    * @param {glsFboUtil.ImageFormat} format
    780    * @return {glsFboCompletenessTests.renderableParamsT}
    781    */
    782    glsFboCompletenessTests.renderableParams = function(attPoint, bufType, format) {
    783        var ret = {
    784            attPoint: attPoint,
    785            bufType: bufType,
    786            format: format
    787        };
    788        return ret;
    789    };
    790    /**
    791    * @param {glsFboCompletenessTests.renderableParamsT} params
    792    * @param {WebGLRenderingContextBase=} gl
    793    * @return {string}
    794    */
    795    glsFboCompletenessTests.renderableParams.getName = function(params, gl) {
    796        return glsFboCompletenessTests.formatName(params.format, gl);
    797    };
    798    /**
    799    * @param {glsFboCompletenessTests.renderableParamsT} params
    800    * @param {WebGLRenderingContextBase=} gl
    801    * @return {string}
    802    */
    803    glsFboCompletenessTests.renderableParams.getDescription = function(params, gl) {
    804        return glsFboCompletenessTests.formatDesc(params.format, gl);
    805    };
    806 
    807    /**
    808    * @constructor
    809    * @extends {glsFboCompletenessTests.TestBase}
    810    * @param {string} name
    811    * @param {string} desc
    812    * @param {glsFboCompletenessTests.Context} ctx
    813    * @param {glsFboCompletenessTests.renderableParamsT} params
    814    */
    815    glsFboCompletenessTests.RenderableTest = function(name, desc, ctx, params) {
    816        glsFboCompletenessTests.TestBase.call(this, name, desc, params);
    817        this.m_ctx = ctx;
    818    };
    819    glsFboCompletenessTests.RenderableTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype);
    820    glsFboCompletenessTests.RenderableTest.prototype.constructor = glsFboCompletenessTests.RenderableTest;
    821 
    822    glsFboCompletenessTests.RenderableTest.prototype.build = function(builder, gl) {
    823        this.attachTargetToNew(this.m_params.attPoint, this.m_params.bufType, this.m_params.format, 64, 64, builder, gl);
    824        return true;
    825    };
    826 
    827    glsFboCompletenessTests.attTypeName = function(bufType, gl) {
    828        if (!(gl = gl || window.gl)) throw new Error('Invalid GL object');
    829        switch (bufType) {
    830            case gl.NONE: return 'none';
    831            case gl.RENDERBUFFER: return 'rbo';
    832            case gl.TEXTURE: return 'tex';
    833            default: break;
    834        }
    835        throw new Error('Impossible case');
    836    };
    837 
    838    /**
    839    * @typedef {{color0Kind: number, colornKind: number, depthKind: number, stencilKind: number}}
    840    */
    841    glsFboCompletenessTests.attachmentParamsT;
    842 
    843    /**
    844    * @param {number} color0Kind
    845    * @param {number} colornKind
    846    * @param {number} depthKind
    847    * @param {number} stencilKind
    848    * @return {glsFboCompletenessTests.attachmentParamsT}
    849    */
    850    glsFboCompletenessTests.attachmentParams = function(color0Kind, colornKind, depthKind, stencilKind) {
    851        var ret = {
    852            color0Kind: color0Kind,
    853            colornKind: colornKind,
    854            depthKind: depthKind,
    855            stencilKind: stencilKind
    856        };
    857        return ret;
    858    };
    859    /**
    860    * @param {glsFboCompletenessTests.attachmentParamsT} params
    861    * @param {WebGLRenderingContextBase=} gl
    862    * @return {string}
    863    */
    864    glsFboCompletenessTests.attachmentParams.getName = function(params, gl) {
    865        return (glsFboCompletenessTests.attTypeName(params.color0Kind, gl) + '_' +
    866                glsFboCompletenessTests.attTypeName(params.colornKind, gl) + '_' +
    867                glsFboCompletenessTests.attTypeName(params.depthKind, gl) + '_' +
    868                glsFboCompletenessTests.attTypeName(params.stencilKind, gl));
    869    };
    870    /**
    871    * @param {glsFboCompletenessTests.attachmentParamsT} params
    872    * @return {string}
    873    */
    874    glsFboCompletenessTests.attachmentParams.getDescription = glsFboCompletenessTests.attachmentParams.getName;
    875 
    876    /**
    877    * @constructor
    878    * @extends {glsFboCompletenessTests.TestBase}
    879    * @param {string} name
    880    * @param {string} desc
    881    * @param {glsFboCompletenessTests.Context} ctx
    882    * @param {glsFboCompletenessTests.attachmentParamsT} params
    883    */
    884    glsFboCompletenessTests.AttachmentTest = function(name, desc, ctx, params) {
    885        glsFboCompletenessTests.TestBase.call(this, name, desc, params);
    886        this.m_ctx = ctx;
    887    };
    888    glsFboCompletenessTests.AttachmentTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype);
    889    glsFboCompletenessTests.AttachmentTest.prototype.constructor = glsFboCompletenessTests.AttachmentTest;
    890 
    891    glsFboCompletenessTests.AttachmentTest.prototype.makeDepthAndStencil = function(builder, gl) {
    892 
    893        /** @type {glsFboUtil.Attachment} */
    894        var att = null;
    895 
    896        if (this.m_params.stencilKind == this.m_params.depthKind) {
    897            // If there is a common stencil+depth -format, try to use a common
    898            // image for both attachments.
    899            var flags = glsFboUtil.FormatFlags.DEPTH_RENDERABLE |
    900                        glsFboUtil.FormatFlags.STENCIL_RENDERABLE |
    901                        glsFboUtil.formatFlag(this.m_params.stencilKind, gl);
    902 
    903            var formats = this.m_ctx.getMinFormats().getFormats(flags);
    904            if (formats.length) {
    905                var format = formats[0];
    906                att = glsFboCompletenessTests.makeAttachment(this.m_params.depthKind, format, 64, 64, builder, gl);
    907                builder.glAttach(gl.DEPTH_ATTACHMENT, att);
    908                builder.glAttach(gl.STENCIL_ATTACHMENT, att);
    909                return;
    910            }
    911        }
    912        // Either the kinds were separate, or a suitable format was not found.
    913        // Create separate images.
    914        this.attachTargetToNew(gl.STENCIL_ATTACHMENT, this.m_params.stencilKind,
    915                               glsFboUtil.ImageFormat.none(), 64, 64, builder, gl);
    916        this.attachTargetToNew(gl.DEPTH_ATTACHMENT, this.m_params.depthKind,
    917                               glsFboUtil.ImageFormat.none(), 64, 64, builder, gl);
    918    };
    919 
    920    glsFboCompletenessTests.AttachmentTest.prototype.build = function(builder, gl) {
    921 
    922        this.attachTargetToNew(gl.COLOR_ATTACHMENT0, this.m_params.color0Kind,
    923                               glsFboUtil.ImageFormat.none(), 64, 64, builder, gl);
    924 
    925        if (this.m_params.colornKind != gl.NONE) {
    926            if (this.m_ctx.haveMultiColorAtts())
    927                throw new Error('Multiple attachments not supported');
    928            var maxAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
    929 
    930            for (var i = 1; i < maxAttachments; ++i) {
    931                this.attachTargetToNew(gl.COLOR_ATTACHMENT0 + i, this.m_params.colornKind,
    932                                       glsFboUtil.ImageFormat.none(), 64, 64, builder, gl);
    933            }
    934        }
    935 
    936        this.makeDepthAndStencil(builder, gl);
    937 
    938        return true;
    939    };
    940 
    941    /**
    942    * @constructor
    943    * @extends {glsFboCompletenessTests.TestBase}
    944    * @param {string} name
    945    * @param {string} desc
    946    * @param {glsFboCompletenessTests.Context} ctx
    947    */
    948    glsFboCompletenessTests.EmptyImageTest = function(name, desc, ctx) {
    949        glsFboCompletenessTests.TestBase.call(this, name, desc, null);
    950        this.m_ctx = ctx;
    951    };
    952    glsFboCompletenessTests.EmptyImageTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype);
    953    glsFboCompletenessTests.EmptyImageTest.prototype.constructor = glsFboCompletenessTests.EmptyImageTest;
    954 
    955    glsFboCompletenessTests.EmptyImageTest.prototype.build = function(builder, gl) {
    956        this.attachTargetToNew(gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER,
    957                               glsFboUtil.ImageFormat.none(), 0, 0, builder, gl);
    958        return true;
    959    };
    960 
    961 });